Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 150777
b: refs/heads/master
c: 23a2d1b
h: refs/heads/master
i:
  150775: 948932f
v: v3
  • Loading branch information
Dave Graham authored and David S. Miller committed Jun 9, 2009
1 parent b0e6170 commit c158d4d
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 8 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: 8459464f07cf67cab07b17d5736d75fb86adab22
refs/heads/master: 23a2d1b233f535fc74f8dca66e488980b4db041b
86 changes: 79 additions & 7 deletions trunk/drivers/net/e1000e/82571.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ static s32 e1000_setup_link_82571(struct e1000_hw *hw);
static void e1000_clear_hw_cntrs_82571(struct e1000_hw *hw);
static bool e1000_check_mng_mode_82574(struct e1000_hw *hw);
static s32 e1000_led_on_82574(struct e1000_hw *hw);
static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw);

/**
* e1000_init_phy_params_82571 - Init PHY func ptrs.
Expand Down Expand Up @@ -212,6 +213,9 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
struct e1000_hw *hw = &adapter->hw;
struct e1000_mac_info *mac = &hw->mac;
struct e1000_mac_operations *func = &mac->ops;
u32 swsm = 0;
u32 swsm2 = 0;
bool force_clear_smbi = false;

/* Set media type */
switch (adapter->pdev->device) {
Expand Down Expand Up @@ -276,6 +280,50 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
break;
}

/*
* Ensure that the inter-port SWSM.SMBI lock bit is clear before
* first NVM or PHY acess. This should be done for single-port
* devices, and for one port only on dual-port devices so that
* for those devices we can still use the SMBI lock to synchronize
* inter-port accesses to the PHY & NVM.
*/
switch (hw->mac.type) {
case e1000_82571:
case e1000_82572:
swsm2 = er32(SWSM2);

if (!(swsm2 & E1000_SWSM2_LOCK)) {
/* Only do this for the first interface on this card */
ew32(SWSM2,
swsm2 | E1000_SWSM2_LOCK);
force_clear_smbi = true;
} else
force_clear_smbi = false;
break;
default:
force_clear_smbi = true;
break;
}

if (force_clear_smbi) {
/* Make sure SWSM.SMBI is clear */
swsm = er32(SWSM);
if (swsm & E1000_SWSM_SMBI) {
/* This bit should not be set on a first interface, and
* indicates that the bootagent or EFI code has
* improperly left this bit enabled
*/
hw_dbg(hw, "Please update your 82571 Bootagent\n");
}
ew32(SWSM, swsm & ~E1000_SWSM_SMBI);
}

/*
* Initialze device specific counter of SMBI acquisition
* timeouts.
*/
hw->dev_spec.e82571.smb_counter = 0;

return 0;
}

Expand Down Expand Up @@ -413,11 +461,37 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
{
u32 swsm;
s32 timeout = hw->nvm.word_size + 1;
s32 sw_timeout = hw->nvm.word_size + 1;
s32 fw_timeout = hw->nvm.word_size + 1;
s32 i = 0;

/*
* If we have timedout 3 times on trying to acquire
* the inter-port SMBI semaphore, there is old code
* operating on the other port, and it is not
* releasing SMBI. Modify the number of times that
* we try for the semaphore to interwork with this
* older code.
*/
if (hw->dev_spec.e82571.smb_counter > 2)
sw_timeout = 1;

/* Get the SW semaphore */
while (i < sw_timeout) {
swsm = er32(SWSM);
if (!(swsm & E1000_SWSM_SMBI))
break;

udelay(50);
i++;
}

if (i == sw_timeout) {
hw_dbg(hw, "Driver can't access device - SMBI bit is set.\n");
hw->dev_spec.e82571.smb_counter++;
}
/* Get the FW semaphore. */
for (i = 0; i < timeout; i++) {
for (i = 0; i < fw_timeout; i++) {
swsm = er32(SWSM);
ew32(SWSM, swsm | E1000_SWSM_SWESMBI);

Expand All @@ -428,9 +502,9 @@ static s32 e1000_get_hw_semaphore_82571(struct e1000_hw *hw)
udelay(50);
}

if (i == timeout) {
if (i == fw_timeout) {
/* Release semaphores */
e1000e_put_hw_semaphore(hw);
e1000_put_hw_semaphore_82571(hw);
hw_dbg(hw, "Driver can't access the NVM\n");
return -E1000_ERR_NVM;
}
Expand All @@ -449,9 +523,7 @@ static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw)
u32 swsm;

swsm = er32(SWSM);

swsm &= ~E1000_SWSM_SWESMBI;

swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
ew32(SWSM, swsm);
}

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 @@ -376,6 +376,8 @@
#define E1000_SWSM_SWESMBI 0x00000002 /* FW Semaphore bit */
#define E1000_SWSM_DRV_LOAD 0x00000008 /* Driver Loaded Bit */

#define E1000_SWSM2_LOCK 0x00000002 /* Secondary driver semaphore bit */

/* Interrupt Cause Read */
#define E1000_ICR_TXDW 0x00000001 /* Transmit desc written back */
#define E1000_ICR_LSC 0x00000004 /* Link Status Change */
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/net/e1000e/hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ enum e1e_registers {
E1000_FACTPS = 0x05B30, /* Function Active and Power State to MNG */
E1000_SWSM = 0x05B50, /* SW Semaphore */
E1000_FWSM = 0x05B54, /* FW Semaphore */
E1000_SWSM2 = 0x05B58, /* Driver-only SW semaphore */
E1000_HICR = 0x08F00, /* Host Interface Control */
};

Expand Down Expand Up @@ -883,6 +884,7 @@ struct e1000_fc_info {
struct e1000_dev_spec_82571 {
bool laa_is_present;
bool alt_mac_addr_is_present;
u32 smb_counter;
};

struct e1000_shadow_ram {
Expand Down

0 comments on commit c158d4d

Please sign in to comment.