📄 skge.c
字号:
SkRlmtInit( pAC, pAC->IoBase, SK_INIT_DATA); SkTimerInit(pAC, pAC->IoBase, SK_INIT_DATA);#ifdef SK_ASF SkAsfInit(pAC, pAC->IoBase, SK_INIT_DATA);#endif pAC->BoardLevel = SK_INIT_DATA; pAC->RxPort[0].RxBufSize = ETH_BUF_SIZE; pAC->RxPort[1].RxBufSize = ETH_BUF_SIZE; SK_PNMI_SET_DRIVER_DESCR(pAC, DescrString); SK_PNMI_SET_DRIVER_VER(pAC, VerStr); /* level 1 init common modules here (HW init) */ if (SkGeInit(pAC, pAC->IoBase, SK_INIT_IO) != 0) { printk("sk98lin: HWInit (1) failed.\n");#ifdef SK_ASF spin_unlock(&pAC->SlowPathLock);#endif#ifndef SK_ASF spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);#endif return(-EAGAIN); } SkI2cInit( pAC, pAC->IoBase, SK_INIT_IO); SkEventInit(pAC, pAC->IoBase, SK_INIT_IO); SkPnmiInit( pAC, pAC->IoBase, SK_INIT_IO); SkAddrInit( pAC, pAC->IoBase, SK_INIT_IO); SkRlmtInit( pAC, pAC->IoBase, SK_INIT_IO); SkTimerInit(pAC, pAC->IoBase, SK_INIT_IO);#ifdef SK_ASF SkAsfInit(pAC, pAC->IoBase, SK_INIT_IO);#endif#ifdef Y2_RECOVERY /* mark entries invalid */ pAC->LastPort = 3; pAC->LastOpc = 0xFF;#endif /* Set chipset type support */ if ((pAC->GIni.GIChipId == CHIP_ID_YUKON) || (pAC->GIni.GIChipId == CHIP_ID_YUKON_LITE) || (pAC->GIni.GIChipId == CHIP_ID_YUKON_LP)) { pAC->ChipsetType = 1; /* Yukon chipset (descriptor logic) */ } else if (CHIP_ID_YUKON_2(pAC)) { pAC->ChipsetType = 2; /* Yukon2 chipset (list logic) */ } else { pAC->ChipsetType = 0; /* Genesis chipset (descriptor logic) */ } /* wake on lan support */ pAC->WolInfo.SupportedWolOptions = 0;#if defined (ETHTOOL_GWOL) && defined (ETHTOOL_SWOL) if (pAC->GIni.GIChipId != CHIP_ID_GENESIS) { pAC->WolInfo.SupportedWolOptions = WAKE_MAGIC; if (pAC->GIni.GIChipId == CHIP_ID_YUKON) { if (pAC->GIni.GIChipRev == 0) { pAC->WolInfo.SupportedWolOptions = 0; } } }#endif pAC->WolInfo.ConfiguredWolOptions = pAC->WolInfo.SupportedWolOptions; GetConfiguration(pAC); if (pAC->RlmtNets == 2) { pAC->GIni.GP[0].PPortUsage = SK_MUL_LINK; pAC->GIni.GP[1].PPortUsage = SK_MUL_LINK; } /* Set the tx moderation parameter */ if (pAC->TxModeration) { pAC->GIni.GITxIdxRepThres = pAC->TxModeration; } pAC->BoardLevel = SK_INIT_IO;#ifdef SK_ASF spin_unlock(&pAC->SlowPathLock);#endif#ifndef SK_ASF spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);#endif if (!CHIP_ID_YUKON_2(pAC)) { if (pAC->GIni.GIMacsFound == 2) {#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21) Ret = request_irq(dev->irq, SkGeIsr, IRQF_SHARED, dev->name, dev);#else Ret = request_irq(dev->irq, SkGeIsr, SA_SHIRQ, dev->name, dev);#endif } else if (pAC->GIni.GIMacsFound == 1) {#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21) Ret = request_irq(dev->irq, SkGeIsrOnePort, IRQF_SHARED, dev->name, dev);#else Ret = request_irq(dev->irq, SkGeIsrOnePort, SA_SHIRQ, dev->name, dev);#endif } else { printk(KERN_WARNING "sk98lin: Illegal number of ports: %d\n", pAC->GIni.GIMacsFound); return -EAGAIN; } } else {#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21) Ret = request_irq(dev->irq, SkY2Isr, IRQF_SHARED, dev->name, dev);#else Ret = request_irq(dev->irq, SkY2Isr, SA_SHIRQ, dev->name, dev);#endif } if (Ret) { printk(KERN_WARNING "sk98lin: Requested IRQ %d is busy.\n", dev->irq); return -EAGAIN; } pAC->AllocFlag |= SK_ALLOC_IRQ; /* ** Alloc descriptor/LETable memory for this board (both RxD/TxD) */ if (CHIP_ID_YUKON_2(pAC)) { if (!SkY2AllocateResources(pAC)) { printk("No memory for Yukon2 settings\n"); return(-EAGAIN); } } else { if(!BoardAllocMem(pAC)) { printk("No memory for descriptor rings.\n"); return(-EAGAIN); } }#ifdef SK_USE_CSUM SkCsSetReceiveFlags(pAC, SKCS_PROTO_IP | SKCS_PROTO_TCP | SKCS_PROTO_UDP, &pAC->CsOfs1, &pAC->CsOfs2, 0); pAC->CsOfs = (pAC->CsOfs2 << 16) | pAC->CsOfs1;#endif /* ** Function BoardInitMem() for Yukon dependent settings... */ BoardInitMem(pAC); /* tschilling: New common function with minimum size check. */ DualNet = SK_FALSE; if (pAC->RlmtNets == 2) { DualNet = SK_TRUE; } /* * Register the device here */ pAC->Next = SkGeRootDev; SkGeRootDev = dev; return (0);} /* SkGeBoardInit *//***************************************************************************** * * BoardAllocMem - allocate the memory for the descriptor rings * * Description: * This function allocates the memory for all descriptor rings. * Each ring is aligned for the desriptor alignment and no ring * has a 4 GByte boundary in it (because the upper 32 bit must * be constant for all descriptiors in one rings). * * Returns: * SK_TRUE, if all memory could be allocated * SK_FALSE, if not */static SK_BOOL BoardAllocMem(SK_AC *pAC){caddr_t pDescrMem; /* pointer to descriptor memory area */size_t AllocLength; /* length of complete descriptor area */int i; /* loop counter */unsigned long BusAddr; /* rings plus one for alignment (do not cross 4 GB boundary) */ /* RX_RING_SIZE is assumed bigger than TX_RING_SIZE */#if (BITS_PER_LONG == 32) AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;#else AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + RX_RING_SIZE + 8;#endif pDescrMem = pci_alloc_consistent(pAC->PciDev, AllocLength, &pAC->pDescrMemDMA); if (pDescrMem == NULL) { return (SK_FALSE); } pAC->pDescrMem = pDescrMem; BusAddr = (unsigned long) pAC->pDescrMemDMA; /* Descriptors need 8 byte alignment, and this is ensured * by pci_alloc_consistent. */ for (i=0; i<pAC->GIni.GIMacsFound; i++) { SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ("TX%d/A: pDescrMem: %lX, PhysDescrMem: %lX\n", i, (unsigned long) pDescrMem, BusAddr)); pAC->TxPort[i][0].pTxDescrRing = pDescrMem; pAC->TxPort[i][0].VTxDescrRing = BusAddr; pDescrMem += TX_RING_SIZE; BusAddr += TX_RING_SIZE; SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ("RX%d: pDescrMem: %lX, PhysDescrMem: %lX\n", i, (unsigned long) pDescrMem, (unsigned long)BusAddr)); pAC->RxPort[i].pRxDescrRing = pDescrMem; pAC->RxPort[i].VRxDescrRing = BusAddr; pDescrMem += RX_RING_SIZE; BusAddr += RX_RING_SIZE; } /* for */ return (SK_TRUE);} /* BoardAllocMem *//**************************************************************************** * * BoardFreeMem - reverse of BoardAllocMem * * Description: * Free all memory allocated in BoardAllocMem: adapter context, * descriptor rings, locks. * * Returns: N/A */static void BoardFreeMem(SK_AC *pAC){size_t AllocLength; /* length of complete descriptor area */ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("BoardFreeMem\n")); if (pAC->pDescrMem) {#if (BITS_PER_LONG == 32) AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + 8;#else AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + RX_RING_SIZE + 8;#endif pci_free_consistent(pAC->PciDev, AllocLength, pAC->pDescrMem, pAC->pDescrMemDMA); pAC->pDescrMem = NULL; }} /* BoardFreeMem *//***************************************************************************** * * BoardInitMem - initiate the descriptor rings * * Description: * This function sets the descriptor rings or LETables up in memory. * The adapter is initialized with the descriptor start addresses. * * Returns: N/A */static void BoardInitMem(SK_AC *pAC) /* pointer to adapter context */{int i; /* loop counter */int RxDescrSize; /* the size of a rx descriptor rounded up to alignment*/int TxDescrSize; /* the size of a tx descriptor rounded up to alignment*/ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("BoardInitMem\n")); if (!pAC->GIni.GIYukon2) { RxDescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN; pAC->RxDescrPerRing = RX_RING_SIZE / RxDescrSize; TxDescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN; pAC->TxDescrPerRing = TX_RING_SIZE / RxDescrSize; for (i=0; i<pAC->GIni.GIMacsFound; i++) { SetupRing( pAC, pAC->TxPort[i][0].pTxDescrRing, pAC->TxPort[i][0].VTxDescrRing, (RXD**)&pAC->TxPort[i][0].pTxdRingHead, (RXD**)&pAC->TxPort[i][0].pTxdRingTail, (RXD**)&pAC->TxPort[i][0].pTxdRingPrev, &pAC->TxPort[i][0].TxdRingFree, &pAC->TxPort[i][0].TxdRingPrevFree, SK_TRUE); SetupRing( pAC, pAC->RxPort[i].pRxDescrRing, pAC->RxPort[i].VRxDescrRing, &pAC->RxPort[i].pRxdRingHead, &pAC->RxPort[i].pRxdRingTail, &pAC->RxPort[i].pRxdRingPrev, &pAC->RxPort[i].RxdRingFree, &pAC->RxPort[i].RxdRingFree, SK_FALSE); } }} /* BoardInitMem *//***************************************************************************** * * SetupRing - create one descriptor ring * * Description: * This function creates one descriptor ring in the given memory area. * The head, tail and number of free descriptors in the ring are set. * * Returns: * none */static void SetupRing(SK_AC *pAC,void *pMemArea, /* a pointer to the memory area for the ring */uintptr_t VMemArea, /* the virtual bus address of the memory area */RXD **ppRingHead, /* address where the head should be written */RXD **ppRingTail, /* address where the tail should be written */RXD **ppRingPrev, /* address where the tail should be written */int *pRingFree, /* address where the # of free descr. goes */int *pRingPrevFree, /* address where the # of free descr. goes */SK_BOOL IsTx) /* flag: is this a tx ring */{int i; /* loop counter */int DescrSize; /* the size of a descriptor rounded up to alignment*/int DescrNum; /* number of descriptors per ring */RXD *pDescr; /* pointer to a descriptor (receive or transmit) */RXD *pNextDescr; /* pointer to the next descriptor */RXD *pPrevDescr; /* pointer to the previous descriptor */uintptr_t VNextDescr; /* the virtual bus address of the next descriptor */ if (IsTx == SK_TRUE) { DescrSize = (((sizeof(TXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN; DescrNum = TX_RING_SIZE / DescrSize; } else { DescrSize = (((sizeof(RXD) - 1) / DESCR_ALIGN) + 1) * DESCR_ALIGN; DescrNum = RX_RING_SIZE / DescrSize; } SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ("Descriptor size: %d Descriptor Number: %d\n", DescrSize,DescrNum)); pDescr = (RXD*) pMemArea; pPrevDescr = NULL; pNextDescr = (RXD*) (((char*)pDescr) + DescrSize); VNextDescr = VMemArea + DescrSize; for(i=0; i<DescrNum; i++) { /* set the pointers right */ pDescr->VNextRxd = VNextDescr & 0xffffffffULL; pDescr->pNextRxd = pNextDescr; pDescr->TcpSumStarts = pAC->CsOfs; /* advance one step */ pPrevDescr = pDescr; pDescr = pNextDescr; pNextDescr = (RXD*) (((char*)pDescr) + DescrSize); VNextDescr += DescrSize; } pPrevDescr->pNextRxd = (RXD*) pMemArea; pPrevDescr->VNextRxd = VMemArea; pDescr = (RXD*) pMemArea; *ppRingHead = (RXD*) pMemArea; *ppRingTail = *ppRingHead; *ppRingPrev = pPrevDescr; *pRingFree = DescrNum; *pRingPrevFree = DescrNum;} /* SetupRing *//***************************************************************************** * * PortReInitBmu - re-initiate the descriptor rings for one port * * Description: * This function reinitializes the descriptor rings of one port * in memory. The port must be stopped before. * The HW is initialized with the descriptor start addresses. * * Returns: * none */static void PortReInitBmu(SK_AC *pAC, /* pointer to adapter context */int PortIndex) /* index of the port for which to re-init */{ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("PortReInitBmu ")); /* set address of first descriptor of ring in BMU */ SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+ Q_DA_L, (uint32_t)(((caddr_t) (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) - pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing + pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) & 0xFFFFFFFF)); SK_OUT32(pAC->IoBase, TxQueueAddr[PortIndex][TX_PRIO_LOW]+ Q_DA_H, (uint32_t)(((caddr_t) (pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxdRingHead) - pAC->TxPort[PortIndex][TX_PRIO_LOW].pTxDescrRing + pAC->TxPort[PortIndex][TX_PRIO_LOW].VTxDescrRing) >> 32)); SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+Q_DA_L, (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) - pAC->RxPort[PortIndex].pRxDescrRing + pAC->RxPort[PortIndex].VRxDescrRing) & 0xFFFFFFFF)); SK_OUT32(pAC->IoBase, RxQueueAddr[PortIndex]+Q_DA_H, (uint32_t)(((caddr_t)(pAC->RxPort[PortIndex].pRxdRingHead) - pAC->RxPort[PortIndex].pRxDescrRing + pAC->RxPort[PortIndex].VRxDescrRing) >> 32));} /* PortReInitBmu *//**************************************************************************** * * SkGeIsr - handle adapter interrupts * * Description: * The interrupt routine is called when the network adapter * generates an interrupt. It may also be called if another device * shares this interrupt vector with the driver. * * Returns: N/A * */#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19)static SkIsrRetVar SkGeIsr(int irq, void *dev_id)#elsestatic SkIsrRetVar SkGeIsr(int irq, void *dev_id, struct pt_regs *ptregs
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -