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

📄 e100_main.c

📁 Linux* Base Driver for the Intel(R) PRO/100 Family of Adapters
💻 C
📖 第 1 页 / 共 5 页
字号:
		cpu_relax();		udelay(1);	}	return false;}/** * e100_wait_exec_simple - issue a command * @bdp: atapter's private data struct * @scb_cmd_low: the command that is to be issued * * This general routine will issue a command to the e100 after waiting for * the previous command to finish. * * Returns: *      true if the command was issued to the chip successfully *      false if the command was not issued to the chip */inline unsigned chare100_wait_exec_simple(struct e100_private *bdp, u8 scb_cmd_low){	if (!e100_wait_scb(bdp)) {		printk(KERN_DEBUG "e100: %s: e100_wait_exec_simple: failed\n",		       bdp->device->name);#ifdef E100_CU_DEBUG				printk(KERN_ERR "e100: %s: Last command (%x/%x) "			"timeout\n", bdp->device->name, 			bdp->last_cmd, bdp->last_sub_cmd);		printk(KERN_ERR "e100: %s: Current simple command (%x) "			"can't be executed\n", 			bdp->device->name, scb_cmd_low);#endif				return false;	}	e100_exec_cmd(bdp, scb_cmd_low);#ifdef E100_CU_DEBUG		bdp->last_cmd = scb_cmd_low;	bdp->last_sub_cmd = 0;#endif		return true;}voide100_exec_cmplx(struct e100_private *bdp, u32 phys_addr, u8 cmd){	writel(phys_addr, &(bdp->scb->scb_gen_ptr));	readw(&(bdp->scb->scb_status));	/* flushes last write, read-safe */	e100_exec_cmd(bdp, cmd);}unsigned chare100_wait_exec_cmplx(struct e100_private *bdp, u32 phys_addr, u8 cmd, u8 sub_cmd){	if (!e100_wait_scb(bdp)) {#ifdef E100_CU_DEBUG				printk(KERN_ERR "e100: %s: Last command (%x/%x) "			"timeout\n", bdp->device->name, 			bdp->last_cmd, bdp->last_sub_cmd);		printk(KERN_ERR "e100: %s: Current complex command "			"(%x/%x) can't be executed\n", 			bdp->device->name, cmd, sub_cmd);#endif				return false;	}	e100_exec_cmplx(bdp, phys_addr, cmd);#ifdef E100_CU_DEBUG		bdp->last_cmd = cmd;	bdp->last_sub_cmd = sub_cmd;#endif		return true;}inline u8e100_wait_cus_idle(struct e100_private *bdp){	int i;	/* loop on the scb for a few times */	for (i = 0; i < 100; i++) {		if (((readw(&(bdp->scb->scb_status)) & SCB_CUS_MASK) !=		     SCB_CUS_ACTIVE)) {			return true;		}		cpu_relax();	}	for (i = 0; i < E100_MAX_CU_IDLE_WAIT; i++) {		if (((readw(&(bdp->scb->scb_status)) & SCB_CUS_MASK) !=		     SCB_CUS_ACTIVE)) {			return true;		}		cpu_relax();		udelay(1);	}	return false;}/** * e100_disable_clear_intr - disable and clear/ack interrupts * @bdp: atapter's private data struct * * This routine disables interrupts at the hardware, by setting * the M (mask) bit in the adapter's CSR SCB command word. * It also clear/ack interrupts. */static inline voide100_disable_clear_intr(struct e100_private *bdp){	u16 intr_status;	/* Disable interrupts on our PCI board by setting the mask bit */	writeb(SCB_INT_MASK, &bdp->scb->scb_cmd_hi);	intr_status = readw(&bdp->scb->scb_status);	/* ack and clear intrs */	writew(intr_status, &bdp->scb->scb_status);	readw(&bdp->scb->scb_status);}/** * e100_set_intr_mask - set interrupts * @bdp: atapter's private data struct * * This routine sets interrupts at the hardware, by resetting * the M (mask) bit in the adapter's CSR SCB command word */static inline voide100_set_intr_mask(struct e100_private *bdp){	writeb(bdp->intr_mask, &bdp->scb->scb_cmd_hi);	readw(&(bdp->scb->scb_status)); /* flushes last write, read-safe */}static inline voide100_trigger_SWI(struct e100_private *bdp){	/* Trigger interrupt on our PCI board by asserting SWI bit */	writeb(SCB_SOFT_INT, &bdp->scb->scb_cmd_hi);	readw(&(bdp->scb->scb_status));	/* flushes last write, read-safe */}static int __devinite100_found1(struct pci_dev *pcid, const struct pci_device_id *ent){	static int first_time = true;	struct net_device *dev = NULL;	struct e100_private *bdp = NULL;	int rc = 0;	u16 cal_checksum, read_checksum;#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4)	dev = init_etherdev(NULL, sizeof (struct e100_private));#else	dev = alloc_etherdev(sizeof (struct e100_private));#endif	if (dev == NULL) {		printk(KERN_ERR "e100: Not able to alloc etherdev struct\n");		rc = -ENODEV;		goto out;	}	SET_MODULE_OWNER(dev);	if (first_time) {		first_time = false;        	printk(KERN_NOTICE "%s - version %s\n",	               e100_full_driver_name, e100_driver_version);		printk(KERN_NOTICE "%s\n", e100_copyright);		printk(KERN_NOTICE "\n");	}	bdp = dev->priv;	bdp->pdev = pcid;	bdp->device = dev;	pci_set_drvdata(pcid, dev);	SET_NETDEV_DEV(dev, &pcid->dev);	bdp->flags = 0;	bdp->ifs_state = 0;	bdp->ifs_value = 0;	bdp->scb = 0;	init_timer(&bdp->nontx_timer_id);	bdp->nontx_timer_id.data = (unsigned long) bdp;	bdp->nontx_timer_id.function = (void *) &e100_non_tx_background;	INIT_LIST_HEAD(&(bdp->non_tx_cmd_list));	bdp->non_tx_command_state = E100_NON_TX_IDLE;	init_timer(&bdp->watchdog_timer);	bdp->watchdog_timer.data = (unsigned long) dev;	bdp->watchdog_timer.function = (void *) &e100_watchdog;	if ((rc = e100_pci_setup(pcid, bdp)) != 0) {		goto err_dev;	}	if ((rc = e100_alloc_space(bdp)) != 0) {		goto err_pci;	}	if (((bdp->pdev->device > 0x1030)	       && (bdp->pdev->device < 0x103F))	    || ((bdp->pdev->device >= 0x1050)	       && (bdp->pdev->device <= 0x1057))	    || ((bdp->pdev->device >= 0x1064)	       && (bdp->pdev->device <= 0x106B))	    || (bdp->pdev->device == 0x2449)	    || (bdp->pdev->device == 0x2459)	    || (bdp->pdev->device == 0x245D)) {		bdp->rev_id = D101MA_REV_ID;	/* workaround for ICH3 */		bdp->flags |= IS_ICH;	}	if (bdp->rev_id == 0xff)		bdp->rev_id = 1;	if ((u8) bdp->rev_id >= D101A4_REV_ID)		bdp->flags |= IS_BACHELOR;	if ((u8) bdp->rev_id >= D102_REV_ID) {		bdp->flags |= USE_IPCB;		bdp->rfd_size = 32;	} else {		bdp->rfd_size = 16;	}#ifdef NETIF_F_HW_VLAN_TX	dev->vlan_rx_register = e100_vlan_rx_register;	dev->vlan_rx_add_vid = e100_vlan_rx_add_vid;	dev->vlan_rx_kill_vid = e100_vlan_rx_kill_vid;#endif	dev->irq = pcid->irq;	dev->open = &e100_open;	dev->hard_start_xmit = &e100_xmit_frame;	dev->stop = &e100_close;	dev->change_mtu = &e100_change_mtu;	dev->get_stats = &e100_get_stats;	dev->set_multicast_list = &e100_set_multi;	dev->set_mac_address = &e100_set_mac;	dev->do_ioctl = &e100_ioctl;#ifdef CONFIG_NET_POLL_CONTROLLER	dev->poll_controller = e100_netpoll;#endif#ifdef MAX_SKB_FRAGS	if (bdp->flags & USE_IPCB)#ifdef NETIF_F_HW_VLAN_TX	dev->features = NETIF_F_SG | NETIF_F_IP_CSUM |			NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;#else	dev->features = NETIF_F_SG | NETIF_F_IP_CSUM;#endif /* NETIF_F_HW_VLAN_TX */#endif /* MAX_SKB_FRAGS */		#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)	if ((rc = register_netdev(dev)) != 0) {		goto err_dealloc;	}#endif	e100_check_options(e100nics, bdp);	if (!e100_init(bdp)) {		printk(KERN_ERR "e100: Failed to initialize, instance #%d\n",		       e100nics);		rc = -ENODEV;		goto err_unregister_netdev;	}	/* Check if checksum is valid */	cal_checksum = e100_eeprom_calculate_chksum(bdp);	read_checksum = e100_eeprom_read(bdp, (bdp->eeprom_size - 1));	if (cal_checksum != read_checksum) {                printk(KERN_ERR "e100: Corrupted EEPROM on instance #%d\n",		       e100nics);                rc = -ENODEV;                goto err_unregister_netdev;	}		e100nics++;#ifdef SIOCETHTOOL	e100_get_speed_duplex_caps(bdp);#endif /*SIOCETHTOOL */	printk(KERN_NOTICE	       "e100: %s: %s\n", 	       bdp->device->name, "Intel(R) PRO/100 Network Connection");	e100_print_brd_conf(bdp);	bdp->wolsupported = 0;	bdp->wolopts = 0;	if (bdp->rev_id >= D101A4_REV_ID)		bdp->wolsupported = WAKE_PHY | WAKE_MAGIC;	if (bdp->rev_id >= D101MA_REV_ID)		bdp->wolsupported |= WAKE_UCAST | WAKE_ARP;		/* Check if WoL is enabled on EEPROM */	if (e100_eeprom_read(bdp, EEPROM_ID_WORD) & BIT_5) {		/* Magic Packet WoL is enabled on device by default */		/* if EEPROM WoL bit is TRUE                        */		bdp->wolopts = WAKE_MAGIC;	}#ifdef STB_WA	if (bdp->rev_id >= D101MA_REV_ID) {		u16 id_reg;		id_reg = e100_eeprom_read(bdp, EEPROM_ID_WORD);		if (id_reg & (0x02)) {			id_reg &= ((u16) (~0x02));			e100_eeprom_write_block(bdp, EEPROM_ID_WORD,						&id_reg, 1);			printk(KERN_NOTICE			       "e100: %s Changed the eeprom values\n", 			       dev->name);			printk(KERN_NOTICE			       "e100: for sane operation, "			       "a reboot is required\n");		}	}#endif	printk(KERN_NOTICE "\n");	goto out;err_unregister_netdev:	unregister_netdev(dev);err_dealloc:	e100_dealloc_space(bdp);err_pci:	iounmap(bdp->scb);	pci_release_regions(pcid);	pci_disable_device(pcid);err_dev:#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,4)	unregister_netdev(dev);#endif	pci_set_drvdata(pcid, NULL);	free_netdev(dev);out:	return rc;}/** * e100_clear_structs - free resources * @dev: adapter's net_device struct * * Free all device specific structs, unmap i/o address, etc. */static void __devexite100_clear_structs(struct net_device *dev){	struct e100_private *bdp = dev->priv;	iounmap(bdp->scb);	pci_release_regions(bdp->pdev);	pci_disable_device(bdp->pdev);	e100_dealloc_space(bdp);	pci_set_drvdata(bdp->pdev, NULL);	free_netdev(dev);}static void __devexite100_remove1(struct pci_dev *pcid){	struct net_device *dev;	struct e100_private *bdp;	if (!(dev = (struct net_device *) pci_get_drvdata(pcid)))		return;	bdp = dev->priv;	unregister_netdev(dev);	e100_sw_reset(bdp, PORT_SELECTIVE_RESET);	if (bdp->non_tx_command_state != E100_NON_TX_IDLE) {		del_timer_sync(&bdp->nontx_timer_id);		e100_free_nontx_list(bdp);		bdp->non_tx_command_state = E100_NON_TX_IDLE;	}	e100_clear_structs(dev);	--e100nics;}static struct pci_device_id e100_id_table[] = {	{0x8086, 0x1229, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x2449, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x1059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x1209, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },  	{0x8086, 0x1029, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x1030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },		{0x8086, 0x1031, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, 	{0x8086, 0x1032, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x1033, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, 	{0x8086, 0x1034, PCI_ANY_ID, PCI_ANY_ID, 0, 0, }, 	{0x8086, 0x1038, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x1039, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x103A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x103B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x103C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x103D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x103E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x1050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x1051, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x1052, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x1053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x1054, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x1055, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x1064, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x1065, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x1066, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x1067, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x1068, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x1069, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x106A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x106B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x2459, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0x8086, 0x245D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, },	{0,} /* This has to be the last entry*/};MODULE_DEVICE_TABLE(pci, e100_id_table);static struct pci_driver e100_driver = {	.name         = "e100",	.id_table     = e100_id_table,	.probe        = e100_found1,	.remove       = __devexit_p(e100_remove1),#ifdef CONFIG_PM	.suspend      = e100_suspend,	.resume       = e100_resume,#endif};#ifdef E100_IA64_DMA_FIXstatic int non_DMA32_memory_present;#endifstatic int __inite100_init_module(void){	int ret;#ifdef E100_IA64_DMA_FIX	struct sysinfo si;	si_meminfo(&si);	if (si.totalram >= (0x100000000UL) / PAGE_SIZE) {		non_DMA32_memory_present = 1;	} else {		non_DMA32_memory_present = 0;	}#endif        ret = pci_module_init(&e100_driver);

⌨️ 快捷键说明

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