aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/igb
diff options
context:
space:
mode:
authorNick Nunley <nicholas.d.nunley@intel.com>2010-07-26 09:15:06 -0400
committerDavid S. Miller <davem@davemloft.net>2010-07-26 21:42:53 -0400
commit4085f746db1b7d6b292cf27cc713a13a1fcb2681 (patch)
treebab50788ad8fc71dbd570c665f9d7b189bf4b235 /drivers/net/igb
parentea7afd31fb45d2d5d1b1e4cf347a688370feee91 (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.c82
-rw-r--r--drivers/net/igb/e1000_defines.h10
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 **/
80static 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
73static s32 igb_get_invariants_82575(struct e1000_hw *hw) 102static 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