/* setup_physical_interface dependent on media type */
.setup_led = e1000e_setup_led_generic,
.config_collision_dist = e1000e_config_collision_dist_generic,
+ .rar_set = e1000e_rar_set_generic,
};
static const struct e1000_phy_operations es2_phy_ops = {
* incoming packets directed to this port are dropped.
* Eventually the LAA will be in RAR[0] and RAR[14].
*/
- e1000e_rar_set(hw, hw->mac.addr, hw->mac.rar_entry_count - 1);
+ hw->mac.ops.rar_set(hw, hw->mac.addr,
+ hw->mac.rar_entry_count - 1);
}
/**
.setup_led = e1000e_setup_led_generic,
.config_collision_dist = e1000e_config_collision_dist_generic,
.read_mac_addr = e1000_read_mac_addr_82571,
+ .rar_set = e1000e_rar_set_generic,
};
static const struct e1000_phy_operations e82_phy_ops_igp = {
extern void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
u8 *mc_addr_list,
u32 mc_addr_count);
-extern void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
+extern void e1000e_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index);
extern s32 e1000e_set_fc_watermarks(struct e1000_hw *hw);
extern void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop);
extern s32 e1000e_get_hw_semaphore(struct e1000_hw *hw);
#define E1000_RA (E1000_RAL(0))
E1000_RAH_BASE = 0x05404, /* Receive Address High - RW */
#define E1000_RAH(_n) (E1000_RAH_BASE + ((_n) * 8))
+ E1000_SHRAL_BASE = 0x05438, /* Shared Receive Address Low - RW */
+#define E1000_SHRAL(_n) (E1000_SHRAL_BASE + ((_n) * 8))
+ E1000_SHRAH_BASE = 0x0543C, /* Shared Receive Address High - RW */
+#define E1000_SHRAH(_n) (E1000_SHRAH_BASE + ((_n) * 8))
E1000_VFTA = 0x05600, /* VLAN Filter Table Array - RW Array */
E1000_WUC = 0x05800, /* Wakeup Control - RW */
E1000_WUFC = 0x05808, /* Wakeup Filter Control - RW */
s32 (*setup_led)(struct e1000_hw *);
void (*write_vfta)(struct e1000_hw *, u32, u32);
void (*config_collision_dist)(struct e1000_hw *);
+ void (*rar_set)(struct e1000_hw *, u8 *, u32);
s32 (*read_mac_addr)(struct e1000_hw *);
};
#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 PHY_PAGE_SHIFT 5
#define PHY_REG(page, reg) (((page) << PHY_PAGE_SHIFT) | \
static s32 e1000_set_mdio_slow_mode_hv(struct e1000_hw *hw);
static bool e1000_check_mng_mode_ich8lan(struct e1000_hw *hw);
static bool e1000_check_mng_mode_pchlan(struct e1000_hw *hw);
+static void e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index);
static s32 e1000_k1_workaround_lv(struct e1000_hw *hw);
static void e1000_gate_hw_phy_config_ich8lan(struct e1000_hw *hw, bool gate);
mac->ops.led_on = e1000_led_on_ich8lan;
mac->ops.led_off = e1000_led_off_ich8lan;
break;
- case e1000_pchlan:
case e1000_pch2lan:
+ mac->rar_entry_count = E1000_PCH2_RAR_ENTRIES;
+ mac->ops.rar_set = e1000_rar_set_pch2lan;
+ /* fall-through */
+ case e1000_pchlan:
/* check management mode */
mac->ops.check_mng_mode = e1000_check_mng_mode_pchlan;
/* ID LED init */
(fwsm & (E1000_ICH_MNG_IAMT_MODE << E1000_FWSM_MODE_SHIFT));
}
+/**
+ * e1000_rar_set_pch2lan - Set receive address register
+ * @hw: pointer to the HW structure
+ * @addr: pointer to the receive address
+ * @index: receive address array register
+ *
+ * Sets the receive address array register at index to the address passed
+ * in by addr. For 82579, RAR[0] is the base address register that is to
+ * contain the MAC address but RAR[1-6] are reserved for manageability (ME).
+ * Use SHRA[0-3] in place of those reserved for ME.
+ **/
+static void e1000_rar_set_pch2lan(struct e1000_hw *hw, u8 *addr, u32 index)
+{
+ u32 rar_low, rar_high;
+
+ /*
+ * HW expects these in little endian so we reverse the byte order
+ * from network order (big endian) to little endian
+ */
+ rar_low = ((u32)addr[0] |
+ ((u32)addr[1] << 8) |
+ ((u32)addr[2] << 16) | ((u32)addr[3] << 24));
+
+ rar_high = ((u32)addr[4] | ((u32)addr[5] << 8));
+
+ /* If MAC address zero, no need to set the AV bit */
+ if (rar_low || rar_high)
+ rar_high |= E1000_RAH_AV;
+
+ if (index == 0) {
+ ew32(RAL(index), rar_low);
+ e1e_flush();
+ ew32(RAH(index), rar_high);
+ e1e_flush();
+ return;
+ }
+
+ if (index < hw->mac.rar_entry_count) {
+ s32 ret_val;
+
+ ret_val = e1000_acquire_swflag_ich8lan(hw);
+ if (ret_val)
+ goto out;
+
+ ew32(SHRAL(index - 1), rar_low);
+ e1e_flush();
+ ew32(SHRAH(index - 1), rar_high);
+ e1e_flush();
+
+ e1000_release_swflag_ich8lan(hw);
+
+ /* verify the register updates */
+ if ((er32(SHRAL(index - 1)) == rar_low) &&
+ (er32(SHRAH(index - 1)) == rar_high))
+ return;
+
+ e_dbg("SHRA[%d] might be locked by ME - FWSM=0x%8.8x\n",
+ (index - 1), er32(FWSM));
+ }
+
+out:
+ e_dbg("Failed to write receive address at index %d\n", index);
+}
+
/**
* e1000_check_reset_block_ich8lan - Check if PHY reset is blocked
* @hw: pointer to the HW structure
.setup_physical_interface= e1000_setup_copper_link_ich8lan,
/* id_led_init dependent on mac type */
.config_collision_dist = e1000e_config_collision_dist_generic,
+ .rar_set = e1000e_rar_set_generic,
};
static const struct e1000_phy_operations ich8_phy_ops = {
/* Setup the receive address */
e_dbg("Programming MAC Address into RAR[0]\n");
- e1000e_rar_set(hw, hw->mac.addr, 0);
+ hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
/* Zero out the other (rar_entry_count - 1) receive addresses */
e_dbg("Clearing RAR[1-%u]\n", rar_count - 1);
for (i = 1; i < rar_count; i++)
- e1000e_rar_set(hw, mac_addr, i);
+ hw->mac.ops.rar_set(hw, mac_addr, i);
}
/**
* same as the normal permanent MAC address stored by the HW into the
* RAR. Do this by mapping this address into RAR0.
*/
- e1000e_rar_set(hw, alt_mac_addr, 0);
+ hw->mac.ops.rar_set(hw, alt_mac_addr, 0);
return 0;
}
/**
- * e1000e_rar_set - Set receive address register
+ * e1000e_rar_set_generic - Set receive address register
* @hw: pointer to the HW structure
* @addr: pointer to the receive address
* @index: receive address array register
* Sets the receive address array register at index to the address passed
* in by addr.
**/
-void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
+void e1000e_rar_set_generic(struct e1000_hw *hw, u8 *addr, u32 index)
{
u32 rar_low, rar_high;
netdev_for_each_uc_addr(ha, netdev) {
if (!rar_entries)
break;
- e1000e_rar_set(hw, ha->addr, rar_entries--);
+ hw->mac.ops.rar_set(hw, ha->addr, rar_entries--);
count++;
}
}
static int e1000_set_mac(struct net_device *netdev, void *p)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
+ struct e1000_hw *hw = &adapter->hw;
struct sockaddr *addr = p;
if (!is_valid_ether_addr(addr->sa_data))
memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
memcpy(adapter->hw.mac.addr, addr->sa_data, netdev->addr_len);
- e1000e_rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
+ hw->mac.ops.rar_set(&adapter->hw, adapter->hw.mac.addr, 0);
if (adapter->flags & FLAG_RESET_OVERWRITES_LAA) {
/* activate the work around */
* are dropped. Eventually the LAA will be in RAR[0] and
* RAR[14]
*/
- e1000e_rar_set(&adapter->hw,
- adapter->hw.mac.addr,
- adapter->hw.mac.rar_entry_count - 1);
+ hw->mac.ops.rar_set(&adapter->hw, adapter->hw.mac.addr,
+ adapter->hw.mac.rar_entry_count - 1);
}
return 0;
* reset from the other port. Set the appropriate LAA in RAR[0]
*/
if (e1000e_get_laa_state_82571(hw))
- e1000e_rar_set(hw, adapter->hw.mac.addr, 0);
+ hw->mac.ops.rar_set(hw, adapter->hw.mac.addr, 0);
if (adapter->flags2 & FLAG2_CHECK_PHY_HANG)
e1000e_check_82574_phy_workaround(adapter);