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
- Lines: 213
- Date:
Fri Aug 2 17:39:44 2002
- Orig file:
linux-2.4.18/drivers/net/starfire.c
- Orig date:
Mon Feb 25 11:37:59 2002
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)