201 lines
5.4 KiB
C
201 lines
5.4 KiB
C
|
#ifndef _MYSON_H
|
||
|
#define _MYSON_H
|
||
|
|
||
|
/** @file
|
||
|
*
|
||
|
* Myson Technology network card driver
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
FILE_LICENCE ( GPL2_OR_LATER );
|
||
|
|
||
|
#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 */
|