📄 acenic_np.c
字号:
#define RX_PANIC_MINI_REFILL (3*RX_PANIC_MINI_THRES)/2#define RX_LOW_MINI_THRES (3*RX_MINI_SIZE)/4#define RX_PANIC_JUMBO_THRES 6#define RX_PANIC_JUMBO_REFILL (3*RX_PANIC_JUMBO_THRES)/2#define RX_LOW_JUMBO_THRES (3*RX_JUMBO_SIZE)/4/* * Size of the mini ring entries, basically these just should be big * enough to take TCP ACKs */#define ACE_MINI_SIZE 100#define ACE_MINI_BUFSIZE (ACE_MINI_SIZE + 2 + 16)#define ACE_STD_BUFSIZE (ACE_STD_MTU + ETH_HLEN + 2+4+16)#define ACE_JUMBO_BUFSIZE (ACE_JUMBO_MTU + ETH_HLEN + 2+4+16)/* * There seems to be a magic difference in the effect between 995 and 996 * but little difference between 900 and 995 ... no idea why. * * There is now a default set of tuning parameters which is set, depending * on whether or not the user enables Jumbo frames. It's assumed that if * Jumbo frames are enabled, the user wants optimal tuning for that case. */#define DEF_TX_COAL 400 /* 996 */#define DEF_TX_MAX_DESC 40//#define DEF_RX_COAL 120 /* 1000 */#define DEF_RX_COAL 1000 /* XXX IAP *///#define DEF_RX_MAX_DESC 25#define DEF_RX_MAX_DESC (RX_RING_SIZE/2) /* XXX IAP */#define DEF_TX_RATIO 21 /* 24 */#define DEF_JUMBO_TX_COAL 20#define DEF_JUMBO_TX_MAX_DESC 60#define DEF_JUMBO_RX_COAL 30#define DEF_JUMBO_RX_MAX_DESC 6#define DEF_JUMBO_TX_RATIO 21#define TX_COAL_INTS_ONLY 0 /* seems not worth it */#define DEF_TRACE 0#define DEF_STAT (2 * TICKS_PER_SEC)static int link[ACE_MAX_MOD_PARMS];static int trace[ACE_MAX_MOD_PARMS];static int tx_coal_tick[ACE_MAX_MOD_PARMS];static int rx_coal_tick[ACE_MAX_MOD_PARMS];static int max_tx_desc[ACE_MAX_MOD_PARMS];static int max_rx_desc[ACE_MAX_MOD_PARMS];static int tx_ratio[ACE_MAX_MOD_PARMS];static int dis_pci_mem_inval[ACE_MAX_MOD_PARMS] = {1, 1, 1, 1, 1, 1, 1, 1};static char version[] __initdata = "acenic.c: v0.50 02/02/2001 Jes Sorensen, linux-acenic@SunSITE.dk\n" " http://home.cern.ch/~jes/gige/acenic.html\n";static struct net_device *root_dev;static int probed __initdata = 0;int __devinit acenic_probe (ACE_PROBE_ARG){#ifdef NEW_NETINIT struct net_device *dev;#endif struct ace_private *ap; struct pci_dev *pdev = NULL; int boards_found = 0; int version_disp; if (probed) return -ENODEV; probed++; if (!pci_present()) /* is PCI support present? */ return -ENODEV; version_disp = 0; while ((pdev = pci_find_class(PCI_CLASS_NETWORK_ETHERNET<<8, pdev))) { if (!((pdev->vendor == PCI_VENDOR_ID_ALTEON) && ((pdev->device == PCI_DEVICE_ID_ALTEON_ACENIC_FIBRE) || (pdev->device == PCI_DEVICE_ID_ALTEON_ACENIC_COPPER)))&& !((pdev->vendor == PCI_VENDOR_ID_3COM) && (pdev->device == PCI_DEVICE_ID_3COM_3C985)) && !((pdev->vendor == PCI_VENDOR_ID_NETGEAR) && ((pdev->device == PCI_DEVICE_ID_NETGEAR_GA620) || (pdev->device == PCI_DEVICE_ID_NETGEAR_GA620T))) && /* * Farallon used the DEC vendor ID on their cards by * mistake for a while */ !((pdev->vendor == PCI_VENDOR_ID_DEC) && (pdev->device == PCI_DEVICE_ID_FARALLON_PN9000SX)) && !((pdev->vendor == PCI_VENDOR_ID_SGI) && (pdev->device == PCI_DEVICE_ID_SGI_ACENIC))) continue; dev = init_etherdev(NULL, sizeof(struct ace_private)); if (dev == NULL) { printk(KERN_ERR "acenic: Unable to allocate " "net_device structure!\n"); break; } SET_MODULE_OWNER(dev); if (!dev->priv) dev->priv = kmalloc(sizeof(*ap), GFP_KERNEL); if (!dev->priv) { printk(KERN_ERR "acenic: Unable to allocate memory\n"); return -ENOMEM; } ap = dev->priv; ap->pdev = pdev; dev->irq = pdev->irq; dev->open = &ace_open; dev->hard_start_xmit = &ace_start_xmit; dev->stop = &ace_close; dev->get_stats = &ace_get_stats; dev->set_multicast_list = &ace_set_multicast_list; dev->do_ioctl = &ace_ioctl; dev->set_mac_address = &ace_set_mac_addr; dev->change_mtu = &ace_change_mtu; /* display version info if adapter is found */ if (!version_disp) { /* set display flag to TRUE so that */ /* we only display this string ONCE */ version_disp = 1; printk(version); } /* * Enable master mode before we start playing with the * pci_command word since pci_set_master() will modify * it. */ pci_set_master(pdev); pci_read_config_word(pdev, PCI_COMMAND, &ap->pci_command); /* OpenFirmware on Mac's does not set this - DOH.. */ if (!(ap->pci_command & PCI_COMMAND_MEMORY)) { printk(KERN_INFO "%s: Enabling PCI Memory Mapped " "access - was not enabled by BIOS/Firmware\n", dev->name); ap->pci_command = ap->pci_command | PCI_COMMAND_MEMORY; pci_write_config_word(ap->pdev, PCI_COMMAND, ap->pci_command); wmb(); } pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &ap->pci_latency); if (ap->pci_latency <= 0x40) { ap->pci_latency = 0x40; pci_write_config_byte(pdev, PCI_LATENCY_TIMER, ap->pci_latency); } /* * Remap the regs into kernel space - this is abuse of * dev->base_addr since it was means for I/O port * addresses but who gives a damn. */ dev->base_addr = pci_resource_start(pdev, 0); ap->regs = (struct ace_regs *) __ioremap(dev->base_addr, 0x4000, _PAGE_USER ); if (!ap->regs) { printk(KERN_ERR "%s: Unable to map I/O register, " "AceNIC %i will be disabled.\n", dev->name, boards_found); break; } switch(pdev->vendor) { case PCI_VENDOR_ID_ALTEON: strncpy(ap->name, "AceNIC Gigabit Ethernet", sizeof (ap->name)); printk(KERN_INFO "%s: Alteon AceNIC ", dev->name); break; case PCI_VENDOR_ID_3COM: strncpy(ap->name, "3Com 3C985 Gigabit Ethernet", sizeof (ap->name)); printk(KERN_INFO "%s: 3Com 3C985 ", dev->name); break; case PCI_VENDOR_ID_NETGEAR: strncpy(ap->name, "NetGear GA620 Gigabit Ethernet", sizeof (ap->name)); printk(KERN_INFO "%s: NetGear GA620 ", dev->name); break; case PCI_VENDOR_ID_DEC: if (pdev->device == PCI_DEVICE_ID_FARALLON_PN9000SX) { strncpy(ap->name, "Farallon PN9000-SX " "Gigabit Ethernet", sizeof (ap->name)); printk(KERN_INFO "%s: Farallon PN9000-SX ", dev->name); break; } case PCI_VENDOR_ID_SGI: strncpy(ap->name, "SGI AceNIC Gigabit Ethernet", sizeof (ap->name)); printk(KERN_INFO "%s: SGI AceNIC ", dev->name); break; default: strncpy(ap->name, "Unknown AceNIC based Gigabit " "Ethernet", sizeof (ap->name)); printk(KERN_INFO "%s: Unknown AceNIC ", dev->name); break; } ap->name [sizeof (ap->name) - 1] = '\0'; printk("Gigabit Ethernet at 0x%08lx, ", dev->base_addr);#ifdef __sparc__ printk("irq %s\n", __irq_itoa(dev->irq));#else printk("irq %i\n", dev->irq);#endif#ifdef CONFIG_ACENIC_OMIT_TIGON_I if ((readl(&ap->regs->HostCtrl) >> 28) == 4) { printk(KERN_ERR "%s: Driver compiled without Tigon I" " support - NIC disabled\n", dev->name); ace_init_cleanup(dev); kfree(dev); continue; }#endif if (ace_allocate_descriptors(dev)) { /* * ace_allocate_descriptors() calls * ace_init_cleanup() on error. */ kfree(dev); continue; }#ifdef MODULE if (boards_found >= ACE_MAX_MOD_PARMS) ap->board_idx = BOARD_IDX_OVERFLOW; else ap->board_idx = boards_found;#else ap->board_idx = BOARD_IDX_STATIC;#endif if (ace_init(dev)) { /* * ace_init() calls ace_init_cleanup() on error. */ kfree(dev); continue; } boards_found++; } /* * If we're at this point we're going through ace_probe() for * the first time. Return success (0) if we've initialized 1 * or more boards. Otherwise, return failure (-ENODEV). */ if (boards_found > 0) return 0; else return -ENODEV;}#ifdef MODULEMODULE_AUTHOR("Jes Sorensen <jes@linuxcare.com>");MODULE_DESCRIPTION("AceNIC/3C985/GA620 Gigabit Ethernet driver");MODULE_PARM(link, "1-" __MODULE_STRING(8) "i");MODULE_PARM(trace, "1-" __MODULE_STRING(8) "i");MODULE_PARM(tx_coal_tick, "1-" __MODULE_STRING(8) "i");MODULE_PARM(max_tx_desc, "1-" __MODULE_STRING(8) "i");MODULE_PARM(rx_coal_tick, "1-" __MODULE_STRING(8) "i");MODULE_PARM(max_rx_desc, "1-" __MODULE_STRING(8) "i");#endifstatic void __exit ace_module_cleanup(void){ struct ace_private *ap; struct ace_regs *regs; struct net_device *next; short i; while (root_dev) { ap = root_dev->priv; next = ap->next; regs = ap->regs; writel(readl(®s->CpuCtrl) | CPU_HALT, ®s->CpuCtrl); if (ap->version >= 2) writel(readl(®s->CpuBCtrl) | CPU_HALT, ®s->CpuBCtrl); /* * This clears any pending interrupts */ writel(1, ®s->Mb0Lo); /* * Make sure no other CPUs are processing interrupts * on the card before the buffers are being released. * Otherwise one might experience some `interesting' * effects. * * Then release the RX buffers - jumbo buffers were * already released in ace_close(). */ synchronize_irq(); for (i = 0; i < RX_STD_RING_ENTRIES; i++) { struct sk_buff *skb = ap->skb->rx_std_skbuff[i].skb; if (skb) { dma_addr_t mapping; mapping = ap->skb->rx_std_skbuff[i].mapping; ap->rx_std_ring[i].size = 0; ap->skb->rx_std_skbuff[i].skb = NULL; pci_unmap_single(ap->pdev, mapping, ACE_STD_BUFSIZE - (2 + 16), PCI_DMA_FROMDEVICE); NP_dev_kfree_skb(skb); } } if (ap->version >= 2) { for (i = 0; i < RX_MINI_RING_ENTRIES; i++) { struct sk_buff *skb = ap->skb->rx_mini_skbuff[i].skb; if (skb) { dma_addr_t mapping; mapping = ap->skb->rx_mini_skbuff[i].mapping; ap->rx_mini_ring[i].size = 0; ap->skb->rx_mini_skbuff[i].skb = NULL; pci_unmap_single(ap->pdev, mapping, ACE_MINI_BUFSIZE - (2 + 16), PCI_DMA_FROMDEVICE); NP_dev_kfree_skb(skb); } } } for (i = 0; i < RX_JUMBO_RING_ENTRIES; i++) { struct sk_buff *skb = ap->skb->rx_jumbo_skbuff[i].skb; if (skb) { dma_addr_t mapping; mapping = ap->skb->rx_jumbo_skbuff[i].mapping; ap->rx_jumbo_ring[i].size = 0; ap->skb->rx_jumbo_skbuff[i].skb = NULL; pci_unmap_single(ap->pdev, mapping, ACE_JUMBO_BUFSIZE - (2 + 16), PCI_DMA_FROMDEVICE); dev_kfree_skb(skb); } } ace_init_cleanup(root_dev); kfree(root_dev); root_dev = next; }}int __init ace_module_init(void){ int status; root_dev = NULL;#ifdef NEW_NETINIT status = acenic_probe();#else status = acenic_probe(NULL);#endif return status;}#if (LINUX_VERSION_CODE < 0x02032a)#ifdef MODULEint init_module(void){ return ace_module_init();}void cleanup_module(void){ ace_module_cleanup();}#endif#elsemodule_init(ace_module_init);module_exit(ace_module_cleanup);#endifstatic void ace_free_descriptors(struct net_device *dev){ struct ace_private *ap = dev->priv; int size; if (ap->rx_std_ring != NULL) { size = (sizeof(struct rx_desc) * (RX_STD_RING_ENTRIES + RX_JUMBO_RING_ENTRIES + RX_MINI_RING_ENTRIES + RX_RETURN_RING_ENTRIES)); pci_free_consistent(ap->pdev, size, ap->rx_std_ring, ap->rx_ring_base_dma); ap->rx_std_ring = NULL; ap->rx_jumbo_ring = NULL; ap->rx_mini_ring = NULL; ap->rx_return_ring = NULL; } if (ap->evt_ring != NULL) { size = (sizeof(struct event) * EVT_RING_ENTRIES); pci_free_consistent(ap->pdev, size, ap->evt_ring, ap->evt_ring_dma); ap->evt_ring = NULL; } if (ap->evt_prd != NULL) { pci_free_consistent(ap->pdev, sizeof(u32), (void *)ap->evt_prd, ap->evt_prd_dma); ap->evt_prd = NULL; } if (ap->rx_ret_prd != NULL) { pci_free_consistent(ap->pdev, sizeof(u32), (void *)ap->rx_ret_prd, ap->rx_ret_prd_dma); ap->rx_ret_prd = NULL; } if (ap->tx_csm != NULL) { pci_free_consistent(ap->pdev, sizeof(u32), (void *)ap->tx_csm, ap->tx_csm_dma); ap->tx_csm = NULL; }}static int ace_allocate_descriptors(struct net_device *dev){ struct ace_private *ap = dev->priv; int size; size = (sizeof(struct rx_desc) * (RX_STD_RING_ENTRIES +
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -