📄 e1000_main.c
字号:
dev->tx_eob = e1000_tx_eob; dev->tx_clean = e1000_tx_clean; dev->tx_queue = e1000_tx_queue; dev->tx_start = e1000_tx_start; dev->poll_off = e1000_poll_off; dev->poll_on = e1000_poll_on;#endif /* now map the phys addr into system space... */ /* * Map the PCI memory base address to a virtual address that can be used * for access by the driver. The amount of memory to be mapped will be * the E1000 register area. */ Adapter->HardwareVirtualAddress = (PE1000_REGISTERS) ioremap(pci_resource_start(pcid, 0), sizeof(E1000_REGISTERS)); if (Adapter->HardwareVirtualAddress == NULL) { /* * If the hardware register space can not be allocated, the driver * must fail to load. */ printk("e1000_probe ioremap failed\n"); /* this is a problem, if the first one inits OK but a secondary one * fails, what should you return? Now it will say the load was OK * but one or more boards may have failed to come up */ break; } bdp->mem_start = pci_resource_start(pcid, 0); if (e1000_debug_level >= 2) printk("memstart = 0x%p, virt_addr = 0x%p\n", (void *) bdp->mem_start, (void *) Adapter->HardwareVirtualAddress); e1000_init(bdp); /* Printout the board configuration */ e1000_print_brd_conf(bdp); /* init the basic stats stuff */ ClearHwStatsCounters(Adapter); /* Update the statistics needed by the upper */ UpdateStatsCounters(bdp); /* up the loop count( it's also the number of our boards found) */ loop_cnt++; if (e1000_debug_level >= 2) { printk("dev = 0x%p ", dev); printk(" priv = 0x%p\n", dev->priv); printk(" irq = 0x%x ", dev->irq); printk(" next = 0x%p ", dev->next); printk(" flags = 0x%x\n", dev->flags); printk(" bdp = 0x%p\n", bdp); printk(" irq_level = 0x%x\n", bdp->irq_level); } } /* end of pci_find_class while loop */ e1000boards = num_boards = loop_cnt; if (num_boards) return (0); else return (-ENODEV);}/* register e1000_probe as our initilization routine */module_init(e1000_probe);/* set some of the modules specific things here */#ifdef MODULEMODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");MODULE_DESCRIPTION("Intel(R) PRO/1000 Gigabit Ethernet driver");MODULE_PARM(TxDescriptors, "1-8i");MODULE_PARM(RxDescriptors, "1-8i");MODULE_PARM(Jumbo, "1-8i");MODULE_PARM(WaitForLink, "1-8i");MODULE_PARM(AutoNeg, "1-8i");MODULE_PARM(Speed, "1-8i");MODULE_PARM(ForceDuplex, "1-8i");MODULE_PARM(SBP, "1-8i");#endif/***************************************************************************** Name: cleanup_module** Description: This routine is an entry point into the driver.** This is a Linux required routine.** Author: IntelCorporation** Born on Date: 07/11/99** Arguments: * NONE** Returns:* It returns 0 and can not fail** Modification log:* Date Who Description* -------- --- -------------------------------------------------------- *****************************************************************************/intcleanup_module(void){ bd_config_t *bdp, *next_bdp; PADAPTER_STRUCT Adapter; device_t *dev, *next_dev; /* start looking at the first device */ if (e1000first) dev = e1000first->device; else return 0; if (e1000_debug_level >= 1) printk("cleanup_module: SOR, dev = 0x%p \n\n\n", dev); while (dev) {#ifdef CONFIG_PROC_FS e1000_remove_proc_dev(dev);#endif bdp = (bd_config_t *) dev->priv; next_bdp = bdp->bd_next; if (next_bdp) next_dev = next_bdp->device; else next_dev = NULL; Adapter = bdp->bddp; /* unregister this instance of the module */ if (e1000_debug_level >= 2) printk("--Cleanup, unreg_netdev\n"); unregister_netdev(dev); /* * Free the memory mapped area that is allocated to the E1000 hardware * registers */ if (e1000_debug_level >= 2) printk("--Cleanup, iounmap\n"); iounmap(Adapter->HardwareVirtualAddress); /* free the irq back to the system */#ifdef IANS kfree(bdp->iANSdata);#endif /* free up any memory here */ if (e1000_debug_level >= 2) printk("--Cleanup, e1000_dealloc_space\n"); e1000_dealloc_space(bdp); dev = next_dev; }#ifdef CONFIG_PROC_FS { struct proc_dir_entry *de; /* check if the subdir list is empty before removing e1000_proc_dir */ for (de = e1000_proc_dir->subdir; de; de = de->next) { /* ignore . and .. */ if (*(de->name) == '.') continue; break; } if (de) return 0; remove_proc_entry(ADAPTERS_PROC_DIR, proc_net); }#endif return (0);}/***************************************************************************** Name: e1000_check_options** Description: This routine does range checking on command line options.** Author: IntelCorporation** Born on Date: 03/28/2000** Arguments: * int board - board number to check values for** Returns:* None*****************************************************************************/static voide1000_check_options(int board){ /* Transmit Descriptor Count */ if (TxDescriptors[board] == -1) { TxDescriptors[board] = MAX_TCB; } else if ((TxDescriptors[board] > E1000_MAX_TXD) || (TxDescriptors[board] < E1000_MIN_TXD)) { printk("Invalid TxDescriptor count specified (%i)," " using default of %i\n", TxDescriptors[board], MAX_TCB); TxDescriptors[board] = MAX_TCB; } else { printk("Using specified value of %i TxDescriptors\n", TxDescriptors[board]); } /* Receive Descriptor Count */ if (RxDescriptors[board] == -1) { RxDescriptors[board] = MAX_RFD; } else if ((RxDescriptors[board] > E1000_MAX_RXD) || (RxDescriptors[board] < E1000_MIN_RXD)) { printk("Invalid RxDescriptor count specified (%i)," " using default of %i\n", RxDescriptors[board], MAX_RFD); RxDescriptors[board] = MAX_RFD; } else { printk("Using specified value of %i RxDescriptors\n", RxDescriptors[board]); } /* Jumbo Frame Enable */ if (Jumbo[board] == -1) { Jumbo[board] = 1; } else if ((Jumbo[board] > 1) || (Jumbo[board] < 0)) { printk("Invalid Jumbo specified (%i), using default of %i\n", Jumbo[board], 1); Jumbo[board] = 1; } else { printk("Jumbo Frames %s\n", Jumbo[board] == 1 ? "Enabled" : "Disabled"); } /* Wait for link at driver load */ if (WaitForLink[board] == -1) { WaitForLink[board] = 1; } else if ((WaitForLink[board] > 1) || (WaitForLink[board] < 0)) { printk("Invalid WaitForLink specified (%i), using default of %i\n", WaitForLink[board], 1); WaitForLink[board] = 1; } else { printk("WaitForLink %s\n", WaitForLink[board] == 1 ? "Enabled" : "Disabled"); } /* Forced Speed and Duplex */ switch (Speed[board]) { case -1: Speed[board] = 0; switch (ForceDuplex[board]) { case -1: ForceDuplex[board] = 0; break; case 0: printk("Speed and Duplex Autonegotiation Enabled\n"); break; case 1: printk("Warning: Half Duplex specified without Speed\n"); printk("Using Autonegotiation at Half Duplex only\n"); break; case 2: printk("Warning: Full Duplex specified without Speed\n"); printk("Using Autonegotiation at Full Duplex only\n"); break; default: printk("Invalid Duplex Specified (%i), Parameter Ignored\n", ForceDuplex[board]); ForceDuplex[board] = 0; printk("Speed and Duplex Autonegotiation Enabled\n"); } break; case 0: switch (ForceDuplex[board]) { case -1: case 0: printk("Speed and Duplex Autonegotiation Enabled\n"); ForceDuplex[board] = 0; break; case 1: printk("Warning: Half Duplex specified without Speed\n"); printk("Using Autonegotiation at Half Duplex only\n"); break; case 2: printk("Warning: Full Duplex specified without Speed\n"); printk("Using Autonegotiation at Full Duplex only\n"); break; default: printk("Invalid Duplex Specified (%i), Parameter Ignored\n", ForceDuplex[board]); ForceDuplex[board] = 0; printk("Speed and Duplex Autonegotiation Enabled\n"); } break; case 10: case 100: switch (ForceDuplex[board]) { case -1: case 0: printk("Warning: %i Mbps Speed specified without Duplex\n", Speed[board]); printk("Using Autonegotiation at %i Mbps only\n", Speed[board]); ForceDuplex[board] = 0; break; case 1: printk("Forcing to %i Mbps Half Duplex\n", Speed[board]); break; case 2: printk("Forcing to %i Mbps Full Duplex\n", Speed[board]); break; default: printk("Invalid Duplex Specified (%i), Parameter Ignored\n", ForceDuplex[board]); ForceDuplex[board] = 0; printk("Warning: %i Mbps Speed specified without Duplex\n", Speed[board]); printk("Using Autonegotiation at %i Mbps only\n", Speed[board]); } break; case 1000: switch (ForceDuplex[board]) { case -1: case 0: printk("Warning: 1000 Mbps Speed specified without Duplex\n"); printk("Using Autonegotiation at 1000 Mbps Full Duplex only\n"); ForceDuplex[board] = 0; break; case 1: printk("Warning: Half Duplex is not supported at 1000 Mbps\n"); printk("Using Autonegotiation at 1000 Mbps Full Duplex only\n"); break; case 2: printk("Using Autonegotiation at 1000 Mbps Full Duplex only\n"); break; default: printk("Invalid Duplex Specified (%i), Parameter Ignored\n", ForceDuplex[board]); ForceDuplex[board] = 0; printk("Warning: 1000 Mbps Speed specified without Duplex\n"); printk("Using Autonegotiation at 1000 Mbps Full Duplex only\n"); } break; default: printk("Invalid Speed Specified (%i), Parameter Ignored\n", Speed[board]); Speed[board] = 0; switch (ForceDuplex[board]) { case -1: case 0: printk("Speed and Duplex Autonegotiation Enabled\n"); ForceDuplex[board] = 0; break; case 1: printk("Warning: Half Duplex specified without Speed\n"); printk("Using Autonegotiation at Half Duplex only\n"); break; case 2: printk("Warning: Full Duplex specified without Speed\n"); printk("Using Autonegotiation at Full Duplex only\n"); break; default: printk("Invalid Duplex Specified (%i), Parameter Ignored\n", ForceDuplex[board]); ForceDuplex[board] = 0; printk("Speed and Duplex Autonegotiation Enabled\n"); } } if (AutoNeg[board] == -1) { AutoNeg[board] = 0x2F; } else { if (AutoNeg[board] & ~0x2F) { printk("Invalid AutoNeg Specified (0x%X)\n", AutoNeg[board]); AutoNeg[board] = 0x2F; } printk("AutoNeg Advertising "); if(AutoNeg[board] & 0x20) { printk("1000/FD"); if(AutoNeg[board] & 0x0F) printk(", "); } if(AutoNeg[board] & 0x08) { printk("100/FD"); if(AutoNeg[board] & 0x07) printk(", "); } if(AutoNeg[board] & 0x04) { printk("100/HD"); if(AutoNeg[board] & 0x03) printk(", "); } if(AutoNeg[board] & 0x02) { printk("10/FD"); if(AutoNeg[board] & 0x01) printk(", "); } if(AutoNeg[board] & 0x01) printk("10/HD"); printk("\n"); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -