Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
David S. Miller [Sat, 22 Nov 2008 01:05:11 +0000 (17:05 -0800)]
17 files changed:
drivers/net/e1000e/82571.c
drivers/net/e1000e/defines.h
drivers/net/e1000e/e1000.h
drivers/net/e1000e/es2lan.c
drivers/net/e1000e/ethtool.c
drivers/net/e1000e/hw.h
drivers/net/e1000e/ich8lan.c
drivers/net/e1000e/lib.c
drivers/net/e1000e/netdev.c
drivers/net/e1000e/phy.c
drivers/net/wan/Kconfig
drivers/net/wan/hdlc_fr.c
drivers/net/wan/pc300_drv.c
include/linux/hdlc.h
include/net/inet_hashtables.h
net/ipv4/inet_diag.c
net/sched/sch_drr.c

index 3027ad5..cf43ee7 100644 (file)
@@ -28,6 +28,7 @@
 
 /*
  * 82571EB Gigabit Ethernet Controller
+ * 82571EB Gigabit Ethernet Controller (Copper)
  * 82571EB Gigabit Ethernet Controller (Fiber)
  * 82571EB Dual Port Gigabit Mezzanine Adapter
  * 82571EB Quad Port Gigabit Mezzanine Adapter
@@ -331,8 +332,9 @@ static s32 e1000_get_variants_82571(struct e1000_adapter *adapter)
 
        case e1000_82573:
                if (pdev->device == E1000_DEV_ID_82573L) {
-                       e1000_read_nvm(&adapter->hw, NVM_INIT_3GIO_3, 1,
-                                      &eeprom_data);
+                       if (e1000_read_nvm(&adapter->hw, NVM_INIT_3GIO_3, 1,
+                                      &eeprom_data) < 0)
+                               break;
                        if (eeprom_data & NVM_WORD1A_ASPM_MASK)
                                adapter->flags &= ~FLAG_HAS_JUMBO_FRAMES;
                }
@@ -1117,8 +1119,8 @@ static s32 e1000_setup_link_82571(struct e1000_hw *hw)
         * set it to full.
         */
        if ((hw->mac.type == e1000_82573 || hw->mac.type == e1000_82574) &&
-           hw->fc.type == e1000_fc_default)
-               hw->fc.type = e1000_fc_full;
+           hw->fc.requested_mode == e1000_fc_default)
+               hw->fc.requested_mode = e1000_fc_full;
 
        return e1000e_setup_link(hw);
 }
@@ -1393,6 +1395,7 @@ static struct e1000_phy_operations e82_phy_ops_igp = {
        .set_d0_lplu_state      = e1000_set_d0_lplu_state_82571,
        .set_d3_lplu_state      = e1000e_set_d3_lplu_state,
        .write_phy_reg          = e1000e_write_phy_reg_igp,
+       .cfg_on_link_up         = NULL,
 };
 
 static struct e1000_phy_operations e82_phy_ops_m88 = {
@@ -1409,6 +1412,7 @@ static struct e1000_phy_operations e82_phy_ops_m88 = {
        .set_d0_lplu_state      = e1000_set_d0_lplu_state_82571,
        .set_d3_lplu_state      = e1000e_set_d3_lplu_state,
        .write_phy_reg          = e1000e_write_phy_reg_m88,
+       .cfg_on_link_up         = NULL,
 };
 
 static struct e1000_phy_operations e82_phy_ops_bm = {
@@ -1425,6 +1429,7 @@ static struct e1000_phy_operations e82_phy_ops_bm = {
        .set_d0_lplu_state      = e1000_set_d0_lplu_state_82571,
        .set_d3_lplu_state      = e1000e_set_d3_lplu_state,
        .write_phy_reg          = e1000e_write_phy_reg_bm2,
+       .cfg_on_link_up         = NULL,
 };
 
 static struct e1000_nvm_operations e82571_nvm_ops = {
index 34a68fc..e6caf29 100644 (file)
 #define E1000_EECD_FLUPD     0x00080000 /* Update FLASH */
 #define E1000_EECD_AUPDEN    0x00100000 /* Enable Autonomous FLASH update */
 #define E1000_EECD_SEC1VAL   0x00400000 /* Sector One Valid */
+#define E1000_EECD_SEC1VAL_VALID_MASK (E1000_EECD_AUTO_RD | E1000_EECD_PRES)
 
 #define E1000_NVM_RW_REG_DATA   16   /* Offset to data in NVM read/write registers */
 #define E1000_NVM_RW_REG_DONE   2    /* Offset to READ/WRITE done bit */
index c55fd6f..37bcb19 100644 (file)
@@ -193,6 +193,7 @@ struct e1000_adapter {
        u16 mng_vlan_id;
        u16 link_speed;
        u16 link_duplex;
+       u16 eeprom_vers;
 
        spinlock_t tx_queue_lock; /* prevent concurrent tail updates */
 
@@ -388,6 +389,7 @@ extern int e1000e_setup_tx_resources(struct e1000_adapter *adapter);
 extern void e1000e_free_rx_resources(struct e1000_adapter *adapter);
 extern void e1000e_free_tx_resources(struct e1000_adapter *adapter);
 extern void e1000e_update_stats(struct e1000_adapter *adapter);
+extern bool e1000_has_link(struct e1000_adapter *adapter);
 extern void e1000e_set_interrupt_capability(struct e1000_adapter *adapter);
 extern void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter);
 
index da9c09c..db51114 100644 (file)
@@ -112,6 +112,11 @@ static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw);
 static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw);
 static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw);
 static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex);
+static s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw);
+static s32  e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
+                                            u16 *data);
+static s32  e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
+                                             u16 data);
 
 /**
  *  e1000_init_phy_params_80003es2lan - Init ESB2 PHY func ptrs.
@@ -275,8 +280,6 @@ static s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw)
        u16 mask;
 
        mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
-       mask |= E1000_SWFW_CSR_SM;
-
        return e1000_acquire_swfw_sync_80003es2lan(hw, mask);
 }
 
@@ -292,7 +295,36 @@ static void e1000_release_phy_80003es2lan(struct e1000_hw *hw)
        u16 mask;
 
        mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
-       mask |= E1000_SWFW_CSR_SM;
+       e1000_release_swfw_sync_80003es2lan(hw, mask);
+}
+
+/**
+ *  e1000_acquire_mac_csr_80003es2lan - Acquire rights to access Kumeran register
+ *  @hw: pointer to the HW structure
+ *
+ *  Acquire the semaphore to access the Kumeran interface.
+ *
+ **/
+static s32 e1000_acquire_mac_csr_80003es2lan(struct e1000_hw *hw)
+{
+       u16 mask;
+
+       mask = E1000_SWFW_CSR_SM;
+
+       return e1000_acquire_swfw_sync_80003es2lan(hw, mask);
+}
+
+/**
+ *  e1000_release_mac_csr_80003es2lan - Release rights to access Kumeran Register
+ *  @hw: pointer to the HW structure
+ *
+ *  Release the semaphore used to access the Kumeran interface
+ **/
+static void e1000_release_mac_csr_80003es2lan(struct e1000_hw *hw)
+{
+       u16 mask;
+
+       mask = E1000_SWFW_CSR_SM;
 
        e1000_release_swfw_sync_80003es2lan(hw, mask);
 }
@@ -347,7 +379,7 @@ static s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask)
        u32 swmask = mask;
        u32 fwmask = mask << 16;
        s32 i = 0;
