e1000e: fix overrun of PHY RAR array
authorDavid Ertman <davidx.m.ertman@intel.com>
Thu, 5 Sep 2013 04:24:25 +0000 (04:24 +0000)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Fri, 13 Sep 2013 17:19:56 +0000 (10:19 -0700)
When copying the MAC RAR registers to PHY there is an error in the
calculation of the rar_entry_count, which causes a write of unknown/
undefined register space in the MAC to unknown/undefined register space in
the PHY.

This patch fixes the overrun with writing to the PHY RAR and also fixes the
ethtool offline register tests so that the correctly addressed registers
have the appropriate bitmasks for R/W and RO bits for affected parts.

Shawn Rader gets credit for finding and fixing the register overrun.

Signed-off-by: Dave Ertman <davidx.m.ertman@intel.com>
CC: Shawn Rader <shawn.t.rader@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
drivers/net/ethernet/intel/e1000e/ethtool.c
drivers/net/ethernet/intel/e1000e/ich8lan.c
drivers/net/ethernet/intel/e1000e/ich8lan.h

index a8633b8f0ac5aaff57b2be97d8e0ac5dfe3ff36a..d14c8f53384cd415c3933015c02bf9d2a369ba11 100644 (file)
@@ -922,6 +922,14 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
                        else
                                mask &= ~(1 << 30);
                }
+               if (mac->type == e1000_pch2lan) {
+                       /* SHRAH[0,1,2] different than previous */
+                       if (i == 7)
+                               mask &= 0xFFF4FFFF;
+                       /* SHRAH[3] different than SHRAH[0,1,2] */
+                       if (i == 10)
+                               mask |= (1 << 30);
+               }
 
                REG_PATTERN_TEST_ARRAY(E1000_RA, ((i << 1) + 1), mask,
                                       0xFFFFFFFF);
index af08188d7e624471ed3e8b87df7d39fd24ba3815..42f0f6717511c21bb0f16edbeee050cc4878db96 100644 (file)
@@ -1371,7 +1371,10 @@ static void e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index)
                return;
        }
 
-       if (index < hw->mac.rar_entry_count) {
+       /* RAR[1-6] are owned by manageability.  Skip those and program the
+        * next address into the SHRA register array.
+        */
+       if (index < (u32)(hw->mac.rar_entry_count - 6)) {
                s32 ret_val;
 
                ret_val = e1000_acquire_swflag_ich8lan(hw);
@@ -1962,8 +1965,8 @@ void e1000_copy_rx_addrs_to_phy_ich8lan(struct e1000_hw *hw)
        if (ret_val)
                goto release;
 
-       /* Copy both RAL/H (rar_entry_count) and SHRAL/H (+4) to PHY */
-       for (i = 0; i < (hw->mac.rar_entry_count + 4); i++) {
+       /* Copy both RAL/H (rar_entry_count) and SHRAL/H to PHY */
+       for (i = 0; i < (hw->mac.rar_entry_count); i++) {
                mac_reg = er32(RAL(i));
                hw->phy.ops.write_reg_page(hw, BM_RAR_L(i),
                                           (u16)(mac_reg & 0xFFFF));
@@ -2007,10 +2010,10 @@ s32 e1000_lv_jumbo_workaround_ich8lan(struct e1000_hw *hw, bool enable)
                return ret_val;
 
        if (enable) {
-               /* Write Rx addresses (rar_entry_count for RAL/H, +4 for
+               /* Write Rx addresses (rar_entry_count for RAL/H, and
                 * SHRAL/H) and initial CRC values to the MAC
                 */
-               for (i = 0; i < (hw->mac.rar_entry_count + 4); i++) {
+               for (i = 0; i < hw->mac.rar_entry_count; i++) {
                        u8 mac_addr[ETH_ALEN] = { 0 };
                        u32 addr_high, addr_low;
 
index 59865695b2826a388b721b2313253e25d86a7c94..217090df33e788d46603f1c0369a2cf4e8041719 100644 (file)
@@ -98,7 +98,7 @@
 #define PCIE_ICH8_SNOOP_ALL    PCIE_NO_SNOOP_ALL
 
 #define E1000_ICH_RAR_ENTRIES  7
-#define E1000_PCH2_RAR_ENTRIES 5       /* RAR[0], SHRA[0-3] */
+#define E1000_PCH2_RAR_ENTRIES 11      /* RAR[0-6], SHRA[0-3] */
 #define E1000_PCH_LPT_RAR_ENTRIES      12      /* RAR[0], SHRA[0-10] */
 
 #define PHY_PAGE_SHIFT         5