Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 183499
b: refs/heads/master
c: 608f8a0
h: refs/heads/master
i:
  183497: 778a918
  183495: 26c0e65
v: v3
  • Loading branch information
Bruce Allan authored and David S. Miller committed Jan 14, 2010
1 parent 60d24f0 commit 47a8948
Show file tree
Hide file tree
Showing 8 changed files with 148 additions and 59 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0159f24ee764927bf44c1a25473bd4517febd21c
refs/heads/master: 608f8a0d014db6cd18d4f535934d4b5d556e3013
33 changes: 30 additions & 3 deletions trunk/drivers/net/e1000e/82571.c
Original file line number Diff line number Diff line change
Expand Up @@ -922,9 +922,12 @@ 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);
/* Install any alternate MAC address into RAR0 */
ret_val = e1000_check_alt_mac_addr_generic(hw);
if (ret_val)
return ret_val;

e1000e_set_laa_state_82571(hw, true);

/* Reinitialize the 82571 serdes link state machine */
if (hw->phy.media_type == e1000_media_type_internal_serdes)
Expand Down Expand Up @@ -1620,6 +1623,29 @@ static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw)
return 0;
}

/**
* e1000_read_mac_addr_82571 - Read device MAC address
* @hw: pointer to the HW structure
**/
static s32 e1000_read_mac_addr_82571(struct e1000_hw *hw)
{
s32 ret_val = 0;

/*
* If there's an alternate MAC address place it in RAR0
* so that it will override the Si installed default perm
* address.
*/
ret_val = e1000_check_alt_mac_addr_generic(hw);
if (ret_val)
goto out;

ret_val = e1000_read_mac_addr_generic(hw);

out:
return ret_val;
}

/**
* e1000_power_down_phy_copper_82571 - Remove link during PHY power down
* @hw: pointer to the HW structure
Expand Down Expand Up @@ -1706,6 +1732,7 @@ static struct e1000_mac_operations e82571_mac_ops = {
.setup_link = e1000_setup_link_82571,
/* .setup_physical_interface: media type dependent */
.setup_led = e1000e_setup_led_generic,
.read_mac_addr = e1000_read_mac_addr_82571,
};

static struct e1000_phy_operations e82_phy_ops_igp = {
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/net/e1000e/defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,8 @@
*/
#define E1000_RAR_ENTRIES 15
#define E1000_RAH_AV 0x80000000 /* Receive descriptor valid */
#define E1000_RAL_MAC_ADDR_LEN 4
#define E1000_RAH_MAC_ADDR_LEN 2

/* Error Codes */
#define E1000_ERR_NVM 1
Expand Down
11 changes: 10 additions & 1 deletion trunk/drivers/net/e1000e/e1000.h
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,7 @@ extern s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw);
extern s32 e1000e_force_mac_fc(struct e1000_hw *hw);
extern s32 e1000e_blink_led(struct e1000_hw *hw);
extern void e1000_write_vfta_generic(struct e1000_hw *hw, u32 offset, u32 value);
extern s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw);
extern void e1000e_reset_adaptive(struct e1000_hw *hw);
extern void e1000e_update_adaptive(struct e1000_hw *hw);

Expand Down Expand Up @@ -629,7 +630,15 @@ extern s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16
extern s32 e1000e_validate_nvm_checksum_generic(struct e1000_hw *hw);
extern void e1000e_release_nvm(struct e1000_hw *hw);
extern void e1000e_reload_nvm(struct e1000_hw *hw);
extern s32 e1000e_read_mac_addr(struct e1000_hw *hw);
extern s32 e1000_read_mac_addr_generic(struct e1000_hw *hw);

static inline s32 e1000e_read_mac_addr(struct e1000_hw *hw)
{
if (hw->mac.ops.read_mac_addr)
return hw->mac.ops.read_mac_addr(hw);

return e1000_read_mac_addr_generic(hw);
}

static inline s32 e1000_validate_nvm_checksum(struct e1000_hw *hw)
{
Expand Down
28 changes: 27 additions & 1 deletion trunk/drivers/net/e1000e/es2lan.c
Original file line number Diff line number Diff line change
Expand Up @@ -814,7 +814,9 @@ static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw)
ew32(IMC, 0xffffffff);
icr = er32(ICR);

return 0;
ret_val = e1000_check_alt_mac_addr_generic(hw);

return ret_val;
}

/**
Expand Down Expand Up @@ -1339,6 +1341,29 @@ static s32 e1000_write_kmrn_reg_80003es2lan(struct e1000_hw *hw, u32 offset,
return ret_val;
}

/**
* e1000_read_mac_addr_80003es2lan - Read device MAC address
* @hw: pointer to the HW structure
**/
static s32 e1000_read_mac_addr_80003es2lan(struct e1000_hw *hw)
{
s32 ret_val = 0;

/*
* If there's an alternate MAC address place it in RAR0
* so that it will override the Si installed default perm
* address.
*/
ret_val = e1000_check_alt_mac_addr_generic(hw);
if (ret_val)
goto out;

ret_val = e1000_read_mac_addr_generic(hw);

out:
return ret_val;
}

