openwrtv4/target/linux/imx6/patches-4.3/202-net-igb-add-i210-i211-support-for-phy-read-write.patch

132 lines
3.6 KiB
Diff
Raw Normal View History

Author: Tim Harvey <tharvey@gateworks.com>
Date: Thu May 15 00:12:26 2014 -0700
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>
Index: linux-4.3/drivers/net/ethernet/intel/igb/e1000_phy.c
===================================================================
--- linux-4.3.orig/drivers/net/ethernet/intel/igb/e1000_phy.c 2015-11-01 16:05:25.000000000 -0800
+++ linux-4.3/drivers/net/ethernet/intel/igb/e1000_phy.c 2015-12-18 10:43:28.000000000 -0800
@@ -129,7 +129,7 @@
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) {
@@ -142,11 +142,25 @@
* 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
@@ -171,6 +185,18 @@
*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;
}
@@ -185,7 +211,7 @@
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) {
@@ -198,12 +224,27 @@
* 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
@@ -227,6 +268,18 @@
}
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;
}