aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2009-08-07 03:41:37 -0400
committerDavid S. Miller <davem@davemloft.net>2009-08-10 00:45:36 -0400
commit373a88d78be540c1331ea5adcb76610dddcb008b (patch)
tree06d1a41276e71a9d34105a848df800f59350b2b3
parent6e455b897bb6be3a4c0c6578f679e83d399e5b92 (diff)
e1000e: fix acquisition of SW/FW/HW semaphore for ICHx parts
For ICHx parts, write the EXTCNF_CTRL.SWFLAG bit once when trying to acquire the SW/FW/HW semaphore instead of multiple times to prevent the hardware from having problems (especially for systems with manageability enabled), and extend the timeout for the hardware to set the SWFLAG bit. Signed-off-by: Bruce Allan <bruce.w.allan@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/e1000e/ich8lan.c44
1 files changed, 31 insertions, 13 deletions
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index d56c7473144a..dd61e7e98ddb 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -594,8 +594,8 @@ static DEFINE_MUTEX(nvm_mutex);
594 **/ 594 **/
595static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw) 595static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
596{ 596{
597 u32 extcnf_ctrl; 597 u32 extcnf_ctrl, timeout = PHY_CFG_TIMEOUT;
598 u32 timeout = PHY_CFG_TIMEOUT; 598 s32 ret_val = 0;
599 599
600 might_sleep(); 600 might_sleep();
601 601
@@ -603,28 +603,46 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
603 603
604 while (timeout) { 604 while (timeout) {
605 extcnf_ctrl = er32(EXTCNF_CTRL); 605 extcnf_ctrl = er32(EXTCNF_CTRL);
606 if (!(extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG))
607 break;
606 608
607 if (!(extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)) { 609 mdelay(1);
608 extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG; 610 timeout--;
609 ew32(EXTCNF_CTRL, extcnf_ctrl); 611 }
612
613 if (!timeout) {
614 hw_dbg(hw, "SW/FW/HW has locked the resource for too long.\n");
615 ret_val = -E1000_ERR_CONFIG;
616 goto out;
617 }
618
619 timeout = PHY_CFG_TIMEOUT * 2;
620
621 extcnf_ctrl |= E1000_EXTCNF_CTRL_SWFLAG;
622 ew32(EXTCNF_CTRL, extcnf_ctrl);
623
624 while (timeout) {
625 extcnf_ctrl = er32(EXTCNF_CTRL);
626 if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)
627 break;
610 628
611 extcnf_ctrl = er32(EXTCNF_CTRL);
612 if (extcnf_ctrl & E1000_EXTCNF_CTRL_SWFLAG)
613 break;
614 }
615 mdelay(1); 629 mdelay(1);
616 timeout--; 630 timeout--;
617 } 631 }
618 632
619 if (!timeout) { 633 if (!timeout) {
620 hw_dbg(hw, "FW or HW has locked the resource for too long.\n"); 634 hw_dbg(hw, "Failed to acquire the semaphore.\n");
621 extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG; 635 extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
622 ew32(EXTCNF_CTRL, extcnf_ctrl); 636 ew32(EXTCNF_CTRL, extcnf_ctrl);
623 mutex_unlock(&nvm_mutex); 637 ret_val = -E1000_ERR_CONFIG;
624 return -E1000_ERR_CONFIG; 638 goto out;
625 } 639 }
626 640
627 return 0; 641out:
642 if (ret_val)
643 mutex_unlock(&nvm_mutex);
644
645 return ret_val;
628} 646}
629 647
630/** 648/**