/**
* e1000_power_down_phy_copper_80003es2lan - Remove link during PHY power down
* @hw: pointer to the HW structure
Expand Down Expand Up @@ -1403,6 +1428,7 @@ static void e1000_clear_hw_cntrs_80003es2lan(struct e1000_hw *hw)
}

static struct e1000_mac_operations es2_mac_ops = {
.read_mac_addr = e1000_read_mac_addr_80003es2lan,
.id_led_init = e1000e_id_led_init,
.check_mng_mode = e1000e_check_mng_mode_generic,
/* check_for_link dependent on media type */
Expand Down
5 changes: 4 additions & 1 deletion trunk/drivers/net/e1000e/hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,9 @@ enum e1e_registers {

#define E1000_FUNC_1 1

#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN0 0
#define E1000_ALT_MAC_ADDRESS_OFFSET_LAN1 3

enum e1000_mac_type {
e1000_82571,
e1000_82572,
Expand Down Expand Up @@ -756,6 +759,7 @@ struct e1000_mac_operations {
s32 (*setup_physical_interface)(struct e1000_hw *);
s32 (*setup_led)(struct e1000_hw *);
void (*write_vfta)(struct e1000_hw *, u32, u32);
s32 (*read_mac_addr)(struct e1000_hw *);
};

/* Function pointers for the PHY. */
Expand Down Expand Up @@ -897,7 +901,6 @@ struct e1000_fc_info {

struct e1000_dev_spec_82571 {
bool laa_is_present;
bool alt_mac_addr_is_present;
u32 smb_counter;
};

Expand Down
124 changes: 73 additions & 51 deletions trunk/drivers/net/e1000e/lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,68 @@ void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count)
e1000e_rar_set(hw, mac_addr, i);
}

/**
* e1000_check_alt_mac_addr_generic - Check for alternate MAC addr
* @hw: pointer to the HW structure
*
* Checks the nvm 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. If an
* alternate MAC address is found it is programmed into RAR0, replacing
* the permanent address that was installed into RAR0 by the Si on reset.
* This function will return SUCCESS unless it encounters an error while
* reading the EEPROM.
**/
s32 e1000_check_alt_mac_addr_generic(struct e1000_hw *hw)
{
u32 i;
s32 ret_val = 0;
u16 offset, nvm_alt_mac_addr_offset, nvm_data;
u8 alt_mac_addr[ETH_ALEN];

ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
&nvm_alt_mac_addr_offset);
if (ret_val) {
e_dbg("NVM Read Error\n");
goto out;
}

if (nvm_alt_mac_addr_offset == 0xFFFF) {
/* There is no Alternate MAC Address */
goto out;
}

if (hw->bus.func == E1000_FUNC_1)
nvm_alt_mac_addr_offset += E1000_ALT_MAC_ADDRESS_OFFSET_LAN1;
for (i = 0; i < ETH_ALEN; i += 2) {
offset = nvm_alt_mac_addr_offset + (i >> 1);
ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data);
if (ret_val) {
e_dbg("NVM Read Error\n");
goto out;
}

alt_mac_addr[i] = (u8)(nvm_data & 0xFF);
alt_mac_addr[i + 1] = (u8)(nvm_data >> 8);
}

/* if multicast bit is set, the alternate address will not be used */
if (alt_mac_addr[0] & 0x01) {
e_dbg("Ignoring Alternate Mac Address with MC bit set\n");
goto out;
}

/*
* We have a valid alternate MAC address, and we want to treat it the
* 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);

out:
return ret_val;
}

/**
* e1000e_rar_set - Set receive address register
* @hw: pointer to the HW structure
Expand Down Expand Up @@ -2072,67 +2134,27 @@ s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
}

/**
* e1000e_read_mac_addr - Read device MAC address
* e1000_read_mac_addr_generic - Read device MAC address
* @hw: pointer to the HW structure
*
* Reads the device MAC address from the EEPROM and stores the value.
* Since devices with two ports use the same EEPROM, we increment the
* last bit in the MAC address for the second port.
**/
s32 e1000e_read_mac_addr(struct e1000_hw *hw)
s32 e1000_read_mac_addr_generic(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) {
e_dbg("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) {
e_dbg("NVM Read Error\n");
return ret_val;
}
if (nvm_data & 0x0001)
mac_addr_offset = 0;
}
u32 rar_high;
u32 rar_low;
u16 i;

if (mac_addr_offset)
hw->dev_spec.e82571.alt_mac_addr_is_present = 1;
}
rar_high = er32(RAH(0));
rar_low = er32(RAL(0));

for (i = 0; i < ETH_ALEN; i += 2) {
offset = mac_addr_offset + (i >> 1);
ret_val = e1000_read_nvm(hw, offset, 1, &nvm_data);
if (ret_val) {
e_dbg("NVM Read Error\n");
return ret_val;
}
hw->mac.perm_addr[i] = (u8)(nvm_data & 0xFF);
hw->mac.perm_addr[i+1] = (u8)(nvm_data >> 8);
}
for (i = 0; i < E1000_RAL_MAC_ADDR_LEN; i++)
hw->mac.perm_addr[i] = (u8)(rar_low >> (i*8));

/* Flip last bit of mac address if we're on second port */
if (!mac_addr_offset && hw->bus.func == E1000_FUNC_1)
hw->mac.perm_addr[5] ^= 1;
for (i = 0; i < E1000_RAH_MAC_ADDR_LEN; i++)
hw->mac.perm_addr[i+4] = (u8)(rar_high >> (i*8));

for (i = 0; i < ETH_ALEN; i++)
hw->mac.addr[i] = hw->mac.perm_addr[i];
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/net/e1000e/netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -5135,7 +5135,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,

e1000_eeprom_checks(adapter);

/* copy the MAC address out of the NVM */
/* copy the MAC address */
if (e1000e_read_mac_addr(&adapter->hw))
e_err("NVM Read Error while reading MAC address\n");

Expand Down

0 comments on commit 47a8948

Please sign in to comment.