Skip to content

Commit

Permalink
e1000e: fix overrun of PHY RAR array
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
David Ertman authored and Jeff Kirsher committed Sep 13, 2013
1 parent 138953b commit c3a0dce
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 6 deletions.
8 changes: 8 additions & 0 deletions drivers/net/ethernet/intel/e1000e/ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
13 changes: 8 additions & 5 deletions drivers/net/ethernet/intel/e1000e/ich8lan.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/e1000e/ich8lan.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit c3a0dce

Please sign in to comment.