📄 e100_main.c
字号:
e100_exec_cmplx(bdp, phys_addr, cmd); 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_dis_intr - disable 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. */static inline voide100_dis_intr(struct e100_private *bdp){ /* Disable interrupts on our PCI board by setting the mask bit */ writeb(SCB_INT_MASK, &bdp->scb->scb_cmd_hi); readw(&(bdp->scb->scb_status)); /* flushes last write, read-safe */}/** * 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; dev = alloc_etherdev(sizeof (struct e100_private)); 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); if ((rc = e100_alloc_space(bdp)) != 0) { goto err_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; init_timer(&bdp->hwi_timer); bdp->hwi_timer.data = (unsigned long) dev; bdp->hwi_timer.function = (void *) &e100_do_hwi; if ((rc = e100_pci_setup(pcid, bdp)) != 0) { goto err_dealloc; } if (((bdp->pdev->device > 0x1030) && (bdp->pdev->device < 0x103F)) || (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; } e100_check_options(e100nics, bdp); if (!e100_init(bdp)) { printk(KERN_ERR "e100: Failed to initialize, instance #%d\n", e100nics); rc = -ENODEV; goto err_pci; } /* 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 EERPROM on instance #%d\n", e100nics); rc = -ENODEV; goto err_pci; } 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; if (bdp->flags & USE_IPCB) { dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; } e100nics++; e100_get_speed_duplex_caps(bdp); if ((rc = register_netdev(dev)) != 0) { goto err_pci; } memcpy(bdp->ifname, dev->name, IFNAMSIZ); bdp->ifname[IFNAMSIZ-1] = 0; bdp->device_type = ent->driver_data; printk(KERN_NOTICE "e100: %s: %s\n", bdp->device->name, e100_get_brand_msg(bdp)); e100_print_brd_conf(bdp); bdp->id_string = e100_get_brand_msg(bdp); e100_get_mdix_status(bdp); if (netif_carrier_ok(bdp->device)) bdp->cable_status = "Cable OK"; else { if (bdp->rev_id < D102_REV_ID) bdp->cable_status = "Not supported"; else bdp->cable_status = "Not available"; } if (e100_create_proc_subdir(bdp, bdp->ifname) < 0) { printk(KERN_ERR "e100: Failed to create proc dir for %s\n", bdp->device->name); } /* Disabling all WOLs as initialization */ bdp->wolsupported = 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; bdp->wolopts = WAKE_MAGIC; } printk(KERN_NOTICE "\n"); goto out;err_pci: iounmap(bdp->scb); pci_release_regions(pcid); pci_disable_device(pcid);err_dealloc: e100_dealloc_space(bdp);err_dev: pci_set_drvdata(pcid, NULL); kfree(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); kfree(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_remove_proc_subdir(bdp, bdp->ifname); 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;}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};static int __inite100_init_module(void){ int ret; ret = pci_module_init(&e100_driver); if(ret >= 0) {#ifdef CONFIG_PM register_reboot_notifier(&e100_notifier_reboot);#endif register_netdevice_notifier(&e100_notifier_netdev); } return ret;}static void __exite100_cleanup_module(void){#ifdef CONFIG_PM unregister_reboot_notifier(&e100_notifier_reboot);#endif unregister_netdevice_notifier(&e100_notifier_netdev); pci_unregister_driver(&e100_driver);}module_init(e100_init_module);module_exit(e100_cleanup_module);/** * e100_check_options - check command line options * @board: board number * @bdp: atapter's private data struct * * This routine does range checking on command-line options */void __devinite100_check_options(int board, struct e100_private *bdp){ if (board >= E100_MAX_NIC) { printk(KERN_NOTICE "e100: No configuration available for board #%d\n", board); printk(KERN_NOTICE "e100: Using defaults for all values\n"); board = E100_MAX_NIC; } e100_set_int_option(&(bdp->params.TxDescriptors), TxDescriptors[board], E100_MIN_TCB, E100_MAX_TCB, E100_DEFAULT_TCB, "TxDescriptor count"); e100_set_int_option(&(bdp->params.RxDescriptors), RxDescriptors[board], E100_MIN_RFD, E100_MAX_RFD, E100_DEFAULT_RFD, "RxDescriptor count"); e100_set_int_option(&(bdp->params.e100_speed_duplex), e100_speed_duplex[board], 0, 4, E100_DEFAULT_SPEED_DUPLEX, "speed/duplex mode"); e100_set_int_option(&(bdp->params.ber), ber[board], 0, ZLOCK_MAX_ERRORS, E100_DEFAULT_BER, "Bit Error Rate count"); e100_set_bool_option(bdp, XsumRX[board], PRM_XSUMRX, E100_DEFAULT_XSUM, "XsumRX value"); /* Default ucode value depended on controller revision */ if (bdp->rev_id >= D101MA_REV_ID) { e100_set_bool_option(bdp, ucode[board], PRM_UCODE, E100_DEFAULT_UCODE, "ucode value"); } else { e100_set_bool_option(bdp, ucode[board], PRM_UCODE, false, "ucode value"); } e100_set_bool_option(bdp, flow_control[board], PRM_FC, E100_DEFAULT_FC, "flow control value"); e100_set_bool_option(bdp, IFS[board], PRM_IFS, E100_DEFAULT_IFS, "IFS value"); e100_set_bool_option(bdp, BundleSmallFr[board], PRM_BUNDLE_SMALL, E100_DEFAULT_BUNDLE_SMALL_FR, "CPU saver bundle small frames value"); e100_set_int_option(&(bdp->params.IntDelay), IntDelay[board], 0x0, 0xFFFF, E100_DEFAULT_CPUSAVER_INTERRUPT_DELAY, "CPU saver interrupt delay value"); e100_set_int_option(&(bdp->params.BundleMax), BundleMax[board], 0x1, 0xFFFF, E100_DEFAULT_CPUSAVER_BUNDLE_MAX, "CPU saver bundle max value");}/** * e100_set_int_option - check and set an integer option * @option: a pointer to the relevant option field * @val: the value specified * @min: the minimum valid value * @max: the maximum valid value * @default_val: the default value * @name: the name of the option * * This routine does range checking on a command-line option. * If the option's value is '-1' use the specified default. * Otherwise, if the value is invalid, change it to the default. */void __devinite100_set_int_option(int *option, int val, int min, int max, int default_val, char *name){ if (val == -1) { /* no value specified. use default */ *option = default_val; } else if ((val < min) || (val > max)) { printk(KERN_NOTICE "e100: Invalid %s specified (%i). " "Valid range is %i-%i\n", name, val, min, max); printk(KERN_NOTICE "e100: Using default %s of %i\n", name, default_val); *option = default_val; } else { printk(KERN_INFO "e100: Using specified %s of %i\n", name, val); *option = val; }}/** * e100_set_bool_option - check and set a boolean option * @bdp: atapter's private data struct * @val: the value specified * @mask: the mask for the relevant option * @default_val: the default value * @name: the name of the option * * This routine checks a boolean command-line option. * If the option's value is '-1' use the specified default. * Otherwise, if the value is invalid (not 0 or 1), * change it to the default. */void __devinite100_set_bool_option(struct e100_private *bdp, int val, u32 mask, int default_val, char *name){ if (val == -1) { if (default_val) bdp->params.b_params |= mask; } else if ((val != true) && (val != false)) { printk(KERN_NOTICE "e100: Invalid %s specified (%i). " "Valid values are %i/%i\n", name, val, false, true); printk(KERN_NOTICE "e100: Using default %s of %i\n", name, default_val); if (default_val) bdp->params.b_params |= mask; } else { printk(KERN_INFO "e100: Using specified %s of %i\n", name, val); if (val) bdp->params.b_params |= mask; }}static int
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -