📄 dp83815.c
字号:
/* Macros */
/*
* SWAP_BUS_TO_CPU_XX and SWAP_CPU_TO_BUS_XX macros swap 16 and 32 bit values
* between the PCI bus' little endian byte-order and the CPU's native
* byte-order.
*/
#ifdef __BIG_ENDIAN
#define BUS_TO_CPU_SWAP_16(X) swap_16(X)
#define BUS_TO_CPU_SWAP_32(X) swap_32(X)
#define CPU_TO_BUS_SWAP_16(X) swap_16(X)
#define CPU_TO_BUS_SWAP_32(X) swap_32(X)
#define CPU_TO_NET_SWAP_16(X) ((u16)(X))
#define CPU_TO_NET_SWAP_32(X) ((u32)(X))
#define NET_TO_CPU_SWAP_16(X) ((u16)(X))
#define NET_TO_CPU_SWAP_32(X) ((u32)(X))
#else
#define BUS_TO_CPU_SWAP_32(X) ((u32)(X))
#define BUS_TO_CPU_SWAP_16(X) ((u16)(X))
#define CPU_TO_BUS_SWAP_32(X) ((u32)(X))
#define CPU_TO_BUS_SWAP_16(X) ((u16)(X))
#define CPU_TO_NET_SWAP_16(X) swap_16(X)
#define CPU_TO_NET_SWAP_32(X) swap_32(X)
#define NET_TO_CPU_SWAP_16(X) swap_16(X)
#define NET_TO_CPU_SWAP_32(X) swap_32(X)
#endif
/* Macros translate addresses between PCI bus and CPU */
#define BUS_TO_CPU_ADDR_XLATE(X) BUS_TO_CPU_SWAP_32(bus_to_virt(X))
#define CPU_TO_BUS_ADDR_XLATE(X) CPU_TO_BUS_SWAP_32(virt_to_bus(X))
/* Macros to read/write 32/16 bit data to/from DP83815 device registers. */
#define DP_REG32_WRITE(reg, val) io_write_32 (iobase+(reg), \
CPU_TO_BUS_SWAP_32(val))
#define DP_REG32_READ(reg) BUS_TO_CPU_SWAP_32(io_read_32 (iobase+(reg)))
#define DP_REG16_WRITE(reg, val) io_write_16 (iobase+(reg), \
CPU_TO_BUS_SWAP_16(val))
#define DP_REG16_READ(reg) BUS_TO_CPU_SWAP_16(io_read_16 (iobase+(reg)))
#define DP_REG32_SET(reg, val) DP_REG32_WRITE(reg,DP_REG32_READ(reg)|(val))
#define DP_REG32_CLR(reg, val) DP_REG32_WRITE(reg,DP_REG32_READ(reg)&~(val))
#define DP_REG16_SET(reg, val) DP_REG16_WRITE(reg,DP_REG16_READ(reg)|(val))
#define DP_REG16_CLR(reg, val) DP_REG16_WRITE(reg,DP_REG16_READ(reg)&~(val))
/* Debug Macros */
#define DP_DEBUG_PROBE 0x00000001
#define DP_DEBUG_OPEN 0x00000002
#define DP_DEBUG_CLOSE 0x00000004
#define DP_DEBUG_IOCTL 0x00000008
#define DP_DEBUG_TX 0x00000010
#define DP_DEBUG_RX 0x00000020
#define DP_DEBUG_MC 0x00000040
#define DP_DEBUG_ANEG 0x00000080
#define DP_DEBUG_INTR 0x00000100
#define DP_DEBUG_LOAD 0x00000200
#define DP_DEBUG_UNLOAD 0x00000400
#define DEBUG
#ifdef DEBUG
u32 dp_debug_level=0;
#define DP_DEBUG(level, X) if (level & dp_debug_level) printk X
#else
#define DP_DEBUG(level, X)
#endif
/* data types */
typedef u32 status; /* return status */
typedef volatile u8 * virt_addr; /* CPU virtual address */
typedef volatile u8 * bus_addr; /* BUS physical address */
typedef u8 bool;
#define OK 0 /* status: OK */
#define ERROR -1 /* status: ERROR */
#define TRUE 1
#define FALSE 0
#ifdef LINK_AGGR
#define DP_RX_DISABLE 0 /* disable rx engine */
#define DP_RX_ENABLE 1 /* enable rx engine */
#endif
/* Default Driver Parameters */
#define DP_DEFAULT_TXQ_SIZE 32
#define DP_DEFAULT_RXQ_SIZE 30
#define DP_RX_COPY_THRESHOLD 128 /* upper limit for rx packet copy */
#define DP_POLYNOMIAL 0x04C11DB6
/* Alignment and packet sizes */
#define ETH_CRC_LEN 4
#define ETH_MAX_PKT_SIZE (ETH_FRAME_LEN + ETH_CRC_LEN)
#define DP_ALIGN 4 /* word alignment */
/* Driver private descriptor macros */
#define DP_DESC_SKBPTR 0x0c /* SKB pointer offset */
#define DP_QUEUE_ELE_SIZE (DP_DESC_SIZE + 4)
#define DP_QUEUE_ELE_NEXT(q) \
q->cur_desc_addr = DP_QUEUE_ELE_NEXT_GET(q, q->cur_desc_addr)
#define DP_QUEUE_ELE_NEXT_GET(q, desc_addr) \
((desc_addr) == (q)->last_desc_addr) ? (q)->first_desc_addr : \
(desc_addr) + DP_QUEUE_ELE_SIZE
/* Macros to get/set the values of the descriptor fields */
#define DP_DESC_LNK_GET(ptr) *(u32 *)((virt_addr)ptr + DP_DESC_LNK)
#define DP_DESC_CMDSTS_GET(ptr) *(u32 *)((virt_addr)ptr + DP_DESC_CMDSTS)
#define DP_DESC_BUFPTR_GET(ptr) *(u32 *)((virt_addr)ptr + DP_DESC_BUFPTR)
#define DP_DESC_SKBPTR_GET(ptr) *(u32 *)((virt_addr)ptr + DP_DESC_SKBPTR)
#define DP_DESC_LNK_SET(ptr, val) DP_DESC_LNK_GET(ptr) = (val)
#define DP_DESC_CMDSTS_SET(ptr, val) DP_DESC_CMDSTS_GET(ptr) = (val)
#define DP_DESC_BUFPTR_SET(ptr,val) DP_DESC_BUFPTR_GET(ptr) = (val)
#define DP_DESC_SKBPTR_SET(ptr,val) DP_DESC_SKBPTR_GET(ptr) = (val)
/*
* Macros to get/set the values of descriptor fields with
* appropriate address and byte order translations
*/
#define DP_DESC_LNK_XLATE_GET(p) BUS_TO_CPU_ADDR_XLATE(DP_DESC_LNK_GET(p))
#define DP_DESC_CMDSTS_XLATE_GET(p) BUS_TO_CPU_SWAP_32(DP_DESC_CMDSTS_GET(p))
#define DP_DESC_BUFPTR_XLATE_GET(p) BUS_TO_CPU_ADDR_XLATE(DP_DESC_BUFPTR_GET(p))
#define DP_DESC_LNK_XLATE_SET(p, v) \
DP_DESC_LNK_SET(p, CPU_TO_BUS_ADDR_XLATE(v))
#define DP_DESC_CMDSTS_XLATE_SET(p, v) \
DP_DESC_CMDSTS_SET(p, CPU_TO_BUS_SWAP_32(v))
#define DP_DESC_BUFPTR_XLATE_SET(p,v) \
DP_DESC_BUFPTR_SET(p, CPU_TO_BUS_ADDR_XLATE(v))
/* FIFO Drain and Fill Threshold */
#define DP_TXCFG_FLTH_VAL 0x10
#define DP_TXCFG_DRTH_VAL 0x30
#define DP_RXCFG_DRTH_VAL 0x08
/* Descriptor queue */
struct dp83815_queue {
virt_addr first_desc_addr; /* descriptor array address */
virt_addr last_desc_addr; /* last descriptor address */
virt_addr cur_desc_addr; /* current descriptor address */
virt_addr read_desc_addr; /* current reclaim desc address */
virt_addr qbuf; /* allocated queue buffer */
u16 count; /* number of elements */
};
/* Queue types -- qtype */
#define DP_QUEUE_TYPE_TX 1 /* Transmit queue */
#define DP_QUEUE_TYPE_RX 2 /* Receive queue */
/* Device private data */
struct dp83815_priv {
struct net_device * next; /* Next dp83815device */
struct dp83815_queue tx_queue; /* Transmit Descriptor Queue */
struct dp83815_queue rx_queue; /* Receive Descriptor Queue */
struct net_device_stats stats; /* MIB data */
unsigned int fullduplex; /* half or full duplex */
unsigned int speed100; /* 10/100 MBps */
unsigned int tx_desc; /* number of transmit descriptor */
unsigned int rx_desc; /* number of receive descriptor */
unsigned int autoneg;
unsigned int PrevLinkSts;
#ifdef LINK_AGGR
struct NsmInfo NsmCtxt;
#endif
};
static struct net_device * dp83815_dev_list; /* List of dp83815devices */
/* Linux Network Driver interface routines */
extern int dp83815_probe (struct net_device *dev);
static int dp83815_open (struct net_device *dev);
static int dp83815_close (struct net_device *dev);
static int dp83815_start_xmit (struct sk_buff *skb, struct net_device *dev);
static int dp83815_start_receive (struct net_device *dev);
static void dp83815_set_multicast_list (struct net_device *dev);
static int dp83815_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
static void dp83815_interrupt (int irq, void *dev_id, struct pt_regs *regs);
static struct net_device_stats *dp83815_get_stats (struct net_device *dev);
/* Support Functions */
/*static u16 swap_16 (u16 us);*/
/*static u32 swap_32 (u32 ui);*/
static u32 io_read_32 (u16 io_port);
static void io_write_32 (u16 io_port, u32 data);
static u16 io_read_16 (u16 io_port);
static void io_write_16 (u16 io_port, u16 data);
/* Driver Private Routines */
#ifdef LINK_AGGR
static void dp83815_mac_address_set (AdapterContext *pAdp, char *mac_addr);
static status dp83815_dev_reset (AdapterContext *pAdp);
static UCHAR dp83815_send_packet (AdapterContext *pAdp, PktInfo *pPkt, int priority);
#else
static void dp83815_mac_address_set (u32 iobase, char *mac_addr);
static status dp83815_dev_reset (u32 iobase);
static int dp83815_send_packet (struct sk_buff *skb, struct net_device *dev);
#endif
static void dp83815_mac_address_get (u32 iobase, char *mac_addr);
static status dp83815_queue_create (struct dp83815_queue *q, int count, int qtype);
static status dp83815_queue_delete (struct dp83815_queue *q);
static virt_addr dp83815_tx_desc_get (struct net_device *dev);
static virt_addr dp83815_rx_desc_get (struct net_device *dev);
static status dp83815_phy_setup (struct net_device *dev);
static int dp83815_crc (char * mc_addr);
static void dp83815_tx_skb_reclaim_irq (struct net_device *dev, virt_addr desc_addr);
static void dp83815_eeprom_delay (u32 iobase);
static u16 dp83815_eeprom_read (u32 iobase, int addr);
/* Short Cable Fixed function */
void dp83815_PhyAdjust(struct net_device *);
void dp83815_PhyCoefAdjust(struct net_device *);
void dp83815_ResetPhy(struct net_device *);
/* LACP specific routines */
#ifdef LINK_AGGR
static void dp83815_rx_control (AdapterContext *pAdp, int flag);
static void dp83815_clear_mca_tbl (AdapterContext *pAdapter);
static unsigned char dp83815_multicast_delete (AdapterContext* pAdp, MultiList *pMulti);
static unsigned char dp83815_multicast_add (AdapterContext *pAdp, MultiList *pMulti, UCHAR ReloadFlag);
static void dp83815_IndicateLinkStatus (AdapterContext *pAdapter);
static unsigned char dp83815_setphy (AdapterContext *pAdapter, UINT PhysFlags, UINT SetSpeed);
static unsigned char dp83815_rxfilter (AdapterContext *pAdapter, UINT rxFilterFlag);
#endif
/* Driver Debug Routines */
#ifdef DEBUG
#if 0 /* not used */
static void dp83815_regs_info (u16 iobase);
#endif /* not used */
#endif
/* default driver parameters */
#define MAX_DEV 10 /* number of devices could be more */
unsigned int fullduplex[MAX_DEV] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
unsigned int speed100[MAX_DEV] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
unsigned int txdesc[MAX_DEV] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
unsigned int rxdesc[MAX_DEV] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
unsigned int autoneg[MAX_DEV] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
unsigned int debug = 0;
unsigned int atan = 1; // NSC20030123 for Atan Fix
/* Module description and parameters */
#ifdef MODULE
MODULE_DESCRIPTION("National Semiconductor DP83815 10/100 Ethernet Driver");
MODULE_PARM(fullduplex, "1-" __MODULE_STRING(MAX_DEV) "i");
MODULE_PARM(speed100, "1-" __MODULE_STRING(MAX_DEV) "i");
MODULE_PARM(autoneg, "1-" __MODULE_STRING(MAX_DEV) "i");
MODULE_PARM(txdesc, "1-" __MODULE_STRING(MAX_DEV) "i");
MODULE_PARM(rxdesc, "1-" __MODULE_STRING(MAX_DEV) "i");
MODULE_PARM(debug, "i");
MODULE_PARM(atan,"i"); // NSC20030123 for Atan Fix
#endif
/*
* dp83815_probe - enumerate the PCI bus for instances of DP83815
*
* This routine enumerates DP83815 ethernet devices on the PCI bus, and
* registers each DP83815 device found.
*/
int
dp83815_probe (struct net_device *dev)
{
int dev_count;
u8 bus;
u8 func;
u8 irq;
u32 iobase;
u32 version;
struct dp83815_priv *dev_priv;
#ifdef LINK_AGGR
NsmContext *pNsm = NULL;
AdapterContext *pAdp = NULL;
#endif
if (! pcibios_present())
return -ENODEV; /* No such device */
dev_count=0;
while (pcibios_find_device (PCI_VENDOR_ID_NS, PCI_VENDOR_ID_NS_83815,
dev_count, &bus, &func)
== PCIBIOS_SUCCESSFUL) {
/* Allocate, name the device and add to ethernet device list */
dev = init_etherdev(dev, sizeof (struct dp83815_priv));
if (dev == NULL) {
printk (KERN_INFO "%s: Failed to create device struct\n",
DP_DRV_NAME);
break;
}
#ifdef LINK_AGGR
pNsm = &((struct dp83815_priv *)(dev->priv))->NsmCtxt;
pNsm->dev = dev;
pAdp = &pNsm->AdpCtxt;
pAdp->pNsmContext = (void *)pNsm;
pAdp->MacStats.txOkCount = 0;
#endif
/* Read PCI Configuration Registers */
pcibios_read_config_byte (bus, func, PCI_INTERRUPT_LINE, &irq);
pcibios_read_config_dword (bus, func, PCI_BASE_ADDRESS_0, &iobase);
iobase &= PCI_BASE_ADDRESS_IO_MASK;
#ifdef LINK_AGGR
pAdp->RegAddr = (UCHAR *)iobase;
#endif
/* set the parameters for the driver */
dev_priv = (struct dp83815_priv *)dev->priv;
if (dev_count < MAX_DEV) {
if (autoneg[dev_count] != 0) {
dev_priv->autoneg = 1;
/* set the speed and duplex mode*/
if (speed100[dev_count] == 1) {
dev_priv->speed100 = 1;
dev_priv->fullduplex = 2;
}
else if (speed100[dev_count] == 0) {
dev_priv->speed100 = 0;
dev_priv->fullduplex = 2;
}
else {
dev_priv->speed100 = 2;
if (fullduplex[dev_count] == 0)
dev_priv->fullduplex = 0;
else
dev_priv->fullduplex = 2;
}
} else {
dev_priv->autoneg = 0;
/* set the speed */
if (speed100[dev_count] == 0)
dev_priv->speed100 = 0;
else
dev_priv->speed100 = 1;
/* set the duplex mode */
if (fullduplex[dev_count] == 1)
dev_priv->fullduplex = 1;
else
dev_priv->fullduplex = 0;
}
dev_priv->tx_desc = ((txdesc[dev_count] == -1) ?
DP_DEFAULT_TXQ_SIZE : txdesc[dev_count]);
dev_priv->rx_desc = ((rxdesc[dev_count] == -1) ?
DP_DEFAULT_RXQ_SIZE : rxdesc[dev_count]);
}
else {
dev_priv->autoneg = 1;
dev_priv->fullduplex = 2;
dev_priv->speed100 = 2;
dev_priv->tx_desc = DP_DEFAULT_TXQ_SIZE;
dev_priv->rx_desc = DP_DEFAULT_RXQ_SIZE;
}
#ifdef DEBUG
dp_debug_level = debug;
#endif
/* Put the device in a quiescent state */
#ifdef LINK_AGGR
if (dp83815_dev_reset (pAdp) != OK)
#else
if (dp83815_dev_reset (iobase) != OK)
#endif
{
printk (KERN_INFO "%s: Device Reset failed.\n",
DP_DRV_NAME);
kfree (dev);
continue; /* Try the next device */
}
/* Get the ethernet address */
dp83815_mac_address_get (iobase, dev->dev_addr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -