patch-2.3.47 linux/drivers/net/acenic.c

Next file: linux/drivers/net/acenic.h
Previous file: linux/drivers/net/a2065.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.46/linux/drivers/net/acenic.c linux/drivers/net/acenic.c
@@ -27,6 +27,8 @@
  *                with 'testing the tx_ret_csm and setting tx_full'
  *   David S. Miller <davem@redhat.com>: conversion to new PCI dma mapping
  *                                       infrastructure and Sparc support
+ *   Pierrick Pinasseau (CERN): For lending me an Ultra 5 to test the
+ *                              driver under Linux/Sparc64
  */
 
 #include <linux/config.h>
@@ -59,6 +61,7 @@
 #include <asm/byteorder.h>
 #include <asm/uaccess.h>
 
+
 #ifdef CONFIG_ACENIC_OMIT_TIGON_I
 #define ACE_IS_TIGON_I(ap)	0
 #else
@@ -118,8 +121,8 @@
 	return virt_ptr;
 }
 #define pci_free_consistent(cookie, size, ptr, dma_ptr)	kfree(ptr)
-#define pci_map_single(cookie, address, size)		virt_to_bus(address)
-#define pci_unmap_single(cookie, address, size)
+#define pci_map_single(cookie, address, size, dir)		virt_to_bus(address)
+#define pci_unmap_single(cookie, address, size, dir)
 #endif
 
 #if (LINUX_VERSION_CODE < 0x02032b)
@@ -144,8 +147,8 @@
 #else
 #define NET_BH			0
 #define ace_mark_net_bh(foo)	{do{} while(0);}
-#define ace_if_busy(dev)	test_bit(LINK_STATE_XOFF, &dev->state)
-#define ace_if_running(dev)	test_bit(LINK_STATE_START, &dev->state)
+#define ace_if_busy(dev)	netif_queue_stopped(dev)
+#define ace_if_running(dev)	netif_running(dev)
 #define ace_if_down(dev)	{do{} while(0);}
 #endif
 
@@ -334,10 +337,14 @@
 #define ACE_JUMBO_BUFSIZE	(ACE_JUMBO_MTU + ETH_HLEN + 2+4+16)
 
 #define DEF_TX_RATIO		24
-#define DEF_TX_COAL		1000
+/*
+ * There seems to be a magic difference in the effect between 995 and 996
+ * but little difference between 900 and 995 ... no idea why.
+ */
+#define DEF_TX_COAL		996
 #define DEF_TX_MAX_DESC		40
 #define DEF_RX_COAL		1000
-#define DEF_RX_MAX_DESC		20
+#define DEF_RX_MAX_DESC		25
 #define TX_COAL_INTS_ONLY	0	/* seems not worth it */
 #define DEF_TRACE		0
 #define DEF_STAT		2 * TICKS_PER_SEC
@@ -352,7 +359,7 @@
 static int dis_pci_mem_inval[8] = {1, 1, 1, 1, 1, 1, 1, 1};
 
 static const char __initdata *version = 
-  "acenic.c: v0.39 02/11/2000  Jes Sorensen, linux-acenic@SunSITE.auc.dk\n"
+  "acenic.c: v0.41 02/16/2000  Jes Sorensen, linux-acenic@SunSITE.auc.dk\n"
   "                            http://home.cern.ch/~jes/gige/acenic.html\n";
 
 static struct net_device *root_dev = NULL;
@@ -421,7 +428,6 @@
 		ap->pdev = pdev;
 
 		dev->irq = pdev->irq;
-
 		dev->open = &ace_open;
 		dev->hard_start_xmit = &ace_start_xmit;
 		dev->stop = &ace_close;
@@ -523,8 +529,12 @@
 			break;
 		}
 		ap->name [sizeof (ap->name) - 1] = '\0';
