aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/e1000e
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2010-11-16 22:50:14 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2010-11-16 22:50:14 -0500
commit1b98c2bb63a4b415d8d894d001b6d0256409e0d9 (patch)
tree820d02cb7aea80c034d3b85fe5fc15eba2cf572a /drivers/net/e1000e
parentd478eb44f7a6b53256ae399fa7e597525b4034ee (diff)
e1000e: 82574 intermittently fails to initialize with manageability f/w
The driver can fail initializing the hardware when manageability firmware is performing concurrent MDIO operations because the hardware semaphore scheme to prevent concurrent operations between software and firmware is incorrect for 82574/82583. Instead of using the SWSM register, the driver should be using the EXTCNF_CTRL register. A software mutex is also added to prevent simultaneous software threads from performing similar concurrent accesses. Signed-off-by: Bruce Allan <bruce.w.allan@intel.com> Tested-by: Emil Tantilov <emil.s.tantilov@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/e1000e')
-rw-r--r--drivers/net/e1000e/82571.c139
1 files changed, 120 insertions, 19 deletions
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index 235856375ff3..9333921010cc 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -74,6 +74,9 @@ static bool e1000_check_mng_mode_82574(struct e1000_hw *hw);
74static s32 e1000_led_on_82574(struct e1000_hw *hw); 74static s32 e1000_led_on_82574(struct e1000_hw *hw);
75static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw); 75static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw);
76static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw); 76static void e1000_power_down_phy_copper_82571(struct e1000_hw *hw);
77static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw);
78static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw);
79static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw);
77 80
78/** 81/**
79 * e1000_init_phy_params_82571 - Init PHY func ptrs. 82 * e1000_init_phy_params_82571 - Init PHY func ptrs.
@@ -107,6 +110,8 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
107 case e1000_82574: 110 case e1000_82574:
108 case e1000_82583: 111 case e1000_82583:
109 phy->type = e1000_phy_bm; 112 phy->type = e1000_phy_bm;
113 phy->ops.acquire = e1000_get_hw_semaphore_82574;
114 phy->ops.release = e1000_put_hw_semaphore_82574;
110 break; 115 break;
111 default: 116 default:
112 return -E1000_ERR_PHY; 117 return -E1000_ERR_PHY;
@@ -200,6 +205,17 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw)
200 break; 205 break;
201 } 206 }
202 207
208 /* Function Pointers */
209 switch (hw->mac.type) {
210 case e1000_82574:
211 case e1000_82583:
212 nvm->ops.acquire = e1000_get_hw_semaphore_82574;
213 nvm->ops.release = e1000_put_hw_semaphore_82574;
214 break;
215 default:
216 break;
217 }
218
203 return 0; 219 return 0;
204} 220}
205 221
@@ -542,6 +558,94 @@ static void e1000_put_hw_semaphore_82571(struct e1000_hw *hw)
542 swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI); 558 swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
543 ew32(SWSM, swsm); 559 ew32(SWSM, swsm);
544} 560}
561/**
562 * e1000_get_hw_semaphore_82573 - Acquire hardware semaphore
563 * @hw: pointer to the HW structure
564 *
565 * Acquire the HW semaphore during reset.
566 *
567 **/
568static s32 e1000_get_hw_semaphore_82573(struct e1000_hw *hw)
569{
570 u32 extcnf_ctrl;
571 s32 ret_val = 0;
572 s32 i = 0;
573
574 extcnf_ctrl = er32(EXTCNF_CTRL);
575 extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
576 do {
577 ew32(EXTCNF_CTRL, extcnf_ctrl);
578 extcnf_ctrl = er32(EXTCNF_CTRL);
579
580 if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP)
581 break;
582
583 extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
584
585 msleep(2);
586 i++;
587 } while (i < MDIO_OWNERSHIP_TIMEOUT);
588
589 if (i == MDIO_OWNERSHIP_TIMEOUT) {
590 /* Release semaphores */
591 e1000_put_hw_semaphore_82573(hw);
592 e_dbg("Driver can't access the PHY\n");
593 ret_val = -E1000_ERR_PHY;
594 goto out;
595 }
596
597out:
598 return ret_val;
599}
600
601/**
602 * e1000_put_hw_semaphore_82573 - Release hardware semaphore
603 * @hw: pointer to the HW structure
604 *
605 * Release hardware semaphore used during reset.
606 *
607 **/
608static void e1000_put_hw_semaphore_82573(struct e1000_hw *hw)
609{
610 u32 extcnf_ctrl;
611
612 extcnf_ctrl = er32(EXTCNF_CTRL);
613 extcnf_ctrl &= ~E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
614 ew32(EXTCNF_CTRL, extcnf_ctrl);
615}
616
617static DEFINE_MUTEX(swflag_mutex);
618
619/**
620 * e1000_get_hw_semaphore_82574 - Acquire hardware semaphore
621 * @hw: pointer to the HW structure
622 *
623 * Acquire the HW semaphore to access the PHY or NVM.
624 *
625 **/
626static s32 e1000_get_hw_semaphore_82574(struct e1000_hw *hw)
627{
628 s32 ret_val;
629
630 mutex_lock(&swflag_mutex);
631 ret_val = e1000_get_hw_semaphore_82573(hw);
632 if (ret_val)
633 mutex_unlock(&swflag_mutex);
634 return ret_val;
635}
636
637/**
638 * e1000_put_hw_semaphore_82574 - Release hardware semaphore
639 * @hw: pointer to the HW structure
640 *
641 * Release hardware semaphore used to access the PHY or NVM
642 *
643 **/
644static void e1000_put_hw_semaphore_82574(struct e1000_hw *hw)
645{
646 e1000_put_hw_semaphore_82573(hw);
647 mutex_unlock(&swflag_mutex);
648}
545 649
546/** 650/**
547 * e1000_acquire_nvm_82571 - Request for access to the EEPROM 651 * e1000_acquire_nvm_82571 - Request for access to the EEPROM
@@ -562,8 +666,6 @@ static s32 e1000_acquire_nvm_82571(struct e1000_hw *hw)
562 666
563 switch (hw->mac.type) { 667 switch (hw->mac.type) {
564 case e1000_82573: 668 case e1000_82573:
565 case e1000_82574:
566 case e1000_82583:
567 break; 669 break;
568 default: 670 default:
569 ret_val = e1000e_acquire_nvm(hw); 671 ret_val = e1000e_acquire_nvm(hw);
@@ -853,9 +955,8 @@ static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active)
853 **/ 955 **/
854static s32 e1000_reset_hw_82571(struct e1000_hw *hw) 956static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
855{ 957{
856 u32 ctrl, extcnf_ctrl, ctrl_ext, icr; 958 u32 ctrl, ctrl_ext, icr;
857 s32 ret_val; 959 s32 ret_val;
858 u16 i = 0;
859 960
860 /* 961 /*
861 * Prevent the PCI-E bus from sticking if there is no TLP connection 962 * 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)
880 */ 981 */
881 switch (hw->mac.type) { 982 switch (hw->mac.type) {
882 case e1000_82573: 983 case e1000_82573:
984 ret_val = e1000_get_hw_semaphore_82573(hw);
985 break;
883 case e1000_82574: 986 case e1000_82574:
884 case e1000_82583: 987 case e1000_82583:
885 extcnf_ctrl = er32(EXTCNF_CTRL); 988 ret_val = e1000_get_hw_semaphore_82574(hw);
886 extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
887
888 do {
889 ew32(EXTCNF_CTRL, extcnf_ctrl);
890 extcnf_ctrl = er32(EXTCNF_CTRL);
891
892 if (extcnf_ctrl & E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP)
893 break;
894
895 extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
896
897 msleep(2);
898 i++;
899 } while (i < MDIO_OWNERSHIP_TIMEOUT);
900 break; 989 break;
901 default: 990 default:
902 break; 991 break;
903 } 992 }
993 if (ret_val)
994 e_dbg("Cannot acquire MDIO ownership\n");
904 995
905 ctrl = er32(CTRL); 996 ctrl = er32(CTRL);
906 997
907 e_dbg("Issuing a global reset to MAC\n"); 998 e_dbg("Issuing a global reset to MAC\n");
908 ew32(CTRL, ctrl | E1000_CTRL_RST); 999 ew32(CTRL, ctrl | E1000_CTRL_RST);
909 1000
1001 /* Must release MDIO ownership and mutex after MAC reset. */
1002 switch (hw->mac.type) {
1003 case e1000_82574:
1004 case e1000_82583:
1005 e1000_put_hw_semaphore_82574(hw);
1006 break;
1007 default:
1008 break;
1009 }
1010
910 if (hw->nvm.type == e1000_nvm_flash_hw) { 1011 if (hw->nvm.type == e1000_nvm_flash_hw) {
911 udelay(10); 1012 udelay(10);
912 ctrl_ext = er32(CTRL_EXT); 1013 ctrl_ext = er32(CTRL_EXT);