-       s32 timeout = 200;
+       s32 timeout = 50;
 
        while (i < timeout) {
                if (e1000e_get_hw_semaphore(hw))
@@ -715,13 +747,7 @@ static s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed,
                ret_val = e1000e_get_speed_and_duplex_copper(hw,
                                                                    speed,
                                                                    duplex);
-               if (ret_val)
-                       return ret_val;
-               if (*speed == SPEED_1000)
-                       ret_val = e1000_cfg_kmrn_1000_80003es2lan(hw);
-               else
-                       ret_val = e1000_cfg_kmrn_10_100_80003es2lan(hw,
-                                                             *duplex);
+               hw->phy.ops.cfg_on_link_up(hw);
        } else {
                ret_val = e1000e_get_speed_and_duplex_fiber_serdes(hw,
                                                                  speed,
@@ -763,8 +789,10 @@ static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw)
 
        ctrl = er32(CTRL);
 
+       ret_val = e1000_acquire_phy_80003es2lan(hw);
        hw_dbg(hw, "Issuing a global reset to MAC\n");
        ew32(CTRL, ctrl | E1000_CTRL_RST);
+       e1000_release_phy_80003es2lan(hw);
 
        ret_val = e1000e_get_auto_rd_done(hw);
        if (ret_val)
@@ -907,8 +935,7 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw)
        struct e1000_phy_info *phy = &hw->phy;
        s32 ret_val;
        u32 ctrl_ext;
-       u32 i = 0;
-       u16 data, data2;
+       u16 data;
 
        ret_val = e1e_rphy(hw, GG82563_PHY_MAC_SPEC_CTRL, &data);
        if (ret_val)
@@ -972,19 +999,20 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw)
        }
 
        /* Bypass Rx and Tx FIFO's */
-       ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL,
+       ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
+                                       E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL,
                                        E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS |
                                        E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS);
        if (ret_val)
                return ret_val;
 
-       ret_val = e1000e_read_kmrn_reg(hw,
+       ret_val = e1000_read_kmrn_reg_80003es2lan(hw,
                                       E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE,
                                       &data);
        if (ret_val)
                return ret_val;
        data |= E1000_KMRNCTRLSTA_OPMODE_E_IDLE;
-       ret_val = e1000e_write_kmrn_reg(hw,
+       ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
                                        E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE,
                                        data);
        if (ret_val)
@@ -1019,18 +1047,9 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw)
                if (ret_val)
                        return ret_val;
 
-               do {
-                       ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL,
-                                          &data);
-                       if (ret_val)
-                               return ret_val;
-
-                       ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL,
-                                          &data2);
-                       if (ret_val)
-                               return ret_val;
-                       i++;
-               } while ((data != data2) && (i < GG82563_MAX_KMRN_RETRY));
+               ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, &data);
+               if (ret_val)
+                       return ret_val;
 
                data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
                ret_val = e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, data);
@@ -1077,23 +1096,27 @@ static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw)
         * iteration and increase the max iterations when
         * polling the phy; this fixes erroneous timeouts at 10Mbps.
         */
-       ret_val = e1000e_write_kmrn_reg(hw, GG82563_REG(0x34, 4), 0xFFFF);
+       ret_val = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 4),
+                                                  0xFFFF);
        if (ret_val)
                return ret_val;
-       ret_val = e1000e_read_kmrn_reg(hw, GG82563_REG(0x34, 9), &reg_data);
+       ret_val = e1000_read_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9),
+                                                 &reg_data);
        if (ret_val)
                return ret_val;
        reg_data |= 0x3F;
-       ret_val = e1000e_write_kmrn_reg(hw, GG82563_REG(0x34, 9), reg_data);
+       ret_val = e1000_write_kmrn_reg_80003es2lan(hw, GG82563_REG(0x34, 9),
+                                                  reg_data);
        if (ret_val)
                return ret_val;
-       ret_val = e1000e_read_kmrn_reg(hw,
+       ret_val = e1000_read_kmrn_reg_80003es2lan(hw,
                                      E1000_KMRNCTRLSTA_OFFSET_INB_CTRL,
                                      &reg_data);
        if (ret_val)
                return ret_val;
        reg_data |= E1000_KMRNCTRLSTA_INB_CTRL_DIS_PADDING;
-       ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_OFFSET_INB_CTRL,
+       ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
+                                       E1000_KMRNCTRLSTA_OFFSET_INB_CTRL,
                                        reg_data);
        if (ret_val)
                return ret_val;
