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

📄 8139too.c

📁 8139driver_in)linux2.4.x
💻 C
📖 第 1 页 / 共 5 页
字号:
	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		0xcb38de43static 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 */	},};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             6struct 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;	pid_t thr_pid;	wait_queue_head_t thr_wait;#if LINUX_VERSION_CODE < 0x20407	struct semaphore thr_exited;	#else	struct completion thr_exited;#endif  // 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];};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 rtl8139_thread (void *data);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);static int __devinit rtl8139_init_board (struct pci_dev *pdev,					 struct net_device **dev_out,					 void **ioaddr_out){	void *ioaddr = NULL;	struct net_device *dev;	struct rtl8139_private *tp;	u8 tmp8;	int rc, i;	u32 pio_start, pio_end, pio_flags, pio_len;	unsigned long mmio_start, mmio_end, mmio_flags, mmio_len;	u32 tmp; 	DPRINTK ("ENTER\n");	assert (pdev != NULL);	assert (ioaddr_out != NULL);	*ioaddr_out = NULL;	*dev_out = NULL;	/* dev zeroed in init_etherdev */	dev = init_etherdev (NULL, sizeof (*tp));	if (dev == NULL) {		printk (KERN_ERR PFX "unable to alloc new ethernet\n");		DPRINTK ("EXIT, returning -ENOMEM\n");		return -ENOMEM;	}	SET_MODULE_OWNER(dev);	tp = dev->priv;	/* enable device (incl. PCI PM wakeup and hotplug setup) */	rc = pci_enable_device (pdev);	if (rc)		goto err_out;	pio_start = pci_resource_start (pdev, 0);	pio_end = pci_resource_end (pdev, 0);	pio_flags = pci_resource_flags (pdev, 0);	pio_len = pci_resource_len (pdev, 0);	mmio_start = pci_resource_start (pdev, 1);	mmio_end = pci_resource_end (pdev, 1);	mmio_flags = pci_resource_flags (pdev, 1);	mmio_len = pci_resource_len (pdev, 1);	/* set this immediately, we need to know before	 * we talk to the chip directly */	DPRINTK("PIO region size == 0x%02X\n", pio_len);	DPRINTK("MMIO region size == 0x%02lX\n", mmio_len);	if (pio_len == RTL8139B_IO_SIZE)		tp->chipset = CH_8139B;	/* make sure PCI base addr 0 is PIO */	if (!(pio_flags & IORESOURCE_IO)) {		printk (KERN_ERR PFX "region #0 not a PIO resource, aborting\n");		rc = -ENODEV;		goto err_out;	}	/* make sure PCI base addr 1 is MMIO */	if (!(mmio_flags & IORESOURCE_MEM)) {		printk (KERN_ERR PFX "region #1 not an MMIO resource, aborting\n");		rc = -ENODEV;		goto err_out;	}	/* check for weird/broken PCI region reporting */	if ((pio_len < RTL_MIN_IO_SIZE) ||	    (mmio_len < RTL_MIN_IO_SIZE)) {		printk (KERN_ERR PFX "Invalid PCI region size(s), aborting\n");		rc = -ENODEV;		goto err_out;	}	rc = pci_request_regions (pdev, dev->name);	if (rc)		goto err_out;	/* enable PCI bus-mastering */	pci_set_master (pdev);#ifdef USE_IO_OPS	ioaddr = (void *) pio_start;#else	/* ioremap MMIO region */	ioaddr = ioremap (mmio_start, mmio_len);	if (ioaddr == NULL) {		printk (KERN_ERR PFX "cannot remap MMIO, aborting\n");		rc = -EIO;		goto err_out_free_res;	}#endif /* USE_IO_OPS */	/* Soft reset the chip. */	RTL_W8 (ChipCmd, (RTL_R8 (ChipCmd) & ChipCmdClear) | CmdReset);	/* Check that the chip has finished the reset. */	for (i = 1000; i > 0; i--)		if ((RTL_R8 (ChipCmd) & CmdReset) == 0)			break;		else			udelay (10);	/* Bring the chip out of low-power mode. */	if (tp->chipset == CH_8139B) {		RTL_W8 (Config1, RTL_R8 (Config1) & ~(1<<4));		RTL_W8 (Config4, RTL_R8 (Config4) & ~(1<<2));	} else {		/* handle RTL8139A and RTL8139 cases */		/* XXX from becker driver. is this right?? */		RTL_W8 (Config1, 0);	}	/* make sure chip thinks PIO and MMIO are enabled */	tmp8 = RTL_R8 (Config1);	if ((tmp8 & Cfg1_PIO) == 0) {		printk (KERN_ERR PFX "PIO not enabled, Cfg1=%02X, aborting\n", tmp8);		rc = -EIO;		goto err_out_iounmap;	}	if ((tmp8 & Cfg1_MMIO) == 0) {		printk (KERN_ERR PFX "MMIO not enabled, Cfg1=%02X, aborting\n", tmp8);		rc = -EIO;		goto err_out_iounmap;	}	/* identify chip attached to board *///	tmp = RTL_R8 (ChipVersion);	tmp = RTL_R32 (TxConfig);	tmp = ( (tmp&0x7c000000) + ( (tmp&0x00800000)<<2 ) )>>24;	for (i = ARRAY_SIZE (rtl_chip_info) - 1; i >= 0; i--)		if (tmp == rtl_chip_info[i].version) {			tp->chipset = i;			goto match;		}	/* if unknown chip, assume array element #0, original RTL-8139 in this case */	printk (KERN_DEBUG PFX "PCI device %s: unknown chip version, assuming RTL-8139\n",		pdev->slot_name);	printk (KERN_DEBUG PFX "PCI device %s: TxConfig = 0x%lx\n", pdev->slot_name, RTL_R32 (TxConfig));	tp->chipset = 0;match:#ifdef FORCE_CPlus_Mode	if(tp->chipset >= (ARRAY_SIZE (rtl_chip_info) - 2))			tp->chipset = ARRAY_SIZE (rtl_chip_info) - 1;#endif#ifdef FORCE_C_Mode	if(tp->chipset > (ARRAY_SIZE (rtl_chip_info) - 2))			tp->chipset = ARRAY_SIZE (rtl_chip_info) - 2;#endif	DPRINTK ("chipset id (%d) == index %d, '%s'\n",		tmp,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -