diff -Naurp linux-2.4.20-pre4-e1000-4/drivers/net/e1000/e1000.h linux-2.4.20-pre4-e1000-5/drivers/net/e1000/e1000.h --- linux-2.4.20-pre4-e1000-4/drivers/net/e1000/e1000.h Fri Aug 23 06:48:03 2002 +++ linux-2.4.20-pre4-e1000-5/drivers/net/e1000/e1000.h Fri Aug 23 06:55:25 2002 @@ -85,11 +85,7 @@ struct e1000_adapter; #define E1000_ERR(args...) printk(KERN_ERR "e1000: " args) -#ifdef CONFIG_PPC -#define E1000_MAX_INTR 1 -#else #define E1000_MAX_INTR 10 -#endif /* Supported Rx Buffer Sizes */ #define E1000_RXBUFFER_2048 2048 diff -Naurp linux-2.4.20-pre4-e1000-4/drivers/net/e1000/e1000_ethtool.c linux-2.4.20-pre4-e1000-5/drivers/net/e1000/e1000_ethtool.c --- linux-2.4.20-pre4-e1000-4/drivers/net/e1000/e1000_ethtool.c Fri Aug 23 06:46:41 2002 +++ linux-2.4.20-pre4-e1000-5/drivers/net/e1000/e1000_ethtool.c Fri Aug 23 09:00:44 2002 @@ -37,6 +37,7 @@ extern char e1000_driver_version[]; extern int e1000_up(struct e1000_adapter *adapter); extern void e1000_down(struct e1000_adapter *adapter); +extern void e1000_reset(struct e1000_adapter *adapter); static void e1000_ethtool_gset(struct e1000_adapter *adapter, struct ethtool_cmd *ecmd) @@ -144,8 +145,11 @@ e1000_ethtool_sset(struct e1000_adapter /* reset the link */ - e1000_down(adapter); - e1000_up(adapter); + if(netif_running(adapter->netdev)) { + e1000_down(adapter); + e1000_up(adapter); + } else + e1000_reset(adapter); return 0; } @@ -166,7 +170,7 @@ e1000_ethtool_gdrvinfo(struct e1000_adap { strncpy(drvinfo->driver, e1000_driver_name, 32); strncpy(drvinfo->version, e1000_driver_version, 32); - strncpy(drvinfo->fw_version, "", 32); + strncpy(drvinfo->fw_version, "N/A", 32); strncpy(drvinfo->bus_info, adapter->pdev->slot_name, 32); #define E1000_REGS_LEN 32 drvinfo->regdump_len = E1000_REGS_LEN * sizeof(uint32_t); @@ -206,7 +210,8 @@ e1000_ethtool_geeprom(struct e1000_adapt struct e1000_hw *hw = &adapter->hw; int i, max_len, first_word, last_word; - if(eeprom->len == 0) return; + if(eeprom->len == 0) + return -EINVAL; eeprom->magic = hw->vendor_id | (hw->device_id << 16); @@ -469,8 +474,10 @@ e1000_ethtool_ioctl(struct net_device *n case ETHTOOL_NWAY_RST: { if(!capable(CAP_NET_ADMIN)) return -EPERM; - e1000_down(adapter); - e1000_up(adapter); + if(netif_running(netdev)) { + e1000_down(adapter); + e1000_up(adapter); + } return 0; } case ETHTOOL_PHYS_ID: { diff -Naurp linux-2.4.20-pre4-e1000-4/drivers/net/e1000/e1000_hw.c linux-2.4.20-pre4-e1000-5/drivers/net/e1000/e1000_hw.c --- linux-2.4.20-pre4-e1000-4/drivers/net/e1000/e1000_hw.c Fri Aug 23 06:46:41 2002 +++ linux-2.4.20-pre4-e1000-5/drivers/net/e1000/e1000_hw.c Fri Aug 23 06:55:25 2002 @@ -48,9 +48,63 @@ static void e1000_shift_out_ee_bits(stru static uint16_t e1000_shift_in_ee_bits(struct e1000_hw *hw); static void e1000_setup_eeprom(struct e1000_hw *hw); static void e1000_standby_eeprom(struct e1000_hw *hw); +static void e1000_clock_eeprom(struct e1000_hw *hw); +static void e1000_cleanup_eeprom(struct e1000_hw *hw); static int32_t e1000_id_led_init(struct e1000_hw * hw); /****************************************************************************** + * Set the mac type member in the hw struct. + * + * hw - Struct containing variables accessed by shared code + *****************************************************************************/ +int32_t +e1000_set_mac_type(struct e1000_hw *hw) +{ + DEBUGFUNC("e1000_set_mac_type"); + + switch (hw->device_id) { + case E1000_DEV_ID_82542: + switch (hw->revision_id) { + case E1000_82542_2_0_REV_ID: + hw->mac_type = e1000_82542_rev2_0; + break; + case E1000_82542_2_1_REV_ID: + hw->mac_type = e1000_82542_rev2_1; + break; + default: + /* Invalid 82542 revision ID */ + return -E1000_ERR_MAC_TYPE; + } + break; + case E1000_DEV_ID_82543GC_FIBER: + case E1000_DEV_ID_82543GC_COPPER: + hw->mac_type = e1000_82543; + break; + case E1000_DEV_ID_82544EI_COPPER: + case E1000_DEV_ID_82544EI_FIBER: + case E1000_DEV_ID_82544GC_COPPER: + case E1000_DEV_ID_82544GC_LOM: + hw->mac_type = e1000_82544; + break; + case E1000_DEV_ID_82540EM: + case E1000_DEV_ID_82540EM_LOM: + hw->mac_type = e1000_82540; + break; + case E1000_DEV_ID_82545EM_COPPER: + case E1000_DEV_ID_82545EM_FIBER: + hw->mac_type = e1000_82545; + break; + case E1000_DEV_ID_82546EB_COPPER: + case E1000_DEV_ID_82546EB_FIBER: + hw->mac_type = e1000_82546; + break; + default: + /* Should never have loaded on this device */ + return -E1000_ERR_MAC_TYPE; + } + return E1000_SUCCESS; +} +/****************************************************************************** * Reset the transmit and receive units; mask and clear all interrupts. * * hw - Struct containing variables accessed by shared code @@ -164,8 +218,8 @@ e1000_init_hw(struct e1000_hw *hw) /* Initialize Identification LED */ ret_val = e1000_id_led_init(hw); if(ret_val < 0) { - DEBUGOUT("Error Initializing Identification LED\n"); - return ret_val; + DEBUGOUT("Error Initializing Identification LED\n"); + return ret_val; } /* Set the Media Type and exit with error if it is not valid. */ @@ -239,6 +293,8 @@ e1000_init_hw(struct e1000_hw *hw) PCIX_COMMAND_MMRBC_SHIFT; stat_mmrbc = (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >> PCIX_STATUS_HI_MMRBC_SHIFT; + if(stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K) + stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K; if(cmd_mmrbc > stat_mmrbc) { pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK; pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT; @@ -249,6 +305,13 @@ e1000_init_hw(struct e1000_hw *hw) /* Call a subroutine to configure the link and setup flow control. */ ret_val = e1000_setup_link(hw); + /* Set the transmit descriptor write-back policy */ + if(hw->mac_type > e1000_82544) { + ctrl = E1000_READ_REG(hw, TXDCTL); + ctrl = (ctrl & ~E1000_TXDCTL_WTHRESH) | E1000_TXDCTL_FULL_TX_DESC_WB; + E1000_WRITE_REG(hw, TXDCTL, ctrl); + } + /* Clear all of the statistics registers (clear on read). It is * important that we do this after we have tried to establish link * because the symbol error count will increment wildly if there @@ -374,7 +437,6 @@ e1000_setup_link(struct e1000_hw *hw) * Sets up link for a fiber based adapter * * hw - Struct containing variables accessed by shared code - * ctrl - Current value of the device control register * * Manipulates Physical Coding Sublayer functions in order to configure * link. Assumes the hardware has been previously reset and the transmitter @@ -505,7 +567,6 @@ e1000_setup_fiber_link(struct e1000_hw * * Detects which PHY is present and the speed and duplex * * hw - Struct containing variables accessed by shared code -* ctrl - current value of the device control register ******************************************************************************/ static int32_t e1000_setup_copper_link(struct e1000_hw *hw) @@ -2986,12 +3047,12 @@ e1000_id_led_init(struct e1000_hw * hw) const uint32_t ledctl_off = E1000_LEDCTL_MODE_LED_OFF; uint16_t eeprom_data, i, temp; const uint16_t led_mask = 0x0F; - + DEBUGFUNC("e1000_id_led_init"); if(hw->mac_type < e1000_82540) { - /* Nothing to do */ - return 0; + /* Nothing to do */ + return 0; } ledctl = E1000_READ_REG(hw, LEDCTL); @@ -3008,39 +3069,39 @@ e1000_id_led_init(struct e1000_hw * hw) for(i = 0; i < 4; i++) { temp = (eeprom_data >> (i << 2)) & led_mask; switch(temp) { - case ID_LED_ON1_DEF2: - case ID_LED_ON1_ON2: - case ID_LED_ON1_OFF2: + case ID_LED_ON1_DEF2: + case ID_LED_ON1_ON2: + case ID_LED_ON1_OFF2: hw->ledctl_mode1 &= ~(ledctl_mask << (i << 3)); hw->ledctl_mode1 |= ledctl_on << (i << 3); break; - case ID_LED_OFF1_DEF2: - case ID_LED_OFF1_ON2: - case ID_LED_OFF1_OFF2: + case ID_LED_OFF1_DEF2: + case ID_LED_OFF1_ON2: + case ID_LED_OFF1_OFF2: hw->ledctl_mode1 &= ~(ledctl_mask << (i << 3)); hw->ledctl_mode1 |= ledctl_off << (i << 3); break; - default: - /* Do nothing */ - break; - } - switch(temp) { - case ID_LED_DEF1_ON2: - case ID_LED_ON1_ON2: - case ID_LED_OFF1_ON2: + default: + /* Do nothing */ + break; + } + switch(temp) { + case ID_LED_DEF1_ON2: + case ID_LED_ON1_ON2: + case ID_LED_OFF1_ON2: hw->ledctl_mode2 &= ~(ledctl_mask << (i << 3)); hw->ledctl_mode2 |= ledctl_on << (i << 3); break; - case ID_LED_DEF1_OFF2: - case ID_LED_ON1_OFF2: - case ID_LED_OFF1_OFF2: + case ID_LED_DEF1_OFF2: + case ID_LED_ON1_OFF2: + case ID_LED_OFF1_OFF2: hw->ledctl_mode2 &= ~(ledctl_mask << (i << 3)); hw->ledctl_mode2 |= ledctl_off << (i << 3); break; - default: - /* Do nothing */ - break; - } + default: + /* Do nothing */ + break; + } } return 0; } diff -Naurp linux-2.4.20-pre4-e1000-4/drivers/net/e1000/e1000_hw.h linux-2.4.20-pre4-e1000-5/drivers/net/e1000/e1000_hw.h --- linux-2.4.20-pre4-e1000-4/drivers/net/e1000/e1000_hw.h Fri Aug 23 06:46:41 2002 +++ linux-2.4.20-pre4-e1000-5/drivers/net/e1000/e1000_hw.h Fri Aug 23 06:55:25 2002 @@ -42,7 +42,8 @@ struct e1000_hw_stats; /* Enumerated types specific to the e1000 hardware */ /* Media Access Controlers */ typedef enum { - e1000_82542_rev2_0 = 0, + e1000_undefined = 0, + e1000_82542_rev2_0, e1000_82542_rev2_1, e1000_82543, e1000_82544, @@ -159,16 +160,18 @@ struct e1000_phy_stats { /* Error Codes */ -#define E1000_SUCCESS 0 -#define E1000_ERR_EEPROM 1 -#define E1000_ERR_PHY 2 -#define E1000_ERR_CONFIG 3 -#define E1000_ERR_PARAM 4 +#define E1000_SUCCESS 0 +#define E1000_ERR_EEPROM 1 +#define E1000_ERR_PHY 2 +#define E1000_ERR_CONFIG 3 +#define E1000_ERR_PARAM 4 +#define E1000_ERR_MAC_TYPE 5 /* Function prototypes */ /* Initialization */ void e1000_reset_hw(struct e1000_hw *hw); int32_t e1000_init_hw(struct e1000_hw *hw); +int32_t e1000_set_mac_type(struct e1000_hw *hw); /* Link Configuration */ int32_t e1000_setup_link(struct e1000_hw *hw); @@ -1185,6 +1188,7 @@ struct e1000_hw { #define E1000_TXDCTL_WTHRESH 0x00FF0000 /* TXDCTL Writeback Threshold */ #define E1000_TXDCTL_GRAN 0x01000000 /* TXDCTL Granularity */ #define E1000_TXDCTL_LWTHRESH 0xFE000000 /* TXDCTL Low Threshold */ +#define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */ /* Transmit Configuration Word */ #define E1000_TXCW_FD 0x00000020 /* TXCW full duplex */ @@ -1424,6 +1428,8 @@ struct e1000_hw { #define PCIX_COMMAND_MMRBC_SHIFT 0x2 #define PCIX_STATUS_HI_MMRBC_MASK 0x0060 #define PCIX_STATUS_HI_MMRBC_SHIFT 0x5 +#define PCIX_STATUS_HI_MMRBC_4K 0x3 +#define PCIX_STATUS_HI_MMRBC_2K 0x2 /* The number of bits that we need to shift right to move the "pause" diff -Naurp linux-2.4.20-pre4-e1000-4/drivers/net/e1000/e1000_main.c linux-2.4.20-pre4-e1000-5/drivers/net/e1000/e1000_main.c --- linux-2.4.20-pre4-e1000-4/drivers/net/e1000/e1000_main.c Fri Aug 23 06:48:03 2002 +++ linux-2.4.20-pre4-e1000-5/drivers/net/e1000/e1000_main.c Fri Aug 23 06:55:25 2002 @@ -31,6 +31,20 @@ /* Change Log * + * 4.3.15 8/9/02 + * o Converted from Dual BSD/GPL license to GPL license. + * o Clean up: use pci_[clear|set]_mwi rather than direct calls to + * pci_write_config_word. + * o Bug fix: added read-behind-write calls to post writes before delays. + * o Bug fix: removed mdelay busy-waits in interrupt context. + * o Clean up: direct clear of descriptor bits rather than using memset. + * o Bug fix: added wmb() for ia-64 between descritor writes and advancing + * descriptor tail. + * o Feature: added locking mechanism for asf functionality. + * o Feature: exposed two Tx and one Rx interrupt delay knobs for finer + * control over interurpt rate tuning. + * o Misc ethtool bug fixes. + * * 4.3.2 7/5/02 * o Bug fix: perform controller reset using I/O rather than mmio because * some chipsets try to perform a 64-bit write, but the controller ignores @@ -51,10 +65,10 @@ * * 4.2.17 5/30/02 */ - + char e1000_driver_name[] = "e1000"; char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; -char e1000_driver_version[] = "4.3.2-k1"; +char e1000_driver_version[] = "4.3.15-k1"; char e1000_copyright[] = "Copyright (c) 1999-2002 Intel Corporation."; /* e1000_pci_tbl - PCI Device ID Table @@ -547,43 +561,8 @@ e1000_sw_init(struct e1000_adapter *adap /* identify the MAC */ - switch (hw->device_id) { - case E1000_DEV_ID_82542: - switch (hw->revision_id) { - case E1000_82542_2_0_REV_ID: - hw->mac_type = e1000_82542_rev2_0; - break; - case E1000_82542_2_1_REV_ID: - hw->mac_type = e1000_82542_rev2_1; - break; - default: - hw->mac_type = e1000_82542_rev2_0; - E1000_ERR("Could not identify 82542 revision\n"); - } - break; - case E1000_DEV_ID_82543GC_FIBER: - case E1000_DEV_ID_82543GC_COPPER: - hw->mac_type = e1000_82543; - break; - case E1000_DEV_ID_82544EI_COPPER: - case E1000_DEV_ID_82544EI_FIBER: - case E1000_DEV_ID_82544GC_COPPER: - case E1000_DEV_ID_82544GC_LOM: - hw->mac_type = e1000_82544; - break; - case E1000_DEV_ID_82540EM: - hw->mac_type = e1000_82540; - break; - case E1000_DEV_ID_82545EM_COPPER: - case E1000_DEV_ID_82545EM_FIBER: - hw->mac_type = e1000_82545; - break; - case E1000_DEV_ID_82546EB_COPPER: - case E1000_DEV_ID_82546EB_FIBER: - hw->mac_type = e1000_82546; - break; - default: - E1000_ERR("Should never have loaded on this device\n"); + if (e1000_set_mac_type(hw)) { + E1000_ERR("Unknown MAC Type\n"); BUG(); } @@ -1418,9 +1397,14 @@ e1000_tx_queue(struct e1000_adapter *ada tx_desc->lower.data |= cpu_to_le32(E1000_TXD_CMD_EOP); + /* Force memory writes to complete before letting h/w + * know there are new descriptors to fetch. (Only + * applicable for weak-ordered memory model archs, + * such as IA-64). */ + wmb(); + tx_ring->next_to_use = i; E1000_WRITE_REG(&adapter->hw, TDT, i); - E1000_WRITE_FLUSH(&adapter->hw); } #define TXD_USE_COUNT(S, X) (((S) / (X)) + (((S) % (X)) ? 1 : 0)) @@ -1940,8 +1924,15 @@ e1000_alloc_rx_buffers(struct e1000_adap rx_desc->buffer_addr = cpu_to_le64(rx_ring->buffer_info[i].dma); - if(!(i % E1000_RX_BUFFER_WRITE)) + if(!(i % E1000_RX_BUFFER_WRITE)) { + /* Force memory writes to complete before letting h/w + * know there are new descriptors to fetch. (Only + * applicable for weak-ordered memory model archs, + * such as IA-64). */ + wmb(); + E1000_WRITE_REG(&adapter->hw, RDT, i); + } i = (i + 1) % rx_ring->count; } diff -Naurp linux-2.4.20-pre4-e1000-4/drivers/net/e1000/e1000_osdep.h linux-2.4.20-pre4-e1000-5/drivers/net/e1000/e1000_osdep.h --- linux-2.4.20-pre4-e1000-4/drivers/net/e1000/e1000_osdep.h Fri Aug 23 06:46:41 2002 +++ linux-2.4.20-pre4-e1000-5/drivers/net/e1000/e1000_osdep.h Fri Aug 23 06:55:25 2002 @@ -96,6 +96,6 @@ typedef enum { readl((a)->hw_addr + E1000_##reg + ((offset) << 2)) : \ readl((a)->hw_addr + E1000_82542_##reg + ((offset) << 2))) -#define E1000_WRITE_FLUSH(a) E1000_READ_REG(a, STATUS); +#define E1000_WRITE_FLUSH(a) ((void)E1000_READ_REG(a, STATUS)) #endif /* _E1000_OSDEP_H_ */ .