Linux 网卡驱动
刺猬@http://blog.csdn.net/littlehedgehog
网上一位前辈写的,时至今日,代码很多编译通不过(主要是Linux 内核变化实在太快),我把代码移植到我的ubuntu 8.10下测试成功,里面也加上了我的注解。不过还有不少东西没有搞懂,手头上也没有相关的硬件资料,就一份Realtek 的datasheet。 TNND,后面要备考备荒,手头的事情只能放一放。
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/compiler.h>
- #include <linux/pci.h>
- #include <linux/init.h>
- #include <linux/ioport.h>
- #include <linux/netdevice.h>
- #include <linux/etherdevice.h>
- #include <linux/rtnetlink.h>
- #include <linux/delay.h>
- #include <linux/ethtool.h>
- #include <linux/completion.h>
- #include <linux/crc32.h>
- #include <linux/mii.h>
- #include <asm/io.h>
- #include <asm/uaccess.h>
- #include <asm/irq.h>
- #if defined(CONFIG_SH_DREAMCAST)
- #define RX_BUF_IDX 1 /* 16K ring */
- #else
- #define RX_BUF_IDX 2 /* 32K ring */
- #endif
- #define RX_BUF_LEN (8192 << RX_BUF_IDX)
- #define RX_BUF_PAD 16
- #define RX_BUF_WRAP_PAD 2048 /* spare padding to handle lack of packet wrap */
- #if RX_BUF_LEN == 65536
- #define RX_BUF_TOT_LEN RX_BUF_LEN
- #else
- #define RX_BUF_TOT_LEN (RX_BUF_LEN + RX_BUF_PAD + RX_BUF_WRAP_PAD)
- #endif
- typedef enum
- {
- RTL8139 = 0,
- RTL8129,
- } board_t;
- static struct pci_device_id xc_id[] =
- {
- {0x10ec, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
- {0x10ec, 0x8138, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
- {0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
- {0x1500, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
- {0x4033, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
- {0x1186, 0x1300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
- {0x1186, 0x1340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
- {0x13d1, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
- {0x1259, 0xa117, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
- {0x1259, 0xa11e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
- {0x14ea, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
- {0x14ea, 0xab07, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
- {0x11db, 0x1234, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
- {0x1432, 0x9130, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
- {0x02ac, 0x1012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
- {0x018a, 0x0106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
- {0x126c, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
- {0x1743, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
- {0x021b, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
- #ifdef CONFIG_SH_SECUREEDGE5410
- /* Bogus 8139 silicon reports 8129 without external PROM :-*/
- {0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
- #endif
- #ifdef CONFIG_8139TOO_8129
- {0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8129 },
- #endif
- {PCI_ANY_ID, 0x8139, 0x10ec, 0x8139, 0, 0, RTL8139 },
- {PCI_ANY_ID, 0x8139, 0x1186, 0x1300, 0, 0, RTL8139 },
- {PCI_ANY_ID, 0x8139, 0x13d1, 0xab06, 0, 0, RTL8139 },
- {0,}
- };
- MODULE_DEVICE_TABLE (pci,xc_id);
- enum RTL8139_registers
- {
- MAC0 = 0, /* Ethernet hardware address. */
- MAR0 = 8, /* Multicast filter. */
- TxStatus0 = 0x10, /* Transmit status (Four 32bit registers). */
- TxAddr0 = 0x20, /*物理地址*/
- RxBuf = 0x30, /*物理地址*/
- ChipCmd = 0x37,
- RxBufPtr = 0x38,
- IntrMask = 0x3C,
- IntrStatus = 0x3E,
- TxConfig = 0x40,
- RxConfig = 0x44,
- RxMissed = 0x4C,
- Cfg9346 = 0x50,
- Config1 = 0x52,
- Config3 = 0x59,
- Config4 = 0x5A,
- HltClk = 0x5B,
- MultiIntr = 0x5C,
- /*MII*/
- BasicModeCtrl = 0x62,
- BasicModeStatus = 0x64,
- NWayAdvert = 0x66,
- NWayLPAR = 0x68,
- NWayExpansion = 0x6A,
- /*MII*/
- CSCR = 0x74,
- };
- enum ChipCmdBits /*ChipCmd = 0x37 register*/
- {
- CmdReset = 0x10,/*chip重置*/
- CmdRxEnb = 0x08,/*开启读*/
- CmdTxEnb = 0x04,/*开启写*/
- RxBufEmpty = 0x01,/*如果设置这个位表示接收缓冲区为空*/
- };
- enum IntrStatusBits
- {
- PCIErr = 0x8000,
- PCSTimeout = 0x4000,
- RxFIFOOver = 0x40,
- RxUnderrun = 0x20,
- RxOverflow = 0x10,
- TxErr = 0x08,
- TxOK = 0x04,
- RxErr = 0x02,
- RxOK = 0x01,
- RxAckBits = RxFIFOOver | RxOverflow | RxOK,
- };
- static const u16 xc_intr_mask =
- PCIErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver |
- TxErr | TxOK | RxErr | RxOK;
- static const u16 xc_norx_intr_mask =/*不包含任何接收中断*/
- PCIErr | PCSTimeout | RxUnderrun | TxErr | TxOK | RxErr ;
- enum Config1Bits /*Config1 = 0x52*/
- {
- Cfg1_PM_Enable = 0x01,/*开启电源管理(cfg9346要设置为可写)*/
- LWAKE = 0x10,/*于Config4的LWPTN共同工作 同时设置为0为(active high)*/
- };
- enum Config3Bits /*Config3 = 0x59*/
- {
- Cfg3_Magic = (1 << 5), /* 1 = wake up on Magic Packet (tm) */
- };
- enum Config4Bits /*Config4 = 0x5A*/
- {
- LWPTN = (1 << 2),/*于Config1的LWAKE共同工作 同时设置为0为(active high)*/
- };
- enum Cfg9346Bits
- {
- Cfg9346_lock = 0x00,/*一般状态*/
- Cfg9346_Unlock = 0xC0,/*可写状态*/
- };
- enum TxStatusBits /*TxStatus0 = 0x10 共4个发送状态register 0x10-0x1f*/
- {
- TxHostOwns = 0x2000,
- TxUnderrun = 0x4000,/*在发送数据时如果,Tx FIFO耗尽时设置为1*/
- TxStatOK = 0x8000,/*发送数据成功*/
- TxOutOfWindow = 0x20000000,/*发生 "out of windown" 冲突*/
- TxAborted = 0x40000000,/*设置为1表示发送被中止,该位是只读的*/
- TxCarrierLost = 0x80000000,/*在发送数据包时,carrier丢失*/
- };
- /* Bits in RxConfig. */
- enum rx_mode_bits
- {
- AcceptErr = 0x20,
- AcceptRunt = 0x10,
- AcceptBroadcast = 0x08,
- AcceptMulticast = 0x04,
- AcceptMyPhys = 0x02,
- AcceptAllPhys = 0x01,
- };
- typedef enum
- {
- CH_8139 = 0,
- CH_8139_K,
- CH_8139A,
- CH_8139A_G,
- CH_8139B,