Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

e1000e: Failure to write SHRA turns on PROMISC mode

Previously, the check to turn on promiscuous mode only took into account
the total number of SHared Receive Address (SHRA) registers and if the
request was for a register within that range. It is possible that the
Management Engine might have locked a number of SHRA and not allowed a
new address to be written to the requested register.

Add a function to determine the number of unlocked SHRA registers. Then
determine if the number of registers available is sufficient for our needs,
if not then return -ENOMEM so that UNICAST PROMISC mode is activated.

Since the method by which ME claims SHRA registers is non-deterministic,
also add a return value to the function attempting to write an address
to a SHRA, and return a -E1000_ERR_CONFIG if the write fails. The error
will be passed up the function chain and allow the driver to also set
UNICAST PROMISC when this happens.

Cc: Vlad Yasevich <vyasevic@redhat.com>
Signed-off-by: Dave Ertman <davidx.m.ertman@intel.com>
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

authored by

David Ertman and committed by
Jeff Kirsher
b3e5bf1f a0cccce2

+71 -13
+1
drivers/net/ethernet/intel/e1000e/80003es2lan.c
··· 1365 1365 .setup_led = e1000e_setup_led_generic, 1366 1366 .config_collision_dist = e1000e_config_collision_dist_generic, 1367 1367 .rar_set = e1000e_rar_set_generic, 1368 + .rar_get_count = e1000e_rar_get_count_generic, 1368 1369 }; 1369 1370 1370 1371 static const struct e1000_phy_operations es2_phy_ops = {
+1
drivers/net/ethernet/intel/e1000e/82571.c
··· 1896 1896 .config_collision_dist = e1000e_config_collision_dist_generic, 1897 1897 .read_mac_addr = e1000_read_mac_addr_82571, 1898 1898 .rar_set = e1000e_rar_set_generic, 1899 + .rar_get_count = e1000e_rar_get_count_generic, 1899 1900 }; 1900 1901 1901 1902 static const struct e1000_phy_operations e82_phy_ops_igp = {
+2 -1
drivers/net/ethernet/intel/e1000e/hw.h
··· 469 469 s32 (*setup_led)(struct e1000_hw *); 470 470 void (*write_vfta)(struct e1000_hw *, u32, u32); 471 471 void (*config_collision_dist)(struct e1000_hw *); 472 - void (*rar_set)(struct e1000_hw *, u8 *, u32); 472 + int (*rar_set)(struct e1000_hw *, u8 *, u32); 473 473 s32 (*read_mac_addr)(struct e1000_hw *); 474 + u32 (*rar_get_count)(struct e1000_hw *); 474 475 }; 475 476 476 477 /* When to use various PHY register access functions:
+49 -8
drivers/net/ethernet/intel/e1000e/ich8lan.c
··· 139 139 static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw); 140 140 static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw); 141 141 static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw); 142 - static void e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index); 143 - static void e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index); 142 + static int e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index); 143 + static int e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index); 144 + static u32 e1000_rar_get_count_pch_lpt(struct e1000_hw *hw); 144 145 static s32 e1000_k1_workaround_lv(struct e1000_hw *hw); 145 146 static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate); 146 147 static s32 e1000_disable_ulp_lpt_lp(struct e1000_hw *hw, bool force); ··· 705 704 mac->ops.rar_set = e1000_rar_set_pch_lpt; 706 705 mac->ops.setup_physical_interface = 707 706 e1000_setup_copper_link_pch_lpt; 707 + mac->ops.rar_get_count = e1000_rar_get_count_pch_lpt; 708 708 } 709 709 710 710 /* Enable PCS Lock-loss workaround for ICH8 */ ··· 1670 1668 * contain the MAC address but RAR[1-6] are reserved for manageability (ME). 1671 1669 * Use SHRA[0-3] in place of those reserved for ME. 1672 1670 **/ 1673 - static void e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index) 1671 + static int e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index) 1674 1672 { 1675 1673 u32 rar_low, rar_high; 1676 1674 ··· 1692 1690 e1e_flush(); 1693 1691 ew32(RAH(index), rar_high); 1694 1692 e1e_flush(); 1695 - return; 1693 + return 0; 1696 1694 } 1697 1695 1698 1696 /* RAR[1-6] are owned by manageability. Skip those and program the ··· 1715 1713 /* verify the register updates */ 1716 1714 if ((er32(SHRAL(index - 1)) == rar_low) && 1717 1715 (er32(SHRAH(index - 1)) == rar_high)) 1718 - return; 1716 + return 0; 1719 1717 1720 1718 e_dbg("SHRA[%d] might be locked by ME - FWSM=0x%8.8x\n", 1721 1719 (index - 1), er32(FWSM)); ··· 1723 1721 1724 1722 out: 1725 1723 e_dbg("Failed to write receive address at index %d\n", index); 1724 + return -E1000_ERR_CONFIG; 1725 + } 1726 + 1727 + /** 1728 + * e1000_rar_get_count_pch_lpt - Get the number of available SHRA 1729 + * @hw: pointer to the HW structure 1730 + * 1731 + * Get the number of available receive registers that the Host can 1732 + * program. SHRA[0-10] are the shared receive address registers 1733 + * that are shared between the Host and manageability engine (ME). 1734 + * ME can reserve any number of addresses and the host needs to be 1735 + * able to tell how many available registers it has access to. 1736 + **/ 1737 + static u32 e1000_rar_get_count_pch_lpt(struct e1000_hw *hw) 1738 + { 1739 + u32 wlock_mac; 1740 + u32 num_entries; 1741 + 1742 + wlock_mac = er32(FWSM) & E1000_FWSM_WLOCK_MAC_MASK; 1743 + wlock_mac >>= E1000_FWSM_WLOCK_MAC_SHIFT; 1744 + 1745 + switch (wlock_mac) { 1746 + case 0: 1747 + /* All SHRA[0..10] and RAR[0] available */ 1748 + num_entries = hw->mac.rar_entry_count; 1749 + break; 1750 + case 1: 1751 + /* Only RAR[0] available */ 1752 + num_entries = 1; 1753 + break; 1754 + default: 1755 + /* SHRA[0..(wlock_mac - 1)] available + RAR[0] */ 1756 + num_entries = wlock_mac + 1; 1757 + break; 1758 + } 1759 + 1760 + return num_entries; 1726 1761 } 1727 1762 1728 1763 /** ··· 1773 1734 * contain the MAC address. SHRA[0-10] are the shared receive address 1774 1735 * registers that are shared between the Host and manageability engine (ME). 1775 1736 **/ 1776 - static void e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index) 1737 + static int e1000_rar_set_pch_lpt(struct e1000_hw *hw, u8 *addr, u32 index) 1777 1738 { 1778 1739 u32 rar_low, rar_high; 1779 1740 u32 wlock_mac; ··· 1795 1756 e1e_flush(); 1796 1757 ew32(RAH(index), rar_high); 1797 1758 e1e_flush(); 1798 - return; 1759 + return 0; 1799 1760 } 1800 1761 1801 1762 /* The manageability engine (ME) can lock certain SHRAR registers that ··· 1827 1788 /* verify the register updates */ 1828 1789 if ((er32(SHRAL_PCH_LPT(index - 1)) == rar_low) && 1829 1790 (er32(SHRAH_PCH_LPT(index - 1)) == rar_high)) 1830 - return; 1791 + return 0; 1831 1792 } 1832 1793 } 1833 1794 1834 1795 out: 1835 1796 e_dbg("Failed to write receive address at index %d\n", index); 1797 + return -E1000_ERR_CONFIG; 1836 1798 } 1837 1799 1838 1800 /** ··· 5017 4977 /* id_led_init dependent on mac type */ 5018 4978 .config_collision_dist = e1000e_config_collision_dist_generic, 5019 4979 .rar_set = e1000e_rar_set_generic, 4980 + .rar_get_count = e1000e_rar_get_count_generic, 5020 4981 }; 5021 4982 5022 4983 static const struct e1000_phy_operations ich8_phy_ops = {
+8 -1
drivers/net/ethernet/intel/e1000e/mac.c
··· 211 211 return 0; 212 212 } 213 213 214 + u32 e1000e_rar_get_count_generic(struct e1000_hw *hw) 215 + { 216 + return hw->mac.rar_entry_count; 217 + } 218 + 214 219 /** 215 220 * e1000e_rar_set_generic - Set receive address register 216 221 * @hw: pointer to the HW structure ··· 225 220 * Sets the receive address array register at index to the address passed 226 221 * in by addr. 227 222 **/ 228 - void e1000e_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index) 223 + int e1000e_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index) 229 224 { 230 225 u32 rar_low, rar_high; 231 226 ··· 249 244 e1e_flush(); 250 245 ew32(RAH(index), rar_high); 251 246 e1e_flush(); 247 + 248 + return 0; 252 249 } 253 250 254 251 /**
+2 -1
drivers/net/ethernet/intel/e1000e/mac.h
··· 61 61 void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value); 62 62 63 63 void e1000_set_lan_id_multi_port_pcie(struct e1000_hw *hw); 64 - void e1000e_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index); 64 + u32 e1000e_rar_get_count_generic(struct e1000_hw *hw); 65 + int e1000e_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index); 65 66 void e1000e_config_collision_dist_generic(struct e1000_hw *hw); 66 67 67 68 #endif
+8 -2
drivers/net/ethernet/intel/e1000e/netdev.c
··· 3311 3311 { 3312 3312 struct e1000_adapter *adapter = netdev_priv(netdev); 3313 3313 struct e1000_hw *hw = &adapter->hw; 3314 - unsigned int rar_entries = hw->mac.rar_entry_count; 3314 + unsigned int rar_entries; 3315 3315 int count = 0; 3316 + 3317 + rar_entries = hw->mac.ops.rar_get_count(hw); 3316 3318 3317 3319 /* save a rar entry for our hardware address */ 3318 3320 rar_entries--; ··· 3334 3332 * combining 3335 3333 */ 3336 3334 netdev_for_each_uc_addr(ha, netdev) { 3335 + int rval; 3336 + 3337 3337 if (!rar_entries) 3338 3338 break; 3339 - hw->mac.ops.rar_set(hw, ha->addr, rar_entries--); 3339 + rval = hw->mac.ops.rar_set(hw, ha->addr, rar_entries--); 3340 + if (rval < 0) 3341 + return -ENOMEM; 3340 3342 count++; 3341 3343 } 3342 3344 }