mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-11-04 06:54:27 -05:00 
			
		
		
		
	Build and boot tested on the following hardware: * GW54xx * GW53xx * GW52xx * GW51xx * GW552x * GW551x Signed-off-by: Pushpal Sidhu <psidhu@gateworks.com> SVN-Revision: 48248
		
			
				
	
	
		
			130 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			130 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
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>
 | 
						|
 | 
						|
--- a/drivers/net/ethernet/intel/igb/e1000_phy.c
 | 
						|
+++ b/drivers/net/ethernet/intel/igb/e1000_phy.c
 | 
						|
@@ -129,7 +129,7 @@ out:
 | 
						|
 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 @@ s32 igb_read_phy_reg_mdic(struct e1000_h
 | 
						|
 	 * 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 @@ s32 igb_read_phy_reg_mdic(struct e1000_h
 | 
						|
 	*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 @@ out:
 | 
						|
 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 @@ s32 igb_write_phy_reg_mdic(struct e1000_
 | 
						|
 	 * 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 @@ s32 igb_write_phy_reg_mdic(struct e1000_
 | 
						|
 	}
 | 
						|
 
 | 
						|
 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;
 | 
						|
 }
 | 
						|
 
 |