diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-02-23 00:40:54 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-02-23 00:40:54 +0000 |
commit | 529c593ece216e4aaffd36bd940cb94f1fa63129 (patch) | |
tree | 78f1c0b805f5656aa7b0417a043c5346f700a2cf /drivers/net/sk98lin/skge.c | |
parent | 0bd079751d25808d1972baee5c4eaa1db2227257 (diff) |
Merge with 2.3.43. I did ignore all modifications to the qlogicisp.c
driver due to the Origin A64 hacks.
Diffstat (limited to 'drivers/net/sk98lin/skge.c')
-rw-r--r-- | drivers/net/sk98lin/skge.c | 190 |
1 files changed, 106 insertions, 84 deletions
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c index b46369541..d7ed239a4 100644 --- a/drivers/net/sk98lin/skge.c +++ b/drivers/net/sk98lin/skge.c @@ -228,6 +228,7 @@ static const char SysKonnectBuildNumber[] = "@(#)SK-BUILD: 3.02 (19991111) PL: 01"; #include <linux/module.h> +#include <linux/init.h> #include "h/skdrv1st.h" #include "h/skdrv2nd.h" @@ -341,13 +342,14 @@ static uintptr_t RxQueueAddr[SK_MAX_MACS] = {0x400, 0x480}; * 0, if everything is ok * !=0, on error */ -int __init skge_probe (struct net_device *dev) +static int __init skge_probe (void) { -int boards_found = 0; -int version_disp = 0; -SK_AC *pAC; -struct pci_dev *pdev = NULL; -unsigned long base_address; + int boards_found = 0; + int version_disp = 0; + SK_AC *pAC; + struct pci_dev *pdev = NULL; + unsigned long base_address; + struct net_device *dev = NULL; if (probed) return -ENODEV; @@ -375,21 +377,12 @@ unsigned long base_address; } dev = init_etherdev(dev, sizeof(SK_AC)); - if (dev == NULL){ + if (dev == NULL || dev->priv == NULL){ printk(KERN_ERR "Unable to allocate etherdev " "structure!\n"); break; } - if (!dev->priv) - dev->priv = kmalloc(sizeof(SK_AC), GFP_KERNEL); - if (dev->priv == NULL){ - printk(KERN_ERR "Unable to allocate adapter " - "structure!\n"); - break; - } - - memset(dev->priv, 0, sizeof(SK_AC)); pAC = dev->priv; @@ -471,14 +464,7 @@ unsigned long base_address; * or more boards. Otherwise, return failure (-ENODEV). */ -#ifdef MODULE return boards_found; -#else - if (boards_found > 0) - return 0; - else - return -ENODEV; -#endif } /* skge_probe */ @@ -515,8 +501,6 @@ SK_AC *pAC; } /* FreeResources */ -#ifdef MODULE - MODULE_AUTHOR("Christoph Goos <cgoos@syskonnect.de>"); MODULE_DESCRIPTION("SysKonnect SK-NET Gigabit Ethernet SK-98xx driver"); MODULE_PARM(AutoNeg_A, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); @@ -533,8 +517,6 @@ MODULE_PARM(RlmtMode, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "s"); MODULE_PARM(options, "1-" __MODULE_STRING(SK_MAX_CARD_PARAM) "i"); MODULE_PARM(debug, "i"); -#endif // MODULE - #ifdef AUTO_NEG_A static char *AutoNeg_A[SK_MAX_CARD_PARAM] = AUTO_NEG_A; @@ -597,15 +579,13 @@ static char *RlmtMode[SK_MAX_CARD_PARAM] = {"", }; #endif -#ifdef MODULE - static int debug = 0; /* not used */ static int options[SK_MAX_CARD_PARAM] = {0, }; /* not used */ /***************************************************************************** * - * init_module - module initialization function + * skge_init_module - module initialization function * * Description: * Very simple, only call skge_probe and return approriate result. @@ -614,9 +594,9 @@ static int options[SK_MAX_CARD_PARAM] = {0, }; /* not used */ * 0, if everything is ok * !=0, on error */ -int init_module(void) +static int __init skge_init_module(void) { -int cards; + int cards; root_dev = NULL; @@ -624,17 +604,17 @@ int cards; debug = 0; options[0] = 0; - cards = skge_probe(NULL); + cards = skge_probe(); if (cards == 0) { printk("No adapter found\n"); } return cards ? 0 : -ENODEV; -} /* init_module */ +} /* skge_init_module */ /***************************************************************************** * - * cleanup_module - module unload function + * skge_cleanup_module - module unload function * * Description: * Disable adapter if it is still running, free resources, @@ -642,7 +622,7 @@ int cards; * * Returns: N/A */ -void cleanup_module(void) +static void __exit skge_cleanup_module(void) { SK_AC *pAC; struct net_device *next; @@ -653,7 +633,7 @@ SK_EVPARA EvPara; pAC = (SK_AC*)root_dev->priv; next = pAC->Next; - root_dev->tbusy = 1; + netif_stop_queue(root_dev); SkGeYellowLED(pAC, pAC->IoBase, 0); if(pAC->BoardLevel == 2) { @@ -687,9 +667,10 @@ SK_EVPARA EvPara; root_dev = next; } -} -#endif /* cleanup_module */ +} /* skge_cleanup_module */ +module_init(skge_init_module); +module_exit(skge_cleanup_module); /***************************************************************************** * @@ -851,41 +832,35 @@ unsigned long BusAddr; AllocLength = (RX_RING_SIZE + TX_RING_SIZE) * pAC->GIni.GIMacsFound + RX_RING_SIZE + 8; #endif - pDescrMem = kmalloc(AllocLength, GFP_KERNEL); + pDescrMem = pci_alloc_consistent(&pAC->PciDev, AllocLength, + &pAC->pDescrMemDMA); if (pDescrMem == NULL) { return (SK_FALSE); } pAC->pDescrMem = pDescrMem; - memset(pDescrMem, 0, AllocLength); - /* Descriptors need 8 byte alignment */ - BusAddr = virt_to_bus(pDescrMem); - if (BusAddr & (DESCR_ALIGN-1)) { - pDescrMem += DESCR_ALIGN - (BusAddr & (DESCR_ALIGN-1)); - } + + /* Descriptors need 8 byte alignment, and this is ensured + * by pci_alloc_consistent. + */ + BusAddr = (unsigned long) pAC->pDescrMemDMA; for (i=0; i<pAC->GIni.GIMacsFound; i++) { - if ((virt_to_bus(pDescrMem) & ~0xFFFFFFFFULL) != - (virt_to_bus(pDescrMem+TX_RING_SIZE) & ~0xFFFFFFFFULL)) { - pDescrMem += TX_RING_SIZE; - } SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_TX_PROGRESS, ("TX%d/A: pDescrMem: %lX, PhysDescrMem: %lX\n", i, (unsigned long) pDescrMem, - (unsigned long)virt_to_bus(pDescrMem))); + BusAddr)); pAC->TxPort[i][0].pTxDescrRing = pDescrMem; - pAC->TxPort[i][0].VTxDescrRing = virt_to_bus(pDescrMem); + pAC->TxPort[i][0].VTxDescrRing = BusAddr; pDescrMem += TX_RING_SIZE; + BusAddr += TX_RING_SIZE; - if ((virt_to_bus(pDescrMem) & ~0xFFFFFFFFULL) != - (virt_to_bus(pDescrMem+RX_RING_SIZE) & ~0xFFFFFFFFULL)) { - pDescrMem += RX_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)(virt_to_bus(pDescrMem)))); + (unsigned long)BusAddr)); pAC->RxPort[i].pRxDescrRing = pDescrMem; - pAC->RxPort[i].VRxDescrRing = virt_to_bus(pDescrMem); + pAC->RxPort[i].VRxDescrRing = BusAddr; pDescrMem += RX_RING_SIZE; + BusAddr += RX_RING_SIZE; } /* for */ return (SK_TRUE); @@ -905,9 +880,19 @@ unsigned long BusAddr; 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")); - kfree(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 */ @@ -1428,10 +1413,6 @@ SK_EVPARA EvPara; /* an event parameter union */ SkEventDispatcher(pAC, pAC->IoBase); spin_unlock_irqrestore(&pAC->SlowPathLock, Flags); - dev->tbusy = 0; - dev->interrupt = 0; - dev->start = 1; - MOD_INC_USE_COUNT; SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, @@ -1460,9 +1441,8 @@ unsigned int Flags; /* for spin lock */ int i; SK_EVPARA EvPara; - dev->start = 0; - set_bit(0, (void*)&dev->tbusy); - + netif_stop_queue(dev); + pAC = (SK_AC*) dev->priv; SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, @@ -1529,8 +1509,10 @@ int Rc; /* return code of XmitFrame */ if (Rc == 0) { /* transmitter out of resources */ - set_bit(0, (void*) &dev->tbusy); - return (0); + netif_stop_queue(dev); + + /* give buffer ownership back to the queueing layer */ + return (1); } dev->trans_start = jiffies; return (0); @@ -1584,7 +1566,6 @@ int BytesSend; SK_DBGCAT_DRV_TX_PROGRESS, ("XmitFrame failed\n")); /* this message can not be sent now */ - DEV_KFREE_SKB(pMessage); return (0); } } @@ -1603,7 +1584,9 @@ int BytesSend; #endif /* set up descriptor and CONTROL dword */ - PhysAddr = virt_to_bus(pMessage->data); + PhysAddr = (SK_U64) pci_map_single(&pAC->PciDev, + pMessage->data, + pMessage->len); pTxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); pTxd->VDataHigh = (SK_U32) (PhysAddr >> 32); pTxd->pMBuf = pMessage; @@ -1662,6 +1645,7 @@ TX_PORT *pTxPort) /* pointer to destination port structure */ TXD *pTxd; /* pointer to the checked descriptor */ TXD *pNewTail; /* pointer to 'end' of the ring */ SK_U32 Control; /* TBControl field of descriptor */ +SK_U64 PhysAddr; /* address of DMA mapping */ pNewTail = pTxPort->pTxdRingTail; pTxd = pNewTail; @@ -1680,17 +1664,23 @@ SK_U32 Control; /* TBControl field of descriptor */ * freed ( -> ring completely free now). */ pTxPort->pTxdRingTail = pTxd; - pAC->dev->tbusy = 0; + netif_start_queue(pAC->dev); return; } if (Control & TX_CTRL_OWN_BMU) { pTxPort->pTxdRingTail = pTxd; if (pTxPort->TxdRingFree > 0) { - pAC->dev->tbusy = 0; + netif_start_queue(pAC->dev); } return; } + /* release the DMA mapping */ + PhysAddr = ((SK_U64) pTxd->VDataHigh) << (SK_U64) 32; + PhysAddr |= (SK_U64) pTxd->VDataLow; + pci_unmap_single(&pAC->PciDev, PhysAddr, + pTxd->pMBuf->len); + DEV_KFREE_SKB(pTxd->pMBuf); /* free message */ pTxPort->TxdRingFree++; pTxd->TBControl &= ~TX_CTRL_SOFTWARE; @@ -1767,7 +1757,9 @@ SK_U64 PhysAddr; /* physical address of a rx buffer */ pRxPort->pRxdRingTail = pRxd->pNextRxd; pRxPort->RxdRingFree--; Length = pAC->RxBufSize; - PhysAddr = virt_to_bus(pMsgBlock->data); + PhysAddr = (SK_U64) pci_map_single(&pAC->PciDev, + pMsgBlock->data, + pAC->RxBufSize - 2); pRxd->VDataLow = (SK_U32) (PhysAddr & 0xffffffff); pRxd->VDataHigh = (SK_U32) (PhysAddr >> 32); pRxd->pMBuf = pMsgBlock; @@ -1845,6 +1837,8 @@ unsigned short Csum1; unsigned short Csum2; unsigned short Type; int Result; +SK_U64 PhysAddr; + rx_start: /* do forever; exit if RX_CTRL_OWN_BMU found */ @@ -1876,17 +1870,19 @@ rx_start: /* * if short frame then copy data to reduce memory waste */ + pNewMsg = NULL; if (FrameLength < SK_COPY_THRESHOLD) { pNewMsg = alloc_skb(FrameLength+2, GFP_ATOMIC); - if (pNewMsg == NULL) { - /* use original skb */ - /* set length in message */ - skb_put(pMsg, FrameLength); - } - else { - /* alloc new skb and copy data */ + if (pNewMsg != NULL) { + PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32; + PhysAddr |= (SK_U64) pRxd->VDataLow; + + /* use new skb and copy data */ skb_reserve(pNewMsg, 2); skb_put(pNewMsg, FrameLength); + pci_dma_sync_single(&pAC->PciDev, + (dma_addr_t) PhysAddr, + FrameLength); eth_copy_and_sum(pNewMsg, pMsg->data, FrameLength, 0); ReQueueRxBuffer(pAC, pRxPort, pMsg, @@ -1894,7 +1890,20 @@ rx_start: pMsg = pNewMsg; } } - else { + + /* + * if large frame, or SKB allocation failed, pass + * the SKB directly to the networking + */ + if (pNewMsg == NULL) { + PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32; + PhysAddr |= (SK_U64) pRxd->VDataLow; + + /* release the DMA mapping */ + pci_unmap_single(&pAC->PciDev, + PhysAddr, + pAC->RxBufSize - 2); + /* set length in message */ skb_put(pMsg, FrameLength); /* hardware checksum */ @@ -2045,6 +2054,13 @@ rx_failed: /* remove error frame */ SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ERROR, ("Schrottdescriptor, length: 0x%x\n", FrameLength)); + + /* release the DMA mapping */ + PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32; + PhysAddr |= (SK_U64) pRxd->VDataLow; + pci_unmap_single(&pAC->PciDev, + PhysAddr, + pAC->RxBufSize - 2); DEV_KFREE_SKB(pRxd->pMBuf); pRxd->pMBuf = NULL; pRxPort->RxdRingFree++; @@ -2110,6 +2126,7 @@ RX_PORT *pRxPort) /* pointer to rx port struct */ { RXD *pRxd; /* pointer to the current descriptor */ unsigned int Flags; + SK_U64 PhysAddr; if (pRxPort->RxdRingFree == pAC->RxDescrPerRing) { return; @@ -2118,6 +2135,11 @@ unsigned int Flags; pRxd = pRxPort->pRxdRingHead; do { if (pRxd->pMBuf != NULL) { + PhysAddr = ((SK_U64) pRxd->VDataHigh) << (SK_U64)32; + PhysAddr |= (SK_U64) pRxd->VDataLow; + pci_unmap_single(&pAC->PciDev, + PhysAddr, + pAC->RxBufSize - 2); DEV_KFREE_SKB(pRxd->pMBuf); pRxd->pMBuf = NULL; } @@ -2254,7 +2276,7 @@ unsigned int Flags; SK_DBG_MSG(NULL, SK_DBGMOD_DRV, SK_DBGCAT_DRV_ENTRY, ("SkGeSetMacAddr starts now...\n")); - if(dev->start) { + if(test_bit(LINK_STATE_START, &dev->state)) { return -EBUSY; } memcpy(dev->dev_addr, addr->sa_data,dev->addr_len); @@ -2380,7 +2402,7 @@ SK_EVPARA EvPara; spin_lock_irqsave( &pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock, Flags); } - pAC->dev->tbusy = 1; + netif_stop_queue(pAC->dev); /* * adjust number of rx buffers allocated @@ -2469,7 +2491,7 @@ SK_EVPARA EvPara; } #endif - pAC->dev->tbusy = 0; + netif_start_queue(pAC->dev); for (i=pAC->GIni.GIMacsFound-1; i>=0; i--) { spin_unlock_irqrestore( &pAC->TxPort[i][TX_PRIO_LOW].TxDesRingLock, Flags); |