diff options
author | Nick Nunley <nicholas.d.nunley@intel.com> | 2010-07-26 09:15:06 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-07-26 21:42:53 -0400 |
commit | 4085f746db1b7d6b292cf27cc713a13a1fcb2681 (patch) | |
tree | bab50788ad8fc71dbd570c665f9d7b189bf4b235 /drivers/net/igb | |
parent | ea7afd31fb45d2d5d1b1e4cf347a688370feee91 (diff) |
igb: add support for SGMII-based MDIO PHYs
This patch adds support for external MDIO PHYs, in addition to
the standard SFP support for SGMII PHYs over the I2C interface.
Signed-off-by: Nicholas Nunley <nicholas.d.nunley@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@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/net/igb')
-rw-r--r-- | drivers/net/igb/e1000_82575.c | 82 | ||||
-rw-r--r-- | drivers/net/igb/e1000_defines.h | 10 |
2 files changed, 75 insertions, 17 deletions
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c index 06251a9e9f1b..2971438bd873 100644 --- a/drivers/net/igb/e1000_82575.c +++ b/drivers/net/igb/e1000_82575.c | |||
@@ -70,6 +70,35 @@ static const u16 e1000_82580_rxpbs_table[] = | |||
70 | #define E1000_82580_RXPBS_TABLE_SIZE \ | 70 | #define E1000_82580_RXPBS_TABLE_SIZE \ |
71 | (sizeof(e1000_82580_rxpbs_table)/sizeof(u16)) | 71 | (sizeof(e1000_82580_rxpbs_table)/sizeof(u16)) |
72 | 72 | ||
73 | /** | ||
74 | * igb_sgmii_uses_mdio_82575 - Determine if I2C pins are for external MDIO | ||
75 | * @hw: pointer to the HW structure | ||
76 | * | ||
77 | * Called to determine if the I2C pins are being used for I2C or as an | ||
78 | * external MDIO interface since the two options are mutually exclusive. | ||
79 | **/ | ||
80 | static bool igb_sgmii_uses_mdio_82575(struct e1000_hw *hw) | ||
81 | { | ||
82 | u32 reg = 0; | ||
83 | bool ext_mdio = false; | ||
84 | |||
85 | switch (hw->mac.type) { | ||
86 | case e1000_82575: | ||
87 | case e1000_82576: | ||
88 | reg = rd32(E1000_MDIC); | ||
89 | ext_mdio = !!(reg & E1000_MDIC_DEST); | ||
90 | break; | ||
91 | case e1000_82580: | ||
92 | case e1000_i350: | ||
93 | reg = rd32(E1000_MDICNFG); | ||
94 | ext_mdio = !!(reg & E1000_MDICNFG_EXT_MDIO); | ||
95 | break; | ||
96 | default: | ||
97 | break; | ||
98 | } | ||
99 | return ext_mdio; | ||
100 | } | ||
101 | |||
73 | static s32 igb_get_invariants_82575(struct e1000_hw *hw) | 102 | static s32 igb_get_invariants_82575(struct e1000_hw *hw) |
74 | { | 103 | { |
75 | struct e1000_phy_info *phy = &hw->phy; | 104 | struct e1000_phy_info *phy = &hw->phy; |
@@ -144,13 +173,6 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) | |||
144 | 173 | ||
145 | wr32(E1000_CTRL_EXT, ctrl_ext); | 174 | wr32(E1000_CTRL_EXT, ctrl_ext); |
146 | 175 | ||
147 | /* | ||
148 | * if using i2c make certain the MDICNFG register is cleared to prevent | ||
149 | * communications from being misrouted to the mdic registers | ||
150 | */ | ||
151 | if ((ctrl_ext & E1000_CTRL_I2C_ENA) && (hw->mac.type == e1000_82580)) | ||
152 | wr32(E1000_MDICNFG, 0); | ||
153 | |||
154 | /* Set mta register count */ | 176 | /* Set mta register count */ |
155 | mac->mta_reg_count = 128; | 177 | mac->mta_reg_count = 128; |
156 | /* Set rar entry count */ | 178 | /* Set rar entry count */ |
@@ -229,18 +251,20 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) | |||
229 | phy->reset_delay_us = 100; | 251 | phy->reset_delay_us = 100; |
230 | 252 | ||
231 | /* PHY function pointers */ | 253 | /* PHY function pointers */ |
232 | if (igb_sgmii_active_82575(hw)) { | 254 | if (igb_sgmii_active_82575(hw)) |
233 | phy->ops.reset = igb_phy_hw_reset_sgmii_82575; | 255 | phy->ops.reset = igb_phy_hw_reset_sgmii_82575; |
234 | phy->ops.read_reg = igb_read_phy_reg_sgmii_82575; | 256 | else |
235 | phy->ops.write_reg = igb_write_phy_reg_sgmii_82575; | 257 | phy->ops.reset = igb_phy_hw_reset; |
258 | |||
259 | if (igb_sgmii_active_82575(hw) && !igb_sgmii_uses_mdio_82575(hw)) { | ||
260 | phy->ops.read_reg = igb_read_phy_reg_sgmii_82575; | ||
261 | phy->ops.write_reg = igb_write_phy_reg_sgmii_82575; | ||
236 | } else if (hw->mac.type >= e1000_82580) { | 262 | } else if (hw->mac.type >= e1000_82580) { |
237 | phy->ops.reset = igb_phy_hw_reset; | 263 | phy->ops.read_reg = igb_read_phy_reg_82580; |
238 | phy->ops.read_reg = igb_read_phy_reg_82580; | 264 | phy->ops.write_reg = igb_write_phy_reg_82580; |
239 | phy->ops.write_reg = igb_write_phy_reg_82580; | ||
240 | } else { | 265 | } else { |
241 | phy->ops.reset = igb_phy_hw_reset; | 266 | phy->ops.read_reg = igb_read_phy_reg_igp; |
242 | phy->ops.read_reg = igb_read_phy_reg_igp; | 267 | phy->ops.write_reg = igb_write_phy_reg_igp; |
243 | phy->ops.write_reg = igb_write_phy_reg_igp; | ||
244 | } | 268 | } |
245 | 269 | ||
246 | /* set lan id */ | 270 | /* set lan id */ |
@@ -400,6 +424,7 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw) | |||
400 | s32 ret_val = 0; | 424 | s32 ret_val = 0; |
401 | u16 phy_id; | 425 | u16 phy_id; |
402 | u32 ctrl_ext; | 426 | u32 ctrl_ext; |
427 | u32 mdic; | ||
403 | 428 | ||
404 | /* | 429 | /* |
405 | * For SGMII PHYs, we try the list of possible addresses until | 430 | * For SGMII PHYs, we try the list of possible addresses until |
@@ -414,6 +439,29 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw) | |||
414 | goto out; | 439 | goto out; |
415 | } | 440 | } |
416 | 441 | ||
442 | if (igb_sgmii_uses_mdio_82575(hw)) { | ||
443 | switch (hw->mac.type) { | ||
444 | case e1000_82575: | ||
445 | case e1000_82576: | ||
446 | mdic = rd32(E1000_MDIC); | ||
447 | mdic &= E1000_MDIC_PHY_MASK; | ||
448 | phy->addr = mdic >> E1000_MDIC_PHY_SHIFT; | ||
449 | break; | ||
450 | case e1000_82580: | ||
451 | case e1000_i350: | ||
452 | mdic = rd32(E1000_MDICNFG); | ||
453 | mdic &= E1000_MDICNFG_PHY_MASK; | ||
454 | phy->addr = mdic >> E1000_MDICNFG_PHY_SHIFT; | ||
455 | break; | ||
456 | default: | ||
457 | ret_val = -E1000_ERR_PHY; | ||
458 | goto out; | ||
459 | break; | ||
460 | } | ||
461 | ret_val = igb_get_phy_id(hw); | ||
462 | goto out; | ||
463 | } | ||
464 | |||
417 | /* Power on sgmii phy if it is disabled */ | 465 | /* Power on sgmii phy if it is disabled */ |
418 | ctrl_ext = rd32(E1000_CTRL_EXT); | 466 | ctrl_ext = rd32(E1000_CTRL_EXT); |
419 | wr32(E1000_CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_SDP3_DATA); | 467 | wr32(E1000_CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_SDP3_DATA); |
diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h index 90bc29d7e182..1d4767f5f110 100644 --- a/drivers/net/igb/e1000_defines.h +++ b/drivers/net/igb/e1000_defines.h | |||
@@ -468,6 +468,11 @@ | |||
468 | 468 | ||
469 | #define E1000_TIMINCA_16NS_SHIFT 24 | 469 | #define E1000_TIMINCA_16NS_SHIFT 24 |
470 | 470 | ||
471 | #define E1000_MDICNFG_EXT_MDIO 0x80000000 /* MDI ext/int destination */ | ||
472 | #define E1000_MDICNFG_COM_MDIO 0x40000000 /* MDI shared w/ lan 0 */ | ||
473 | #define E1000_MDICNFG_PHY_MASK 0x03E00000 | ||
474 | #define E1000_MDICNFG_PHY_SHIFT 21 | ||
475 | |||
471 | /* PCI Express Control */ | 476 | /* PCI Express Control */ |
472 | #define E1000_GCR_CMPL_TMOUT_MASK 0x0000F000 | 477 | #define E1000_GCR_CMPL_TMOUT_MASK 0x0000F000 |
473 | #define E1000_GCR_CMPL_TMOUT_10ms 0x00001000 | 478 | #define E1000_GCR_CMPL_TMOUT_10ms 0x00001000 |
@@ -698,12 +703,17 @@ | |||
698 | #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X 0x0800 | 703 | #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X 0x0800 |
699 | 704 | ||
700 | /* MDI Control */ | 705 | /* MDI Control */ |
706 | #define E1000_MDIC_DATA_MASK 0x0000FFFF | ||
707 | #define E1000_MDIC_REG_MASK 0x001F0000 | ||
701 | #define E1000_MDIC_REG_SHIFT 16 | 708 | #define E1000_MDIC_REG_SHIFT 16 |
709 | #define E1000_MDIC_PHY_MASK 0x03E00000 | ||
702 | #define E1000_MDIC_PHY_SHIFT 21 | 710 | #define E1000_MDIC_PHY_SHIFT 21 |
703 | #define E1000_MDIC_OP_WRITE 0x04000000 | 711 | #define E1000_MDIC_OP_WRITE 0x04000000 |
704 | #define E1000_MDIC_OP_READ 0x08000000 | 712 | #define E1000_MDIC_OP_READ 0x08000000 |
705 | #define E1000_MDIC_READY 0x10000000 | 713 | #define E1000_MDIC_READY 0x10000000 |
714 | #define E1000_MDIC_INT_EN 0x20000000 | ||
706 | #define E1000_MDIC_ERROR 0x40000000 | 715 | #define E1000_MDIC_ERROR 0x40000000 |
716 | #define E1000_MDIC_DEST 0x80000000 | ||
707 | 717 | ||
708 | /* SerDes Control */ | 718 | /* SerDes Control */ |
709 | #define E1000_GEN_CTL_READY 0x80000000 | 719 | #define E1000_GEN_CTL_READY 0x80000000 |