@@ -1108,6 +1131,35 @@ static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw)
 }
 
 /**
+ *  e1000_cfg_on_link_up_80003es2lan - es2 link configuration after link-up
+ *  @hw: pointer to the HW structure
+ *  @duplex: current duplex setting
+ *
+ *  Configure the KMRN interface by applying last minute quirks for
+ *  10/100 operation.
+ **/
+static s32 e1000_cfg_on_link_up_80003es2lan(struct e1000_hw *hw)
+{
+       s32 ret_val = 0;
+       u16 speed;
+       u16 duplex;
+
+       if (hw->phy.media_type == e1000_media_type_copper) {
+               ret_val = e1000e_get_speed_and_duplex_copper(hw, &speed,
+                                                            &duplex);
+               if (ret_val)
+                       return ret_val;
+
+               if (speed == SPEED_1000)
+                       ret_val = e1000_cfg_kmrn_1000_80003es2lan(hw);
+               else
+                       ret_val = e1000_cfg_kmrn_10_100_80003es2lan(hw, duplex);
+       }
+
+       return ret_val;
+}
+
+/**
  *  e1000_cfg_kmrn_10_100_80003es2lan - Apply "quirks" for 10/100 operation
  *  @hw: pointer to the HW structure
  *  @duplex: current duplex setting
@@ -1123,8 +1175,9 @@ static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex)
        u16 reg_data, reg_data2;
 
        reg_data = E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT;
-       ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_OFFSET_HD_CTRL,
-                                       reg_data);
+       ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
+                                      E1000_KMRNCTRLSTA_OFFSET_HD_CTRL,
+                                      reg_data);
        if (ret_val)
                return ret_val;
 
@@ -1170,8 +1223,9 @@ static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw)
        u32 i = 0;
 
        reg_data = E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT;
-       ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_OFFSET_HD_CTRL,
-                                       reg_data);
+       ret_val = e1000_write_kmrn_reg_80003es2lan(hw,
+                                      E1000_KMRNCTRLSTA_OFFSET_HD_CTRL,
+                                      reg_data);
        if (ret_val)
                return ret_val;
 
@@ -1199,6 +1253,69 @@ static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw)
 }
 
 /**
+ *  e1000_read_kmrn_reg_80003es2lan - Read kumeran register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to be read
+ *  @data: pointer to the read data
+ *
+ *  Acquire semaphore, then read the PHY register at offset
+ *  using the kumeran interface.  The information retrieved is stored in data.
+ *  Release the semaphore before exiting.
+ **/
+s32 e1000_read_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+       u32 kmrnctrlsta;
+       s32 ret_val = 0;
+
+       ret_val = e1000_acquire_mac_csr_80003es2lan(hw);
+       if (ret_val)
+               return ret_val;
+
+       kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
+                      E1000_KMRNCTRLSTA_OFFSET) | E1000_KMRNCTRLSTA_REN;
+       ew32(KMRNCTRLSTA, kmrnctrlsta);
+
+       udelay(2);
+
+       kmrnctrlsta = er32(KMRNCTRLSTA);
+       *data = (u16)kmrnctrlsta;
+
+       e1000_release_mac_csr_80003es2lan(hw);
+
+       return ret_val;
+}
+
+/**
+ *  e1000_write_kmrn_reg_80003es2lan - Write kumeran register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to write to
+ *  @data: data to write at register offset
+ *
+ *  Acquire semaphore, then write the data to PHY register
+ *  at the offset using the kumeran interface.  Release semaphore
+ *  before exiting.
+ **/
+s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset, u16 data)
+{
+       u32 kmrnctrlsta;
+       s32 ret_val = 0;
+
+       ret_val = e1000_acquire_mac_csr_80003es2lan(hw);
+       if (ret_val)
+               return ret_val;
+
+       kmrnctrlsta = ((offset << E1000_KMRNCTRLSTA_OFFSET_SHIFT) &
+                      E1000_KMRNCTRLSTA_OFFSET) | data;
+       ew32(KMRNCTRLSTA, kmrnctrlsta);
+
+       udelay(2);
+
+       e1000_release_mac_csr_80003es2lan(hw);
+
+       return ret_val;
+}
+
+/**
  *  e1000_clear_hw_cntrs_80003es2lan - Clear device specific hardware counters
  *  @hw: pointer to the HW structure
  *
@@ -1276,6 +1393,7 @@ static struct e1000_phy_operations es2_phy_ops = {
        .set_d0_lplu_state      = NULL,
        .set_d3_lplu_state      = e1000e_set_d3_lplu_state,
        .write_phy_reg          = e1000_write_phy_reg_gg82563_80003es2lan,
+       .cfg_on_link_up         = e1000_cfg_on_link_up_80003es2lan,
 };
 
 static struct e1000_nvm_operations es2_nvm_ops = {
index 62421ce..e48956d 100644 (file)
@@ -173,11 +173,8 @@ static int e1000_get_settings(struct net_device *netdev,
 static u32 e1000_get_link(struct net_device *netdev)
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
-       struct e1000_hw *hw = &adapter->hw;
-       u32 status;
-       
-       status = er32(STATUS);
-       return (status & E1000_STATUS_LU) ? 1 : 0;
+
+       return e1000_has_link(adapter);
 }
 
 static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
@@ -249,7 +246,7 @@ static int e1000_set_settings(struct net_device *netdev,
                                                     ADVERTISED_Autoneg;
                ecmd->advertising = hw->phy.autoneg_advertised;
                if (adapter->fc_autoneg)
-                       hw->fc.original_type = e1000_fc_default;
+                       hw->fc.requested_mode = e1000_fc_default;
        } else {
                if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
                        clear_bit(__E1000_RESETTING, &adapter->state);
@@ -279,11 +276,11 @@ static void e1000_get_pauseparam(struct net_device *netdev,
        pause->autoneg =
                (adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
 
-       if (hw->fc.type == e1000_fc_rx_pause) {
+       if (hw->fc.current_mode == e1000_fc_rx_pause) {
                pause->rx_pause = 1;
-       } else if (hw->fc.type == e1000_fc_tx_pause) {
+       } else if (hw->fc.current_mode == e1000_fc_tx_pause) {
                pause->tx_pause = 1;
-       } else if (hw->fc.type == e1000_fc_full) {
+       } else if (hw->fc.current_mode == e1000_fc_full) {
                pause->rx_pause = 1;
                pause->tx_pause = 1;
        }
@@ -301,19 +298,8 @@ static int e1000_set_pauseparam(struct net_device *netdev,
        while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
                msleep(1);
 
-       if (pause->rx_pause && pause->tx_pause)
-               hw->fc.type = e1000_fc_full;
-       else if (pause->rx_pause && !pause->tx_pause)
-               hw->fc.type = e1000_fc_rx_pause;
-       else if (!pause->rx_pause && pause->tx_pause)
-               hw->fc.type = e1000_fc_tx_pause;
-       else if (!pause->rx_pause && !pause->tx_pause)
-               hw->fc.type = e1000_fc_none;
-
-       hw->fc.original_type = hw->fc.type;
-
        if (adapter->fc_autoneg == AUTONEG_ENABLE) {
-               hw->fc.type = e1000_fc_default;
+               hw->fc.requested_mode = e1000_fc_default;
                if (netif_running(adapter->netdev)) {
                        e1000e_down(adapter);
                        e1000e_up(adapter);
@@ -321,6 +307,17 @@ static int e1000_set_pauseparam(struct net_device *netdev,
                        e1000e_reset(adapter);
                }
        } else {
+               if (pause->rx_pause && pause->tx_pause)
+                       hw->fc.requested_mode = e1000_fc_full;
+               else if (pause->rx_pause && !pause->tx_pause)
+                       hw->fc.requested_mode = e1000_fc_rx_pause;
+               else if (!pause->rx_pause && pause->tx_pause)
+                       hw->fc.requested_mode = e1000_fc_tx_pause;
+               else if (!pause->rx_pause && !pause->tx_pause)
+                       hw->fc.requested_mode = e1000_fc_none;
+
+               hw->fc.current_mode = hw->fc.requested_mode;
+
                retval = ((hw->phy.media_type == e1000_media_type_fiber) ?
                          hw->mac.ops.setup_link(hw) : e1000e_force_mac_fc(hw));
        }
@@ -495,18 +492,19 @@ static int e1000_get_eeprom(struct net_device *netdev,
                for (i = 0; i < last_word - first_word + 1; i++) {
                        ret_val = e1000_read_nvm(hw, first_word + i, 1,
                                                      &eeprom_buff[i]);
-                       if (ret_val) {
-                               /* a read error occurred, throw away the
-                                * result */
-                               memset(eeprom_buff, 0xff, sizeof(eeprom_buff));
+                       if (ret_val)
                                break;
-                       }
                }
        }
 
-       /* Device's eeprom is always little-endian, word addressable */
-       for (i = 0; i < last_word - first_word + 1; i++)
-               le16_to_cpus(&eeprom_buff[i]);
+       if (ret_val) {
+               /* a read error occurred, throw away the result */
+               memset(eeprom_buff, 0xff, sizeof(eeprom_buff));
+       } else {
+               /* Device's eeprom is always little-endian, word addressable */
+               for (i = 0; i < last_word - first_word + 1; i++)
+                       le16_to_cpus(&eeprom_buff[i]);
+       }
 
        memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len);
        kfree(eeprom_buff);
