📄 skge.c
字号:
if ((pAC->GIni.GIMacsFound == 2 ) && (pAC->RlmtNets == 2)) { if ((dev = init_etherdev(NULL, sizeof(DEV_NET))) == 0) { printk(KERN_ERR "Unable to allocate etherdev " "structure!\n"); break; } pAC->dev[1] = dev; pNet = dev->priv; pNet->PortNr = 1; pNet->NetNr = 1; pNet->pAC = pAC; pNet->Mtu = 1500; pNet->Up = 0; dev->open = &SkGeOpen; dev->stop = &SkGeClose; dev->hard_start_xmit = &SkGeXmit; dev->get_stats = &SkGeStats; dev->set_multicast_list = &SkGeSetRxMode; dev->set_mac_address = &SkGeSetMacAddr; dev->do_ioctl = &SkGeIoctl; dev->change_mtu = &SkGeChangeMtu; dev->flags &= ~IFF_RUNNING;#ifdef SK_ZEROCOPY#ifdef USE_SK_TX_CHECKSUM if (pAC->ChipsetType) { /* SG and ZEROCOPY - fly baby... */ dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; }#endif#endif#ifdef CONFIG_PROC_FS pProcFile = create_proc_entry(dev->name, S_IFREG | S_IXUSR | S_IWGRP | S_IROTH, pSkRootDir); pProcFile->read_proc = sk_proc_read; pProcFile->write_proc = NULL; pProcFile->nlink = 1; pProcFile->size = sizeof(dev->name + 1); pProcFile->data = (void *)pProcFile; pProcFile->owner = THIS_MODULE;#endif memcpy((caddr_t) &dev->dev_addr, (caddr_t) &pAC->Addr.Net[1].CurrentMacAddress, 6); printk("%s: %s\n", dev->name, pAC->DeviceStr); printk(" PrefPort:B RlmtMode:Dual Check Link State\n"); } /* Save the hardware revision */ pAC->HWRevision = (((pAC->GIni.GIPciHwRev >> 4) & 0x0F)*10) + (pAC->GIni.GIPciHwRev & 0x0F); /* Set driver globals */ pAC->Pnmi.pDriverFileName = DRIVER_FILE_NAME; pAC->Pnmi.pDriverReleaseDate = DRIVER_REL_DATE; SK_MEMSET(&(pAC->PnmiBackup), 0, sizeof(SK_PNMI_STRUCT_DATA)); SK_MEMCPY(&(pAC->PnmiBackup), &(pAC->PnmiStruct), sizeof(SK_PNMI_STRUCT_DATA)); /* * This is bollocks, but we need to tell the net-init * code that it shall go for the next device. */#ifndef MODULE dev->base_addr = 0;#endif } /* * If we're at this point we're going through skge_probe() for * the first time. Return success (0) if we've initialized 1 * or more boards. Otherwise, return failure (-ENODEV). */ return boards_found;} /* skge_probe *//***************************************************************************** * * SkGeInitPCI - Init the PCI resources * * Description: * This function initialize the PCI resources and IO * * Returns: N/A * */int SkGeInitPCI(SK_AC *pAC){ struct SK_NET_DEVICE *dev = pAC->dev[0]; struct pci_dev *pdev = pAC->PciDev; int retval; if (pci_enable_device(pdev) != 0) { return 1; } dev->mem_start = pci_resource_start (pdev, 0); pci_set_master(pdev); if (pci_request_regions(pdev, pAC->Name) != 0) { retval = 2; goto out_disable; }#ifdef SK_BIG_ENDIAN /* * On big endian machines, we use the adapter's aibility of * reading the descriptors as big endian. */ { SK_U32 our2; SkPciReadCfgDWord(pAC, PCI_OUR_REG_2, &our2); our2 |= PCI_REV_DESC; SkPciWriteCfgDWord(pAC, PCI_OUR_REG_2, our2); }#endif /* * Remap the regs into kernel space. */ pAC->IoBase = (char*)ioremap_nocache(dev->mem_start, 0x4000); if (!pAC->IoBase){ retval = 3; goto out_release; } return 0; out_release: pci_release_regions(pdev); out_disable: pci_disable_device(pdev); return retval;}/***************************************************************************** * * FreeResources - release resources allocated for adapter * * Description: * This function releases the IRQ, unmaps the IO and * frees the desriptor ring. * * Returns: N/A * */static void FreeResources(struct SK_NET_DEVICE *dev){SK_U32 AllocFlag;DEV_NET *pNet;SK_AC *pAC; if (dev->priv) { pNet = (DEV_NET*) dev->priv; pAC = pNet->pAC; AllocFlag = pAC->AllocFlag; if (pAC->PciDev) { pci_release_regions(pAC->PciDev); } if (AllocFlag & SK_ALLOC_IRQ) { free_irq(dev->irq, dev); } if (pAC->IoBase) { iounmap(pAC->IoBase); } if (pAC->pDescrMem) { BoardFreeMem(pAC); } } } /* FreeResources */MODULE_AUTHOR("Mirko Lindner <mlindner@syskonnect.de>");MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver");MODULE_LICENSE("GPL");MODULE_PARM(Speed_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");MODULE_PARM(Speed_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");MODULE_PARM(AutoNeg_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");MODULE_PARM(AutoNeg_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");MODULE_PARM(DupCap_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");MODULE_PARM(DupCap_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");MODULE_PARM(FlowCtrl_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");MODULE_PARM(FlowCtrl_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");MODULE_PARM(Role_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");MODULE_PARM(Role_B, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");MODULE_PARM(ConType, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");MODULE_PARM(PrefPort, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");MODULE_PARM(RlmtMode, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");/* not used, just there because every driver should have them: */MODULE_PARM(options, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "i");MODULE_PARM(debug, "i");/* used for interrupt moderation */MODULE_PARM(IntsPerSec, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "i");MODULE_PARM(Moderation, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");MODULE_PARM(Stats, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");MODULE_PARM(ModerationMask, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");MODULE_PARM(AutoSizing, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s");#ifdef LINK_SPEED_Astatic char *Speed_A[SK_MAX_CARD_PARAM] = LINK_SPEED;#elsestatic char *Speed_A[SK_MAX_CARD_PARAM] = {"", };#endif#ifdef LINK_SPEED_Bstatic char *Speed_B[SK_MAX_CARD_PARAM] = LINK_SPEED;#elsestatic char *Speed_B[SK_MAX_CARD_PARAM] = {"", };#endif#ifdef AUTO_NEG_Astatic char *AutoNeg_A[SK_MAX_CARD_PARAM] = AUTO_NEG_A;#elsestatic char *AutoNeg_A[SK_MAX_CARD_PARAM] = {"", };#endif#ifdef DUP_CAP_Astatic char *DupCap_A[SK_MAX_CARD_PARAM] = DUP_CAP_A;#elsestatic char *DupCap_A[SK_MAX_CARD_PARAM] = {"", };#endif#ifdef FLOW_CTRL_Astatic char *FlowCtrl_A[SK_MAX_CARD_PARAM] = FLOW_CTRL_A;#elsestatic char *FlowCtrl_A[SK_MAX_CARD_PARAM] = {"", };#endif#ifdef ROLE_Astatic char *Role_A[SK_MAX_CARD_PARAM] = ROLE_A;#elsestatic char *Role_A[SK_MAX_CARD_PARAM] = {"", };#endif#ifdef AUTO_NEG_Bstatic char *AutoNeg_B[SK_MAX_CARD_PARAM] = AUTO_NEG_B;#elsestatic char *AutoNeg_B[SK_MAX_CARD_PARAM] = {"", };#endif#ifdef DUP_CAP_Bstatic char *DupCap_B[SK_MAX_CARD_PARAM] = DUP_CAP_B;#elsestatic char *DupCap_B[SK_MAX_CARD_PARAM] = {"", };#endif#ifdef FLOW_CTRL_Bstatic char *FlowCtrl_B[SK_MAX_CARD_PARAM] = FLOW_CTRL_B;#elsestatic char *FlowCtrl_B[SK_MAX_CARD_PARAM] = {"", };#endif#ifdef ROLE_Bstatic char *Role_B[SK_MAX_CARD_PARAM] = ROLE_B;#elsestatic char *Role_B[SK_MAX_CARD_PARAM] = {"", };#endif#ifdef CON_TYPEstatic char *ConType[SK_MAX_CARD_PARAM] = CON_TYPE;#elsestatic char *ConType[SK_MAX_CARD_PARAM] = {"", };#endif#ifdef PREF_PORTstatic char *PrefPort[SK_MAX_CARD_PARAM] = PREF_PORT;#elsestatic char *PrefPort[SK_MAX_CARD_PARAM] = {"", };#endif#ifdef RLMT_MODEstatic char *RlmtMode[SK_MAX_CARD_PARAM] = RLMT_MODE;#elsestatic char *RlmtMode[SK_MAX_CARD_PARAM] = {"", };#endifstatic int debug = 0; /* not used */static int options[SK_MAX_CARD_PARAM] = {0, }; /* not used */static int IntsPerSec[SK_MAX_CARD_PARAM];static char *Moderation[SK_MAX_CARD_PARAM];static char *ModerationMask[SK_MAX_CARD_PARAM];static char *AutoSizing[SK_MAX_CARD_PARAM];static char *Stats[SK_MAX_CARD_PARAM];/***************************************************************************** * * skge_init_module - module initialization function * * Description: * Very simple, only call skge_probe and return approriate result. * * Returns: * 0, if everything is ok * !=0, on error */static int __init skge_init_module(void){ int cards; SkGeRootDev = NULL; /* just to avoid warnings ... */ debug = 0; options[0] = 0; cards = skge_probe(); if (cards == 0) { printk("sk98lin: No adapter found.\n"); } return cards ? 0 : -ENODEV;} /* skge_init_module *//***************************************************************************** * * skge_cleanup_module - module unload function * * Description: * Disable adapter if it is still running, free resources, * free device struct. * * Returns: N/A */static void __exit skge_cleanup_module(void){DEV_NET *pNet;SK_AC *pAC;struct SK_NET_DEVICE *next;unsigned long Flags;SK_EVPARA EvPara; while (SkGeRootDev) { pNet = (DEV_NET*) SkGeRootDev->priv; pAC = pNet->pAC; next = pAC->Next; netif_stop_queue(SkGeRootDev); SkGeYellowLED(pAC, pAC->IoBase, 0); if(pAC->BoardLevel == SK_INIT_RUN) { /* board is still alive */ spin_lock_irqsave(&pAC->SlowPathLock, Flags); EvPara.Para32[0] = 0; EvPara.Para32[1] = -1; SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); EvPara.Para32[0] = 1; EvPara.Para32[1] = -1; SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STOP, EvPara); SkEventDispatcher(pAC, pAC->IoBase); /* disable interrupts */ SK_OUT32(pAC->IoBase, B0_IMSK, 0); SkGeDeInit(pAC, pAC->IoBase); spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); pAC->BoardLevel = SK_INIT_DATA; /* We do NOT check here, if IRQ was pending, of course*/ } if(pAC->BoardLevel == SK_INIT_IO) { /* board is still alive */ SkGeDeInit(pAC, pAC->IoBase); pAC->BoardLevel = SK_INIT_DATA; } if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 2){ unregister_netdev(pAC->dev[1]); kfree(pAC->dev[1]); } FreeResources(SkGeRootDev); SkGeRootDev->get_stats = NULL; /* * otherwise unregister_netdev calls get_stats with * invalid IO ... :-( */ unregister_netdev(SkGeRootDev); kfree(SkGeRootDev); kfree(pAC); SkGeRootDev = next; }#ifdef CONFIG_PROC_FS /* clear proc-dir */ remove_proc_entry(pSkRootDir->name, proc_net);#endif} /* skge_cleanup_module */module_init(skge_init_module);module_exit(skge_cleanup_module);/***************************************************************************** * * SkGeBoardInit - do level 0 and 1 initialization * * Description: * This function prepares the board hardware for running. The desriptor * ring is set up, the IRQ is allocated and the configuration settings * are examined. * * Returns: * 0, if everything is ok * !=0, on error */static int __init SkGeBoardInit(struct SK_NET_DEVICE *dev, SK_AC *pAC){short i;unsigned long Flags;char *DescrString = "sk98lin: Driver for Linux"; /* this is given to PNMI */char *VerStr = VER_STRING;int Ret; /* return code of request_irq */SK_BOOL DualNet; SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("IoBase: %08lX\n", (unsigned long)pAC->IoBase)); for (i=0; i<SK_MAX_MACS; i++) { pAC->TxPort[i][0].HwAddr = pAC->IoBase + TxQueueAddr[i][0]; pAC->TxPort[i][0].PortIndex = i; pAC->RxPort[i].HwAddr = pAC->IoBase + RxQueueAddr[i]; pAC->RxPort[i].PortIndex = i; } /* Initialize the mutexes */ for (i=0; i<SK_MAX_MACS; i++) { spin_lock_init(&pAC->TxPort[i][0].TxDesRingLock); spin_lock_init(&pAC->RxPort[i].RxDesRingLock); } spin_lock_init(&pAC->SlowPathLock); /* level 0 init common modules here */ spin_lock_irqsave(&pAC->SlowPathLock, Flags); /* Does a RESET on board ...*/ if (SkGeInit(pAC, pAC->IoBase, SK_INIT_DATA) != 0) { printk("HWInit (0) failed.\n"); spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); return(-EAGAIN); } SkI2cInit( pAC, pAC->IoBase, SK_INIT_DATA); SkEventInit(pAC, pAC->IoBase, SK_INIT_DATA); SkPnmiInit( pAC, pAC->IoBase, SK_INIT_DATA); SkAddrInit( pAC, pAC->IoBase, SK_INIT_DATA); SkRlmtInit( pAC, pAC->IoBase, SK_INIT_DATA); SkTimerInit(pAC, pAC->IoBase, SK_INIT_DATA); pAC->BoardLevel = SK_INIT_DATA; pAC->RxBufSize = ETH_BUF_SIZE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -