| #ifndef _MYSON_H | |
| #define _MYSON_H | |
| /** @file | |
| * | |
| * Myson Technology network card driver | |
| * | |
| */ | |
| FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); | |
| #include <stdint.h> | |
| #include <ipxe/if_ether.h> | |
| /** 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 */ |