@@ -558,6 +556,9 @@ static int e1000_set_eeprom(struct net_device *netdev,
                ret_val = e1000_read_nvm(hw, last_word, 1,
                                  &eeprom_buff[last_word - first_word]);
 
+       if (ret_val)
+               goto out;
+
        /* Device's eeprom is always little-endian, word addressable */
        for (i = 0; i < last_word - first_word + 1; i++)
                le16_to_cpus(&eeprom_buff[i]);
@@ -570,15 +571,18 @@ static int e1000_set_eeprom(struct net_device *netdev,
        ret_val = e1000_write_nvm(hw, first_word,
                                  last_word - first_word + 1, eeprom_buff);
 
+       if (ret_val)
+               goto out;
+
        /*
         * Update the checksum over the first part of the EEPROM if needed
-        * and flush shadow RAM for 82573 controllers
+        * and flush shadow RAM for applicable controllers
         */
-       if ((ret_val == 0) && ((first_word <= NVM_CHECKSUM_REG) ||
-                              (hw->mac.type == e1000_82574) ||
-                              (hw->mac.type == e1000_82573)))
-               e1000e_update_nvm_checksum(hw);
+       if ((first_word <= NVM_CHECKSUM_REG) ||
+           (hw->mac.type == e1000_82574) || (hw->mac.type == e1000_82573))
+               ret_val = e1000e_update_nvm_checksum(hw);
 
+out:
        kfree(eeprom_buff);
        return ret_val;
 }
@@ -588,7 +592,6 @@ static void e1000_get_drvinfo(struct net_device *netdev,
 {
        struct e1000_adapter *adapter = netdev_priv(netdev);
        char firmware_version[32];
-       u16 eeprom_data;
 
        strncpy(drvinfo->driver,  e1000e_driver_name, 32);
        strncpy(drvinfo->version, e1000e_driver_version, 32);
@@ -597,11 +600,10 @@ static void e1000_get_drvinfo(struct net_device *netdev,
         * EEPROM image version # is reported as firmware version # for
         * PCI-E controllers
         */
-       e1000_read_nvm(&adapter->hw, 5, 1, &eeprom_data);
        sprintf(firmware_version, "%d.%d-%d",
-               (eeprom_data & 0xF000) >> 12,
-               (eeprom_data & 0x0FF0) >> 4,
-               eeprom_data & 0x000F);
+               (adapter->eeprom_vers & 0xF000) >> 12,
+               (adapter->eeprom_vers & 0x0FF0) >> 4,
+               (adapter->eeprom_vers & 0x000F));
 
        strncpy(drvinfo->fw_version, firmware_version, 32);
        strncpy(drvinfo->bus_info, pci_name(adapter->pdev), 32);
@@ -865,7 +867,7 @@ static int e1000_eeprom_test(struct e1000_adapter *adapter, u64 *data)
        for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
                if ((e1000_read_nvm(&adapter->hw, i, 1, &temp)) < 0) {
                        *data = 1;
-                       break;
+                       return *data;
                }
                checksum += temp;
        }
index c4ffd4b..f25e961 100644 (file)
@@ -437,7 +437,7 @@ enum e1000_rev_polarity{
        e1000_rev_polarity_undefined = 0xFF
 };
 
-enum e1000_fc_type {
+enum e1000_fc_mode {
        e1000_fc_none = 0,
        e1000_fc_rx_pause,
        e1000_fc_tx_pause,
@@ -739,6 +739,7 @@ struct e1000_phy_operations {
        s32  (*set_d0_lplu_state)(struct e1000_hw *, bool);
        s32  (*set_d3_lplu_state)(struct e1000_hw *, bool);
        s32  (*write_phy_reg)(struct e1000_hw *, u32, u16);
+       s32  (*cfg_on_link_up)(struct e1000_hw *);
 };
 
 /* Function pointers for the NVM. */
@@ -849,8 +850,8 @@ struct e1000_fc_info {
        u16 pause_time;          /* Flow control pause timer */
        bool send_xon;           /* Flow control send XON */
        bool strict_ieee;        /* Strict IEEE mode */
-       enum e1000_fc_type type; /* Type of flow control */
-       enum e1000_fc_type original_type;
+       enum e1000_fc_mode current_mode; /* FC mode in effect */
+       enum e1000_fc_mode requested_mode; /* FC mode requested by caller */
 };
 
 struct e1000_dev_spec_82571 {
index 523b971..92f2ace 100644 (file)
@@ -27,6 +27,7 @@
 *******************************************************************************/
 
 /*
+ * 82562G 10/100 Network Connection
  * 82562G-2 10/100 Network Connection
  * 82562GT 10/100 Network Connection
  * 82562GT-2 10/100 Network Connection
@@ -40,6 +41,7 @@
  * 82566MM Gigabit Network Connection
  * 82567LM Gigabit Network Connection
  * 82567LF Gigabit Network Connection
+ * 82567V Gigabit Network Connection
  * 82567LM-2 Gigabit Network Connection
  * 82567LF-2 Gigabit Network Connection
  * 82567V-2 Gigabit Network Connection
@@ -92,6 +94,8 @@
 
 #define E1000_ICH_NVM_SIG_WORD         0x13
 #define E1000_ICH_NVM_SIG_MASK         0xC000
+#define E1000_ICH_NVM_VALID_SIG_MASK    0xC0
+#define E1000_ICH_NVM_SIG_VALUE         0x80
 
 #define E1000_ICH8_LAN_INIT_TIMEOUT    1500
 
@@ -956,45 +960,62 @@ static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
  *  @bank:  pointer to the variable that returns the active bank
  *
  *  Reads signature byte from the NVM using the flash access registers.
+ *  Word 0x13 bits 15:14 = 10b indicate a valid signature for that bank.
  **/
 static s32 e1000_valid_nvm_bank_detect_ich8lan(struct e1000_hw *hw, u32 *bank)
 {
+       u32 eecd;
        struct e1000_nvm_info *nvm = &hw->nvm;
-       /* flash bank size is in words */
        u32 bank1_offset = nvm->flash_bank_size * sizeof(u16);
        u32 act_offset = E1000_ICH_NVM_SIG_WORD * 2 + 1;
-       u8 bank_high_byte = 0;
+       u8 sig_byte = 0;
+       s32 ret_val = 0;
 
-       if (hw->mac.type != e1000_ich10lan) {
-               if (er32(EECD) & E1000_EECD_SEC1VAL)
-                       *bank = 1;
-               else
-                       *bank = 0;
-       } else {
-               /*
-                * Make sure the signature for bank 0 is valid,
-                * if not check for bank1
-                */
-               e1000_read_flash_byte_ich8lan(hw, act_offset, &bank_high_byte);
-               if ((bank_high_byte & 0xC0) == 0x80) {
+       switch (hw->mac.type) {
+       case e1000_ich8lan:
+       case e1000_ich9lan:
+               eecd = er32(EECD);
+               if ((eecd & E1000_EECD_SEC1VAL_VALID_MASK) ==
+                   E1000_EECD_SEC1VAL_VALID_MASK) {
+                       if (eecd & E1000_EECD_SEC1VAL)
+                               *bank = 1;
+                       else
+                               *bank = 0;
+
+                       return 0;
+               }
+               hw_dbg(hw, "Unable to determine valid NVM bank via EEC - "
+                      "reading flash signature\n");
+               /* fall-thru */
+       default:
+               /* set bank to 0 in case flash read fails */
+               *bank = 0;
+
+               /* Check bank 0 */
+               ret_val = e1000_read_flash_byte_ich8lan(hw, act_offset,
+                                                       &sig_byte);
+               if (ret_val)
+                       return ret_val;
+               if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) ==
+                   E1000_ICH_NVM_SIG_VALUE) {
                        *bank = 0;
-               } else {
-                       /*
-                        * find if segment 1 is valid by verifying
-                        * bit 15:14 = 10b in word 0x13
-                        */
-                       e1000_read_flash_byte_ich8lan(hw,
-                                                     act_offset + bank1_offset,
-                                                     &bank_high_byte);
+                       return 0;
+               }
 
-                       /* bank1 has a valid signature equivalent to SEC1V */
-                       if ((bank_high_byte & 0xC0) == 0x80) {
-                               *bank = 1;
-                       } else {
-                               hw_dbg(hw, "ERROR: EEPROM not present\n");
-                               return -E1000_ERR_NVM;
-                       }
+               /* Check bank 1 */
+               ret_val = e1000_read_flash_byte_ich8lan(hw, act_offset +
+                                                       bank1_offset,
+                                                       &sig_byte);
+               if (ret_val)
+                       return ret_val;
+               if ((sig_byte & E1000_ICH_NVM_VALID_SIG_MASK) ==
+                   E1000_ICH_NVM_SIG_VALUE) {
+                       *bank = 1;
+                       return 0;
                }
+
+               hw_dbg(hw, "ERROR: No valid NVM bank present\n");
+               return -E1000_ERR_NVM;
        }
 
        return 0;
@@ -1027,11 +1048,11 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
 
        ret_val = e1000_acquire_swflag_ich8lan(hw);
        if (ret_val)
-               return ret_val;
+               goto out;
 
        ret_val = e1000_valid_nvm_bank_detect_ich8lan(hw, &bank);
        if (ret_val)
-               return ret_val;
+               goto release;
 
        act_offset = (bank) ? nvm->flash_bank_size : 0;
        act_offset += offset;
@@ -1050,8 +1071,13 @@ static s32 e1000_read_nvm_ich8lan(struct e1000_hw *hw, u16 offset, u16 words,
                }
        }
 
+release:
        e1000_release_swflag_ich8lan(hw);
 
+out:
+       if (ret_val)
+               hw_dbg(hw, "NVM read error: %d\n", ret_val);
+
        return ret_val;
 }
 
@@ -1340,14 +1366,14 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
 
        ret_val = e1000e_update_nvm_checksum_generic(hw);
        if (ret_val)
-               return ret_val;
+               goto out;
 
        if (nvm->type != e1000_nvm_flash_sw)
-               return ret_val;
+               goto out;
 
        ret_val = e1000_acquire_swflag_ich8lan(hw);
        if (ret_val)
-               return ret_val;
+               goto out;
 
        /*
         * We're writing to the opposite bank so if we're on bank 1,
@@ -1355,17 +1381,27 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
         * is going to be written
         */
        ret_val =  e1000_valid_nvm_bank_detect_ich8lan(hw, &bank);
-       if (ret_val)
-               return ret_val;
+       if (ret_val) {
+               e1000_release_swflag_ich8lan(hw);
+               goto out;
+       }
 
        if (bank == 0) {
                new_bank_offset = nvm->flash_bank_size;
                old_bank_offset = 0;
-               e1000_erase_flash_bank_ich8lan(hw, 1);
+               ret_val = e1000_erase_flash_bank_ich8lan(hw, 1);
+               if (ret_val) {
+                       e1000_release_swflag_ich8lan(hw);
+                       goto out;
+               }
        } else {
                old_bank_offset = nvm->flash_bank_size;
                new_bank_offset = 0;
-               e1000_erase_flash_bank_ich8lan(hw, 0);
+               ret_val = e1000_erase_flash_bank_ich8lan(hw, 0);
+               if (ret_val) {
+                       e1000_release_swflag_ich8lan(hw);
+                       goto out;
+               }
        }
 
        for (i = 0; i < E1000_ICH8_SHADOW_RAM_WORDS; i++) {
@@ -1377,9 +1413,11 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
                if (dev_spec->shadow_ram[i].modified) {
                        data = dev_spec->shadow_ram[i].value;
                } else {
-                       e1000_read_flash_word_ich8lan(hw,
-                                                     i + old_bank_offset,
-                                                     &data);
+                       ret_val = e1000_read_flash_word_ich8lan(hw, i +
+                                                               old_bank_offset,
+                                                               &data);
+                       if (ret_val)
+                               break;
                }
 
                /*
@@ -1420,7 +1458,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
                /* Possibly read-only, see e1000e_write_protect_nvm_ich8lan() */
                hw_dbg(hw, "Flash commit failed.\n");
                e1000_release_swflag_ich8lan(hw);
-               return ret_val;
+               goto out;
        }
 
        /*
@@ -1430,14 +1468,18 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
         * and we need to change bit 14 to 0b
         */
        act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD;
-       e1000_read_flash_word_ich8lan(hw, act_offset, &data);
+       ret_val = e1000_read_flash_word_ich8lan(hw, act_offset, &data);
+       if (ret_val) {
+               e1000_release_swflag_ich8lan(hw);
+               goto out;
+       }
        data &= 0xBFFF;
        ret_val = e1000_retry_write_flash_byte_ich8lan(hw,
                                                       act_offset * 2 + 1,
                                                       (u8)(data >> 8));
        if (ret_val) {
                e1000_release_swflag_ich8lan(hw);
-               return ret_val;
+               goto out;
        }
 
        /*
@@ -1450,7 +1492,7 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
        ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, 0);
        if (ret_val) {
                e1000_release_swflag_ich8lan(hw);
-               return ret_val;
+               goto out;
        }
 
        /* Great!  Everything worked, we can now clear the cached entries. */
@@ -1468,6 +1510,10 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
        e1000e_reload_nvm(hw);
        msleep(10);
 
+out:
+       if (ret_val)
+               hw_dbg(hw, "NVM update error: %d\n", ret_val);
+
        return ret_val;
 }
 
@@ -1893,7 +1939,7 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
                ctrl |= E1000_CTRL_PHY_RST;
        }
        ret_val = e1000_acquire_swflag_ich8lan(hw);
-       hw_dbg(hw, "Issuing a global reset to ich8lan");
+       hw_dbg(hw, "Issuing a global reset to ich8lan\n");
        ew32(CTRL, (ctrl | E1000_CTRL_RST));
        msleep(20);
 
@@ -2069,12 +2115,17 @@ static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw)
         * the default flow control setting, so we explicitly
         * set it to full.
         */
-       if (hw->fc.type == e1000_fc_default)
-               hw->fc.type = e1000_fc_full;
+       if (hw->fc.requested_mode == e1000_fc_default)
+               hw->fc.requested_mode = e1000_fc_full;
 
-       hw->fc.original_type = hw->fc.type;
+       /*
+        * Save off the requested flow control mode for use later.  Depending
+        * on the link partner's capabilities, we may or may not use this mode.
+        */
+       hw->fc.current_mode = hw->fc.requested_mode;
 
-       hw_dbg(hw, "After fix-ups FlowControl is now = %x\n", hw->fc.type);
+       hw_dbg(hw, "After fix-ups FlowControl is now = %x\n",
+               hw->fc.current_mode);
 
        /* Continue to configure the copper link. */
        ret_val = e1000_setup_copper_link_ich8lan(hw);
index 089578f..6674110 100644 (file)
@@ -575,20 +575,42 @@ s32 e1000e_check_for_serdes_link(struct e1000_hw *hw)
                 */
                /* SYNCH bit and IV bit are sticky. */
                udelay(10);
-               if (E1000_RXCW_SYNCH & er32(RXCW)) {
+               rxcw = er32(RXCW);
+               if (rxcw & E1000_RXCW_SYNCH) {
                        if (!(rxcw & E1000_RXCW_IV)) {
-                               mac->serdes_has_link = 1;
-                               hw_dbg(hw, "SERDES: Link is up.\n");
+                               mac->serdes_has_link = true;
+                               hw_dbg(hw, "SERDES: Link up - forced.\n");
                        }
                } else {
-                       mac->serdes_has_link = 0;
-                       hw_dbg(hw, "SERDES: Link is down.\n");
+                       mac->serdes_has_link = false;
+                       hw_dbg(hw, "SERDES: Link down - force failed.\n");
                }
        }
 
        if (E1000_TXCW_ANE & er32(TXCW)) {
                status = er32(STATUS);
-               mac->serdes_has_link = (status & E1000_STATUS_LU);
+               if (status & E1000_STATUS_LU) {
+                       /* SYNCH bit and IV bit are sticky, so reread rxcw.  */
+                       udelay(10);
+                       rxcw = er32(RXCW);
+                       if (rxcw & E1000_RXCW_SYNCH) {
+                               if (!(rxcw & E1000_RXCW_IV)) {
+                                       mac->serdes_has_link = true;
+                                       hw_dbg(hw, "SERDES: Link up - autoneg "
+                                          "completed sucessfully.\n");
+                               } else {
+                                       mac->serdes_has_link = false;
+                                       hw_dbg(hw, "SERDES: Link down - invalid"
+                                          "codewords detected in autoneg.\n");
+                               }
+                       } else {
+                               mac->serdes_has_link = false;
+                               hw_dbg(hw, "SERDES: Link down - no sync.\n");
+                       }
+               } else {
+                       mac->serdes_has_link = false;
+                       hw_dbg(hw, "SERDES: Link down - autoneg failed\n");
+               }
        }
 
        return 0;
@@ -623,12 +645,12 @@ static s32 e1000_set_default_fc_generic(struct e1000_hw *hw)
        }
 
        if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == 0)
