📄 8139too.c
字号:
Cfg1_MMIO = 0x08,
Cfg1_LWAKE = 0x10,
Cfg1_Driver_Load = 0x20,
Cfg1_LED0 = 0x40,
Cfg1_LED1 = 0x80,
};
enum RxConfigBits {
/* Early Rx threshold, none or X/16 */
RxCfgEarlyRxNone = 0,
RxCfgEarlyRxShift = 24,
/* rx fifo threshold */
RxCfgFIFOShift = 13,
RxCfgFIFONone = (7 << RxCfgFIFOShift),
/* Max DMA burst */
RxCfgDMAShift = 8,
RxCfgDMAUnlimited = (7 << RxCfgDMAShift),
/* rx ring buffer length */
RxCfgRcv8K = 0,
RxCfgRcv16K = (1 << 11),
RxCfgRcv32K = (1 << 12),
RxCfgRcv64K = (1 << 11) | (1 << 12),
/* Disable packet wrap at end of Rx buffer */
RxNoWrap = (1 << 7),
};
/* Twister tuning parameters from RealTek.
Completely undocumented, but required to tune bad links. */
enum CSCRBits {
CSCR_LinkOKBit = 0x0400,
CSCR_LinkChangeBit = 0x0800,
CSCR_LinkStatusBits = 0x0f000,
CSCR_LinkDownOffCmd = 0x003c0,
CSCR_LinkDownCmd = 0x0f3c0,
};
enum Cfg9346Bits {
Cfg9346_Lock = 0x00,
Cfg9346_Unlock = 0xC0,
};
enum NegotiationBits {
AutoNegotiationEnable = 0x1000,
AutoNegotiationRestart = 0x0200,
AutoNegoAbility10half = 0x21,
AutoNegoAbility10full = 0x41,
AutoNegoAbility100half = 0x81,
AutoNegoAbility100full = 0x101,
};
enum MediaStatusBits {
DuplexMode = 0x0100, //in BasicModeControlRegister
Speed_10 = 0x08, //in Media Status Register
};
#define PARA78_default 0x78fa8388
#define PARA7c_default 0xcb38de43 /* param[0][3] */
#define PARA7c_xxx 0xcb38de43
static const unsigned long param[4][4] =
{
{
0xcb39de43, 0xcb39ce43, 0xfb38de03, 0xcb38de43
},
{0xcb39de43, 0xcb39ce43, 0xcb39ce83, 0xcb39ce83},
{0xcb39de43, 0xcb39ce43, 0xcb39ce83, 0xcb39ce83},
{0xbb39de43, 0xbb39ce43, 0xbb39ce83, 0xbb39ce83}
};
struct ring_info
{
struct sk_buff *skb;
dma_addr_t mapping;
};
typedef enum {
CH_8139 = 0,
CH_8139_K,
CH_8139A,
CH_8139B,
CH_8130,
CH_8139C,
CH_8139CP,
} chip_t;
/* directly indexed by chip_t, above */
const static struct
{
const char *name;
u8 version; /* from RTL8139C docs */
u32 RxConfigMask; /* should clear the bits supported by this chip */
}
rtl_chip_info[] = {
{ "RTL-8139",
0x40,
0xf0fe0040, /* XXX copied from RTL8139A, verify */
},
{ "RTL-8139 rev K",
0x60,
0xf0fe0040,
},
{ "RTL-8139A",
0x70,
0xf0fe0040,
},
{ "RTL-8139B",
0x78,
0xf0fc0040
},
{ "RTL-8130",
0x7C,
0xf0fe0040, /* XXX copied from RTL8139A, verify */
},
{ "RTL-8139C",
0x74,
0xf0fc0040, /* XXX copied from RTL8139B, verify */
},
{ "RTL-8139CP",
0x76,
0xf0fc0040, /* XXX copied from RTL8139B, verify */
},
{ "RTL-8101",
0x77,
0xf0fc0040, /* RTL8101 */
},
};
struct CPlusTxDesc
{
u32 status;
u32 vlan_tag;
u32 buf_addr;
u32 buf_Haddr;
};
struct CPlusRxDesc
{
u32 status;
u32 vlan_tag;
u32 buf_addr;
u32 buf_Haddr;
};
/********************************************************************** */
#define IP_PROTOCOL 0x0008 /* Network Byte order */
#define TCP_PROTOCOL 6
#define UDP_PROTOCOL 17
#define ADDRESS_LEN 6
struct ethernet_ii_header
{
uint8_t DestAddr[ADDRESS_LEN];
uint8_t SourceAddr[ADDRESS_LEN];
uint16_t TypeLength;
};
/********************************************************************** */
/* Internet Protocol Version 4 (IPV4) Header Definition */
/********************************************************************** */
typedef struct _ip_v4_header_
{
uint32_t HdrLength:
4, /* Network Byte order */
HdrVersion:
4, /* Network Byte order */
TOS:
8, /* Network Byte order */
Length:
16; /* Network Byte order */
union {
uint32_t IdThruOffset;
struct
{
uint32_t DatagramId:
16, FragOffset1:
5, /* Network Byte order */
MoreFragments:
1, NoFragment:
1, Reserved2:
1, FragOffset:
8;
}
Bits;
struct
{
uint32_t DatagramId:
16, FragsNFlags:
16; /* Network Byte order */
}
Fields;
} FragmentArea;
uint8_t TimeToLive;
uint8_t ProtocolCarried;
uint16_t Checksum;
union {
uint32_t SourceIPAddress;
struct
{
uint32_t SrcAddrLo:
16, /* Network Byte order */
SrcAddrHi:
16;
}
Fields;
struct
{
uint32_t OctA:
8, OctB:
8, OctC:
8, OctD:
8;
}
SFields;
} SrcAddr;
union {
uint32_t TargetIPAddress;
struct
{
uint32_t DestAddrLo:
16, /* Network Byte order */
DestAddrHi:
16;
}
Fields;
struct
{
uint32_t OctA:
8, OctB:
8, OctC:
8, OctD:
8;
}
DFields;
} DestAddr;
uint16_t IpOptions[20]; /* Maximum of 40 bytes (20 words) of IP options */
}
ip_v4_header;
/********************************************************************** */
struct rtl8139_private
{
void *mmio_addr;
int drv_flags;
struct pci_dev *pci_dev;
struct net_device_stats stats;
unsigned char *rx_ring;
unsigned int cur_rx; /* Index into the Rx buffer of next Rx pkt. */
unsigned int tx_flag;
unsigned long cur_tx;
unsigned long dirty_tx;
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
struct ring_info tx_info[NUM_TX_DESC];
unsigned char *tx_buf[NUM_TX_DESC]; /* Tx bounce buffers */
unsigned char *tx_bufs; /* Tx bounce buffer region. */
dma_addr_t rx_ring_dma;
dma_addr_t tx_bufs_dma;
signed char phys[4]; /* MII device addresses. */
u16 advertising; /* NWay media advertisement */
char twistie, twist_row, twist_col; /* Twister tune state. */
unsigned int full_duplex:
1; /* Full-duplex operation requested. */
unsigned int duplex_lock:
1;
unsigned int default_port:
4; /* Last dev->if_port value. */
unsigned int media2:
4; /* Secondary monitored media port. */
unsigned int medialock:
1; /* Don't sense media type. */
unsigned int mediasense:
1; /* Media sensing in progress. */
spinlock_t lock;
chip_t chipset;
// For 8139C+
int AutoNegoAbility;
unsigned long CP_cur_tx;
unsigned long CP_dirty_tx;
unsigned long CP_cur_rx;
unsigned char *TxDescArrays;
unsigned char *RxDescArrays;
struct CPlusTxDesc *TxDescArray;
struct CPlusRxDesc *RxDescArray;
unsigned char *RxBufferRings;
unsigned char *RxBufferRing[NUM_CP_RX_DESC]
;
struct sk_buff* Tx_skbuff[NUM_CP_TX_DESC];
atomic_t CRC32DoubleCheck_ERR;
#ifdef ZERO_COPY
queue_t *rx_q;
queue_t *free_q;
ulong *phy_addr_table;
#endif
};
MODULE_AUTHOR ("Jeff Garzik <jgarzik@mandrakesoft.com>");
MODULE_DESCRIPTION ("RealTek RTL-8139CP Fast Ethernet driver");
MODULE_PARM (multicast_filter_limit, "i");
MODULE_PARM (max_interrupt_work, "i");
MODULE_PARM (media, "1-" __MODULE_STRING(MAX_UNITS) "i");
MODULE_PARM (full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
static int read_eeprom (void *ioaddr, int location, int addr_len);
static int rtl8139CP_open (struct net_device *dev);
static int rtl8139CP_start_xmit (struct sk_buff *skb, struct net_device *dev);
static void rtl8139CP_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
static void rtl8139CP_init_ring (struct net_device *dev);
static void rtl8139CP_hw_start (struct net_device *dev);
static int rtl8139CP_close (struct net_device *dev);
static void rtl8139CP_tx_timeout (struct net_device *dev);
static int rtl8139_open (struct net_device *dev);
static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev);
static void rtl8139_interrupt (int irq, void *dev_instance, struct pt_regs *regs);
static void rtl8139_init_ring (struct net_device *dev);
static void rtl8139_hw_start (struct net_device *dev);
static int rtl8139_close (struct net_device *dev);
static void rtl8139_tx_timeout (struct net_device *dev);
static int mdio_read (struct net_device *dev, int phy_id, int location);
static void mdio_write (struct net_device *dev, int phy_id, int location, int val);
static int mii_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
static struct net_device_stats *rtl8139_get_stats (struct net_device *dev);
static inline u32 ether_crc (int length, unsigned char *data);
static void rtl8139_set_rx_mode (struct net_device *dev);
#ifdef USE_IO_OPS
#define RTL_R8(reg) inb (((unsigned long)ioaddr) + (reg))
#define RTL_R16(reg) inw (((unsigned long)ioaddr) + (reg))
#define RTL_R32(reg) ((unsigned long) inl (((unsigned long)ioaddr) + (reg)))
#define RTL_W8(reg, val8) outb ((val8), ((unsigned long)ioaddr) + (reg))
#define RTL_W16(reg, val16) outw ((val16), ((unsigned long)ioaddr) + (reg))
#define RTL_W32(reg, val32) outl ((val32), ((unsigned long)ioaddr) + (reg))
#define RTL_W8_F RTL_W8
#define RTL_W16_F RTL_W16
#define RTL_W32_F RTL_W32
#undef readb
#undef readw
#undef readl
#undef writeb
#undef writew
#undef writel
#define readb(addr) inb((unsigned long)(addr))
#define readw(addr) inw((unsigned long)(addr))
#define readl(addr) inl((unsigned long)(addr))
#define writeb(val,addr) outb((val),(unsigned long)(addr))
#define writew(val,addr) outw((val),(unsigned long)(addr))
#define writel(val,addr) outl((val),(unsigned long)(addr))
#else
/* write MMIO register, with flush */
/* Flush avoids rtl8139 bug w/ posted MMIO writes */
#define RTL_W8_F(reg, val8) do { writeb ((val8), ioaddr + (reg)); readb (ioaddr + (reg)); } while (0)
#define RTL_W16_F(reg, val16) do { writew ((val16), ioaddr + (reg)); readw (ioaddr + (reg)); } while (0)
#define RTL_W32_F(reg, val32) do { writel ((val32), ioaddr + (reg)); readl (ioaddr + (reg)); } while (0)
#if MMIO_FLUSH_AUDIT_COMPLETE
/* write MMIO register */
#define RTL_W8(reg, val8) writeb ((val8), ioaddr + (reg))
#define RTL_W16(reg, val16) writew ((val16), ioaddr + (reg))
#define RTL_W32(reg, val32) writel ((val32), ioaddr + (reg))
#else
/* write MMIO register, then flush */
#define RTL_W8 RTL_W8_F
#define RTL_W16 RTL_W16_F
#define RTL_W32 RTL_W32_F
#endif /* MMIO_FLUSH_AUDIT_COMPLETE */
/* read MMIO register */
#define RTL_R8(reg) readb (ioaddr + (reg))
#define RTL_R16(reg) readw (ioaddr + (reg))
#define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg)))
#endif /* USE_IO_OPS */
static const u16 rtl8139_intr_mask =
PCIErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver |
TxErr | TxOK | RxErr | RxOK;
static const unsigned int rtl8139_rx_config =
RxCfgEarlyRxNone | RxCfgRcv32K | RxNoWrap |
(RX_FIFO_THRESH << RxCfgFIFOShift) |
(RX_DMA_BURST << RxCfgDMAShift);
//==========================================================================================
unsigned long crc32_table[256];
#define CRC32_POLY 0x04c11db7
#define ReverseBit(data) ( ((data<<7)&0x80) | ((data<<5)&0x40) | ((data<<3)&0x20) | ((data<<1)&0x10) |\
((data>>1)&0x08) | ((data>>3)&0x04) | ((data>>5)&0x02) | ((data>>7)&0x01) )
//==========================================================================================
void init_crc32( struct net_device *dev )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -