summaryrefslogtreecommitdiffstats
path: root/drivers/net/sk98lin/skge.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-02-23 00:40:54 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-02-23 00:40:54 +0000
commit529c593ece216e4aaffd36bd940cb94f1fa63129 (patch)
tree78f1c0b805f5656aa7b0417a043c5346f700a2cf /drivers/net/sk98lin/skge.c
parent0bd079751d25808d1972baee5c4eaa1db2227257 (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.c190
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);