Commit 93ca1610 authored by Bill Hayes's avatar Bill Hayes Committed by David S. Miller
Browse files

e1000e: alternate MAC address support



Port alternate MAC address support from the sourceforge
e1000 driver to the upstream e1000e driver.

Signed-off-by: default avatarBill Hayes <bill.hayes@hp.com>
Signed-off-by: default avatarAuke Kok <auke-jan.h.kok@intel.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 3df5920c
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -752,6 +752,10 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
	ew32(IMC, 0xffffffff);
	icr = er32(ICR);

	if (hw->mac.type == e1000_82571 &&
		hw->dev_spec.e82571.alt_mac_addr_is_present)
			e1000e_set_laa_state_82571(hw, true);

	return 0;
}

+1 −0
Original line number Diff line number Diff line
@@ -557,6 +557,7 @@
#define NVM_INIT_3GIO_3            0x001A
#define NVM_INIT_CONTROL3_PORT_A   0x0024
#define NVM_CFG                    0x0012
#define NVM_ALT_MAC_ADDR_PTR       0x0037
#define NVM_CHECKSUM_REG           0x003F

#define E1000_NVM_CFG_DONE_PORT_0  0x40000 /* MNG config cycle done */
+1 −0
Original line number Diff line number Diff line
@@ -816,6 +816,7 @@ struct e1000_bus_info {

struct e1000_dev_spec_82571 {
	bool laa_is_present;
	bool alt_mac_addr_is_present;
};

struct e1000_shadow_ram {
+37 −2
Original line number Diff line number Diff line
@@ -2059,9 +2059,44 @@ s32 e1000e_read_mac_addr(struct e1000_hw *hw)
{
	s32 ret_val;
	u16 offset, nvm_data, i;
	u16 mac_addr_offset = 0;

	if (hw->mac.type == e1000_82571) {
		/* Check for an alternate MAC address.  An alternate MAC
		 * address can be setup by pre-boot software and must be
		 * treated like a permanent address and must override the
		 * actual permanent MAC address. */
		ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
						&mac_addr_offset);
		if (ret_val) {
			hw_dbg(hw, "NVM Read Error\n");
			return ret_val;
		}
		if (mac_addr_offset == 0xFFFF)
			mac_addr_offset = 0;

		if (mac_addr_offset) {
			if (hw->bus.func == E1000_FUNC_1)
				mac_addr_offset += ETH_ALEN/sizeof(u16);

			/* make sure we have a valid mac address here
			 * before using it */
			ret_val = e1000_read_nvm(hw, mac_addr_offset, 1,
						 &nvm_data);
			if (ret_val) {
				hw_dbg(hw, "NVM Read Error\n");
				return ret_val;
			}
			if (nvm_data & 0x0001)
				mac_addr_offset = 0;
		}

		if (mac_addr_offset)
			hw->dev_spec.e82571.alt_mac_addr_is_present = 1;
	}

	for (i = 0; i < ETH_ALEN; i += 2) {
		offset = i >> 1;
		offset = mac_addr_offset + (i >> 1);
		ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data);
		if (ret_val) {
			hw_dbg(hw, "NVM Read Error\n");
@@ -2072,7 +2107,7 @@ s32 e1000e_read_mac_addr(struct e1000_hw *hw)
	}

	/* Flip last bit of mac address if we're on second port */
	if (hw->bus.func == E1000_FUNC_1)
	if (!mac_addr_offset && hw->bus.func == E1000_FUNC_1)
		hw->mac.perm_addr[5] ^= 1;

	for (i = 0; i < ETH_ALEN; i++)