Permalink
Browse files

net: igb: add i210/i211 support for phy read/write

The i210/i211 uses the MDICNFG register for the phy address instead of the
MDIC register.

Signed-off-by: Tim Harvey <tharvey@gateworks.com>
  • Loading branch information...
Gateworks committed May 15, 2014
1 parent e3afbdc commit aacf6137bdeded2acb1f6638c14d98ed19ec1461
Showing with 62 additions and 9 deletions.
  1. +62 −9 drivers/net/ethernet/intel/igb/e1000_phy.c
@@ -135,7 +135,7 @@ static s32 igb_phy_reset_dsp(struct e1000_hw *hw)
s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
{
struct e1000_phy_info *phy = &hw->phy;
u32 i, mdic = 0;
u32 i, mdicnfg, mdic = 0;
s32 ret_val = 0;
if (offset > MAX_PHY_REG_ADDRESS) {
@@ -148,11 +148,25 @@ s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
* Control register. The MAC will take care of interfacing with the
* PHY to retrieve the desired data.
*/
mdic = ((offset << E1000_MDIC_REG_SHIFT) |
(phy->addr << E1000_MDIC_PHY_SHIFT) |
(E1000_MDIC_OP_READ));
switch (hw->mac.type) {
case e1000_i210:
case e1000_i211:
mdicnfg = rd32(E1000_MDICNFG);
mdicnfg &= ~(E1000_MDICNFG_PHY_MASK);
mdicnfg |= (phy->addr << E1000_MDICNFG_PHY_SHIFT);
wr32(E1000_MDICNFG, mdicnfg);
mdic = ((offset << E1000_MDIC_REG_SHIFT) |
(E1000_MDIC_OP_READ));
break;
default:
mdic = ((offset << E1000_MDIC_REG_SHIFT) |
(phy->addr << E1000_MDIC_PHY_SHIFT) |
(E1000_MDIC_OP_READ));
break;
}
wr32(E1000_MDIC, mdic);
wrfl();
/* Poll the ready bit to see if the MDI read completed
* Increasing the time out as testing showed failures with
@@ -177,6 +191,18 @@ s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
*data = (u16) mdic;
out:
switch (hw->mac.type) {
/* restore MDICNFG to have phy's addr */
case e1000_i210:
case e1000_i211:
mdicnfg = rd32(E1000_MDICNFG);
mdicnfg &= ~(E1000_MDICNFG_PHY_MASK);
mdicnfg |= (hw->phy.addr << E1000_MDICNFG_PHY_SHIFT);
wr32(E1000_MDICNFG, mdicnfg);
break;
default:
break;
}
return ret_val;
}
@@ -191,7 +217,7 @@ s32 igb_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
{
struct e1000_phy_info *phy = &hw->phy;
u32 i, mdic = 0;
u32 i, mdicnfg, mdic = 0;
s32 ret_val = 0;
if (offset > MAX_PHY_REG_ADDRESS) {
@@ -204,12 +230,27 @@ s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
* Control register. The MAC will take care of interfacing with the
* PHY to retrieve the desired data.
*/
mdic = (((u32)data) |
(offset << E1000_MDIC_REG_SHIFT) |
(phy->addr << E1000_MDIC_PHY_SHIFT) |
(E1000_MDIC_OP_WRITE));
switch (hw->mac.type) {
case e1000_i210:
case e1000_i211:
mdicnfg = rd32(E1000_MDICNFG);
mdicnfg &= ~(E1000_MDICNFG_PHY_MASK);
mdicnfg |= (phy->addr << E1000_MDICNFG_PHY_SHIFT);
wr32(E1000_MDICNFG, mdicnfg);
mdic = (((u32)data) |
(offset << E1000_MDIC_REG_SHIFT) |
(E1000_MDIC_OP_WRITE));
break;
default:
mdic = (((u32)data) |
(offset << E1000_MDIC_REG_SHIFT) |
(phy->addr << E1000_MDIC_PHY_SHIFT) |
(E1000_MDIC_OP_WRITE));
break;
}
wr32(E1000_MDIC, mdic);
wrfl();
/* Poll the ready bit to see if the MDI read completed
* Increasing the time out as testing showed failures with
@@ -233,6 +274,18 @@ s32 igb_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
}
out:
switch (hw->mac.type) {
/* restore MDICNFG to have phy's addr */
case e1000_i210:
case e1000_i211:
mdicnfg = rd32(E1000_MDICNFG);
mdicnfg &= ~(E1000_MDICNFG_PHY_MASK);
mdicnfg |= (hw->phy.addr << E1000_MDICNFG_PHY_SHIFT);
wr32(E1000_MDICNFG, mdicnfg);
break;
default:
break;
}
return ret_val;
}

0 comments on commit aacf613

Please sign in to comment.