-               hw->fc.type = e1000_fc_none;
+               hw->fc.requested_mode = e1000_fc_none;
        else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) ==
                 NVM_WORD0F_ASM_DIR)
-               hw->fc.type = e1000_fc_tx_pause;
+               hw->fc.requested_mode = e1000_fc_tx_pause;
        else
-               hw->fc.type = e1000_fc_full;
+               hw->fc.requested_mode = e1000_fc_full;
 
        return 0;
 }
@@ -656,23 +678,23 @@ s32 e1000e_setup_link(struct e1000_hw *hw)
                return 0;
 
        /*
-        * If flow control is set to default, set flow control based on
-        * the EEPROM flow control settings.
+        * If requested flow control is set to default, set flow control
+        * based on the EEPROM flow control settings.
         */
-       if (hw->fc.type == e1000_fc_default) {
+       if (hw->fc.requested_mode == e1000_fc_default) {
                ret_val = e1000_set_default_fc_generic(hw);
                if (ret_val)
                        return ret_val;
        }
 
        /*
-        * We want to save off the original Flow Control configuration just
-        * in case we get disconnected and then reconnected into a different
-        * hub or switch with different Flow Control capabilities.
+        * Save off the requested flow control mode for use later.  Depending
+        * on the link partner's capabilities, we may or may not use this mode.
         */
-       hw->fc.original_type = hw->fc.type;
+       hw->fc.current_mode = hw->fc.requested_mode;
 
-       hw_dbg(hw, "After fix-ups FlowControl is now = %x\n", hw->fc.type);
+       hw_dbg(hw, "After fix-ups FlowControl is now = %x\n",
+               hw->fc.current_mode);
 
        /* Call the necessary media_type subroutine to configure the link. */
        ret_val = mac->ops.setup_physical_interface(hw);
@@ -724,7 +746,7 @@ static s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw)
         *        do not support receiving pause frames).
         *      3:  Both Rx and Tx flow control (symmetric) are enabled.
         */
