#ifndef _MYSON_H #define _MYSON_H /** @file * * Myson Technology network card driver * */ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include /** BAR size */ #define MYSON_BAR_SIZE 256 /** A packet descriptor */ struct myson_descriptor { /** Status */ uint32_t status; /** Control */ uint32_t control; /** Buffer start address */ uint32_t address; /** Next descriptor address */ uint32_t next; } __attribute__ (( packed )); /* Transmit status */ #define MYSON_TX_STAT_OWN 0x80000000UL /**< Owner */ #define MYSON_TX_STAT_ABORT 0x00002000UL /**< Abort */ #define MYSON_TX_STAT_CSL 0x00001000UL /**< Carrier sense lost */ /* Transmit control */ #define MYSON_TX_CTRL_IC 0x80000000UL /**< Interrupt control */ #define MYSON_TX_CTRL_LD 0x20000000UL /**< Last descriptor */ #define MYSON_TX_CTRL_FD 0x10000000UL /**< First descriptor */ #define MYSON_TX_CTRL_CRC 0x08000000UL /**< CRC append */ #define MYSON_TX_CTRL_PAD 0x04000000UL /**< Pad control */ #define MYSON_TX_CTRL_RTLC 0x02000000UL /**< Retry late collision */ #define MYSON_TX_CTRL_PKTS(x) ( (x) << 11 ) /**< Packet size */ #define MYSON_TX_CTRL_TBS(x) ( (x) << 0 ) /**< Transmit buffer size */ /* Receive status */ #define MYSON_RX_STAT_OWN 0x80000000UL /**< Owner */ #define MYSON_RX_STAT_FLNG(status) ( ( (status) >> 16 ) & 0xfff ) #define MYSON_RX_STAT_ES 0x00000080UL /**< Error summary */ /* Receive control */ #define MYSON_RX_CTRL_RBS(x) ( (x) << 0 ) /**< Receive buffer size */ /** Descriptor ring alignment */ #define MYSON_RING_ALIGN 4 /** Physical Address Register 0 */ #define MYSON_PAR0 0x00 /** Physical Address Register 4 */ #define MYSON_PAR4 0x04 /** Physical address */ union myson_physical_address { struct { uint32_t low; uint32_t high; } __attribute__ (( packed )) reg; uint8_t raw[ETH_ALEN]; }; /** Transmit and Receive Configuration Register */ #define MYSON_TCR_RCR 0x18 #define MYSON_TCR_TXS 0x80000000UL /**< Transmit status */ #define MYSON_TCR_TE 0x00040000UL /**< Transmit enable */ #define MYSON_RCR_RXS 0x00008000UL /**< Receive status */ #define MYSON_RCR_PROM 0x00000080UL /**< Promiscuous mode */ #define MYSON_RCR_AB 0x00000040UL /**< Accept broadcast */ #define MYSON_RCR_AM 0x00000020UL /**< Accept multicast */ #define MYSON_RCR_ARP 0x00000008UL /**< Accept runt packet */ #define MYSON_RCR_ALP 0x00000004UL /**< Accept long packet */ #define MYSON_RCR_RE 0x00000001UL /**< Receive enable */ /** Maximum time to wait for transmit and receive to be idle, in milliseconds */ #define MYSON_IDLE_MAX_WAIT_MS 100 /** Bus Command Register */ #define MYSON_BCR 0x1c #define MYSON_BCR_RLE 0x00000100UL /**< Read line enable */ #define MYSON_BCR_RME 0x00000080UL /**< Read multiple enable */ #define MYSON_BCR_WIE 0x00000040UL /**< Write and invalidate */ #define MYSON_BCR_PBL(x) ( (x) << 3 ) /**< Burst length */ #define MYSON_BCR_PBL_MASK MYSON_BCR_PBL ( 0x7 ) #define MYSON_BCR_PBL_DEFAULT MYSON_BCR_PBL ( 0x6 ) #define MYSON_BCR_SWR 0x00000001UL /**< Software reset */ /** Maximum time to wait for a reset, in milliseconds */ #define MYSON_RESET_MAX_WAIT_MS 100 /** Transmit Poll Demand Register */ #define MYSON_TXPDR 0x20 /** Receive Poll Demand Register */ #define MYSON_RXPDR 0x24 /** Transmit List Base Address */ #define MYSON_TXLBA 0x2c /** Number of transmit descriptors */ #define MYSON_NUM_TX_DESC 4 /** Receive List Base Address */ #define MYSON_RXLBA 0x30 /** Number of receive descriptors */ #define MYSON_NUM_RX_DESC 4 /** Receive buffer length */ #define MYSON_RX_MAX_LEN ( ETH_FRAME_LEN + 4 /* VLAN */ + 4 /* CRC */ ) /** Interrupt Status Register */ #define MYSON_ISR 0x34 #define MYSON_IRQ_TI 0x00000008UL /**< Transmit interrupt */ #define MYSON_IRQ_RI 0x00000004UL /**< Receive interrupt */ /** Number of I/O delays between ISR reads */ #define MYSON_ISR_IODELAY_COUNT 4 /** Interrupt Mask Register */ #define MYSON_IMR 0x38 /** Boot ROM / EEPROM / MII Management Register */ #define MYSON_ROM_MII 0x40 #define MYSON_ROM_AUTOLD 0x00100000UL /**< Auto load */ /** Maximum time to wait for a configuration reload, in milliseconds */ #define MYSON_AUTOLD_MAX_WAIT_MS 100 /** A Myson descriptor ring */ struct myson_ring { /** Descriptors */ struct myson_descriptor *desc; /** Producer index */ unsigned int prod; /** Consumer index */ unsigned int cons; /** Number of descriptors */ unsigned int count; /** Descriptor start address register */ unsigned int reg; }; /** * Initialise descriptor ring * * @v ring Descriptor ring * @v count Number of descriptors * @v reg Descriptor base address register */ static inline __attribute__ (( always_inline)) void myson_init_ring ( struct myson_ring *ring, unsigned int count, unsigned int reg ) { ring->count = count; ring->reg = reg; } /** A myson network card */ struct myson_nic { /** Registers */ void *regs; /** Transmit descriptor ring */ struct myson_ring tx; /** Receive descriptor ring */ struct myson_ring rx; /** Receive I/O buffers */ struct io_buffer *rx_iobuf[MYSON_NUM_RX_DESC]; }; /** * Check if card can access physical address * * @v address Physical address * @v address_ok Card can access physical address */ static inline __attribute__ (( always_inline )) int myson_address_ok ( physaddr_t address ) { /* In a 32-bit build, all addresses can be accessed */ if ( sizeof ( physaddr_t ) <= sizeof ( uint32_t ) ) return 1; /* Card can access all addresses below 4GB */ if ( ( address & ~0xffffffffULL ) == 0 ) return 1; return 0; } #endif /* _MYSON_H */