⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 8139too.c

📁 我实现的一个基于零拷贝技术高速捕包的原型代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    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 + -