-       switch (hw->fc.type) {
+       switch (hw->fc.current_mode) {
        case e1000_fc_none:
                /* Flow control completely disabled by a software over-ride. */
                txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
@@ -906,7 +928,7 @@ s32 e1000e_set_fc_watermarks(struct e1000_hw *hw)
         * ability to transmit pause frames is not enabled, then these
         * registers will be set to 0.
         */
-       if (hw->fc.type & e1000_fc_tx_pause) {
+       if (hw->fc.current_mode & e1000_fc_tx_pause) {
                /*
                 * We need to set up the Receive Threshold high and low water
                 * marks as well as (optionally) enabling the transmission of
@@ -945,7 +967,7 @@ s32 e1000e_force_mac_fc(struct e1000_hw *hw)
         * receive flow control.
         *
         * The "Case" statement below enables/disable flow control
-        * according to the "hw->fc.type" parameter.
+        * according to the "hw->fc.current_mode" parameter.
         *
         * The possible values of the "fc" parameter are:
         *      0:  Flow control is completely disabled
@@ -956,9 +978,9 @@ s32 e1000e_force_mac_fc(struct e1000_hw *hw)
         *      3:  Both Rx and Tx flow control (symmetric) is enabled.
         *  other:  No other values should be possible at this point.
         */
-       hw_dbg(hw, "hw->fc.type = %u\n", hw->fc.type);
+       hw_dbg(hw, "hw->fc.current_mode = %u\n", hw->fc.current_mode);
 
-       switch (hw->fc.type) {
+       switch (hw->fc.current_mode) {
        case e1000_fc_none:
                ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
                break;
@@ -1102,11 +1124,11 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
                         * ONLY. Hence, we must now check to see if we need to
                         * turn OFF  the TRANSMISSION of PAUSE frames.
                         */
-                       if (hw->fc.original_type == e1000_fc_full) {
-                               hw->fc.type = e1000_fc_full;
+                       if (hw->fc.requested_mode == e1000_fc_full) {
+                               hw->fc.current_mode = e1000_fc_full;
                                hw_dbg(hw, "Flow Control = FULL.\r\n");
                        } else {
-                               hw->fc.type = e1000_fc_rx_pause;
+                               hw->fc.current_mode = e1000_fc_rx_pause;
                                hw_dbg(hw, "Flow Control = "
                                         "RX PAUSE frames only.\r\n");
                        }
@@ -1124,7 +1146,7 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
                          (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
                          (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
                          (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
-                       hw->fc.type = e1000_fc_tx_pause;
+                       hw->fc.current_mode = e1000_fc_tx_pause;
                        hw_dbg(hw, "Flow Control = Tx PAUSE frames only.\r\n");
                }
                /*
@@ -1140,14 +1162,14 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
                         (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
                         !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
                         (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
-                       hw->fc.type = e1000_fc_rx_pause;
+                       hw->fc.current_mode = e1000_fc_rx_pause;
                        hw_dbg(hw, "Flow Control = Rx PAUSE frames only.\r\n");
                } else {
                        /*
                         * Per the IEEE spec, at this point flow control
                         * should be disabled.
                         */
-                       hw->fc.type = e1000_fc_none;
+                       hw->fc.current_mode = e1000_fc_none;
                        hw_dbg(hw, "Flow Control = NONE.\r\n");
                }
 
@@ -1163,7 +1185,7 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
                }
 
                if (duplex == HALF_DUPLEX)
-                       hw->fc.type = e1000_fc_none;
+                       hw->fc.current_mode = e1000_fc_none;
 
                /*
                 * Now we call a subroutine to actually force the MAC
index cc0502b..ca5d3f5 100644 (file)
@@ -2785,7 +2785,7 @@ void e1000e_reset(struct e1000_adapter *adapter)
        else
                fc->pause_time = E1000_FC_PAUSE_TIME;
        fc->send_xon = 1;
-       fc->type = fc->original_type;
+       fc->current_mode = fc->requested_mode;
 
        /* Allow time for pending master requests to run */
        mac->ops.reset_hw(hw);
@@ -3408,7 +3408,10 @@ static void e1000_print_link_info(struct e1000_adapter *adapter)
        struct e1000_hw *hw = &adapter->hw;
        u32 ctrl = er32(CTRL);
 
-       e_info("Link is Up %d Mbps %s, Flow Control: %s\n",
+       /* Link status message must follow this format for user tools */
+       printk(KERN_INFO "e1000e: %s NIC Link is Up %d Mbps %s, "
+              "Flow Control: %s\n",
+              adapter->netdev->name,
               adapter->link_speed,
               (adapter->link_duplex == FULL_DUPLEX) ?
                                "Full Duplex" : "Half Duplex",
@@ -3418,7 +3421,7 @@ static void e1000_print_link_info(struct e1000_adapter *adapter)
               ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None" )));
 }
 
-static bool e1000_has_link(struct e1000_adapter *adapter)
+bool e1000_has_link(struct e1000_adapter *adapter)
 {
        struct e1000_hw *hw = &adapter->hw;
        bool link_active = 0;
@@ -3493,6 +3496,7 @@ static void e1000_watchdog_task(struct work_struct *work)
                                        struct e1000_adapter, watchdog_task);
        struct net_device *netdev = adapter->netdev;
        struct e1000_mac_info *mac = &adapter->hw.mac;
+       struct e1000_phy_info *phy = &adapter->hw.phy;
        struct e1000_ring *tx_ring = adapter->tx_ring;
        struct e1000_hw *hw = &adapter->hw;
        u32 link, tctl;
@@ -3599,6 +3603,13 @@ static void e1000_watchdog_task(struct work_struct *work)
                        tctl |= E1000_TCTL_EN;
                        ew32(TCTL, tctl);
 
+                        /*
+                        * Perform any post-link-up configuration before
+                        * reporting link up.
+                        */
+                       if (phy->ops.cfg_on_link_up)
+                               phy->ops.cfg_on_link_up(hw);
+
                        netif_carrier_on(netdev);
                        netif_tx_wake_all_queues(netdev);
 
@@ -3610,7 +3621,9 @@ static void e1000_watchdog_task(struct work_struct *work)
                if (netif_carrier_ok(netdev)) {
                        adapter->link_speed = 0;
                        adapter->link_duplex = 0;
-                       e_info("Link is Down\n");
+                       /* Link status message must follow this format */
+                       printk(KERN_INFO "e1000e: %s NIC Link is Down\n",
+                              adapter->netdev->name);
                        netif_carrier_off(netdev);
                        netif_tx_stop_all_queues(netdev);
                        if (!test_bit(__E1000_DOWN, &adapter->state))
@@ -4462,7 +4475,27 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
 
        pci_disable_device(pdev);
 
-       pci_set_power_state(pdev, pci_choose_state(pdev, state));
+       /*
+        * The pci-e switch on some quad port adapters will report a
+        * correctable error when the MAC transitions from D0 to D3.  To
+        * prevent this we need to mask off the correctable errors on the
+        * downstream port of the pci-e switch.
+        */
+       if (adapter->flags & FLAG_IS_QUAD_PORT) {
+               struct pci_dev *us_dev = pdev->bus->self;
+               int pos = pci_find_capability(us_dev, PCI_CAP_ID_EXP);
+               u16 devctl;
+
+               pci_read_config_word(us_dev, pos + PCI_EXP_DEVCTL, &devctl);
+               pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL,
+                                     (devctl & ~PCI_EXP_DEVCTL_CERE));
+
+               pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+               pci_write_config_word(us_dev, pos + PCI_EXP_DEVCTL, devctl);
+       } else {
+               pci_set_power_state(pdev, pci_choose_state(pdev, state));
+       }
 
        return 0;
 }
@@ -4690,14 +4723,14 @@ static void e1000_eeprom_checks(struct e1000_adapter *adapter)
                return;
 
        ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &buf);
-       if (!(le16_to_cpu(buf) & (1 << 0))) {
+       if (!ret_val && (!(le16_to_cpu(buf) & (1 << 0)))) {
                /* Deep Smart Power Down (DSPD) */
                dev_warn(&adapter->pdev->dev,
                         "Warning: detected DSPD enabled in EEPROM\n");
        }
 
        ret_val = e1000_read_nvm(hw, NVM_INIT_3GIO_3, 1, &buf);
-       if (le16_to_cpu(buf) & (3 << 2)) {
+       if (!ret_val && (le16_to_cpu(buf) & (3 << 2))) {
                /* ASPM enable */
                dev_warn(&adapter->pdev->dev,
                         "Warning: detected ASPM enabled in EEPROM\n");
@@ -4782,7 +4815,10 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
                goto err_pci_reg;
 
        pci_set_master(pdev);
-       pci_save_state(pdev);
+       /* PCI config space info */
+       err = pci_save_state(pdev);
+       if (err)
+               goto err_alloc_etherdev;
 
        err = -ENOMEM;
        netdev = alloc_etherdev(sizeof(struct e1000_adapter));
@@ -4947,8 +4983,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
        /* Initialize link parameters. User can change them with ethtool */
        adapter->hw.mac.autoneg = 1;
        adapter->fc_autoneg = 1;
-       adapter->hw.fc.original_type = e1000_fc_default;
-       adapter->hw.fc.type = e1000_fc_default;
+       adapter->hw.fc.requested_mode = e1000_fc_default;
+       adapter->hw.fc.current_mode = e1000_fc_default;
        adapter->hw.phy.autoneg_advertised = 0x2f;
 
        /* ring size defaults */
@@ -4989,6 +5025,9 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
        adapter->wol = adapter->eeprom_wol;
        device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
 
+       /* save off EEPROM version number */
+       e1000_read_nvm(&adapter->hw, 5, 1, &adapter->eeprom_vers);
+
        /* reset the hardware with the new settings */
        e1000e_reset(adapter);
 
index 6cd333a..dc4a9cb 100644 (file)
@@ -744,7 +744,7 @@ static s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
         *  other:  No software override.  The flow control configuration
         *        in the EEPROM is used.
         */
-       switch (hw->fc.type) {
+       switch (hw->fc.current_mode) {
        case e1000_fc_none:
                /*
                 * Flow control (Rx & Tx) is completely disabled by a
@@ -1030,14 +1030,14 @@ s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw)
 
        e1000e_phy_force_speed_duplex_setup(hw, &phy_data);
 
-       /* Reset the phy to commit changes. */
-       phy_data |= MII_CR_RESET;
-
        ret_val = e1e_wphy(hw, PHY_CONTROL, phy_data);
        if (ret_val)
                return ret_val;
 
-       udelay(1);
+       /* Reset the phy to commit changes. */
+       ret_val = e1000e_commit_phy(hw);
+       if (ret_val)
+               return ret_val;
 
        if (phy->autoneg_wait_to_complete) {
                hw_dbg(hw, "Waiting for forced speed/duplex link on M88 phy.\n");
@@ -1114,7 +1114,7 @@ void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl)
        u32 ctrl;
 
        /* Turn off flow control when forcing speed/duplex */
-       hw->fc.type = e1000_fc_none;
+       hw->fc.current_mode = e1000_fc_none;
 
        /* Force speed/duplex on the mac */
        ctrl = er32(CTRL);
index 21efd99..0725161 100644 (file)
@@ -207,6 +207,8 @@ config PC300
        tristate "Cyclades-PC300 support (RS-232/V.35, X.21, T1/E1 boards)"
        depends on HDLC && PCI && BROKEN
        ---help---
+         This driver is broken because of struct tty_driver change.
+
          Driver for the Cyclades-PC300 synchronous communication boards.
 
          These boards provide synchronous serial interfaces to your
index d3d5055..f1ddd7c 100644 (file)
@@ -342,7 +342,7 @@ static int fr_hard_header(struct sk_buff **skb_p, u16 dlci)
 
 static int pvc_open(struct net_device *dev)
 {
-       pvc_device *pvc = dev->priv;
+       pvc_device *pvc = dev->ml_priv;
 
        if ((pvc->frad->flags & IFF_UP) == 0)
                return -EIO;  /* Frad must be UP in order to activate PVC */
@@ -362,7 +362,7 @@ static int pvc_open(struct net_device *dev)
 
 static int pvc_close(struct net_device *dev)
 {
-       pvc_device *pvc = dev->priv;
+       pvc_device *pvc = dev->ml_priv;
 
        if (--pvc->open_count == 0) {
                hdlc_device *hdlc = dev_to_hdlc(pvc->frad);
@@ -381,7 +381,7 @@ static int pvc_close(struct net_device *dev)
 
 static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
-       pvc_device *pvc = dev->priv;
+       pvc_device *pvc = dev->ml_priv;
        fr_proto_pvc_info info;
 
        if (ifr->ifr_settings.type == IF_GET_PROTO) {
@@ -409,7 +409,7 @@ static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 
 static int pvc_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       pvc_device *pvc = dev->priv;
+       pvc_device *pvc = dev->ml_priv;
 
        if (pvc->state.active) {
                if (dev->type == ARPHRD_ETHER) {
@@ -1111,7 +1111,7 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
        dev->change_mtu = pvc_change_mtu;
        dev->mtu = HDLC_MAX_MTU;
        dev->tx_queue_len = 0;
-       dev->priv = pvc;
+       dev->ml_priv = pvc;
 
        result = dev_alloc_name(dev, dev->name);
        if (result < 0) {
index d0a8d1e..d67957a 100644 (file)
@@ -1769,7 +1769,7 @@ cpc_trace(struct net_device *dev, struct sk_buff *skb_main, char rx_tx)
 
 static void cpc_tx_timeout(struct net_device *dev)
 {
-       pc300dev_t *d = (pc300dev_t *) dev->priv;
+       pc300dev_t *d = (pc300dev_t *) dev_to_hdlc(dev)->priv;
        pc300ch_t *chan = (pc300ch_t *) d->chan;
        pc300_t *card = (pc300_t *) chan->card;
        int ch = chan->channel;
@@ -1796,7 +1796,7 @@ static void cpc_tx_timeout(struct net_device *dev)
 
 static int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       pc300dev_t *d = (pc300dev_t *) dev->priv;
+       pc300dev_t *d = (pc300dev_t *) dev_to_hdlc(dev)->priv;
        pc300ch_t *chan = (pc300ch_t *) d->chan;
        pc300_t *card = (pc300_t *) chan->card;
        int ch = chan->channel;
@@ -1874,7 +1874,7 @@ static int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
 
 static void cpc_net_rx(struct net_device *dev)
 {
-       pc300dev_t *d = (pc300dev_t *) dev->priv;
+       pc300dev_t *d = (pc300dev_t *) dev_to_hdlc(dev)->priv;
        pc300ch_t *chan = (pc300ch_t *) d->chan;
        pc300_t *card = (pc300_t *) chan->card;
        int ch = chan->channel;
@@ -2522,7 +2522,7 @@ static int cpc_change_mtu(struct net_device *dev, int new_mtu)
 
 static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
-       pc300dev_t *d = (pc300dev_t *) dev->priv;
+       pc300dev_t *d = (pc300dev_t *) dev_to_hdlc(dev)->priv;
        pc300ch_t *chan = (pc300ch_t *) d->chan;
        pc300_t *card = (pc300_t *) chan->card;
        pc300conf_t conf_aux;
@@ -3058,7 +3058,7 @@ static int tx_config(pc300dev_t * d)
 static int cpc_attach(struct net_device *dev, unsigned short encoding,
                      unsigned short parity)
 {
-       pc300dev_t *d = (pc300dev_t *)dev->priv;
+       pc300dev_t *d = (pc300dev_t *)dev_to_hdlc(dev)->priv;
        pc300ch_t *chan = (pc300ch_t *)d->chan;
        pc300_t *card = (pc300_t *)chan->card;
        pc300chconf_t *conf = (pc300chconf_t *)&chan->conf;
@@ -3138,7 +3138,7 @@ static void cpc_closech(pc300dev_t * d)
 
 int cpc_open(struct net_device *dev)
 {
-       pc300dev_t *d = (pc300dev_t *) dev->priv;
+       pc300dev_t *d = (pc300dev_t *) dev_to_hdlc(dev)->priv;
        struct ifreq ifr;
        int result;
 
@@ -3166,7 +3166,7 @@ err_out:
 
 static int cpc_close(struct net_device *dev)
 {
-       pc300dev_t *d = (pc300dev_t *) dev->priv;
+       pc300dev_t *d = (pc300dev_t *) dev_to_hdlc(dev)->priv;
        pc300ch_t *chan = (pc300ch_t *) d->chan;
        pc300_t *card = (pc300_t *) chan->card;
        unsigned long flags;
@@ -3347,7 +3347,7 @@ static void cpc_init_card(pc300_t * card)
                d->line_on = 0;
                d->line_off = 0;
 
-               dev = alloc_hdlcdev(NULL);
+               dev = alloc_hdlcdev(d);
                if (dev == NULL)
                        continue;
 
@@ -3372,7 +3372,6 @@ static void cpc_init_card(pc300_t * card)
                dev->do_ioctl = cpc_ioctl;
 
                if (register_hdlc_device(dev) == 0) {
-                       dev->priv = d;  /* We need 'priv', hdlc doesn't */
                        printk("%s: Cyclades-PC300/", dev->name);
                        switch (card->hw.type) {
                                case PC300_TE:
index c597696..e960faa 100644 (file)
@@ -80,7 +80,7 @@ struct net_device *alloc_hdlcdev(void *priv);
 
 static inline struct hdlc_device* dev_to_hdlc(struct net_device *dev)
 {
-       return dev->priv;
+       return netdev_priv(dev);
 }
 
 static __inline__ void debug_frame(const struct sk_buff *skb)
index 28b3ee3..ec7ee2e 100644 (file)
@@ -291,25 +291,25 @@ typedef __u64 __bitwise __addrpair;
                                   ((__force __u64)(__be32)(__saddr)));
 #endif /* __BIG_ENDIAN */
 #define INET_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
-       (((__sk)->sk_hash == (__hash)) && sock_net((__sk)) == (__net)   &&      \
+       (((__sk)->sk_hash == (__hash)) && net_eq(sock_net(__sk), (__net)) &&    \
         ((*((__addrpair *)&(inet_sk(__sk)->daddr))) == (__cookie))     &&      \
         ((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports))      &&      \
         (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
 #define INET_TW_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif)\
-       (((__sk)->sk_hash == (__hash)) && sock_net((__sk)) == (__net)   &&      \
+       (((__sk)->sk_hash == (__hash)) && net_eq(sock_net(__sk), (__net)) &&    \
         ((*((__addrpair *)&(inet_twsk(__sk)->tw_daddr))) == (__cookie)) &&     \
         ((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) &&      \
         (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
 #else /* 32-bit arch */
 #define INET_ADDR_COOKIE(__name, __saddr, __daddr)
 #define INET_MATCH(__sk, __net, __hash, __cookie, __saddr, __daddr, __ports, __dif)    \
-       (((__sk)->sk_hash == (__hash)) && sock_net((__sk)) == (__net)   &&      \
+       (((__sk)->sk_hash == (__hash)) && net_eq(sock_net(__sk), (__net))       &&      \
         (inet_sk(__sk)->daddr          == (__saddr))           &&      \
         (inet_sk(__sk)->rcv_saddr      == (__daddr))           &&      \
         ((*((__portpair *)&(inet_sk(__sk)->dport))) == (__ports))      &&      \
         (!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
 #define INET_TW_MATCH(__sk, __net, __hash,__cookie, __saddr, __daddr, __ports, __dif)  \
-       (((__sk)->sk_hash == (__hash)) && sock_net((__sk)) == (__net)   &&      \
+       (((__sk)->sk_hash == (__hash)) && net_eq(sock_net(__sk), (__net))       &&      \
         (inet_twsk(__sk)->tw_daddr     == (__saddr))           &&      \
         (inet_twsk(__sk)->tw_rcv_saddr == (__daddr))           &&      \
         ((*((__portpair *)&(inet_twsk(__sk)->tw_dport))) == (__ports)) &&      \
index 1cb154e..998a78f 100644 (file)
@@ -778,7 +778,7 @@ skip_listen_ht:
 
        for (i = s_i; i < hashinfo->ehash_size; i++) {
                struct inet_ehash_bucket *head = &hashinfo->ehash[i];
-               rwlock_t *lock = inet_ehash_lockp(hashinfo, i);
+               spinlock_t *lock = inet_ehash_lockp(hashinfo, i);
                struct sock *sk;
                struct hlist_nulls_node *node;
 
@@ -791,7 +791,7 @@ skip_listen_ht:
                if (i > s_i)
                        s_num = 0;
 
-               read_lock_bh(lock);
+               spin_lock_bh(lock);
                sk_nulls_for_each(sk, node, &head->chain) {
                        struct inet_sock *inet = inet_sk(sk);
 
@@ -806,7 +806,7 @@ skip_listen_ht:
                            r->id.idiag_dport)
                                goto next_normal;
                        if (inet_csk_diag_dump(sk, skb, cb) < 0) {
-                               read_unlock_bh(lock);
+                               spin_unlock_bh(lock);
                                goto done;
                        }
 next_normal:
@@ -828,14 +828,14 @@ next_normal:
                                    r->id.idiag_dport)
                                        goto next_dying;
                                if (inet_twsk_diag_dump(tw, skb, cb) < 0) {
-                                       read_unlock_bh(lock);
+                                       spin_unlock_bh(lock);
                                        goto done;
                                }
 next_dying:
                                ++num;
                        }
                }
-               read_unlock_bh(lock);
+               spin_unlock_bh(lock);
        }
 
 done:
index 8d523d9..37e6ab9 100644 (file)
@@ -406,6 +406,7 @@ static unsigned int drr_drop(struct Qdisc *sch)
                if (cl->qdisc->ops->drop) {
                        len = cl->qdisc->ops->drop(cl->qdisc);
                        if (len > 0) {
+                               sch->q.qlen--;
                                if (cl->qdisc->q.qlen == 0)
                                        list_del(&cl->alist);
                                return len;