patch-2.4.19 linux-2.4.19/drivers/net/starfire.c

Next file: linux-2.4.19/drivers/net/starfire_firmware.pl
Previous file: linux-2.4.19/drivers/net/sonic.h
Back to the patch index
Back to the overall index

diff -urN linux-2.4.18/drivers/net/starfire.c linux-2.4.19/drivers/net/starfire.c
@@ -96,13 +96,19 @@
 	LK1.3.5 (jgarzik)
 	- ethtool NWAY_RST, GLINK, [GS]MSGLVL support
 
+	LK1.3.6:
+	- Sparc64 support and fixes (Ion Badulescu)
+	- Better stats and error handling (Ion Badulescu)
+	- Use new pci_set_mwi() PCI API function (jgarzik)
+
 TODO:
 	- implement tx_timeout() properly
+	- VLAN support
 */
 
 #define DRV_NAME	"starfire"
-#define DRV_VERSION	"1.03+LK1.3.5"
-#define DRV_RELDATE	"November 17, 2001"
+#define DRV_VERSION	"1.03+LK1.3.6"
+#define DRV_RELDATE	"March 7, 2002"
 
 #include <linux/version.h>
 #include <linux/module.h>
@@ -112,6 +118,7 @@
 #include <linux/etherdevice.h>
 #include <linux/init.h>
 #include <linux/delay.h>
+#include <linux/crc32.h>
 #include <asm/processor.h>		/* Processor type for cache alignment. */
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -121,14 +128,14 @@
  * firmware files) does not allow one to redistribute them. Thus, we can't
  * include the firmware with this driver.
  *
- * However, an end-user is allowed to download and use it, after
- * converting it to C header files using starfire_firmware.pl.
+ * However, should a legal-to-use firmware become available,
+ * the driver developer would need only to obtain the firmware in the
+ * form of a C header file.
  * Once that's done, the #undef below must be changed into a #define
  * for this driver to really use the firmware. Note that Rx/Tx
  * hardware TCP checksumming is not possible without the firmware.
  *
- * I'm currently [Feb 2001] talking to Adaptec about this redistribution
- * issue. Stay tuned...
+ * WANTED: legal firmware to include with this GPL'd driver.
  */
 #undef HAS_FIRMWARE
 /*
@@ -608,7 +615,10 @@
 	long ioaddr;
 	int drv_flags, io_size;
 	int boguscnt;
+#ifndef HAVE_PCI_SET_MWI
+	u16 cmd;
 	u8 cache;
+#endif
 
 /* when built into the kernel, we only print version if device is found */
 #ifndef MODULE
@@ -643,14 +653,25 @@
 		goto err_out_free_netdev;
 	}
 
-	ioaddr = (long) ioremap (ioaddr, io_size);
+	/* ioremap is borken in Linux-2.2.x/sparc64 */
+#if !defined(CONFIG_SPARC64) || LINUX_VERSION_CODE > 0x20300
+	ioaddr = (long) ioremap(ioaddr, io_size);
 	if (!ioaddr) {
 		printk (KERN_ERR DRV_NAME " %d: cannot remap 0x%x @ 0x%lx, aborting\n",
 			card_idx, io_size, ioaddr);
 		goto err_out_free_res;
 	}
+#endif /* !CONFIG_SPARC64 || Linux 2.3.0+ */
 
-	pci_set_master (pdev);
+	pci_set_master(pdev);
+
+#ifdef HAVE_PCI_SET_MWI
+	pci_set_mwi(pdev);
+#else
+	/* enable MWI -- it vastly improves Rx performance on sparc64 */
+	pci_read_config_word(pdev, PCI_COMMAND, &cmd);
+	cmd |= PCI_COMMAND_INVALIDATE;
+	pci_write_config_word(pdev, PCI_COMMAND, cmd);
 
 	/* set PCI cache size */
 	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache);
@@ -661,6 +682,7 @@
 		pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE,
 				      SMP_CACHE_BYTES >> 2);
 	}
+#endif
 
 #ifdef ZEROCOPY
 	/* Starfire can do SG and TCP/UDP checksumming */
@@ -669,7 +691,7 @@
 
 	/* Serial EEPROM reads are hidden by the hardware. */
 	for (i = 0; i < 6; i++)
-		dev->dev_addr[i] = readb(ioaddr + EEPROMCtrl + 20-i);
+		dev->dev_addr[i] = readb(ioaddr + EEPROMCtrl + 20 - i);
 
 #if ! defined(final_version) /* Dump the EEPROM contents during development. */
 	if (debug > 4)
@@ -931,7 +953,7 @@
 
 	/* Fill both the unused Tx SA register and the Rx perfect filter. */
 	for (i = 0; i < 6; i++)
