patch-2.3.43 linux/drivers/net/sk98lin/skge.c

Next file: linux/drivers/net/sk_g16.c
Previous file: linux/drivers/net/sk98lin/h/skdrv2nd.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.42/linux/drivers/net/sk98lin/skge.c linux/drivers/net/sk98lin/skge.c
@@ -228,6 +228,7 @@
 	"@(#)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 @@
  *	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 @@
 		}
 		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 @@
 	 * 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 @@
 } /* 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(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 @@
 #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 @@
  *	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 @@
 	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 @@
  *
  * 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 @@
 		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 @@
 
 		root_dev = next;
 	}
-}
-#endif /* cleanup_module */
+} /* skge_cleanup_module */
 
+module_init(skge_init_module);
+module_exit(skge_cleanup_module);
 
 /*****************************************************************************
  *
@@ -851,41 +832,35 @@
 	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 @@
 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 @@
 	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 @@
 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 @@
 
 	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 @@
 				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 @@
 #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 @@
 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 @@
 			 * 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 @@
 	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	Csum2;
 unsigned short	Type;
 int		Result;
+SK_U64		PhysAddr;
+
 
 rx_start:	
 	/* do forever; exit if RX_CTRL_OWN_BMU found */
@@ -1876,17 +1870,19 @@
 		/*
 		 * 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 @@
 				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 @@
 	/* 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 @@
 {
 RXD		*pRxd;	/* pointer to the current descriptor */
 unsigned int	Flags;
+ SK_U64		PhysAddr;
 
 	if (pRxPort->RxdRingFree == pAC->RxDescrPerRing) {
 		return;
@@ -2118,6 +2135,11 @@
 	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 @@
 	
 	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 @@
 		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 @@
 	}
 #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);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)