-		printk("Gigabit Ethernet at 0x%08lx, irq %i\n",
-		       dev->base_addr, dev->irq);
+		printk("Gigabit Ethernet at 0x%08lx, ", dev->base_addr);
+#ifdef __sparc__
+		printk("irq %s\n", __irq_itoa(dev->irq));
+#else
+		printk("irq %i\n", dev->irq);
+#endif
 
 #ifdef CONFIG_ACENIC_OMIT_TIGON_I
 		if ((readl(&ap->regs->HostCtrl) >> 28) == 4) {
@@ -598,7 +608,7 @@
 		/*
 		 * This clears any pending interrupts
 		 */
-		writel(0, &regs->Mb0Lo);
+		writel(1, &regs->Mb0Lo);
 
 		/*
 		 * Make sure no other CPUs are processing interrupts
@@ -622,7 +632,8 @@
 				ap->rx_std_ring[i].size = 0;
 				ap->skb->rx_std_skbuff[i].skb = NULL;
 				pci_unmap_single(ap->pdev, mapping,
-						 ACE_STD_BUFSIZE - (2 + 16));
+						 ACE_STD_BUFSIZE - (2 + 16),
+						 PCI_DMA_FROMDEVICE);
 				dev_kfree_skb(skb);
 			}
 		}
@@ -637,7 +648,8 @@
 					ap->rx_mini_ring[i].size = 0;
 					ap->skb->rx_mini_skbuff[i].skb = NULL;
 					pci_unmap_single(ap->pdev, mapping,
-							 ACE_MINI_BUFSIZE - (2 + 16));
+							 ACE_MINI_BUFSIZE - (2 + 16),
+							 PCI_DMA_FROMDEVICE);
 					dev_kfree_skb(skb);
 				}
 			}
@@ -652,7 +664,8 @@
 				ap->rx_jumbo_ring[i].size = 0;
 				ap->skb->rx_jumbo_skbuff[i].skb = NULL;
 				pci_unmap_single(ap->pdev, mapping,
-						 ACE_JUMBO_BUFSIZE - (2 + 16));
+						 ACE_JUMBO_BUFSIZE - (2 + 16),
+						 PCI_DMA_FROMDEVICE);
 				dev_kfree_skb(skb);
 			}
 		}
@@ -668,8 +681,8 @@
 			kfree(ap->skb);
 		if (root_dev->irq)
 			free_irq(root_dev->irq, root_dev);
-		iounmap(regs);
 		unregister_netdev(root_dev);
+		iounmap(regs);
 		kfree(root_dev);
 
 		root_dev = next;
@@ -677,20 +690,6 @@
 }
 
 
-#if (LINUX_VERSION_CODE < 0x02032b)
-int init_module(void)
-{
-	return ace_module_init();
-}
-
-
-void cleanup_module(void)
-{
-	ace_module_cleanup();
-}
-#endif
-#endif
-
 int __init ace_module_init(void)
 {
 	int cards;
@@ -706,7 +705,22 @@
 }
 
 
-#if (LINUX_VERSION_CODE >= 0x02032b)
+#if (LINUX_VERSION_CODE < 0x02032a)
+int init_module(void)
+{
+	return ace_module_init();
+}
+
+
+void cleanup_module(void)
+{
+	ace_module_cleanup();
+}
+#endif
+#endif
+
+
+#if (LINUX_VERSION_CODE >= 0x02032a)
 module_init(ace_module_init);
 module_exit(ace_module_cleanup);
 #endif
@@ -726,6 +740,7 @@
 		pci_free_consistent(ap->pdev, size,
 				    ap->rx_std_ring,
 				    ap->rx_ring_base_dma);
+		ap->rx_std_ring = NULL;
 		ap->rx_jumbo_ring = NULL;
 		ap->rx_mini_ring = NULL;
 		ap->rx_return_ring = NULL;
@@ -759,7 +774,7 @@
 {
 	struct ace_private *ap = dev->priv;
 	int size;
- 
+
 	size = (sizeof(struct rx_desc) *
 		(RX_STD_RING_ENTRIES +
 		 RX_JUMBO_RING_ENTRIES +
@@ -843,7 +858,7 @@
 	 * address the `Firmware not running' problem subsequent
 	 * to any crashes involving the NIC
 	 */
-	writel(HW_RESET, &regs->HostCtrl);
+	writel(HW_RESET | (HW_RESET << 24), &regs->HostCtrl);
 	wmb();
 
 	/*
@@ -854,7 +869,7 @@
 	 * This will most likely need BYTE_SWAP once we switch
 	 * to using __raw_writel()
 	 */
-	writel(((WORD_SWAP | CLR_INT) |
+	writel((WORD_SWAP | CLR_INT |
 		((WORD_SWAP | CLR_INT) << 24)),
 	       &regs->HostCtrl);
 #else
@@ -888,7 +903,7 @@
 		writel(readl(&regs->CpuBCtrl) | CPU_HALT, &regs->CpuBCtrl);
 		/*
 		 * The SRAM bank size does _not_ indicate the amount
-		 * of memory on the card, it controls the bank size!
+		 * of memory on the card, it controls the _bank_ size!
 		 * Ie. a 1MB AceNIC will have two banks of 512KB.
 		 */
 		writel(SRAM_BANK_512K, &regs->LocalCtrl);
@@ -909,13 +924,14 @@
 	 * value a second time works as well. This is what caused the
 	 * `Firmware not running' problem on the Tigon II.
 	 */
-#ifdef __LITTLE_ENDIAN
-	writel(ACE_BYTE_SWAP_DATA | ACE_WARN | ACE_FATAL |
-	       ACE_WORD_SWAP | ACE_NO_JUMBO_FRAG, &regs->ModeStat);
+#ifdef __BIG_ENDIAN
+	writel(ACE_BYTE_SWAP_DMA | ACE_WARN | ACE_FATAL | ACE_BYTE_SWAP_BD |
+	       ACE_WORD_SWAP_BD | ACE_NO_JUMBO_FRAG, &regs->ModeStat);
 #else
-	writel(ACE_BYTE_SWAP_DATA | ACE_WARN | ACE_FATAL | ACE_BYTE_SWAP |
-	       ACE_WORD_SWAP | ACE_NO_JUMBO_FRAG, &regs->ModeStat);
+	writel(ACE_BYTE_SWAP_DMA | ACE_WARN | ACE_FATAL |
+	       ACE_WORD_SWAP_BD | ACE_NO_JUMBO_FRAG, &regs->ModeStat);
 #endif
+	mb();
 
 	mac1 = 0;
 	for(i = 0; i < 4; i++) {
@@ -1007,6 +1023,21 @@
 			}
 		}
 	}
+#ifdef __sparc__
+	/* On this platform, we know what the best dma settings
+	 * are.  We use 64-byte maximum bursts, because if we
+	 * burst larger than the cache line size (or even cross
+	 * a 64byte boundry in a single burst) the UltraSparc
+	 * PCI controller will disconnect at 64-byte multiples.
+	 *
+	 * Read-multiple will be properly enabled above, and when
+	 * set will give the PCI controller proper hints about
+	 * prefetching.
+	 */
+	tmp = (tmp & ~(0xfc));
+	tmp |= DMA_READ_MAX_64;
+	tmp |= DMA_WRITE_MAX_64;
+#endif
 	writel(tmp, &regs->PciState);
 
 	/*
@@ -1301,8 +1332,10 @@
 	 */
 	myjif = jiffies + 3 * HZ;
 	while (time_before(jiffies, myjif) && !ap->fw_running);
+
 	if (!ap->fw_running) {
 		printk(KERN_ERR "%s: Firmware NOT running!\n", dev->name);
+
 		ace_dump_trace(ap);
 		writel(readl(&regs->CpuCtrl) | CPU_HALT, &regs->CpuCtrl);
 
@@ -1344,6 +1377,8 @@
 	}
 	return 0;
  init_error:
+	iounmap(ap->regs);
+	unregister_netdev(dev);
 	if (ap->skb) {
 		kfree(ap->skb);
 		ap->skb = NULL;
@@ -1460,7 +1495,8 @@
 		 */
 		skb_reserve(skb, 2 + 16);
 		mapping = pci_map_single(ap->pdev, skb->data,
-					 ACE_STD_BUFSIZE - (2 + 16));
+					 ACE_STD_BUFSIZE - (2 + 16),
+					 PCI_DMA_FROMDEVICE);
 		ap->skb->rx_std_skbuff[idx].skb = skb;
 		ap->skb->rx_std_skbuff[idx].mapping = mapping;
 
@@ -1521,7 +1557,8 @@
 		 */
 		skb_reserve(skb, 2 + 16);
 		mapping = pci_map_single(ap->pdev, skb->data,
-					 ACE_MINI_BUFSIZE - (2 + 16));
+					 ACE_MINI_BUFSIZE - (2 + 16),
+					 PCI_DMA_FROMDEVICE);
 		ap->skb->rx_mini_skbuff[idx].skb = skb;
 		ap->skb->rx_mini_skbuff[idx].mapping = mapping;
 
@@ -1579,7 +1616,8 @@
 		 */
 		skb_reserve(skb, 2 + 16);
 		mapping = pci_map_single(ap->pdev, skb->data,
-					 ACE_JUMBO_BUFSIZE - (2 + 16));
+					 ACE_JUMBO_BUFSIZE - (2 + 16),
+					 PCI_DMA_FROMDEVICE);
 		ap->skb->rx_jumbo_skbuff[idx].skb = skb;
 		ap->skb->rx_jumbo_skbuff[idx].mapping = mapping;
 
@@ -1634,6 +1672,7 @@
 			printk(KERN_INFO "%s: Firmware up and running\n",
 			       dev->name);
 			ap->fw_running = 1;
+			wmb();
 			break;
 		case E_STATS_UPDATED:
 			break;
@@ -1756,8 +1795,7 @@
 
 		skb = rip->skb;
 		rip->skb = NULL;
-		pci_unmap_single(ap->pdev, rip->mapping, mapsize);
-		rxdesc->size = 0;
+		pci_unmap_single(ap->pdev, rip->mapping, mapsize, PCI_DMA_FROMDEVICE);
 		skb_put(skb, retdesc->size);
 #if 0
 		/* unncessary */
@@ -1864,7 +1902,7 @@
 
 			ap->stats.tx_packets++;
 			ap->stats.tx_bytes += skb->len;
-			pci_unmap_single(ap->pdev, mapping, skb->len);
+			pci_unmap_single(ap->pdev, mapping, skb->len, PCI_DMA_TODEVICE);
 			dev_kfree_skb_irq(skb);
 
 			ap->skb->tx_skbuff[idx].skb = NULL;
@@ -2105,7 +2143,7 @@
 			writel(0, &ap->tx_ring[i].addr.addrhi);
 			writel(0, &ap->tx_ring[i].addr.addrlo);
 			writel(0, &ap->tx_ring[i].flagsize);
-			pci_unmap_single(ap->pdev, mapping, skb->len);
+			pci_unmap_single(ap->pdev, mapping, skb->len, PCI_DMA_TODEVICE);
 			dev_kfree_skb(skb);
 			ap->skb->tx_skbuff[i].skb = NULL;
 		}
@@ -2155,7 +2193,7 @@
 
 	ap->skb->tx_skbuff[idx].skb = skb;
 	ap->skb->tx_skbuff[idx].mapping =
-		pci_map_single(ap->pdev, skb->data, skb->len);
+		pci_map_single(ap->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
 	addr = (unsigned long) ap->skb->tx_skbuff[idx].mapping;
 #if (BITS_PER_LONG == 64)
 	writel(addr >> 32, &ap->tx_ring[idx].addr.addrhi);

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