|
@@ -74,6 +74,9 @@ static bool e1000_check_mng_mode_82574(struct e1000_hw *hw);
|
|
static s32 e1000_led_on_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);
|
|
static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw);
|
|
static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw);
|
|
static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw);
|
|
|
|
+static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw);
|
|
|
|
+static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw);
|
|
|
|
+static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw);
|
|
|
|
|
|
/**
|
|
/**
|
|
* e1000_init_phy_params_82571 - Init PHY func ptrs.
|
|
* e1000_init_phy_params_82571 - Init PHY func ptrs.
|
|
@@ -107,6 +110,8 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
|
|
case e1000_82574:
|
|
case e1000_82574:
|
|
case e1000_82583:
|
|
case e1000_82583:
|
|
phy->type = e1000_phy_bm;
|
|
phy->type = e1000_phy_bm;
|
|
|
|
+ phy->ops.acquire = e1000_get_hw_semaphore_82574;
|
|
|
|
+ phy->ops.release = e1000_put_hw_semaphore_82574;
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
return -E1000_ERR_PHY;
|
|
return -E1000_ERR_PHY;
|
|
@@ -200,6 +205,17 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw)
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /* Function Pointers */
|
|
|
|
+ switch (hw->mac.type) {
|
|
|
|
+ case e1000_82574:
|
|
|
|
+ case e1000_82583:
|
|
|
|
+ nvm->ops.acquire = e1000_get_hw_semaphore_82574;
|
|
|
|
+ nvm->ops.release = e1000_put_hw_semaphore_82574;
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -542,6 +558,94 @@ static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw)
|
|
swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
|
|
swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
|
|
ew32(SWSM, swsm);
|
|
ew32(SWSM, swsm);
|
|
}
|
|
}
|
|
|
|
+/**
|
|
|
|
+ * e1000_get_hw_semaphore_82573 - Acquire hardware semaphore
|
|
|
|
+ * @hw: pointer to the HW structure
|
|
|
|
+ *
|
|
|
|
+ * Acquire the HW semaphore during reset.
|
|
|
|
+ *
|
|
|
|
+ **/
|
|
|
|
+static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw)
|
|
|
|
+{
|
|
|
|
+ u32 extcnf_ctrl;
|
|
|
|
+ s32 ret_val = 0;
|
|
|
|
+ s32 i = 0;
|
|
|
|
+
|
|
|
|
+ extcnf_ctrl = er32(EXTCNF_CTRL);
|
|
|
|
+ extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
|
|
|
|
+ do {
|
|
|
|
+ ew32(EXTCNF_CTRL, extcnf_ctrl);
|
|
|
|
+ extcnf_ctrl = er32(EXTCNF_CTRL);
|
|
|
|
+
|
|
|
|
+ if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP)
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
|
|
|
|
+
|
|
|
|
+ msleep(2);
|
|
|
|
+ i++;
|
|
|
|
+ } while (i < MDIO_OWNERSHIP_TIMEOUT);
|
|
|
|
+
|
|
|
|
+ if (i == MDIO_OWNERSHIP_TIMEOUT) {
|
|
|
|
+ /* Release semaphores */
|
|
|
|
+ e1000_put_hw_semaphore_82573(hw);
|
|
|
|
+ e_dbg("Driver can't access the PHY\n");
|
|
|
|
+ ret_val = -E1000_ERR_PHY;
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+out:
|
|
|
|
+ return ret_val;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * e1000_put_hw_semaphore_82573 - Release hardware semaphore
|
|
|
|
+ * @hw: pointer to the HW structure
|
|
|
|
+ *
|
|
|
|
+ * Release hardware semaphore used during reset.
|
|
|
|
+ *
|
|
|
|
+ **/
|
|
|
|
+static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw)
|
|
|
|
+{
|
|
|
|
+ u32 extcnf_ctrl;
|
|
|
|
+
|
|
|
|
+ extcnf_ctrl = er32(EXTCNF_CTRL);
|
|
|
|
+ extcnf_ctrl &= ~E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
|
|
|
|
+ ew32(EXTCNF_CTRL, extcnf_ctrl);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static DEFINE_MUTEX(swflag_mutex);
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * e1000_get_hw_semaphore_82574 - Acquire hardware semaphore
|
|
|
|
+ * @hw: pointer to the HW structure
|
|
|
|
+ *
|
|
|
|
+ * Acquire the HW semaphore to access the PHY or NVM.
|
|
|
|
+ *
|
|
|
|
+ **/
|
|
|
|
+static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw)
|
|
|
|
+{
|
|
|
|
+ s32 ret_val;
|
|
|
|
+
|
|
|
|
+ mutex_lock(&swflag_mutex);
|
|
|
|
+ ret_val = e1000_get_hw_semaphore_82573(hw);
|
|
|
|
+ if (ret_val)
|
|
|
|
+ mutex_unlock(&swflag_mutex);
|
|
|
|
+ return ret_val;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * e1000_put_hw_semaphore_82574 - Release hardware semaphore
|
|
|
|
+ * @hw: pointer to the HW structure
|
|
|
|
+ *
|
|
|
|
+ * Release hardware semaphore used to access the PHY or NVM
|
|
|
|
+ *
|
|
|
|
+ **/
|
|
|
|
+static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw)
|
|
|
|
+{
|
|
|
|
+ e1000_put_hw_semaphore_82573(hw);
|
|
|
|
+ mutex_unlock(&swflag_mutex);
|
|
|
|
+}
|
|
|
|
|
|
/**
|
|
/**
|
|
* e1000_acquire_nvm_82571 - Request for access to the EEPROM
|
|
* e1000_acquire_nvm_82571 - Request for access to the EEPROM
|
|
@@ -562,8 +666,6 @@ static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw)
|
|
|
|
|
|
switch (hw->mac.type) {
|
|
switch (hw->mac.type) {
|
|
case e1000_82573:
|
|
case e1000_82573:
|
|
- case e1000_82574:
|
|
|
|
- case e1000_82583:
|
|
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
ret_val = e1000e_acquire_nvm(hw);
|
|
ret_val = e1000e_acquire_nvm(hw);
|
|
@@ -853,9 +955,8 @@ static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active)
|
|
**/
|
|
**/
|
|
static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
|
|
static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
|
|
{
|
|
{
|
|
- u32 ctrl, extcnf_ctrl, ctrl_ext, icr;
|
|
|
|
|
|
+ u32 ctrl, ctrl_ext, icr;
|
|
s32 ret_val;
|
|
s32 ret_val;
|
|
- u16 i = 0;
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
* Prevent the PCI-E bus from sticking if there is no TLP connection
|
|
* Prevent the PCI-E bus from sticking if there is no TLP connection
|
|
@@ -880,33 +981,33 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
|
|
*/
|
|
*/
|
|
switch (hw->mac.type) {
|
|
switch (hw->mac.type) {
|
|
case e1000_82573:
|
|
case e1000_82573:
|
|
|
|
+ ret_val = e1000_get_hw_semaphore_82573(hw);
|
|
|
|
+ break;
|
|
case e1000_82574:
|
|
case e1000_82574:
|
|
case e1000_82583:
|
|
case e1000_82583:
|
|
- extcnf_ctrl = er32(EXTCNF_CTRL);
|
|
|
|
- extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
|
|
|
|
-
|
|
|
|
- do {
|
|
|
|
- ew32(EXTCNF_CTRL, extcnf_ctrl);
|
|
|
|
- extcnf_ctrl = er32(EXTCNF_CTRL);
|
|
|
|
-
|
|
|
|
- if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP)
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
|
|
|
|
-
|
|
|
|
- msleep(2);
|
|
|
|
- i++;
|
|
|
|
- } while (i < MDIO_OWNERSHIP_TIMEOUT);
|
|
|
|
|
|
+ ret_val = e1000_get_hw_semaphore_82574(hw);
|
|
break;
|
|
break;
|
|
default:
|
|
default:
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
+ if (ret_val)
|
|
|
|
+ e_dbg("Cannot acquire MDIO ownership\n");
|
|
|
|
|
|
ctrl = er32(CTRL);
|
|
ctrl = er32(CTRL);
|
|
|
|
|
|
e_dbg("Issuing a global reset to MAC\n");
|
|
e_dbg("Issuing a global reset to MAC\n");
|
|
ew32(CTRL, ctrl | E1000_CTRL_RST);
|
|
ew32(CTRL, ctrl | E1000_CTRL_RST);
|
|
|
|
|
|
|
|
+ /* Must release MDIO ownership and mutex after MAC reset. */
|
|
|
|
+ switch (hw->mac.type) {
|
|
|
|
+ case e1000_82574:
|
|
|
|
+ case e1000_82583:
|
|
|
|
+ e1000_put_hw_semaphore_82574(hw);
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
if (hw->nvm.type == e1000_nvm_flash_hw) {
|
|
if (hw->nvm.type == e1000_nvm_flash_hw) {
|
|
udelay(10);
|
|
udelay(10);
|
|
ctrl_ext = er32(CTRL_EXT);
|
|
ctrl_ext = er32(CTRL_EXT);
|