改写drivers/net/8139too.c(1)
改写drivers/net/8139too.c,虽说是改写,只是对8139too的代码进行了剪裁。
由原来的2600多行,减少到现在的800多行,但基本功能依然保留,这样有兴趣的朋友分析起来较方便。
#include <linux/config.h>
#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,
CH_8130,
CH_8139C,
CH_8100,
CH_8100B_8139D,/*网卡类型*/
CH_8101,
} chip_t;
enum chip_flags {
HasHltClk = (1 << 0),
HasLWake = (1 << 1),
};
#define HW_REVID(b30, b29, b28, b27, b26, b23, b22) \
(b30<<30 | b29<<29 | b28<<28 | b27<<27 | b26<<26 | b23<<23 | b22<<22)
#define HW_REVID_MASK HW_REVID(1, 1, 1, 1, 1, 1, 1)
static const struct {
const char *name;
u32 version; /* from RTL8139C/RTL8139D docs */
u32 flags;
} rtl_chip_info[] = {
{ "RTL-8139",HW_REVID(1, 0, 0, 0, 0, 0, 0),HasHltClk,},
{ "RTL-8139 rev K",HW_REVID(1, 1, 0, 0, 0, 0, 0),HasHltClk,},
{ "RTL-8139A",HW_REVID(1, 1, 1, 0, 0, 0, 0),HasHltClk,},
{ "RTL-8139A rev G",HW_REVID(1, 1, 1, 0, 0, 1, 0),HasHltClk,},
{ "RTL-8139B",HW_REVID(1, 1, 1, 1, 0, 0, 0),HasLWake,},
{ "RTL-8130",HW_REVID(1, 1, 1, 1, 1, 0, 0),HasLWake,},
{ "RTL-8139C",HW_REVID(1, 1, 1, 0, 1, 0, 0),HasLWake,},
{ "RTL-8100",HW_REVID(1, 1, 1, 1, 0, 1, 0),HasLWake,},
{ "RTL-8100B/8139D",HW_REVID(1, 1, 1, 0, 1, 0, 1),HasHltClk | HasLWake,},
{ "RTL-8101", HW_REVID(1, 1, 1, 0, 1, 1, 1),HasLWake,},
};
struct xc_priv
{
void __iomem *ioaddr;
spinlock_t lock;
spinlock_t rx_lock;
chip_t chipset;
struct pci_dev *pdev;
struct net_device_stats stats;
u32 rx_config;
unsigned char *rx_bufs;
unsigned int cur_rx;
dma_addr_t rx_bufs_dma;
unsigned int tx_flag;
unsigned long cur_tx;
unsigned long dirty_tx;
unsigned char *tx_bufs;
unsigned char *tx_buf[4];
dma_addr_t tx_bufs_dma;
/*MII define*/
u32 msg_enable;
unsigned int default_port : 4; /* Last dev->if_port value. */
signed char phys[4]; /* MII device addresses. */
struct mii_if_info mii;
/*MII*/
};
#if RX_BUF_IDX == 1
static const unsigned int xc_rx_config =
(1 << 11) | (1 << 7) | (7 << 13) | (7 << ;/*(1<<11) 16k-0x00002980*/
#elif RX_BUF_IDX == 2
static const unsigned int xc_rx_config =
(1 << 12) | (1 << 7) | (7 << 13) | (7 << ;/*(1<<12) 32k-0x00003180*/
#else
#error "Invalid configuration for 8139_RXBUF_IDX"
#endif
/*MII*/
static char mii_2_8139_map[8] = {
BasicModeCtrl,BasicModeStatus,0,0,
NWayAdvert,NWayLPAR,NWayExpansion,0
};/*一些于MII相关的8139register*/
static void xc_check_media(struct net_device *dev, unsigned int init_media)
{
struct xc_priv *tp = netdev_priv(dev);
if(tp->phys[0] >= 0)
mii_check_media(&tp->mii, netif_msg_link(tp), init_media);
}
static int mdio_read (struct net_device *dev, int phy_id, int location)
{
struct xc_priv *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->ioaddr;
return location < 8 && mii_2_8139_map[location] ?
ioread16(ioaddr+mii_2_8139_map[location]) : 0;
}
static void mdio_write(struct net_device *dev, int phy_id, int location,int value)
{
struct xc_priv *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->ioaddr;
if(location < 8 && mii_2_8139_map[location])
{
if(location == 0)
{
iowrite8(Cfg9346_Unlock,ioaddr+Cfg9346);
iowrite16(value,ioaddr+BasicModeCtrl);
iowrite8(Cfg9346_lock,ioaddr+Cfg9346);
}
else
iowrite32(value,ioaddr+mii_2_8139_map[location]);
}
}
/*MII*/
/*ethtool*/
static u32 xc_get_link(struct net_device *dev)
{
struct xc_priv *tp = netdev_priv(dev);
return mii_link_ok(&tp->mii);
}
static int xc_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
struct xc_priv *tp = netdev_priv(dev);
spin_lock_irq(&tp->lock);
mii_ethtool_gset(&tp->mii, cmd);
spin_unlock_irq(&tp->lock);
return 0;
}
static struct ethtool_ops xc_ethtool_ops = {
.get_settings = xc_get_settings,
.get_link = xc_get_link,
};
/*ethtool*/
文章来源CU社区:改写drivers/net/8139too.c
相关文章