diff -Nru a/MAINTAINERS b/MAINTAINERS --- a/MAINTAINERS Sat Jul 19 12:53:01 2003 +++ b/MAINTAINERS Sat Jul 19 12:53:01 2003 @@ -456,8 +456,8 @@ S: Supported COMX/MULTIGATE SYNC SERIAL DRIVERS -P: Gergely Madarasz -M: Gergely Madarasz +P: Pasztor Szilard +M: Pasztor Szilard S: Supported CONFIGURE, MENUCONFIG, XCONFIG diff -Nru a/drivers/net/e100/e100_main.c b/drivers/net/e100/e100_main.c --- a/drivers/net/e100/e100_main.c Sat Jul 19 12:53:01 2003 +++ b/drivers/net/e100/e100_main.c Sat Jul 19 12:53:01 2003 @@ -46,6 +46,13 @@ /* Change Log * + * 2.3.18 07/08/03 + * o Bug fix: read skb->len after freeing skb + * [Andrew Morton] akpm@zip.com.au + * o Bug fix: 82557 (with National PHY) timeout during init + * [Adam Kropelin] akropel1@rochester.rr.com + * o Feature add: allow to change Wake On LAN when EEPROM disabled + * * 2.3.13 05/08/03 * o Feature remove: /proc/net/PRO_LAN_Adapters support gone completely * o Feature remove: IDIAG support (use ethtool -t instead) @@ -65,20 +72,6 @@ * o Bug fix: statistic command failure would stop statistic collection. * * 2.2.21 02/11/03 - * o Removed marketing brand strings. Instead, Using generic string - * "Intel(R) PRO/100 Network Connection" for all adapters. - * o Implemented ethtool -S option - * o Strip /proc/net/PRO_LAN_Adapters files for kernel driver - * o Bug fix: Read wrong byte in EEPROM when offset is odd number - * o Bug fix: PHY loopback test fails on ICH devices - * o Bug fix: System panic on e100_close when repeating Hot Remove and - * Add in a team - * o Bug fix: Linux Bonding driver claims adapter's link loss because of - * not updating last_rx field - * o Bug fix: e100 does not check validity of MAC address - * o New feature: added ICH5 support - * - * 2.1.27 11/20/02 */ #include @@ -144,7 +137,7 @@ static inline void e100_tx_skb_free(struct e100_private *bdp, tcb_t *tcb); /* Global Data structures and variables */ char e100_copyright[] __devinitdata = "Copyright (c) 2003 Intel Corporation"; -char e100_driver_version[]="2.3.13-k1"; +char e100_driver_version[]="2.3.18-k1"; const char *e100_full_driver_name = "Intel(R) PRO/100 Network Driver"; char e100_short_driver_name[] = "e100"; static int e100nics = 0; @@ -688,17 +681,16 @@ bdp->wolsupported = 0; bdp->wolopts = 0; + if (bdp->rev_id >= D101A4_REV_ID) + bdp->wolsupported = WAKE_PHY | WAKE_MAGIC; + if (bdp->rev_id >= D101MA_REV_ID) + bdp->wolsupported |= WAKE_UCAST | WAKE_ARP; /* Check if WoL is enabled on EEPROM */ if (e100_eeprom_read(bdp, EEPROM_ID_WORD) & BIT_5) { /* Magic Packet WoL is enabled on device by default */ /* if EEPROM WoL bit is TRUE */ - bdp->wolsupported = WAKE_MAGIC; bdp->wolopts = WAKE_MAGIC; - if (bdp->rev_id >= D101A4_REV_ID) - bdp->wolsupported = WAKE_PHY | WAKE_MAGIC; - if (bdp->rev_id >= D101MA_REV_ID) - bdp->wolsupported |= WAKE_UCAST | WAKE_ARP; } printk(KERN_NOTICE "\n"); @@ -1084,10 +1076,10 @@ goto exit1; } - e100_prepare_xmit_buff(bdp, skb); - bdp->drv_stats.net_stats.tx_bytes += skb->len; + e100_prepare_xmit_buff(bdp, skb); + dev->trans_start = jiffies; exit1: @@ -2066,13 +2058,14 @@ skb->ip_summed = CHECKSUM_NONE; } + bdp->drv_stats.net_stats.rx_bytes += skb->len; + if(bdp->vlgrp && (rfd_status & CB_STATUS_VLAN)) { vlan_hwaccel_rx(skb, bdp->vlgrp, be16_to_cpu(rfd->vlanid)); } else { netif_rx(skb); } dev->last_rx = jiffies; - bdp->drv_stats.net_stats.rx_bytes += skb->len; rfd_cnt++; } /* end of rfd loop */ @@ -4255,13 +4248,13 @@ static int e100_notify_reboot(struct notifier_block *nb, unsigned long event, void *p) { - struct pci_dev *pdev; + struct pci_dev *pdev = NULL; switch(event) { case SYS_DOWN: case SYS_HALT: case SYS_POWER_OFF: - pci_for_each_dev(pdev) { + while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) { if(pci_dev_driver(pdev) == &e100_driver) { /* If net_device struct is allocated? */ if (pci_get_drvdata(pdev)) diff -Nru a/drivers/net/e100/e100_phy.c b/drivers/net/e100/e100_phy.c --- a/drivers/net/e100/e100_phy.c Sat Jul 19 12:53:01 2003 +++ b/drivers/net/e100/e100_phy.c Sat Jul 19 12:53:01 2003 @@ -919,6 +919,7 @@ unsigned char __devinit e100_phy_init(struct e100_private *bdp) { + e100_phy_reset(bdp); e100_phy_address_detect(bdp); e100_phy_isolate(bdp); e100_phy_id_detect(bdp); @@ -930,7 +931,6 @@ bdp->PhyDelay = 0; bdp->zlock_state = ZLOCK_INITIAL; - e100_phy_reset(bdp); e100_phy_set_speed_duplex(bdp, false); e100_fix_polarity(bdp); diff -Nru a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h --- a/drivers/net/e1000/e1000.h Sat Jul 19 12:53:01 2003 +++ b/drivers/net/e1000/e1000.h Sat Jul 19 12:53:01 2003 @@ -224,6 +224,5 @@ uint32_t pci_state[16]; - char ifname[IFNAMSIZ]; }; #endif /* _E1000_H_ */ diff -Nru a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c --- a/drivers/net/e1000/e1000_ethtool.c Sat Jul 19 12:53:01 2003 +++ b/drivers/net/e1000/e1000_ethtool.c Sat Jul 19 12:53:01 2003 @@ -1112,8 +1112,9 @@ if(if_running) e1000_down(adapter); - - e1000_reset(adapter); + else + e1000_reset(adapter); + if(e1000_reg_test(adapter, &data[0])) eth_test->flags |= ETH_TEST_FL_FAILED; diff -Nru a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c --- a/drivers/net/e1000/e1000_hw.c Sat Jul 19 12:53:01 2003 +++ b/drivers/net/e1000/e1000_hw.c Sat Jul 19 12:53:01 2003 @@ -135,6 +135,41 @@ e1000_write_phy_reg(hw,IGP01E1000_PHY_PAGE_SELECT,0x0000); e1000_write_phy_reg(hw,0x0000,0x3300); + + + if(hw->mac_type == e1000_82547) { + uint16_t fused, fine, coarse; + + /* Move to analog registers page */ + e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, + IGP01E1000_ANALOG_REGS_PAGE); + + e1000_read_phy_reg(hw, IGP01E1000_ANALOG_SPARE_FUSE_STATUS, &fused); + + if(!(fused & IGP01E1000_ANALOG_SPARE_FUSE_ENABLED)) { + e1000_read_phy_reg(hw, IGP01E1000_ANALOG_FUSE_STATUS, &fused); + + fine = fused & IGP01E1000_ANALOG_FUSE_FINE_MASK; + coarse = fused & IGP01E1000_ANALOG_FUSE_COARSE_MASK; + + if(coarse > IGP01E1000_ANALOG_FUSE_COARSE_THRESH) { + coarse -= IGP01E1000_ANALOG_FUSE_COARSE_10; + fine -= IGP01E1000_ANALOG_FUSE_FINE_1; + } else if(coarse == IGP01E1000_ANALOG_FUSE_COARSE_THRESH) + fine -= IGP01E1000_ANALOG_FUSE_FINE_10; + + fused = (fused & IGP01E1000_ANALOG_FUSE_POLY_MASK) | + (fine & IGP01E1000_ANALOG_FUSE_FINE_MASK) | + (coarse & IGP01E1000_ANALOG_FUSE_COARSE_MASK); + + e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_CONTROL, fused); + e1000_write_phy_reg(hw, IGP01E1000_ANALOG_FUSE_BYPASS, + IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL); + } + /* Return to first page of registers */ + e1000_write_phy_reg(hw, IGP01E1000_PHY_PAGE_SELECT, + IGP01E1000_IEEE_REGS_PAGE); + } } } @@ -259,10 +294,20 @@ msec_delay(5); } - if(hw->mac_type > e1000_82543) - E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST)); - else - E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST)); + switch(hw->mac_type) { + case e1000_82544: + case e1000_82540: + case e1000_82545: + case e1000_82546: + case e1000_82541: + /* These controllers can't ack the 64-bit write when issuing the + * reset, so use IO-mapping as a workaround to issue the reset */ + E1000_WRITE_REG_IO(hw, CTRL, (ctrl | E1000_CTRL_RST)); + break; + default: + E1000_WRITE_REG(hw, CTRL, (ctrl | E1000_CTRL_RST)); + break; + } /* Force a reload from the EEPROM if necessary */ if(hw->mac_type < e1000_82540) { @@ -687,7 +732,8 @@ static int32_t e1000_setup_copper_link(struct e1000_hw *hw) { - uint32_t ctrl, led_ctrl; + uint32_t ctrl; + uint32_t led_ctrl; int32_t ret_val; uint16_t i; uint16_t phy_data; @@ -2249,7 +2295,8 @@ void e1000_phy_hw_reset(struct e1000_hw *hw) { - uint32_t ctrl, ctrl_ext, led_ctrl; + uint32_t ctrl, ctrl_ext; + uint32_t led_ctrl; DEBUGFUNC("e1000_phy_hw_reset"); diff -Nru a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h --- a/drivers/net/e1000/e1000_hw.h Sat Jul 19 12:53:01 2003 +++ b/drivers/net/e1000/e1000_hw.h Sat Jul 19 12:53:01 2003 @@ -1668,6 +1668,7 @@ #define M88E1000_EXT_PHY_SPEC_CTRL 0x14 /* Extended PHY Specific Control */ #define M88E1000_RX_ERR_CNTR 0x15 /* Receive Error Counter */ +#define IGP01E1000_IEEE_REGS_PAGE 0x0000 /* IGP01E1000 Specific Registers */ #define IGP01E1000_PHY_PORT_CONFIG 0x10 /* PHY Specific Port Config Register */ #define IGP01E1000_PHY_PORT_STATUS 0x11 /* PHY Specific Status Register */ @@ -1690,6 +1691,7 @@ * speed = 1000 Mbps. */ #define IGP01E1000_PHY_PCS_INIT_REG 0x00B4 +#define IGP01E1000_ANALOG_REGS_PAGE 0x20C0 #define MAX_PHY_REG_ADDRESS 0x1F /* 5 bit address bus (0-0x1F) */ @@ -1980,6 +1982,22 @@ #define IGP01E1000_GMII_FLEX_SPD 0x10 /* Enable flexible speed * on Link-Up */ #define IGP01E1000_GMII_SPD 0x20 /* Enable SPD */ +/* IGP01E1000 Analog Register */ +#define IGP01E1000_ANALOG_SPARE_FUSE_STATUS 0x0011 +#define IGP01E1000_ANALOG_FUSE_STATUS 0x0010 +#define IGP01E1000_ANALOG_FUSE_CONTROL 0x001C +#define IGP01E1000_ANALOG_FUSE_BYPASS 0x001E + +#define IGP01E1000_ANALOG_FUSE_POLY_MASK 0xF000 +#define IGP01E1000_ANALOG_FUSE_FINE_MASK 0x0F80 +#define IGP01E1000_ANALOG_FUSE_COARSE_MASK 0x0070 +#define IGP01E1000_ANALOG_SPARE_FUSE_ENABLED 0x0100 +#define IGP01E1000_ANALOG_FUSE_ENABLE_SW_CONTROL 0x0002 + +#define IGP01E1000_ANALOG_FUSE_COARSE_THRESH 0x0040 +#define IGP01E1000_ANALOG_FUSE_COARSE_10 0x0010 +#define IGP01E1000_ANALOG_FUSE_FINE_1 0x0080 +#define IGP01E1000_ANALOG_FUSE_FINE_10 0x0500 /* Bit definitions for valid PHY IDs. */ #define M88E1000_E_PHY_ID 0x01410C50 diff -Nru a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c --- a/drivers/net/e1000/e1000_main.c Sat Jul 19 12:53:01 2003 +++ b/drivers/net/e1000/e1000_main.c Sat Jul 19 12:53:01 2003 @@ -30,6 +30,14 @@ /* Change Log * + * 5.1.13 5/28/03 + * o Bug fix: request_irq() failure resulted in freeing resources twice! + * [Don Fry (brazilnut@us.ibm.com)] + * o Bug fix: fix VLAN support on ppc64 [Mark Rakes (mrakes@vivato.net)] + * o Bug fix: missing Tx cleanup opportunities during interrupt handling. + * o Bug fix: alloc_etherdev failure didn't cleanup regions in probe. + * o Cleanup: s/int/unsigned int/ for descriptor ring indexes. + * * 5.1.11 5/6/03 * o Feature: Added support for 82546EB (Quad-port) hardware. * o Feature: Added support for Diagnostics through Ethtool. @@ -38,26 +46,11 @@ * o Bug fix: TSO bug fixes. * * 5.0.42 3/5/03 - * o Feature: Added support for 82541 and 82547 hardware. - * o Feature: Added support for Intel Gigabit PHY (IGP) and a variety of - * eeproms. - * o Feature: Added support for TCP Segmentation Offload (TSO). - * o Feature: Added MII ioctl. - * o Feature: Added support for statistics reporting through ethtool. - * o Cleanup: Removed proprietary hooks for ANS. - * o Cleanup: Miscellaneous code changes to improve CPU utilization. - * - Replaced "%" with conditionals and "+-" operators. - * - Implemented dynamic Interrupt Throttle Rate (ITR). - * - Reduced expensive PCI reads of ICR in interrupt. - * o Bug fix: Request IRQ after descriptor ring setup to avoid panic in - * shared interrupt instances. - * - * 4.4.18 11/27/02 */ char e1000_driver_name[] = "e1000"; char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; -char e1000_driver_version[] = "5.1.11-k1"; +char e1000_driver_version[] = "5.1.13-k1"; char e1000_copyright[] = "Copyright (c) 1999-2003 Intel Corporation."; /* e1000_pci_tbl - PCI Device ID Table @@ -128,6 +121,7 @@ static inline void e1000_irq_disable(struct e1000_adapter *adapter); static inline void e1000_irq_enable(struct e1000_adapter *adapter); static void e1000_intr(int irq, void *data, struct pt_regs *regs); +static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter); #ifdef CONFIG_E1000_NAPI static int e1000_clean(struct net_device *netdev, int *budget); static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter, @@ -135,7 +129,6 @@ #else static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter); #endif -static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter); static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter); static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd); static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, @@ -248,12 +241,8 @@ e1000_alloc_rx_buffers(adapter); if(request_irq(netdev->irq, &e1000_intr, SA_SHIRQ | SA_SAMPLE_RANDOM, - netdev->name, netdev)) { - e1000_reset_hw(&adapter->hw); - e1000_free_tx_resources(adapter); - e1000_free_rx_resources(adapter); + netdev->name, netdev)) return -1; - } mod_timer(&adapter->watchdog_timer, jiffies); e1000_irq_enable(adapter); @@ -503,9 +492,9 @@ err_eeprom: iounmap(adapter->hw.hw_addr); err_ioremap: - pci_release_regions(pdev); kfree(netdev); err_alloc_etherdev: + pci_release_regions(pdev); return -ENOMEM; } @@ -980,35 +969,38 @@ static void e1000_clean_tx_ring(struct e1000_adapter *adapter) { + struct e1000_desc_ring *tx_ring = &adapter->tx_ring; + struct e1000_buffer *buffer_info; struct pci_dev *pdev = adapter->pdev; unsigned long size; - int i; + unsigned int i; /* Free all the Tx ring sk_buffs */ - for(i = 0; i < adapter->tx_ring.count; i++) { - if(adapter->tx_ring.buffer_info[i].skb) { + for(i = 0; i < tx_ring->count; i++) { + buffer_info = &tx_ring->buffer_info[i]; + if(buffer_info->skb) { pci_unmap_page(pdev, - adapter->tx_ring.buffer_info[i].dma, - adapter->tx_ring.buffer_info[i].length, + buffer_info->dma, + buffer_info->length, PCI_DMA_TODEVICE); - dev_kfree_skb(adapter->tx_ring.buffer_info[i].skb); + dev_kfree_skb(buffer_info->skb); - adapter->tx_ring.buffer_info[i].skb = NULL; + buffer_info->skb = NULL; } } - size = sizeof(struct e1000_buffer) * adapter->tx_ring.count; - memset(adapter->tx_ring.buffer_info, 0, size); + size = sizeof(struct e1000_buffer) * tx_ring->count; + memset(tx_ring->buffer_info, 0, size); /* Zero out the descriptor ring */ - memset(adapter->tx_ring.desc, 0, adapter->tx_ring.size); + memset(tx_ring->desc, 0, tx_ring->size); - adapter->tx_ring.next_to_use = 0; - adapter->tx_ring.next_to_clean = 0; + tx_ring->next_to_use = 0; + tx_ring->next_to_clean = 0; E1000_WRITE_REG(&adapter->hw, TDH, 0); E1000_WRITE_REG(&adapter->hw, TDT, 0); @@ -1024,17 +1016,17 @@ static void e1000_free_rx_resources(struct e1000_adapter *adapter) { + struct e1000_desc_ring *rx_ring = &adapter->rx_ring; struct pci_dev *pdev = adapter->pdev; e1000_clean_rx_ring(adapter); - kfree(adapter->rx_ring.buffer_info); - adapter->rx_ring.buffer_info = NULL; + kfree(rx_ring->buffer_info); + rx_ring->buffer_info = NULL; - pci_free_consistent(pdev, adapter->rx_ring.size, - adapter->rx_ring.desc, adapter->rx_ring.dma); + pci_free_consistent(pdev, rx_ring->size, rx_ring->desc, rx_ring->dma); - adapter->rx_ring.desc = NULL; + rx_ring->desc = NULL; } /** @@ -1045,35 +1037,38 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter) { + struct e1000_desc_ring *rx_ring = &adapter->rx_ring; + struct e1000_buffer *buffer_info; struct pci_dev *pdev = adapter->pdev; unsigned long size; - int i; + unsigned int i; /* Free all the Rx ring sk_buffs */ - for(i = 0; i < adapter->rx_ring.count; i++) { - if(adapter->rx_ring.buffer_info[i].skb) { + for(i = 0; i < rx_ring->count; i++) { + buffer_info = &rx_ring->buffer_info[i]; + if(buffer_info->skb) { pci_unmap_single(pdev, - adapter->rx_ring.buffer_info[i].dma, - adapter->rx_ring.buffer_info[i].length, + buffer_info->dma, + buffer_info->length, PCI_DMA_FROMDEVICE); - dev_kfree_skb(adapter->rx_ring.buffer_info[i].skb); + dev_kfree_skb(buffer_info->skb); - adapter->rx_ring.buffer_info[i].skb = NULL; + buffer_info->skb = NULL; } } - size = sizeof(struct e1000_buffer) * adapter->rx_ring.count; - memset(adapter->rx_ring.buffer_info, 0, size); + size = sizeof(struct e1000_buffer) * rx_ring->count; + memset(rx_ring->buffer_info, 0, size); /* Zero out the descriptor ring */ - memset(adapter->rx_ring.desc, 0, adapter->rx_ring.size); + memset(rx_ring->desc, 0, rx_ring->size); - adapter->rx_ring.next_to_clean = 0; - adapter->rx_ring.next_to_use = 0; + rx_ring->next_to_clean = 0; + rx_ring->next_to_use = 0; E1000_WRITE_REG(&adapter->hw, RDH, 0); E1000_WRITE_REG(&adapter->hw, RDT, 0); @@ -1323,7 +1318,7 @@ struct e1000_adapter *adapter = (struct e1000_adapter *) data; struct net_device *netdev = adapter->netdev; struct e1000_desc_ring *txdr = &adapter->tx_ring; - int i; + unsigned int i; e1000_check_for_link(&adapter->hw); @@ -1409,7 +1404,7 @@ { #ifdef NETIF_F_TSO struct e1000_context_desc *context_desc; - int i; + unsigned int i; uint8_t ipcss, ipcso, tucss, tucso, hdr_len; uint16_t ipcse, tucse, mss; @@ -1460,7 +1455,7 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb) { struct e1000_context_desc *context_desc; - int i; + unsigned int i; uint8_t css, cso; if(skb->ip_summed == CHECKSUM_HW) { @@ -1493,18 +1488,21 @@ unsigned int first) { struct e1000_desc_ring *tx_ring = &adapter->tx_ring; - int len = skb->len, offset = 0, size, count = 0, i; + struct e1000_buffer *buffer_info; + int len = skb->len; + unsigned int offset = 0, size, count = 0, i; #ifdef NETIF_F_TSO - int tso = skb_shinfo(skb)->tso_size; + unsigned int tso = skb_shinfo(skb)->tso_size; #endif - int nr_frags = skb_shinfo(skb)->nr_frags; - int f; + unsigned int nr_frags = skb_shinfo(skb)->nr_frags; + unsigned int f; len -= skb->data_len; i = tx_ring->next_to_use; while(len) { + buffer_info = &tx_ring->buffer_info[i]; size = min(len, E1000_MAX_DATA_PER_TXD); #ifdef NETIF_F_TSO /* Workaround for premature desc write-backs @@ -1512,13 +1510,13 @@ if(tso && !nr_frags && size == len && size > 4) size -= 4; #endif - tx_ring->buffer_info[i].length = size; - tx_ring->buffer_info[i].dma = + buffer_info->length = size; + buffer_info->dma = pci_map_single(adapter->pdev, skb->data + offset, size, PCI_DMA_TODEVICE); - tx_ring->buffer_info[i].time_stamp = jiffies; + buffer_info->time_stamp = jiffies; len -= size; offset += size; @@ -1534,6 +1532,7 @@ offset = 0; while(len) { + buffer_info = &tx_ring->buffer_info[i]; size = min(len, E1000_MAX_DATA_PER_TXD); #ifdef NETIF_F_TSO /* Workaround for premature desc write-backs @@ -1541,14 +1540,14 @@ if(tso && f == (nr_frags-1) && size == len && size > 4) size -= 4; #endif - tx_ring->buffer_info[i].length = size; - tx_ring->buffer_info[i].dma = + buffer_info->length = size; + buffer_info->dma = pci_map_page(adapter->pdev, frag->page, frag->page_offset + offset, size, PCI_DMA_TODEVICE); - tx_ring->buffer_info[i].time_stamp = jiffies; + buffer_info->time_stamp = jiffies; len -= size; offset += size; @@ -1556,7 +1555,7 @@ if(++i == tx_ring->count) i = 0; } } - if(--i < 0) i = tx_ring->count - 1; + i = (i == 0) ? tx_ring->count - 1 : i - 1; tx_ring->buffer_info[i].skb = skb; tx_ring->buffer_info[first].next_to_watch = i; @@ -1568,8 +1567,9 @@ { struct e1000_desc_ring *tx_ring = &adapter->tx_ring; struct e1000_tx_desc *tx_desc = NULL; + struct e1000_buffer *buffer_info; uint32_t txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS; - int i; + unsigned int i; if(tx_flags & E1000_TX_FLAGS_TSO) { txd_lower |= E1000_TXD_CMD_DEXT | E1000_TXD_DTYP_D | @@ -1590,10 +1590,11 @@ i = tx_ring->next_to_use; while(count--) { + buffer_info = &tx_ring->buffer_info[i]; tx_desc = E1000_TX_DESC(*tx_ring, i); - tx_desc->buffer_addr = cpu_to_le64(tx_ring->buffer_info[i].dma); + tx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); tx_desc->lower.data = - cpu_to_le32(txd_lower | tx_ring->buffer_info[i].length); + cpu_to_le32(txd_lower | buffer_info->length); tx_desc->upper.data = cpu_to_le32(txd_upper); if(++i == tx_ring->count) i = 0; } @@ -1659,7 +1660,7 @@ { struct e1000_adapter *adapter = netdev->priv; unsigned int first; - int tx_flags = 0; + unsigned int tx_flags = 0; if(skb->len <= 0) { dev_kfree_skb_any(skb); @@ -1971,7 +1972,7 @@ struct e1000_adapter *adapter = netdev->priv; uint32_t icr = E1000_READ_REG(&adapter->hw, ICR); #ifndef CONFIG_E1000_NAPI - int i; + unsigned int i; #endif if(!icr) @@ -1995,7 +1996,7 @@ } #else for(i = 0; i < E1000_MAX_INTR; i++) - if(!e1000_clean_rx_irq(adapter) && + if(!e1000_clean_rx_irq(adapter) & !e1000_clean_tx_irq(adapter)) break; #endif @@ -2042,7 +2043,8 @@ struct pci_dev *pdev = adapter->pdev; struct e1000_tx_desc *tx_desc, *eop_desc; struct e1000_buffer *buffer_info; - int i, eop, cleaned = FALSE; + unsigned int i, eop; + boolean_t cleaned = FALSE; i = tx_ring->next_to_clean; eop = tx_ring->buffer_info[i].next_to_watch; @@ -2108,16 +2110,19 @@ struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; struct e1000_rx_desc *rx_desc; + struct e1000_buffer *buffer_info; struct sk_buff *skb; unsigned long flags; uint32_t length; uint8_t last_byte; - int i, cleaned = FALSE; + unsigned int i; + boolean_t cleaned = FALSE; i = rx_ring->next_to_clean; rx_desc = E1000_RX_DESC(*rx_ring, i); while(rx_desc->status & E1000_RXD_STAT_DD) { + buffer_info = &rx_ring->buffer_info[i]; #ifdef CONFIG_E1000_NAPI if(*work_done >= work_to_do) @@ -2129,11 +2134,11 @@ cleaned = TRUE; pci_unmap_single(pdev, - rx_ring->buffer_info[i].dma, - rx_ring->buffer_info[i].length, + buffer_info->dma, + buffer_info->length, PCI_DMA_FROMDEVICE); - skb = rx_ring->buffer_info[i].skb; + skb = buffer_info->skb; length = le16_to_cpu(rx_desc->length); if(!(rx_desc->status & E1000_RXD_STAT_EOP)) { @@ -2144,7 +2149,7 @@ dev_kfree_skb_irq(skb); rx_desc->status = 0; - rx_ring->buffer_info[i].skb = NULL; + buffer_info->skb = NULL; if(++i == rx_ring->count) i = 0; @@ -2172,7 +2177,7 @@ dev_kfree_skb_irq(skb); rx_desc->status = 0; - rx_ring->buffer_info[i].skb = NULL; + buffer_info->skb = NULL; if(++i == rx_ring->count) i = 0; @@ -2191,14 +2196,16 @@ #ifdef CONFIG_E1000_NAPI if(adapter->vlgrp && (rx_desc->status & E1000_RXD_STAT_VP)) { vlan_hwaccel_receive_skb(skb, adapter->vlgrp, - (rx_desc->special & E1000_RXD_SPC_VLAN_MASK)); + le16_to_cpu(rx_desc->special & + E1000_RXD_SPC_VLAN_MASK)); } else { netif_receive_skb(skb); } #else /* CONFIG_E1000_NAPI */ if(adapter->vlgrp && (rx_desc->status & E1000_RXD_STAT_VP)) { vlan_hwaccel_rx(skb, adapter->vlgrp, - (rx_desc->special & E1000_RXD_SPC_VLAN_MASK)); + le16_to_cpu(rx_desc->special & + E1000_RXD_SPC_VLAN_MASK)); } else { netif_rx(skb); } @@ -2206,7 +2213,7 @@ netdev->last_rx = jiffies; rx_desc->status = 0; - rx_ring->buffer_info[i].skb = NULL; + buffer_info->skb = NULL; if(++i == rx_ring->count) i = 0; @@ -2232,13 +2239,15 @@ struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; struct e1000_rx_desc *rx_desc; + struct e1000_buffer *buffer_info; struct sk_buff *skb; int reserve_len = 2; - int i; + unsigned int i; i = rx_ring->next_to_use; + buffer_info = &rx_ring->buffer_info[i]; - while(!rx_ring->buffer_info[i].skb) { + while(!buffer_info->skb) { rx_desc = E1000_RX_DESC(*rx_ring, i); skb = dev_alloc_skb(adapter->rx_buffer_len + reserve_len); @@ -2256,15 +2265,15 @@ skb->dev = netdev; - rx_ring->buffer_info[i].skb = skb; - rx_ring->buffer_info[i].length = adapter->rx_buffer_len; - rx_ring->buffer_info[i].dma = + buffer_info->skb = skb; + buffer_info->length = adapter->rx_buffer_len; + buffer_info->dma = pci_map_single(pdev, skb->data, adapter->rx_buffer_len, PCI_DMA_FROMDEVICE); - rx_desc->buffer_addr = cpu_to_le64(rx_ring->buffer_info[i].dma); + rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma); if((i & ~(E1000_RX_BUFFER_WRITE - 1)) == i) { /* Force memory writes to complete before letting h/w @@ -2277,6 +2286,7 @@ } if(++i == rx_ring->count) i = 0; + buffer_info = &rx_ring->buffer_info[i]; } rx_ring->next_to_use = i; diff -Nru a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c --- a/drivers/net/ne2k-pci.c Sat Jul 19 12:53:01 2003 +++ b/drivers/net/ne2k-pci.c Sat Jul 19 12:53:01 2003 @@ -634,6 +634,7 @@ unregister_netdev(dev); release_region(dev->base_addr, NE_IO_EXTENT); + kfree(dev->priv); kfree(dev); pci_set_drvdata(pdev, NULL); } diff -Nru a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c --- a/drivers/net/via-rhine.c Sat Jul 19 12:53:01 2003 +++ b/drivers/net/via-rhine.c Sat Jul 19 12:53:01 2003 @@ -122,11 +122,14 @@ - No filtering multicast in promisc mode (Edward Peng) - Fix for Rhine-I Tx timeouts + LK1.1.19 (Roger Luethi) + - Increase Tx threshold for unspecified errors + */ #define DRV_NAME "via-rhine" -#define DRV_VERSION "1.1.18" -#define DRV_RELDATE "July-4-2003" +#define DRV_VERSION "1.1.19" +#define DRV_RELDATE "July-12-2003" /* A few user-configurable values. @@ -1659,9 +1662,13 @@ } if ((intr_status & IntrTxError) && ~( IntrTxAborted | IntrTxUnderrun | IntrTxDescRace )) { - if (debug > 2) - printk(KERN_INFO "%s: Unspecified error.\n", - dev->name); + if (np->tx_thresh < 0xE0) { + writeb(np->tx_thresh += 0x20, ioaddr + TxConfig); + } + if (debug > 1) + printk(KERN_INFO "%s: Unspecified error. Tx " + "threshold now %2.2x.\n", + dev->name, np->tx_thresh); } if (intr_status & ( IntrTxAborted | IntrTxUnderrun | IntrTxDescRace | IntrTxError )) diff -Nru a/include/linux/ethtool.h b/include/linux/ethtool.h --- a/include/linux/ethtool.h Sat Jul 19 12:53:01 2003 +++ b/include/linux/ethtool.h Sat Jul 19 12:53:01 2003 @@ -281,6 +281,8 @@ #define ETHTOOL_GSTRINGS 0x0000001b /* get specified string set */ #define ETHTOOL_PHYS_ID 0x0000001c /* identify the NIC */ #define ETHTOOL_GSTATS 0x0000001d /* get NIC-specific statistics */ +#define ETHTOOL_GTSO 0x0000001e /* Get TSO enable (ethtool_value) */ +#define ETHTOOL_STSO 0x0000001f /* Set TSO enable (ethtool_value) */ /* compatibility with older code */ #define SPARC_ETH_GSET ETHTOOL_GSET