-		writeb(dev->dev_addr[i], ioaddr + StationAddr + 5-i);
+		writeb(dev->dev_addr[i], ioaddr + StationAddr + 5 - i);
 	for (i = 0; i < 16; i++) {
 		u16 *eaddrs = (u16 *)dev->dev_addr;
 		long setup_frm = ioaddr + PerfFilterTable + i * 16;
@@ -978,9 +1000,9 @@
 #ifdef HAS_FIRMWARE
 	/* Load Rx/Tx firmware into the frame processors */
 	for (i = 0; i < FIRMWARE_RX_SIZE * 2; i++)
-		writel(cpu_to_le32(firmware_rx[i]), ioaddr + RxGfpMem + i * 4);
+		writel(firmware_rx[i], ioaddr + RxGfpMem + i * 4);
 	for (i = 0; i < FIRMWARE_TX_SIZE * 2; i++)
-		writel(cpu_to_le32(firmware_tx[i]), ioaddr + TxGfpMem + i * 4);
+		writel(firmware_tx[i], ioaddr + TxGfpMem + i * 4);
 	/* Enable the Rx and Tx units, and the Rx/Tx frame processors. */
 	writel(0x003F, ioaddr + GenCtrl);
 #else  /* not HAS_FIRMWARE */
@@ -1155,8 +1177,8 @@
 
 	np->tx_ring[entry].first_addr = cpu_to_le32(np->tx_info[entry].first_mapping);
 #ifdef ZEROCOPY
-	np->tx_ring[entry].first_len = cpu_to_le32(skb_first_frag_len(skb));
-	np->tx_ring[entry].total_len = cpu_to_le32(skb->len);
+	np->tx_ring[entry].first_len = cpu_to_le16(skb_first_frag_len(skb));
+	np->tx_ring[entry].total_len = cpu_to_le16(skb->len);
 	/* Add "| TxDescIntr" to generate Tx-done interrupts. */
 	np->tx_ring[entry].status = cpu_to_le32(TxDescID | TxCRCEn);
 	np->tx_ring[entry].nbufs = cpu_to_le32(skb_shinfo(skb)->nr_frags + 1);
@@ -1169,8 +1191,10 @@
 		np->tx_ring[entry].status |= cpu_to_le32(TxRingWrap | TxDescIntr);
 
 #ifdef ZEROCOPY
-	if (skb->ip_summed == CHECKSUM_HW)
+	if (skb->ip_summed == CHECKSUM_HW) {
 		np->tx_ring[entry].status |= cpu_to_le32(TxCalTCP);
+		np->stats.tx_compressed++;
+	}
 #endif /* ZEROCOPY */
 
 	if (debug > 5) {
@@ -1448,6 +1472,7 @@
 #if defined(full_rx_status) || defined(csum_rx_status)
 		if (le32_to_cpu(np->rx_done_q[np->rx_done].status2) & 0x01000000) {
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
+			np->stats.rx_compressed++;
 		}
 		/*
 		 * This feature doesn't seem to be working, at least
@@ -1579,12 +1604,17 @@
 		printk(KERN_NOTICE "%s: Increasing Tx FIFO threshold to %d bytes\n",
 		       dev->name, np->tx_threshold * 16);
 	}
-	if ((intr_status & ~(IntrNormalMask | IntrAbnormalSummary | IntrLinkChange | IntrStatsMax | IntrTxDataLow | IntrPCIPad)) && debug)
+	if (intr_status & IntrRxGFPDead) {
+		np->stats.rx_fifo_errors++;
+		np->stats.rx_errors++;
+	}
+	if (intr_status & (IntrNoTxCsum | IntrDMAErr)) {
+		np->stats.tx_fifo_errors++;
+		np->stats.tx_errors++;
+	}
+	if ((intr_status & ~(IntrNormalMask | IntrAbnormalSummary | IntrLinkChange | IntrStatsMax | IntrTxDataLow | IntrRxGFPDead | IntrNoTxCsum | IntrPCIPad)) && debug)
 		printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n",
 		       dev->name, intr_status);
-	/* Hmmmmm, it's not clear how to recover from DMA faults. */
-	if (intr_status & IntrDMAErr)
-		np->stats.tx_fifo_errors++;
 }
 
 
@@ -1615,32 +1645,9 @@
 }
 
 
-/* The little-endian AUTODIN II ethernet CRC calculations.
-   A big-endian version is also available.
-   This is slow but compact code.  Do not use this routine for bulk data,
-   use a table-based routine instead.
-   This is common code and should be moved to net/core/crc.c.
-   Chips may use the upper or lower CRC bits, and may reverse and/or invert
+/* Chips may use the upper or lower CRC bits, and may reverse and/or invert
    them.  Select the endian-ness that results in minimal calculations.
 */
-static unsigned const ethernet_polynomial_le = 0xedb88320U;
-static inline unsigned ether_crc_le(int length, unsigned char *data)
-{
-	unsigned int crc = 0xffffffff;	/* Initial value. */
-	while(--length >= 0) {
-		unsigned char current_octet = *data++;
-		int bit;
-		for (bit = 8; --bit >= 0; current_octet >>= 1) {
-			if ((crc ^ current_octet) & 1) {
-				crc >>= 1;
-				crc ^= ethernet_polynomial_le;
-			} else
-				crc >>= 1;
-		}
-	}
-	return crc;
-}
-
 
 static void set_rx_mode(struct net_device *dev)
 {

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