diff -Nru a/drivers/net/8139too.c b/drivers/net/8139too.c --- a/drivers/net/8139too.c Tue Jul 8 03:59:36 2003 +++ b/drivers/net/8139too.c Tue Jul 8 03:59:36 2003 @@ -2070,7 +2070,7 @@ RTL_W16 (IntrStatus, ackstat); DPRINTK ("%s: interrupt status=%#4.4x ackstat=%#4.4x new intstat=%#4.4x.\n", - dev->name, ackstat, status, RTL_R16 (IntrStatus)); + dev->name, status, ackstat, RTL_R16 (IntrStatus)); if (netif_running (dev) && (status & RxAckBits)) rtl8139_rx_interrupt (dev, tp, ioaddr); diff -Nru a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h --- a/drivers/net/e1000/e1000.h Tue Jul 8 03:59:36 2003 +++ b/drivers/net/e1000/e1000.h Tue Jul 8 03:59:36 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 Tue Jul 8 03:59:36 2003 +++ b/drivers/net/e1000/e1000_ethtool.c Tue Jul 8 03:59:36 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 Tue Jul 8 03:59:36 2003 +++ b/drivers/net/e1000/e1000_hw.c Tue Jul 8 03:59:36 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 Tue Jul 8 03:59:36 2003 +++ b/drivers/net/e1000/e1000_hw.h Tue Jul 8 03:59:36 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 Tue Jul 8 03:59:36 2003 +++ b/drivers/net/e1000/e1000_main.c Tue Jul 8 03:59:36 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 irqreturn_t 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); @@ -504,9 +493,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; } @@ -981,35 +970,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); @@ -1025,17 +1017,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; } /** @@ -1046,35 +1038,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); @@ -1324,7 +1319,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); @@ -1410,7 +1405,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; @@ -1461,7 +1456,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) { @@ -1494,18 +1489,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 @@ -1513,13 +1511,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; @@ -1535,6 +1533,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 @@ -1542,14 +1541,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; @@ -1557,7 +1556,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; @@ -1569,8 +1568,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 | @@ -1591,10 +1591,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; } @@ -1660,7 +1661,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); @@ -1972,7 +1973,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) @@ -1996,7 +1997,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 @@ -2044,7 +2045,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; @@ -2110,16 +2112,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) @@ -2131,11 +2136,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)) { @@ -2146,7 +2151,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; @@ -2174,7 +2179,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; @@ -2193,14 +2198,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); } @@ -2208,7 +2215,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; @@ -2234,13 +2241,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); @@ -2258,15 +2267,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 @@ -2279,6 +2288,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/via-rhine.c b/drivers/net/via-rhine.c --- a/drivers/net/via-rhine.c Tue Jul 8 03:59:36 2003 +++ b/drivers/net/via-rhine.c Tue Jul 8 03:59:36 2003 @@ -2,6 +2,8 @@ /* Written 1998-2001 by Donald Becker. + Current Maintainer: Roger Luethi + This software may be used and distributed according to the terms of the GNU General Public License (GPL), incorporated herein by reference. Drivers based on or derived from this code fall under the GPL and must @@ -9,8 +11,9 @@ a complete program and may only be used when the entire operating system is licensed under the GPL. - This driver is designed for the VIA VT86C100A Rhine-I. - It also works with the 6102 Rhine-II, and 6105/6105M Rhine-III. + This driver is designed for the VIA VT86C100A Rhine-I. + It also works with the Rhine-II (6102) and Rhine-III (6105/6105L/6105LOM + and management NIC 6105M). The author may be reached as becker@scyld.com, or C/O Scyld Computing Corporation @@ -115,11 +118,15 @@ - Force flushing for PCI posted writes - More reset code changes + LK1.1.18 (Roger Luethi) + - No filtering multicast in promisc mode (Edward Peng) + - Fix for Rhine-I Tx timeouts + */ #define DRV_NAME "via-rhine" -#define DRV_VERSION "1.1.17" -#define DRV_RELDATE "March-1-2003" +#define DRV_VERSION "1.1.18-2.5" +#define DRV_RELDATE "July-4-2003" /* A few user-configurable values. @@ -386,17 +393,17 @@ { "VIA VT6102 Rhine-II", RHINE_IOTYPE, 256, CanHaveMII | HasWOL }, { "VIA VT6105 Rhine-III", RHINE_IOTYPE, 256, - CanHaveMII | HasWOL }, + CanHaveMII | HasWOL }, { "VIA VT6105M Rhine-III", RHINE_IOTYPE, 256, - CanHaveMII | HasWOL }, + CanHaveMII | HasWOL }, }; static struct pci_device_id via_rhine_pci_tbl[] __devinitdata = { {0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT86C100A}, {0x1106, 0x3065, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6102}, - {0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105}, - {0x1106, 0x3053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105M}, + {0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105}, /* 6105{,L,LOM} */ + {0x1106, 0x3053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VT6105M}, {0,} /* terminate list */ }; MODULE_DEVICE_TABLE(pci, via_rhine_pci_tbl); @@ -441,7 +448,7 @@ IntrRxWakeUp=0x8000, IntrNormalSummary=0x0003, IntrAbnormalSummary=0xC260, IntrTxDescRace=0x080000, /* mapped from IntrStatus2 */ - IntrTxErrSummary=0x082210, + IntrTxErrSummary=0x082218, }; /* The Rx and Tx buffer descriptors. */ @@ -1655,11 +1662,18 @@ printk(KERN_INFO "%s: Tx descriptor write-back race.\n", dev->name); } - if (intr_status & ( IntrTxAborted | IntrTxUnderrun | IntrTxDescRace )) + if ((intr_status & IntrTxError) && ~( IntrTxAborted | IntrTxUnderrun | + IntrTxDescRace )) { + if (debug > 2) + printk(KERN_INFO "%s: Unspecified error.\n", + dev->name); + } + if (intr_status & ( IntrTxAborted | IntrTxUnderrun | IntrTxDescRace | + IntrTxError )) via_rhine_restart_tx(dev); if (intr_status & ~( IntrLinkChange | IntrStatsMax | IntrTxUnderrun | - IntrTxError | IntrTxAborted | IntrNormalSummary | + IntrTxError | IntrTxAborted | IntrNormalSummary | IntrTxDescRace )) { if (debug > 1) printk(KERN_ERR "%s: Something Wicked happened! %8.8x.\n",