aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorBruce Allan <bruce.w.allan@intel.com>2009-12-08 02:28:20 -0500
committerDavid S. Miller <davem@davemloft.net>2009-12-08 23:10:12 -0500
commit3421eecdee750bafc78b12ac25b3e980195265eb (patch)
tree40df8a228f3971487a3f48bd1e880df1f88d5861 /drivers
parent0781895067444db98050a1537bafbc7a0235ec9f (diff)
e1000e: only perform ESB2 MDIC workaround on certain configurations
A workaround added for all ESB2 devices (adds a delay for all MDIC accesses which resolves an issue with the MDIC ready bit being set prematurely) is applicable only to devices in which the MAC-PHY interconnect is not operating in a certain mode with in-band MDIO. Check the control register for the operating mode and enable the workaround accordingly. 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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/e1000e/es2lan.c97
-rw-r--r--drivers/net/e1000e/hw.h5
2 files changed, 69 insertions, 33 deletions
diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c
index d2a104794609..3028f23da891 100644
--- a/drivers/net/e1000e/es2lan.c
+++ b/drivers/net/e1000e/es2lan.c
@@ -46,6 +46,9 @@
46#define E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT 0x0000 46#define E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT 0x0000
47#define E1000_KMRNCTRLSTA_OPMODE_E_IDLE 0x2000 47#define E1000_KMRNCTRLSTA_OPMODE_E_IDLE 0x2000
48 48
49#define E1000_KMRNCTRLSTA_OPMODE_MASK 0x000C
50#define E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO 0x0004
51
49#define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */ 52#define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */
50#define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN 0x00010000 53#define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN 0x00010000
51 54
@@ -462,28 +465,36 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
462 return ret_val; 465 return ret_val;
463 } 466 }
464 467
465 /* 468 if (hw->dev_spec.e80003es2lan.mdic_wa_enable == true) {
466 * The "ready" bit in the MDIC register may be incorrectly set 469 /*
467 * before the device has completed the "Page Select" MDI 470 * The "ready" bit in the MDIC register may be incorrectly set
468 * transaction. So we wait 200us after each MDI command... 471 * before the device has completed the "Page Select" MDI
469 */ 472 * transaction. So we wait 200us after each MDI command...
470 udelay(200); 473 */
474 udelay(200);
471 475
472 /* ...and verify the command was successful. */ 476 /* ...and verify the command was successful. */
473 ret_val = e1000e_read_phy_reg_mdic(hw, page_select, &temp); 477 ret_val = e1000e_read_phy_reg_mdic(hw, page_select, &temp);
474 478
475 if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { 479 if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {
476 ret_val = -E1000_ERR_PHY; 480 ret_val = -E1000_ERR_PHY;
477 e1000_release_phy_80003es2lan(hw); 481 e1000_release_phy_80003es2lan(hw);
478 return ret_val; 482 return ret_val;
479 } 483 }
480 484
481 udelay(200); 485 udelay(200);
482 486
483 ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, 487 ret_val = e1000e_read_phy_reg_mdic(hw,
484 data); 488 MAX_PHY_REG_ADDRESS & offset,
489 data);
490
491 udelay(200);
492 } else {
493 ret_val = e1000e_read_phy_reg_mdic(hw,
494 MAX_PHY_REG_ADDRESS & offset,
495 data);
496 }
485 497
486 udelay(200);
487 e1000_release_phy_80003es2lan(hw); 498 e1000_release_phy_80003es2lan(hw);
488 499
489 return ret_val; 500 return ret_val;
@@ -526,28 +537,35 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
526 return ret_val; 537 return ret_val;
527 } 538 }
528 539
540 if (hw->dev_spec.e80003es2lan.mdic_wa_enable == true) {
541 /*
542 * The "ready" bit in the MDIC register may be incorrectly set
543 * before the device has completed the "Page Select" MDI
544 * transaction. So we wait 200us after each MDI command...
545 */
546 udelay(200);
529 547
530 /* 548 /* ...and verify the command was successful. */
531 * The "ready" bit in the MDIC register may be incorrectly set 549 ret_val = e1000e_read_phy_reg_mdic(hw, page_select, &temp);
532 * before the device has completed the "Page Select" MDI
533 * transaction. So we wait 200us after each MDI command...
534 */
535 udelay(200);
536 550
537 /* ...and verify the command was successful. */ 551 if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {
538 ret_val = e1000e_read_phy_reg_mdic(hw, page_select, &temp); 552 e1000_release_phy_80003es2lan(hw);
553 return -E1000_ERR_PHY;
554 }
539 555
540 if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) { 556 udelay(200);
541 e1000_release_phy_80003es2lan(hw);
542 return -E1000_ERR_PHY;
543 }
544 557
545 udelay(200); 558 ret_val = e1000e_write_phy_reg_mdic(hw,
559 MAX_PHY_REG_ADDRESS & offset,
560 data);
546 561
547 ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset, 562 udelay(200);
548 data); 563 } else {
564 ret_val = e1000e_write_phy_reg_mdic(hw,
565 MAX_PHY_REG_ADDRESS & offset,
566 data);
567 }
549 568
550 udelay(200);
551 e1000_release_phy_80003es2lan(hw); 569 e1000_release_phy_80003es2lan(hw);
552 570
553 return ret_val; 571 return ret_val;
@@ -866,6 +884,19 @@ static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw)
866 reg_data &= ~0x00100000; 884 reg_data &= ~0x00100000;
867 E1000_WRITE_REG_ARRAY(hw, E1000_FFLT, 0x0001, reg_data); 885 E1000_WRITE_REG_ARRAY(hw, E1000_FFLT, 0x0001, reg_data);
868 886
887 /* default to true to enable the MDIC W/A */
888 hw->dev_spec.e80003es2lan.mdic_wa_enable = true;
889
890 ret_val = e1000_read_kmrn_reg_80003es2lan(hw,
891 E1000_KMRNCTRLSTA_OFFSET >>
892 E1000_KMRNCTRLSTA_OFFSET_SHIFT,
893 &i);
894 if (!ret_val) {
895 if ((i & E1000_KMRNCTRLSTA_OPMODE_MASK) ==
896 E1000_KMRNCTRLSTA_OPMODE_INBAND_MDIO)
897 hw->dev_spec.e80003es2lan.mdic_wa_enable = false;
898 }
899
869 /* 900 /*
870 * Clear all of the statistics registers (clear on read). It is 901 * Clear all of the statistics registers (clear on read). It is
871 * important that we do this after we have tried to establish link 902 * important that we do this after we have tried to establish link
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index 5ed17889e64d..2784cf44a6f3 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -900,6 +900,10 @@ struct e1000_dev_spec_82571 {
900 u32 smb_counter; 900 u32 smb_counter;
901}; 901};
902 902
903struct e1000_dev_spec_80003es2lan {
904 bool mdic_wa_enable;
905};
906
903struct e1000_shadow_ram { 907struct e1000_shadow_ram {
904 u16 value; 908 u16 value;
905 bool modified; 909 bool modified;
@@ -928,6 +932,7 @@ struct e1000_hw {
928 932
929 union { 933 union {
930 struct e1000_dev_spec_82571 e82571; 934 struct e1000_dev_spec_82571 e82571;
935 struct e1000_dev_spec_80003es2lan e80003es2lan;
931 struct e1000_dev_spec_ich8lan ich8lan; 936 struct e1000_dev_spec_ich8lan ich8lan;
932 } dev_spec; 937 } dev_spec;
933}; 938};