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

📄 tulip_core.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 4 页
字号:
					   &tp->rx_ring_dma);	if (!tp->rx_ring)		goto err_out_free_mmio_res;	tp->tx_ring = (struct tulip_tx_desc *)(tp->rx_ring + RX_RING_SIZE);	tp->tx_ring_dma = tp->rx_ring_dma + sizeof(struct tulip_rx_desc) * RX_RING_SIZE;	tp->chip_id = chip_idx;	tp->flags = tulip_tbl[chip_idx].flags;	tp->pdev = pdev;	tp->base_addr = ioaddr;	tp->revision = chip_rev;	tp->csr0 = csr0;	spin_lock_init(&tp->lock);	dev->base_addr = ioaddr;	dev->irq = irq;	pci_set_drvdata(pdev, dev);#ifdef TULIP_FULL_DUPLEX	tp->full_duplex = 1;	tp->full_duplex_lock = 1;#endif#ifdef TULIP_DEFAULT_MEDIA	tp->default_port = TULIP_DEFAULT_MEDIA;#endif#ifdef TULIP_NO_MEDIA_SWITCH	tp->medialock = 1;#endif	printk(KERN_INFO "%s: %s rev %d at %#3lx,",		   dev->name, tulip_tbl[chip_idx].chip_name, chip_rev, ioaddr);	/* bugfix: the ASIX must have a burst limit or horrible things happen. */	if (chip_idx == AX88140) {		if ((tp->csr0 & 0x3f00) == 0)			tp->csr0 |= 0x2000;	}	else if (chip_idx == DC21143  &&  chip_rev == 65)		tp->csr0 &= ~0x01000000;	/* Stop the chip's Tx and Rx processes. */	tulip_stop_rxtx(tp, inl(ioaddr + CSR6));	/* Clear the missed-packet counter. */	inl(ioaddr + CSR8);	if (chip_idx == DC21041) {		if (inl(ioaddr + CSR9) & 0x8000) {			printk(" 21040 compatible mode,");			chip_idx = DC21040;		} else {			printk(" 21041 mode,");		}	}	/* The station address ROM is read byte serially.  The register must	   be polled, waiting for the value to be read bit serially from the	   EEPROM.	   */	sum = 0;	if (chip_idx == DC21040) {		outl(0, ioaddr + CSR9);		/* Reset the pointer with a dummy write. */		for (i = 0; i < 6; i++) {			int value, boguscnt = 100000;			do				value = inl(ioaddr + CSR9);			while (value < 0  && --boguscnt > 0);			dev->dev_addr[i] = value;			sum += value & 0xff;		}	} else if (chip_idx == LC82C168) {		for (i = 0; i < 3; i++) {			int value, boguscnt = 100000;			outl(0x600 | i, ioaddr + 0x98);			do				value = inl(ioaddr + CSR9);			while (value < 0  && --boguscnt > 0);			put_unaligned(le16_to_cpu(value), ((u16*)dev->dev_addr) + i);			sum += value & 0xffff;		}	} else if (chip_idx == COMET) {		/* No need to read the EEPROM. */		put_unaligned(inl(ioaddr + 0xA4), (u32 *)dev->dev_addr);		put_unaligned(inl(ioaddr + 0xA8), (u16 *)(dev->dev_addr + 4));		for (i = 0; i < 6; i ++)			sum += dev->dev_addr[i];	} else {		/* A serial EEPROM interface, we read now and sort it out later. */		int sa_offset = 0;		int ee_addr_size = tulip_read_eeprom(ioaddr, 0xff, 8) & 0x40000 ? 8 : 6;		for (i = 0; i < sizeof(ee_data)/2; i++)			((u16 *)ee_data)[i] =				le16_to_cpu(tulip_read_eeprom(ioaddr, i, ee_addr_size));		/* DEC now has a specification (see Notes) but early board makers		   just put the address in the first EEPROM locations. */		/* This does  memcmp(eedata, eedata+16, 8) */		for (i = 0; i < 8; i ++)			if (ee_data[i] != ee_data[16+i])				sa_offset = 20;		if (ee_data[0] == 0xff  &&  ee_data[1] == 0xff &&  ee_data[2] == 0) {			sa_offset = 2;		/* Grrr, damn Matrox boards. */			multiport_cnt = 4;		}		for (i = 0; i < 6; i ++) {			dev->dev_addr[i] = ee_data[i + sa_offset];			sum += ee_data[i + sa_offset];		}	}	/* Lite-On boards have the address byte-swapped. */	if ((dev->dev_addr[0] == 0xA0  ||  dev->dev_addr[0] == 0xC0)		&&  dev->dev_addr[1] == 0x00)		for (i = 0; i < 6; i+=2) {			char tmp = dev->dev_addr[i];			dev->dev_addr[i] = dev->dev_addr[i+1];			dev->dev_addr[i+1] = tmp;		}	/* On the Zynx 315 Etherarray and other multiport boards only the	   first Tulip has an EEPROM.	   The addresses of the subsequent ports are derived from the first.	   Many PCI BIOSes also incorrectly report the IRQ line, so we correct	   that here as well. */	if (sum == 0  || sum == 6*0xff) {		printk(" EEPROM not present,");		for (i = 0; i < 5; i++)			dev->dev_addr[i] = last_phys_addr[i];		dev->dev_addr[i] = last_phys_addr[i] + 1;#if defined(__i386__)		/* Patch up x86 BIOS bug. */		if (last_irq)			irq = last_irq;#endif	}	for (i = 0; i < 6; i++)		printk("%c%2.2X", i ? ':' : ' ', last_phys_addr[i] = dev->dev_addr[i]);	printk(", IRQ %d.\n", irq);	last_irq = irq;	/* The lower four bits are the media type. */	if (board_idx >= 0  &&  board_idx < MAX_UNITS) {		tp->default_port = options[board_idx] & 15;		if ((options[board_idx] & 0x90) || full_duplex[board_idx] > 0)			tp->full_duplex = 1;		if (mtu[board_idx] > 0)			dev->mtu = mtu[board_idx];	}	if (dev->mem_start)		tp->default_port = dev->mem_start;	if (tp->default_port) {		tp->medialock = 1;		if (tulip_media_cap[tp->default_port] & MediaAlwaysFD)			tp->full_duplex = 1;	}	if (tp->full_duplex)		tp->full_duplex_lock = 1;	if (tulip_media_cap[tp->default_port] & MediaIsMII) {		u16 media2advert[] = { 0x20, 0x40, 0x03e0, 0x60, 0x80, 0x100, 0x200 };		tp->to_advertise = media2advert[tp->default_port - 9];	} else if (tp->flags & HAS_8023X)		tp->to_advertise = 0x05e1;	else		tp->to_advertise = 0x01e1;	/* This is logically part of _init_one(), but too complex to write inline. */	if (tp->flags & HAS_MEDIA_TABLE) {		memcpy(tp->eeprom, ee_data, sizeof(tp->eeprom));		tulip_parse_eeprom(dev);	}	if ((tp->flags & ALWAYS_CHECK_MII) ||		(tp->mtable  &&  tp->mtable->has_mii) ||		( ! tp->mtable  &&  (tp->flags & HAS_MII))) {		int phy, phy_idx;		if (tp->mtable  &&  tp->mtable->has_mii) {			for (i = 0; i < tp->mtable->leafcount; i++)				if (tp->mtable->mleaf[i].media == 11) {					tp->cur_index = i;					tp->saved_if_port = dev->if_port;					tulip_select_media(dev, 1);					dev->if_port = tp->saved_if_port;					break;				}		}		/* Find the connected MII xcvrs.		   Doing this in open() would allow detecting external xcvrs later,		   but takes much time. */		for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < sizeof(tp->phys);			 phy++) {			int mii_status = tulip_mdio_read(dev, phy, 1);			if ((mii_status & 0x8301) == 0x8001 ||				((mii_status & 0x8000) == 0  && (mii_status & 0x7800) != 0)) {				int mii_reg0 = tulip_mdio_read(dev, phy, 0);				int mii_advert = tulip_mdio_read(dev, phy, 4);				int reg4 = ((mii_status>>6) & tp->to_advertise) | 1;				tp->phys[phy_idx] = phy;				tp->advertising[phy_idx++] = reg4;				printk(KERN_INFO "%s:  MII transceiver #%d "					   "config %4.4x status %4.4x advertising %4.4x.\n",					   dev->name, phy, mii_reg0, mii_status, mii_advert);				/* Fixup for DLink with miswired PHY. */				if (mii_advert != reg4) {					printk(KERN_DEBUG "%s:  Advertising %4.4x on PHY %d,"						   " previously advertising %4.4x.\n",						   dev->name, reg4, phy, mii_advert);					printk(KERN_DEBUG "%s:  Advertising %4.4x (to advertise"						   " is %4.4x).\n",						   dev->name, reg4, tp->to_advertise);					tulip_mdio_write(dev, phy, 4, reg4);				}				/* Enable autonegotiation: some boards default to off. */				tulip_mdio_write(dev, phy, 0, mii_reg0 |						   (tp->full_duplex ? 0x1100 : 0x1000) |						   (tulip_media_cap[tp->default_port]&MediaIs100 ? 0x2000:0));			}		}		tp->mii_cnt = phy_idx;		if (tp->mtable  &&  tp->mtable->has_mii  &&  phy_idx == 0) {			printk(KERN_INFO "%s: ***WARNING***: No MII transceiver found!\n",				   dev->name);			tp->phys[0] = 1;		}	}	/* The Tulip-specific entries in the device structure. */	dev->open = tulip_open;	dev->hard_start_xmit = tulip_start_xmit;	dev->tx_timeout = tulip_tx_timeout;	dev->watchdog_timeo = TX_TIMEOUT;	dev->stop = tulip_close;	dev->get_stats = tulip_get_stats;	dev->do_ioctl = private_ioctl;	dev->set_multicast_list = set_rx_mode;	if ((tp->flags & HAS_NWAY)  || tp->chip_id == DC21041)		tp->link_change = t21142_lnk_change;	else if (tp->flags & HAS_PNICNWAY)		tp->link_change = pnic_lnk_change;	/* Reset the xcvr interface and turn on heartbeat. */	switch (chip_idx) {	case DC21041:		tp->to_advertise = 0x0061;		outl(0x00000000, ioaddr + CSR13);		outl(0xFFFFFFFF, ioaddr + CSR14);		outl(0x00000008, ioaddr + CSR15); /* Listen on AUI also. */		tulip_outl_csr(tp, inl(ioaddr + CSR6) | csr6_fd, CSR6);		outl(0x0000EF05, ioaddr + CSR13);		break;	case DC21040:		outl(0x00000000, ioaddr + CSR13);		outl(0x00000004, ioaddr + CSR13);		break;	case DC21140:	case DM910X:	default:		if (tp->mtable)			outl(tp->mtable->csr12dir | 0x100, ioaddr + CSR12);		break;	case DC21142:	case PNIC2:		if (tp->mii_cnt  ||  tulip_media_cap[dev->if_port] & MediaIsMII) {			tulip_outl_csr(tp, csr6_mask_defstate, CSR6);			outl(0x0000, ioaddr + CSR13);			outl(0x0000, ioaddr + CSR14);			tulip_outl_csr(tp, csr6_mask_hdcap, CSR6);		} else			t21142_start_nway(dev);		break;	case LC82C168:		if ( ! tp->mii_cnt) {			tp->nway = 1;			tp->nwayset = 0;			tulip_outl_csr(tp, csr6_ttm | csr6_ca, CSR6);			outl(0x30, ioaddr + CSR12);			tulip_outl_csr(tp, 0x0001F078, CSR6);			tulip_outl_csr(tp, 0x0201F078, CSR6); /* Turn on autonegotiation. */		}		break;	case MX98713:	case COMPEX9881:		tulip_outl_csr(tp, 0x00000000, CSR6);		outl(0x000711C0, ioaddr + CSR14); /* Turn on NWay. */		outl(0x00000001, ioaddr + CSR13);		break;	case MX98715:	case MX98725:		tulip_outl_csr(tp, 0x01a80000, CSR6);		outl(0xFFFFFFFF, ioaddr + CSR14);		outl(0x00001000, ioaddr + CSR12);		break;	case COMET:		/* No initialization necessary. */		break;	}	/* put the chip in snooze mode until opened */	tulip_set_power_state (tp, 0, 1);	return 0;err_out_free_mmio_res:	release_mem_region (pci_resource_start (pdev, 1),			    pci_resource_len (pdev, 1));err_out_free_pio_res:	release_region (pci_resource_start (pdev, 0),			pci_resource_len (pdev, 0));err_out_free_netdev:	unregister_netdev (dev);	kfree (dev);	return -ENODEV;}static void tulip_suspend (struct pci_dev *pdev){	struct net_device *dev = pci_get_drvdata(pdev);	if (dev && netif_device_present (dev)) {		netif_device_detach (dev);		tulip_down (dev);		/* pci_power_off(pdev, -1); */	}}static void tulip_resume(struct pci_dev *pdev){	struct net_device *dev = pci_get_drvdata(pdev);#if 1	pci_enable_device (pdev);#endif	if (dev && !netif_device_present (dev)) {		/* pci_power_on(pdev); */		tulip_up (dev);		netif_device_attach (dev);	}}static void __devexit tulip_remove_one (struct pci_dev *pdev){	struct net_device *dev = pci_get_drvdata (pdev);	struct tulip_private *tp;	if (!dev)		return;	tp = dev->priv;	pci_free_consistent (pdev,			     sizeof (struct tulip_rx_desc) * RX_RING_SIZE +			     sizeof (struct tulip_tx_desc) * TX_RING_SIZE,			     tp->rx_ring, tp->rx_ring_dma);	unregister_netdev (dev);	release_mem_region (pci_resource_start (pdev, 1),			    pci_resource_len (pdev, 1));	release_region (pci_resource_start (pdev, 0),			pci_resource_len (pdev, 0));	if (tp->mtable)		kfree (tp->mtable);	kfree (dev);	pci_set_drvdata (pdev, NULL);	/* pci_power_off (pdev, -1); */}static struct pci_driver tulip_driver = {	name:		TULIP_MODULE_NAME,	id_table:	tulip_pci_tbl,	probe:		tulip_init_one,	remove:		tulip_remove_one,};static int __init tulip_init (void){	/* copy module parms into globals */	tulip_rx_copybreak = rx_copybreak;	tulip_max_interrupt_work = max_interrupt_work;	/* probe for and init boards */	return pci_module_init (&tulip_driver);}static void __exit tulip_cleanup (void){	pci_unregister_driver (&tulip_driver);}module_init(tulip_init);module_exit(tulip_cleanup);

⌨️ 快捷键说明

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