1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
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;
}
|