diff options
Diffstat (limited to 'drivers/net/cxgb3/ael1002.c')
-rw-r--r-- | drivers/net/cxgb3/ael1002.c | 958 |
1 files changed, 829 insertions, 129 deletions
diff --git a/drivers/net/cxgb3/ael1002.c b/drivers/net/cxgb3/ael1002.c index e1b22490ff59..9fe008ec9ba5 100644 --- a/drivers/net/cxgb3/ael1002.c +++ b/drivers/net/cxgb3/ael1002.c | |||
@@ -33,14 +33,6 @@ | |||
33 | #include "regs.h" | 33 | #include "regs.h" |
34 | 34 | ||
35 | enum { | 35 | enum { |
36 | PMD_RSD = 10, /* PMA/PMD receive signal detect register */ | ||
37 | PCS_STAT1_X = 24, /* 10GBASE-X PCS status 1 register */ | ||
38 | PCS_STAT1_R = 32, /* 10GBASE-R PCS status 1 register */ | ||
39 | XS_LN_STAT = 24 /* XS lane status register */ | ||
40 | }; | ||
41 | |||
42 | enum { | ||
43 | AEL100X_TX_DISABLE = 9, | ||
44 | AEL100X_TX_CONFIG1 = 0xc002, | 36 | AEL100X_TX_CONFIG1 = 0xc002, |
45 | AEL1002_PWR_DOWN_HI = 0xc011, | 37 | AEL1002_PWR_DOWN_HI = 0xc011, |
46 | AEL1002_PWR_DOWN_LO = 0xc012, | 38 | AEL1002_PWR_DOWN_LO = 0xc012, |
@@ -52,12 +44,33 @@ enum { | |||
52 | AEL_I2C_STAT = 0xc30c, | 44 | AEL_I2C_STAT = 0xc30c, |
53 | AEL2005_GPIO_CTRL = 0xc214, | 45 | AEL2005_GPIO_CTRL = 0xc214, |
54 | AEL2005_GPIO_STAT = 0xc215, | 46 | AEL2005_GPIO_STAT = 0xc215, |
47 | |||
48 | AEL2020_GPIO_INTR = 0xc103, /* Latch High (LH) */ | ||
49 | AEL2020_GPIO_CTRL = 0xc108, /* Store Clear (SC) */ | ||
50 | AEL2020_GPIO_STAT = 0xc10c, /* Read Only (RO) */ | ||
51 | AEL2020_GPIO_CFG = 0xc110, /* Read Write (RW) */ | ||
52 | |||
53 | AEL2020_GPIO_SDA = 0, /* IN: i2c serial data */ | ||
54 | AEL2020_GPIO_MODDET = 1, /* IN: Module Detect */ | ||
55 | AEL2020_GPIO_0 = 3, /* IN: unassigned */ | ||
56 | AEL2020_GPIO_1 = 2, /* OUT: unassigned */ | ||
57 | AEL2020_GPIO_LSTAT = AEL2020_GPIO_1, /* wired to link status LED */ | ||
55 | }; | 58 | }; |
56 | 59 | ||
57 | enum { edc_none, edc_sr, edc_twinax }; | 60 | enum { edc_none, edc_sr, edc_twinax }; |
58 | 61 | ||
59 | /* PHY module I2C device address */ | 62 | /* PHY module I2C device address */ |
60 | #define MODULE_DEV_ADDR 0xa0 | 63 | enum { |
64 | MODULE_DEV_ADDR = 0xa0, | ||
65 | SFF_DEV_ADDR = 0xa2, | ||
66 | }; | ||
67 | |||
68 | /* PHY transceiver type */ | ||
69 | enum { | ||
70 | phy_transtype_unknown = 0, | ||
71 | phy_transtype_sfp = 3, | ||
72 | phy_transtype_xfp = 6, | ||
73 | }; | ||
61 | 74 | ||
62 | #define AEL2005_MODDET_IRQ 4 | 75 | #define AEL2005_MODDET_IRQ 4 |
63 | 76 | ||
@@ -74,8 +87,8 @@ static int set_phy_regs(struct cphy *phy, const struct reg_val *rv) | |||
74 | 87 | ||
75 | for (err = 0; rv->mmd_addr && !err; rv++) { | 88 | for (err = 0; rv->mmd_addr && !err; rv++) { |
76 | if (rv->clear_bits == 0xffff) | 89 | if (rv->clear_bits == 0xffff) |
77 | err = mdio_write(phy, rv->mmd_addr, rv->reg_addr, | 90 | err = t3_mdio_write(phy, rv->mmd_addr, rv->reg_addr, |
78 | rv->set_bits); | 91 | rv->set_bits); |
79 | else | 92 | else |
80 | err = t3_mdio_change_bits(phy, rv->mmd_addr, | 93 | err = t3_mdio_change_bits(phy, rv->mmd_addr, |
81 | rv->reg_addr, rv->clear_bits, | 94 | rv->reg_addr, rv->clear_bits, |
@@ -86,21 +99,54 @@ static int set_phy_regs(struct cphy *phy, const struct reg_val *rv) | |||
86 | 99 | ||
87 | static void ael100x_txon(struct cphy *phy) | 100 | static void ael100x_txon(struct cphy *phy) |
88 | { | 101 | { |
89 | int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL; | 102 | int tx_on_gpio = |
103 | phy->mdio.prtad == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL; | ||
90 | 104 | ||
91 | msleep(100); | 105 | msleep(100); |
92 | t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 0, tx_on_gpio); | 106 | t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 0, tx_on_gpio); |
93 | msleep(30); | 107 | msleep(30); |
94 | } | 108 | } |
95 | 109 | ||
110 | /* | ||
111 | * Read an 8-bit word from a device attached to the PHY's i2c bus. | ||
112 | */ | ||
113 | static int ael_i2c_rd(struct cphy *phy, int dev_addr, int word_addr) | ||
114 | { | ||
115 | int i, err; | ||
116 | unsigned int stat, data; | ||
117 | |||
118 | err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL_I2C_CTRL, | ||
119 | (dev_addr << 8) | (1 << 8) | word_addr); | ||
120 | if (err) | ||
121 | return err; | ||
122 | |||
123 | for (i = 0; i < 200; i++) { | ||
124 | msleep(1); | ||
125 | err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_STAT, &stat); | ||
126 | if (err) | ||
127 | return err; | ||
128 | if ((stat & 3) == 1) { | ||
129 | err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_DATA, | ||
130 | &data); | ||
131 | if (err) | ||
132 | return err; | ||
133 | return data >> 8; | ||
134 | } | ||
135 | } | ||
136 | CH_WARN(phy->adapter, "PHY %u i2c read of dev.addr %#x.%#x timed out\n", | ||
137 | phy->mdio.prtad, dev_addr, word_addr); | ||
138 | return -ETIMEDOUT; | ||
139 | } | ||
140 | |||
96 | static int ael1002_power_down(struct cphy *phy, int enable) | 141 | static int ael1002_power_down(struct cphy *phy, int enable) |
97 | { | 142 | { |
98 | int err; | 143 | int err; |
99 | 144 | ||
100 | err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_DISABLE, !!enable); | 145 | err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, MDIO_PMA_TXDIS, !!enable); |
101 | if (!err) | 146 | if (!err) |
102 | err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, | 147 | err = mdio_set_flag(&phy->mdio, phy->mdio.prtad, |
103 | BMCR_PDOWN, enable ? BMCR_PDOWN : 0); | 148 | MDIO_MMD_PMAPMD, MDIO_CTRL1, |
149 | MDIO_CTRL1_LPOWER, enable); | ||
104 | return err; | 150 | return err; |
105 | } | 151 | } |
106 | 152 | ||
@@ -109,11 +155,11 @@ static int ael1002_reset(struct cphy *phy, int wait) | |||
109 | int err; | 155 | int err; |
110 | 156 | ||
111 | if ((err = ael1002_power_down(phy, 0)) || | 157 | if ((err = ael1002_power_down(phy, 0)) || |
112 | (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_CONFIG1, 1)) || | 158 | (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL100X_TX_CONFIG1, 1)) || |
113 | (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_HI, 0)) || | 159 | (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_PWR_DOWN_HI, 0)) || |
114 | (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_LO, 0)) || | 160 | (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_PWR_DOWN_LO, 0)) || |
115 | (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_XFI_EQL, 0x18)) || | 161 | (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_XFI_EQL, 0x18)) || |
116 | (err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL1002_LB_EN, | 162 | (err = t3_mdio_change_bits(phy, MDIO_MMD_PMAPMD, AEL1002_LB_EN, |
117 | 0, 1 << 5))) | 163 | 0, 1 << 5))) |
118 | return err; | 164 | return err; |
119 | return 0; | 165 | return 0; |
@@ -132,12 +178,15 @@ static int get_link_status_r(struct cphy *phy, int *link_ok, int *speed, | |||
132 | { | 178 | { |
133 | if (link_ok) { | 179 | if (link_ok) { |
134 | unsigned int stat0, stat1, stat2; | 180 | unsigned int stat0, stat1, stat2; |
135 | int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0); | 181 | int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, |
182 | MDIO_PMA_RXDET, &stat0); | ||
136 | 183 | ||
137 | if (!err) | 184 | if (!err) |
138 | err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_R, &stat1); | 185 | err = t3_mdio_read(phy, MDIO_MMD_PCS, |
186 | MDIO_PCS_10GBRT_STAT1, &stat1); | ||
139 | if (!err) | 187 | if (!err) |
140 | err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2); | 188 | err = t3_mdio_read(phy, MDIO_MMD_PHYXS, |
189 | MDIO_PHYXS_LNSTAT, &stat2); | ||
141 | if (err) | 190 | if (err) |
142 | return err; | 191 | return err; |
143 | *link_ok = (stat0 & stat1 & (stat2 >> 12)) & 1; | 192 | *link_ok = (stat0 & stat1 & (stat2 >> 12)) & 1; |
@@ -157,6 +206,7 @@ static struct cphy_ops ael1002_ops = { | |||
157 | .intr_handler = ael1002_intr_noop, | 206 | .intr_handler = ael1002_intr_noop, |
158 | .get_link_status = get_link_status_r, | 207 | .get_link_status = get_link_status_r, |
159 | .power_down = ael1002_power_down, | 208 | .power_down = ael1002_power_down, |
209 | .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, | ||
160 | }; | 210 | }; |
161 | 211 | ||
162 | int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter, | 212 | int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter, |
@@ -171,13 +221,13 @@ int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter, | |||
171 | 221 | ||
172 | static int ael1006_reset(struct cphy *phy, int wait) | 222 | static int ael1006_reset(struct cphy *phy, int wait) |
173 | { | 223 | { |
174 | return t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait); | 224 | return t3_phy_reset(phy, MDIO_MMD_PMAPMD, wait); |
175 | } | 225 | } |
176 | 226 | ||
177 | static int ael1006_power_down(struct cphy *phy, int enable) | 227 | static int ael1006_power_down(struct cphy *phy, int enable) |
178 | { | 228 | { |
179 | return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, | 229 | return mdio_set_flag(&phy->mdio, phy->mdio.prtad, MDIO_MMD_PMAPMD, |
180 | BMCR_PDOWN, enable ? BMCR_PDOWN : 0); | 230 | MDIO_CTRL1, MDIO_CTRL1_LPOWER, enable); |
181 | } | 231 | } |
182 | 232 | ||
183 | static struct cphy_ops ael1006_ops = { | 233 | static struct cphy_ops ael1006_ops = { |
@@ -188,6 +238,7 @@ static struct cphy_ops ael1006_ops = { | |||
188 | .intr_handler = t3_phy_lasi_intr_handler, | 238 | .intr_handler = t3_phy_lasi_intr_handler, |
189 | .get_link_status = get_link_status_r, | 239 | .get_link_status = get_link_status_r, |
190 | .power_down = ael1006_power_down, | 240 | .power_down = ael1006_power_down, |
241 | .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, | ||
191 | }; | 242 | }; |
192 | 243 | ||
193 | int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, | 244 | int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, |
@@ -200,12 +251,57 @@ int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, | |||
200 | return 0; | 251 | return 0; |
201 | } | 252 | } |
202 | 253 | ||
254 | /* | ||
255 | * Decode our module type. | ||
256 | */ | ||
257 | static int ael2xxx_get_module_type(struct cphy *phy, int delay_ms) | ||
258 | { | ||
259 | int v; | ||
260 | |||
261 | if (delay_ms) | ||
262 | msleep(delay_ms); | ||
263 | |||
264 | /* see SFF-8472 for below */ | ||
265 | v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 3); | ||
266 | if (v < 0) | ||
267 | return v; | ||
268 | |||
269 | if (v == 0x10) | ||
270 | return phy_modtype_sr; | ||
271 | if (v == 0x20) | ||
272 | return phy_modtype_lr; | ||
273 | if (v == 0x40) | ||
274 | return phy_modtype_lrm; | ||
275 | |||
276 | v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 6); | ||
277 | if (v < 0) | ||
278 | return v; | ||
279 | if (v != 4) | ||
280 | goto unknown; | ||
281 | |||
282 | v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 10); | ||
283 | if (v < 0) | ||
284 | return v; | ||
285 | |||
286 | if (v & 0x80) { | ||
287 | v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0x12); | ||
288 | if (v < 0) | ||
289 | return v; | ||
290 | return v > 10 ? phy_modtype_twinax_long : phy_modtype_twinax; | ||
291 | } | ||
292 | unknown: | ||
293 | return phy_modtype_unknown; | ||
294 | } | ||
295 | |||
296 | /* | ||
297 | * Code to support the Aeluros/NetLogic 2005 10Gb PHY. | ||
298 | */ | ||
203 | static int ael2005_setup_sr_edc(struct cphy *phy) | 299 | static int ael2005_setup_sr_edc(struct cphy *phy) |
204 | { | 300 | { |
205 | static struct reg_val regs[] = { | 301 | static struct reg_val regs[] = { |
206 | { MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x181 }, | 302 | { MDIO_MMD_PMAPMD, 0xc003, 0xffff, 0x181 }, |
207 | { MDIO_DEV_PMA_PMD, 0xc010, 0xffff, 0x448a }, | 303 | { MDIO_MMD_PMAPMD, 0xc010, 0xffff, 0x448a }, |
208 | { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5200 }, | 304 | { MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5200 }, |
209 | { 0, 0, 0, 0 } | 305 | { 0, 0, 0, 0 } |
210 | }; | 306 | }; |
211 | static u16 sr_edc[] = { | 307 | static u16 sr_edc[] = { |
@@ -490,8 +586,8 @@ static int ael2005_setup_sr_edc(struct cphy *phy) | |||
490 | msleep(50); | 586 | msleep(50); |
491 | 587 | ||
492 | for (i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2) | 588 | for (i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2) |
493 | err = mdio_write(phy, MDIO_DEV_PMA_PMD, sr_edc[i], | 589 | err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, sr_edc[i], |
494 | sr_edc[i + 1]); | 590 | sr_edc[i + 1]); |
495 | if (!err) | 591 | if (!err) |
496 | phy->priv = edc_sr; | 592 | phy->priv = edc_sr; |
497 | return err; | 593 | return err; |
@@ -500,12 +596,12 @@ static int ael2005_setup_sr_edc(struct cphy *phy) | |||
500 | static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype) | 596 | static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype) |
501 | { | 597 | { |
502 | static struct reg_val regs[] = { | 598 | static struct reg_val regs[] = { |
503 | { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5a00 }, | 599 | { MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5a00 }, |
504 | { 0, 0, 0, 0 } | 600 | { 0, 0, 0, 0 } |
505 | }; | 601 | }; |
506 | static struct reg_val preemphasis[] = { | 602 | static struct reg_val preemphasis[] = { |
507 | { MDIO_DEV_PMA_PMD, 0xc014, 0xffff, 0xfe16 }, | 603 | { MDIO_MMD_PMAPMD, 0xc014, 0xffff, 0xfe16 }, |
508 | { MDIO_DEV_PMA_PMD, 0xc015, 0xffff, 0xa000 }, | 604 | { MDIO_MMD_PMAPMD, 0xc015, 0xffff, 0xa000 }, |
509 | { 0, 0, 0, 0 } | 605 | { 0, 0, 0, 0 } |
510 | }; | 606 | }; |
511 | static u16 twinax_edc[] = { | 607 | static u16 twinax_edc[] = { |
@@ -887,132 +983,73 @@ static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype) | |||
887 | msleep(50); | 983 | msleep(50); |
888 | 984 | ||
889 | for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2) | 985 | for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2) |
890 | err = mdio_write(phy, MDIO_DEV_PMA_PMD, twinax_edc[i], | 986 | err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, twinax_edc[i], |
891 | twinax_edc[i + 1]); | 987 | twinax_edc[i + 1]); |
892 | if (!err) | 988 | if (!err) |
893 | phy->priv = edc_twinax; | 989 | phy->priv = edc_twinax; |
894 | return err; | 990 | return err; |
895 | } | 991 | } |
896 | 992 | ||
897 | static int ael2005_i2c_rd(struct cphy *phy, int dev_addr, int word_addr) | 993 | static int ael2005_get_module_type(struct cphy *phy, int delay_ms) |
898 | { | ||
899 | int i, err; | ||
900 | unsigned int stat, data; | ||
901 | |||
902 | err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL, | ||
903 | (dev_addr << 8) | (1 << 8) | word_addr); | ||
904 | if (err) | ||
905 | return err; | ||
906 | |||
907 | for (i = 0; i < 5; i++) { | ||
908 | msleep(1); | ||
909 | err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat); | ||
910 | if (err) | ||
911 | return err; | ||
912 | if ((stat & 3) == 1) { | ||
913 | err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA, | ||
914 | &data); | ||
915 | if (err) | ||
916 | return err; | ||
917 | return data >> 8; | ||
918 | } | ||
919 | } | ||
920 | CH_WARN(phy->adapter, "PHY %u I2C read of addr %u timed out\n", | ||
921 | phy->addr, word_addr); | ||
922 | return -ETIMEDOUT; | ||
923 | } | ||
924 | |||
925 | static int get_module_type(struct cphy *phy, int delay_ms) | ||
926 | { | 994 | { |
927 | int v; | 995 | int v; |
928 | unsigned int stat; | 996 | unsigned int stat; |
929 | 997 | ||
930 | v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, &stat); | 998 | v = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, &stat); |
931 | if (v) | 999 | if (v) |
932 | return v; | 1000 | return v; |
933 | 1001 | ||
934 | if (stat & (1 << 8)) /* module absent */ | 1002 | if (stat & (1 << 8)) /* module absent */ |
935 | return phy_modtype_none; | 1003 | return phy_modtype_none; |
936 | 1004 | ||
937 | if (delay_ms) | 1005 | return ael2xxx_get_module_type(phy, delay_ms); |
938 | msleep(delay_ms); | ||
939 | |||
940 | /* see SFF-8472 for below */ | ||
941 | v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 3); | ||
942 | if (v < 0) | ||
943 | return v; | ||
944 | |||
945 | if (v == 0x10) | ||
946 | return phy_modtype_sr; | ||
947 | if (v == 0x20) | ||
948 | return phy_modtype_lr; | ||
949 | if (v == 0x40) | ||
950 | return phy_modtype_lrm; | ||
951 | |||
952 | v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 6); | ||
953 | if (v < 0) | ||
954 | return v; | ||
955 | if (v != 4) | ||
956 | goto unknown; | ||
957 | |||
958 | v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 10); | ||
959 | if (v < 0) | ||
960 | return v; | ||
961 | |||
962 | if (v & 0x80) { | ||
963 | v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 0x12); | ||
964 | if (v < 0) | ||
965 | return v; | ||
966 | return v > 10 ? phy_modtype_twinax_long : phy_modtype_twinax; | ||
967 | } | ||
968 | unknown: | ||
969 | return phy_modtype_unknown; | ||
970 | } | 1006 | } |
971 | 1007 | ||
972 | static int ael2005_intr_enable(struct cphy *phy) | 1008 | static int ael2005_intr_enable(struct cphy *phy) |
973 | { | 1009 | { |
974 | int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x200); | 1010 | int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0x200); |
975 | return err ? err : t3_phy_lasi_intr_enable(phy); | 1011 | return err ? err : t3_phy_lasi_intr_enable(phy); |
976 | } | 1012 | } |
977 | 1013 | ||
978 | static int ael2005_intr_disable(struct cphy *phy) | 1014 | static int ael2005_intr_disable(struct cphy *phy) |
979 | { | 1015 | { |
980 | int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x100); | 1016 | int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0x100); |
981 | return err ? err : t3_phy_lasi_intr_disable(phy); | 1017 | return err ? err : t3_phy_lasi_intr_disable(phy); |
982 | } | 1018 | } |
983 | 1019 | ||
984 | static int ael2005_intr_clear(struct cphy *phy) | 1020 | static int ael2005_intr_clear(struct cphy *phy) |
985 | { | 1021 | { |
986 | int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0xd00); | 1022 | int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0xd00); |
987 | return err ? err : t3_phy_lasi_intr_clear(phy); | 1023 | return err ? err : t3_phy_lasi_intr_clear(phy); |
988 | } | 1024 | } |
989 | 1025 | ||
990 | static int ael2005_reset(struct cphy *phy, int wait) | 1026 | static int ael2005_reset(struct cphy *phy, int wait) |
991 | { | 1027 | { |
992 | static struct reg_val regs0[] = { | 1028 | static struct reg_val regs0[] = { |
993 | { MDIO_DEV_PMA_PMD, 0xc001, 0, 1 << 5 }, | 1029 | { MDIO_MMD_PMAPMD, 0xc001, 0, 1 << 5 }, |
994 | { MDIO_DEV_PMA_PMD, 0xc017, 0, 1 << 5 }, | 1030 | { MDIO_MMD_PMAPMD, 0xc017, 0, 1 << 5 }, |
995 | { MDIO_DEV_PMA_PMD, 0xc013, 0xffff, 0xf341 }, | 1031 | { MDIO_MMD_PMAPMD, 0xc013, 0xffff, 0xf341 }, |
996 | { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 }, | 1032 | { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8000 }, |
997 | { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8100 }, | 1033 | { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8100 }, |
998 | { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 }, | 1034 | { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8000 }, |
999 | { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0 }, | 1035 | { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0 }, |
1000 | { 0, 0, 0, 0 } | 1036 | { 0, 0, 0, 0 } |
1001 | }; | 1037 | }; |
1002 | static struct reg_val regs1[] = { | 1038 | static struct reg_val regs1[] = { |
1003 | { MDIO_DEV_PMA_PMD, 0xca00, 0xffff, 0x0080 }, | 1039 | { MDIO_MMD_PMAPMD, 0xca00, 0xffff, 0x0080 }, |
1004 | { MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0 }, | 1040 | { MDIO_MMD_PMAPMD, 0xca12, 0xffff, 0 }, |
1005 | { 0, 0, 0, 0 } | 1041 | { 0, 0, 0, 0 } |
1006 | }; | 1042 | }; |
1007 | 1043 | ||
1008 | int err; | 1044 | int err; |
1009 | unsigned int lasi_ctrl; | 1045 | unsigned int lasi_ctrl; |
1010 | 1046 | ||
1011 | err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl); | 1047 | err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL, |
1048 | &lasi_ctrl); | ||
1012 | if (err) | 1049 | if (err) |
1013 | return err; | 1050 | return err; |
1014 | 1051 | ||
1015 | err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 0); | 1052 | err = t3_phy_reset(phy, MDIO_MMD_PMAPMD, 0); |
1016 | if (err) | 1053 | if (err) |
1017 | return err; | 1054 | return err; |
1018 | 1055 | ||
@@ -1024,7 +1061,7 @@ static int ael2005_reset(struct cphy *phy, int wait) | |||
1024 | 1061 | ||
1025 | msleep(50); | 1062 | msleep(50); |
1026 | 1063 | ||
1027 | err = get_module_type(phy, 0); | 1064 | err = ael2005_get_module_type(phy, 0); |
1028 | if (err < 0) | 1065 | if (err < 0) |
1029 | return err; | 1066 | return err; |
1030 | phy->modtype = err; | 1067 | phy->modtype = err; |
@@ -1051,18 +1088,18 @@ static int ael2005_intr_handler(struct cphy *phy) | |||
1051 | unsigned int stat; | 1088 | unsigned int stat; |
1052 | int ret, edc_needed, cause = 0; | 1089 | int ret, edc_needed, cause = 0; |
1053 | 1090 | ||
1054 | ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_STAT, &stat); | 1091 | ret = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_STAT, &stat); |
1055 | if (ret) | 1092 | if (ret) |
1056 | return ret; | 1093 | return ret; |
1057 | 1094 | ||
1058 | if (stat & AEL2005_MODDET_IRQ) { | 1095 | if (stat & AEL2005_MODDET_IRQ) { |
1059 | ret = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, | 1096 | ret = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, |
1060 | 0xd00); | 1097 | 0xd00); |
1061 | if (ret) | 1098 | if (ret) |
1062 | return ret; | 1099 | return ret; |
1063 | 1100 | ||
1064 | /* modules have max 300 ms init time after hot plug */ | 1101 | /* modules have max 300 ms init time after hot plug */ |
1065 | ret = get_module_type(phy, 300); | 1102 | ret = ael2005_get_module_type(phy, 300); |
1066 | if (ret < 0) | 1103 | if (ret < 0) |
1067 | return ret; | 1104 | return ret; |
1068 | 1105 | ||
@@ -1098,6 +1135,7 @@ static struct cphy_ops ael2005_ops = { | |||
1098 | .intr_handler = ael2005_intr_handler, | 1135 | .intr_handler = ael2005_intr_handler, |
1099 | .get_link_status = get_link_status_r, | 1136 | .get_link_status = get_link_status_r, |
1100 | .power_down = ael1002_power_down, | 1137 | .power_down = ael1002_power_down, |
1138 | .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, | ||
1101 | }; | 1139 | }; |
1102 | 1140 | ||
1103 | int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter, | 1141 | int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter, |
@@ -1107,11 +1145,667 @@ int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter, | |||
1107 | SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE | | 1145 | SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE | |
1108 | SUPPORTED_IRQ, "10GBASE-R"); | 1146 | SUPPORTED_IRQ, "10GBASE-R"); |
1109 | msleep(125); | 1147 | msleep(125); |
1110 | return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL_OPT_SETTINGS, 0, | 1148 | return t3_mdio_change_bits(phy, MDIO_MMD_PMAPMD, AEL_OPT_SETTINGS, 0, |
1111 | 1 << 5); | 1149 | 1 << 5); |
1112 | } | 1150 | } |
1113 | 1151 | ||
1114 | /* | 1152 | /* |
1153 | * Setup EDC and other parameters for operation with an optical module. | ||
1154 | */ | ||
1155 | static int ael2020_setup_sr_edc(struct cphy *phy) | ||
1156 | { | ||
1157 | static struct reg_val regs[] = { | ||
1158 | /* set CDR offset to 10 */ | ||
1159 | { MDIO_MMD_PMAPMD, 0xcc01, 0xffff, 0x488a }, | ||
1160 | |||
1161 | /* adjust 10G RX bias current */ | ||
1162 | { MDIO_MMD_PMAPMD, 0xcb1b, 0xffff, 0x0200 }, | ||
1163 | { MDIO_MMD_PMAPMD, 0xcb1c, 0xffff, 0x00f0 }, | ||
1164 | { MDIO_MMD_PMAPMD, 0xcc06, 0xffff, 0x00e0 }, | ||
1165 | |||
1166 | /* end */ | ||
1167 | { 0, 0, 0, 0 } | ||
1168 | }; | ||
1169 | int err; | ||
1170 | |||
1171 | err = set_phy_regs(phy, regs); | ||
1172 | msleep(50); | ||
1173 | if (err) | ||
1174 | return err; | ||
1175 | |||
1176 | phy->priv = edc_sr; | ||
1177 | return 0; | ||
1178 | } | ||
1179 | |||
1180 | /* | ||
1181 | * Setup EDC and other parameters for operation with an TWINAX module. | ||
1182 | */ | ||
1183 | static int ael2020_setup_twinax_edc(struct cphy *phy, int modtype) | ||
1184 | { | ||
1185 | /* set uC to 40MHz */ | ||
1186 | static struct reg_val uCclock40MHz[] = { | ||
1187 | { MDIO_MMD_PMAPMD, 0xff28, 0xffff, 0x4001 }, | ||
1188 | { MDIO_MMD_PMAPMD, 0xff2a, 0xffff, 0x0002 }, | ||
1189 | { 0, 0, 0, 0 } | ||
1190 | }; | ||
1191 | |||
1192 | /* activate uC clock */ | ||
1193 | static struct reg_val uCclockActivate[] = { | ||
1194 | { MDIO_MMD_PMAPMD, 0xd000, 0xffff, 0x5200 }, | ||
1195 | { 0, 0, 0, 0 } | ||
1196 | }; | ||
1197 | |||
1198 | /* set PC to start of SRAM and activate uC */ | ||
1199 | static struct reg_val uCactivate[] = { | ||
1200 | { MDIO_MMD_PMAPMD, 0xd080, 0xffff, 0x0100 }, | ||
1201 | { MDIO_MMD_PMAPMD, 0xd092, 0xffff, 0x0000 }, | ||
1202 | { 0, 0, 0, 0 } | ||
1203 | }; | ||
1204 | |||
1205 | /* TWINAX EDC firmware */ | ||
1206 | static u16 twinax_edc[] = { | ||
1207 | 0xd800, 0x4009, | ||
1208 | 0xd801, 0x2fff, | ||
1209 | 0xd802, 0x300f, | ||
1210 | 0xd803, 0x40aa, | ||
1211 | 0xd804, 0x401c, | ||
1212 | 0xd805, 0x401e, | ||
1213 | 0xd806, 0x2ff4, | ||
1214 | 0xd807, 0x3dc4, | ||
1215 | 0xd808, 0x2035, | ||
1216 | 0xd809, 0x3035, | ||
1217 | 0xd80a, 0x6524, | ||
1218 | 0xd80b, 0x2cb2, | ||
1219 | 0xd80c, 0x3012, | ||
1220 | 0xd80d, 0x1002, | ||
1221 | 0xd80e, 0x26e2, | ||
1222 | 0xd80f, 0x3022, | ||
1223 | 0xd810, 0x1002, | ||
1224 | 0xd811, 0x27d2, | ||
1225 | 0xd812, 0x3022, | ||
1226 | 0xd813, 0x1002, | ||
1227 | 0xd814, 0x2822, | ||
1228 | 0xd815, 0x3012, | ||
1229 | 0xd816, 0x1002, | ||
1230 | 0xd817, 0x2492, | ||
1231 | 0xd818, 0x3022, | ||
1232 | 0xd819, 0x1002, | ||
1233 | 0xd81a, 0x2772, | ||
1234 | 0xd81b, 0x3012, | ||
1235 | 0xd81c, 0x1002, | ||
1236 | 0xd81d, 0x23d2, | ||
1237 | 0xd81e, 0x3022, | ||
1238 | 0xd81f, 0x1002, | ||
1239 | 0xd820, 0x22cd, | ||
1240 | 0xd821, 0x301d, | ||
1241 | 0xd822, 0x27f2, | ||
1242 | 0xd823, 0x3022, | ||
1243 | 0xd824, 0x1002, | ||
1244 | 0xd825, 0x5553, | ||
1245 | 0xd826, 0x0307, | ||
1246 | 0xd827, 0x2522, | ||
1247 | 0xd828, 0x3022, | ||
1248 | 0xd829, 0x1002, | ||
1249 | 0xd82a, 0x2142, | ||
1250 | 0xd82b, 0x3012, | ||
1251 | 0xd82c, 0x1002, | ||
1252 | 0xd82d, 0x4016, | ||
1253 | 0xd82e, 0x5e63, | ||
1254 | 0xd82f, 0x0344, | ||
1255 | 0xd830, 0x2142, | ||
1256 | 0xd831, 0x3012, | ||
1257 | 0xd832, 0x1002, | ||
1258 | 0xd833, 0x400e, | ||
1259 | 0xd834, 0x2522, | ||
1260 | 0xd835, 0x3022, | ||
1261 | 0xd836, 0x1002, | ||
1262 | 0xd837, 0x2b52, | ||
1263 | 0xd838, 0x3012, | ||
1264 | 0xd839, 0x1002, | ||
1265 | 0xd83a, 0x2742, | ||
1266 | 0xd83b, 0x3022, | ||
1267 | 0xd83c, 0x1002, | ||
1268 | 0xd83d, 0x25e2, | ||
1269 | 0xd83e, 0x3022, | ||
1270 | 0xd83f, 0x1002, | ||
1271 | 0xd840, 0x2fa4, | ||
1272 | 0xd841, 0x3dc4, | ||
1273 | 0xd842, 0x6624, | ||
1274 | 0xd843, 0x414b, | ||
1275 | 0xd844, 0x56b3, | ||
1276 | 0xd845, 0x03c6, | ||
1277 | 0xd846, 0x866b, | ||
1278 | 0xd847, 0x400c, | ||
1279 | 0xd848, 0x2712, | ||
1280 | 0xd849, 0x3012, | ||
1281 | 0xd84a, 0x1002, | ||
1282 | 0xd84b, 0x2c4b, | ||
1283 | 0xd84c, 0x309b, | ||
1284 | 0xd84d, 0x56b3, | ||
1285 | 0xd84e, 0x03c3, | ||
1286 | 0xd84f, 0x866b, | ||
1287 | 0xd850, 0x400c, | ||
1288 | 0xd851, 0x2272, | ||
1289 | 0xd852, 0x3022, | ||
1290 | 0xd853, 0x1002, | ||
1291 | 0xd854, 0x2742, | ||
1292 | 0xd855, 0x3022, | ||
1293 | 0xd856, 0x1002, | ||
1294 | 0xd857, 0x25e2, | ||
1295 | 0xd858, 0x3022, | ||
1296 | 0xd859, 0x1002, | ||
1297 | 0xd85a, 0x2fb4, | ||
1298 | 0xd85b, 0x3dc4, | ||
1299 | 0xd85c, 0x6624, | ||
1300 | 0xd85d, 0x56b3, | ||
1301 | 0xd85e, 0x03c3, | ||
1302 | 0xd85f, 0x866b, | ||
1303 | 0xd860, 0x401c, | ||
1304 | 0xd861, 0x2c45, | ||
1305 | 0xd862, 0x3095, | ||
1306 | 0xd863, 0x5b53, | ||
1307 | 0xd864, 0x2372, | ||
1308 | 0xd865, 0x3012, | ||
1309 | 0xd866, 0x13c2, | ||
1310 | 0xd867, 0x5cc3, | ||
1311 | 0xd868, 0x2712, | ||
1312 | 0xd869, 0x3012, | ||
1313 | 0xd86a, 0x1312, | ||
1314 | 0xd86b, 0x2b52, | ||
1315 | 0xd86c, 0x3012, | ||
1316 | 0xd86d, 0x1002, | ||
1317 | 0xd86e, 0x2742, | ||
1318 | 0xd86f, 0x3022, | ||
1319 | 0xd870, 0x1002, | ||
1320 | 0xd871, 0x2582, | ||
1321 | 0xd872, 0x3022, | ||
1322 | 0xd873, 0x1002, | ||
1323 | 0xd874, 0x2142, | ||
1324 | 0xd875, 0x3012, | ||
1325 | 0xd876, 0x1002, | ||
1326 | 0xd877, 0x628f, | ||
1327 | 0xd878, 0x2985, | ||
1328 | 0xd879, 0x33a5, | ||
1329 | 0xd87a, 0x25e2, | ||
1330 | 0xd87b, 0x3022, | ||
1331 | 0xd87c, 0x1002, | ||
1332 | 0xd87d, 0x5653, | ||
1333 | 0xd87e, 0x03d2, | ||
1334 | 0xd87f, 0x401e, | ||
1335 | 0xd880, 0x6f72, | ||
1336 | 0xd881, 0x1002, | ||
1337 | 0xd882, 0x628f, | ||
1338 | 0xd883, 0x2304, | ||
1339 | 0xd884, 0x3c84, | ||
1340 | 0xd885, 0x6436, | ||
1341 | 0xd886, 0xdff4, | ||
1342 | 0xd887, 0x6436, | ||
1343 | 0xd888, 0x2ff5, | ||
1344 | 0xd889, 0x3005, | ||
1345 | 0xd88a, 0x8656, | ||
1346 | 0xd88b, 0xdfba, | ||
1347 | 0xd88c, 0x56a3, | ||
1348 | 0xd88d, 0xd05a, | ||
1349 | 0xd88e, 0x2972, | ||
1350 | 0xd88f, 0x3012, | ||
1351 | 0xd890, 0x1392, | ||
1352 | 0xd891, 0xd05a, | ||
1353 | 0xd892, 0x56a3, | ||
1354 | 0xd893, 0xdfba, | ||
1355 | 0xd894, 0x0383, | ||
1356 | 0xd895, 0x6f72, | ||
1357 | 0xd896, 0x1002, | ||
1358 | 0xd897, 0x2b45, | ||
1359 | 0xd898, 0x3005, | ||
1360 | 0xd899, 0x4178, | ||
1361 | 0xd89a, 0x5653, | ||
1362 | 0xd89b, 0x0384, | ||
1363 | 0xd89c, 0x2a62, | ||
1364 | 0xd89d, 0x3012, | ||
1365 | 0xd89e, 0x1002, | ||
1366 | 0xd89f, 0x2f05, | ||
1367 | 0xd8a0, 0x3005, | ||
1368 | 0xd8a1, 0x41c8, | ||
1369 | 0xd8a2, 0x5653, | ||
1370 | 0xd8a3, 0x0382, | ||
1371 | 0xd8a4, 0x0002, | ||
1372 | 0xd8a5, 0x4218, | ||
1373 | 0xd8a6, 0x2474, | ||
1374 | 0xd8a7, 0x3c84, | ||
1375 | 0xd8a8, 0x6437, | ||
1376 | 0xd8a9, 0xdff4, | ||
1377 | 0xd8aa, 0x6437, | ||
1378 | 0xd8ab, 0x2ff5, | ||
1379 | 0xd8ac, 0x3c05, | ||
1380 | 0xd8ad, 0x8757, | ||
1381 | 0xd8ae, 0xb888, | ||
1382 | 0xd8af, 0x9787, | ||
1383 | 0xd8b0, 0xdff4, | ||
1384 | 0xd8b1, 0x6724, | ||
1385 | 0xd8b2, 0x866a, | ||
1386 | 0xd8b3, 0x6f72, | ||
1387 | 0xd8b4, 0x1002, | ||
1388 | 0xd8b5, 0x2641, | ||
1389 | 0xd8b6, 0x3021, | ||
1390 | 0xd8b7, 0x1001, | ||
1391 | 0xd8b8, 0xc620, | ||
1392 | 0xd8b9, 0x0000, | ||
1393 | 0xd8ba, 0xc621, | ||
1394 | 0xd8bb, 0x0000, | ||
1395 | 0xd8bc, 0xc622, | ||
1396 | 0xd8bd, 0x00ce, | ||
1397 | 0xd8be, 0xc623, | ||
1398 | 0xd8bf, 0x007f, | ||
1399 | 0xd8c0, 0xc624, | ||
1400 | 0xd8c1, 0x0032, | ||
1401 | 0xd8c2, 0xc625, | ||
1402 | 0xd8c3, 0x0000, | ||
1403 | 0xd8c4, 0xc627, | ||
1404 | 0xd8c5, 0x0000, | ||
1405 | 0xd8c6, 0xc628, | ||
1406 | 0xd8c7, 0x0000, | ||
1407 | 0xd8c8, 0xc62c, | ||
1408 | 0xd8c9, 0x0000, | ||
1409 | 0xd8ca, 0x0000, | ||
1410 | 0xd8cb, 0x2641, | ||
1411 | 0xd8cc, 0x3021, | ||
1412 | 0xd8cd, 0x1001, | ||
1413 | 0xd8ce, 0xc502, | ||
1414 | 0xd8cf, 0x53ac, | ||
1415 | 0xd8d0, 0xc503, | ||
1416 | 0xd8d1, 0x2cd3, | ||
1417 | 0xd8d2, 0xc600, | ||
1418 | 0xd8d3, 0x2a6e, | ||
1419 | 0xd8d4, 0xc601, | ||
1420 | 0xd8d5, 0x2a2c, | ||
1421 | 0xd8d6, 0xc605, | ||
1422 | 0xd8d7, 0x5557, | ||
1423 | 0xd8d8, 0xc60c, | ||
1424 | 0xd8d9, 0x5400, | ||
1425 | 0xd8da, 0xc710, | ||
1426 | 0xd8db, 0x0700, | ||
1427 | 0xd8dc, 0xc711, | ||
1428 | 0xd8dd, 0x0f06, | ||
1429 | 0xd8de, 0xc718, | ||
1430 | 0xd8df, 0x0700, | ||
1431 | 0xd8e0, 0xc719, | ||
1432 | 0xd8e1, 0x0f06, | ||
1433 | 0xd8e2, 0xc720, | ||
1434 | 0xd8e3, 0x4700, | ||
1435 | 0xd8e4, 0xc721, | ||
1436 | 0xd8e5, 0x0f06, | ||
1437 | 0xd8e6, 0xc728, | ||
1438 | 0xd8e7, 0x0700, | ||
1439 | 0xd8e8, 0xc729, | ||
1440 | 0xd8e9, 0x1207, | ||
1441 | 0xd8ea, 0xc801, | ||
1442 | 0xd8eb, 0x7f50, | ||
1443 | 0xd8ec, 0xc802, | ||
1444 | 0xd8ed, 0x7760, | ||
1445 | 0xd8ee, 0xc803, | ||
1446 | 0xd8ef, 0x7fce, | ||
1447 | 0xd8f0, 0xc804, | ||
1448 | 0xd8f1, 0x520e, | ||
1449 | 0xd8f2, 0xc805, | ||
1450 | 0xd8f3, 0x5c11, | ||
1451 | 0xd8f4, 0xc806, | ||
1452 | 0xd8f5, 0x3c51, | ||
1453 | 0xd8f6, 0xc807, | ||
1454 | 0xd8f7, 0x4061, | ||
1455 | 0xd8f8, 0xc808, | ||
1456 | 0xd8f9, 0x49c1, | ||
1457 | 0xd8fa, 0xc809, | ||
1458 | 0xd8fb, 0x3840, | ||
1459 | 0xd8fc, 0xc80a, | ||
1460 | 0xd8fd, 0x0000, | ||
1461 | 0xd8fe, 0xc821, | ||
1462 | 0xd8ff, 0x0002, | ||
1463 | 0xd900, 0xc822, | ||
1464 | 0xd901, 0x0046, | ||
1465 | 0xd902, 0xc844, | ||
1466 | 0xd903, 0x182f, | ||
1467 | 0xd904, 0xc013, | ||
1468 | 0xd905, 0xf341, | ||
1469 | 0xd906, 0xc084, | ||
1470 | 0xd907, 0x0030, | ||
1471 | 0xd908, 0xc904, | ||
1472 | 0xd909, 0x1401, | ||
1473 | 0xd90a, 0xcb0c, | ||
1474 | 0xd90b, 0x0004, | ||
1475 | 0xd90c, 0xcb0e, | ||
1476 | 0xd90d, 0xa00a, | ||
1477 | 0xd90e, 0xcb0f, | ||
1478 | 0xd90f, 0xc0c0, | ||
1479 | 0xd910, 0xcb10, | ||
1480 | 0xd911, 0xc0c0, | ||
1481 | 0xd912, 0xcb11, | ||
1482 | 0xd913, 0x00a0, | ||
1483 | 0xd914, 0xcb12, | ||
1484 | 0xd915, 0x0007, | ||
1485 | 0xd916, 0xc241, | ||
1486 | 0xd917, 0xa000, | ||
1487 | 0xd918, 0xc243, | ||
1488 | 0xd919, 0x7fe0, | ||
1489 | 0xd91a, 0xc604, | ||
1490 | 0xd91b, 0x000e, | ||
1491 | 0xd91c, 0xc609, | ||
1492 | 0xd91d, 0x00f5, | ||
1493 | 0xd91e, 0xc611, | ||
1494 | 0xd91f, 0x000e, | ||
1495 | 0xd920, 0xc660, | ||
1496 | 0xd921, 0x9600, | ||
1497 | 0xd922, 0xc687, | ||
1498 | 0xd923, 0x0004, | ||
1499 | 0xd924, 0xc60a, | ||
1500 | 0xd925, 0x04f5, | ||
1501 | 0xd926, 0x0000, | ||
1502 | 0xd927, 0x2641, | ||
1503 | 0xd928, 0x3021, | ||
1504 | 0xd929, 0x1001, | ||
1505 | 0xd92a, 0xc620, | ||
1506 | 0xd92b, 0x14e5, | ||
1507 | 0xd92c, 0xc621, | ||
1508 | 0xd92d, 0xc53d, | ||
1509 | 0xd92e, 0xc622, | ||
1510 | 0xd92f, 0x3cbe, | ||
1511 | 0xd930, 0xc623, | ||
1512 | 0xd931, 0x4452, | ||
1513 | 0xd932, 0xc624, | ||
1514 | 0xd933, 0xc5c5, | ||
1515 | 0xd934, 0xc625, | ||
1516 | 0xd935, 0xe01e, | ||
1517 | 0xd936, 0xc627, | ||
1518 | 0xd937, 0x0000, | ||
1519 | 0xd938, 0xc628, | ||
1520 | 0xd939, 0x0000, | ||
1521 | 0xd93a, 0xc62c, | ||
1522 | 0xd93b, 0x0000, | ||
1523 | 0xd93c, 0x0000, | ||
1524 | 0xd93d, 0x2b84, | ||
1525 | 0xd93e, 0x3c74, | ||
1526 | 0xd93f, 0x6435, | ||
1527 | 0xd940, 0xdff4, | ||
1528 | 0xd941, 0x6435, | ||
1529 | 0xd942, 0x2806, | ||
1530 | 0xd943, 0x3006, | ||
1531 | 0xd944, 0x8565, | ||
1532 | 0xd945, 0x2b24, | ||
1533 | 0xd946, 0x3c24, | ||
1534 | 0xd947, 0x6436, | ||
1535 | 0xd948, 0x1002, | ||
1536 | 0xd949, 0x2b24, | ||
1537 | 0xd94a, 0x3c24, | ||
1538 | 0xd94b, 0x6436, | ||
1539 | 0xd94c, 0x4045, | ||
1540 | 0xd94d, 0x8656, | ||
1541 | 0xd94e, 0x5663, | ||
1542 | 0xd94f, 0x0302, | ||
1543 | 0xd950, 0x401e, | ||
1544 | 0xd951, 0x1002, | ||
1545 | 0xd952, 0x2807, | ||
1546 | 0xd953, 0x31a7, | ||
1547 | 0xd954, 0x20c4, | ||
1548 | 0xd955, 0x3c24, | ||
1549 | 0xd956, 0x6724, | ||
1550 | 0xd957, 0x1002, | ||
1551 | 0xd958, 0x2807, | ||
1552 | 0xd959, 0x3187, | ||
1553 | 0xd95a, 0x20c4, | ||
1554 | 0xd95b, 0x3c24, | ||
1555 | 0xd95c, 0x6724, | ||
1556 | 0xd95d, 0x1002, | ||
1557 | 0xd95e, 0x24f4, | ||
1558 | 0xd95f, 0x3c64, | ||
1559 | 0xd960, 0x6436, | ||
1560 | 0xd961, 0xdff4, | ||
1561 | 0xd962, 0x6436, | ||
1562 | 0xd963, 0x1002, | ||
1563 | 0xd964, 0x2006, | ||
1564 | 0xd965, 0x3d76, | ||
1565 | 0xd966, 0xc161, | ||
1566 | 0xd967, 0x6134, | ||
1567 | 0xd968, 0x6135, | ||
1568 | 0xd969, 0x5443, | ||
1569 | 0xd96a, 0x0303, | ||
1570 | 0xd96b, 0x6524, | ||
1571 | 0xd96c, 0x00fb, | ||
1572 | 0xd96d, 0x1002, | ||
1573 | 0xd96e, 0x20d4, | ||
1574 | 0xd96f, 0x3c24, | ||
1575 | 0xd970, 0x2025, | ||
1576 | 0xd971, 0x3005, | ||
1577 | 0xd972, 0x6524, | ||
1578 | 0xd973, 0x1002, | ||
1579 | 0xd974, 0xd019, | ||
1580 | 0xd975, 0x2104, | ||
1581 | 0xd976, 0x3c24, | ||
1582 | 0xd977, 0x2105, | ||
1583 | 0xd978, 0x3805, | ||
1584 | 0xd979, 0x6524, | ||
1585 | 0xd97a, 0xdff4, | ||
1586 | 0xd97b, 0x4005, | ||
1587 | 0xd97c, 0x6524, | ||
1588 | 0xd97d, 0x2e8d, | ||
1589 | 0xd97e, 0x303d, | ||
1590 | 0xd97f, 0x2408, | ||
1591 | 0xd980, 0x35d8, | ||
1592 | 0xd981, 0x5dd3, | ||
1593 | 0xd982, 0x0307, | ||
1594 | 0xd983, 0x8887, | ||
1595 | 0xd984, 0x63a7, | ||
1596 | 0xd985, 0x8887, | ||
1597 | 0xd986, 0x63a7, | ||
1598 | 0xd987, 0xdffd, | ||
1599 | 0xd988, 0x00f9, | ||
1600 | 0xd989, 0x1002, | ||
1601 | 0xd98a, 0x0000, | ||
1602 | }; | ||
1603 | int i, err; | ||
1604 | |||
1605 | /* set uC clock and activate it */ | ||
1606 | err = set_phy_regs(phy, uCclock40MHz); | ||
1607 | msleep(500); | ||
1608 | if (err) | ||
1609 | return err; | ||
1610 | err = set_phy_regs(phy, uCclockActivate); | ||
1611 | msleep(500); | ||
1612 | if (err) | ||
1613 | return err; | ||
1614 | |||
1615 | /* write TWINAX EDC firmware into PHY */ | ||
1616 | for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2) | ||
1617 | err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, twinax_edc[i], | ||
1618 | twinax_edc[i + 1]); | ||
1619 | /* activate uC */ | ||
1620 | err = set_phy_regs(phy, uCactivate); | ||
1621 | if (!err) | ||
1622 | phy->priv = edc_twinax; | ||
1623 | return err; | ||
1624 | } | ||
1625 | |||
1626 | /* | ||
1627 | * Return Module Type. | ||
1628 | */ | ||
1629 | static int ael2020_get_module_type(struct cphy *phy, int delay_ms) | ||
1630 | { | ||
1631 | int v; | ||
1632 | unsigned int stat; | ||
1633 | |||
1634 | v = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_STAT, &stat); | ||
1635 | if (v) | ||
1636 | return v; | ||
1637 | |||
1638 | if (stat & (0x1 << (AEL2020_GPIO_MODDET*4))) { | ||
1639 | /* module absent */ | ||
1640 | return phy_modtype_none; | ||
1641 | } | ||
1642 | |||
1643 | return ael2xxx_get_module_type(phy, delay_ms); | ||
1644 | } | ||
1645 | |||
1646 | /* | ||
1647 | * Enable PHY interrupts. We enable "Module Detection" interrupts (on any | ||
1648 | * state transition) and then generic Link Alarm Status Interrupt (LASI). | ||
1649 | */ | ||
1650 | static int ael2020_intr_enable(struct cphy *phy) | ||
1651 | { | ||
1652 | int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL, | ||
1653 | 0x2 << (AEL2020_GPIO_MODDET*4)); | ||
1654 | return err ? err : t3_phy_lasi_intr_enable(phy); | ||
1655 | } | ||
1656 | |||
1657 | /* | ||
1658 | * Disable PHY interrupts. The mirror of the above ... | ||
1659 | */ | ||
1660 | static int ael2020_intr_disable(struct cphy *phy) | ||
1661 | { | ||
1662 | int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL, | ||
1663 | 0x1 << (AEL2020_GPIO_MODDET*4)); | ||
1664 | return err ? err : t3_phy_lasi_intr_disable(phy); | ||
1665 | } | ||
1666 | |||
1667 | /* | ||
1668 | * Clear PHY interrupt state. | ||
1669 | */ | ||
1670 | static int ael2020_intr_clear(struct cphy *phy) | ||
1671 | { | ||
1672 | /* | ||
1673 | * The GPIO Interrupt register on the AEL2020 is a "Latching High" | ||
1674 | * (LH) register which is cleared to the current state when it's read. | ||
1675 | * Thus, we simply read the register and discard the result. | ||
1676 | */ | ||
1677 | unsigned int stat; | ||
1678 | int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_INTR, &stat); | ||
1679 | return err ? err : t3_phy_lasi_intr_clear(phy); | ||
1680 | } | ||
1681 | |||
1682 | /* | ||
1683 | * Reset the PHY and put it into a canonical operating state. | ||
1684 | */ | ||
1685 | static int ael2020_reset(struct cphy *phy, int wait) | ||
1686 | { | ||
1687 | static struct reg_val regs0[] = { | ||
1688 | /* Erratum #2: CDRLOL asserted, causing PMA link down status */ | ||
1689 | { MDIO_MMD_PMAPMD, 0xc003, 0xffff, 0x3101 }, | ||
1690 | |||
1691 | /* force XAUI to send LF when RX_LOS is asserted */ | ||
1692 | { MDIO_MMD_PMAPMD, 0xcd40, 0xffff, 0x0001 }, | ||
1693 | |||
1694 | /* RX_LOS pin is active high */ | ||
1695 | { MDIO_MMD_PMAPMD, AEL_OPT_SETTINGS, | ||
1696 | 0x0020, 0x0020 }, | ||
1697 | |||
1698 | /* output Module's Loss Of Signal (LOS) to LED */ | ||
1699 | { MDIO_MMD_PMAPMD, AEL2020_GPIO_CFG+AEL2020_GPIO_LSTAT, | ||
1700 | 0xffff, 0x0004 }, | ||
1701 | { MDIO_MMD_PMAPMD, AEL2020_GPIO_CTRL, | ||
1702 | 0xffff, 0x8 << (AEL2020_GPIO_LSTAT*4) }, | ||
1703 | |||
1704 | /* end */ | ||
1705 | { 0, 0, 0, 0 } | ||
1706 | }; | ||
1707 | int err; | ||
1708 | unsigned int lasi_ctrl; | ||
1709 | |||
1710 | /* grab current interrupt state */ | ||
1711 | err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL, | ||
1712 | &lasi_ctrl); | ||
1713 | if (err) | ||
1714 | return err; | ||
1715 | |||
1716 | err = t3_phy_reset(phy, MDIO_MMD_PMAPMD, 125); | ||
1717 | if (err) | ||
1718 | return err; | ||
1719 | msleep(100); | ||
1720 | |||
1721 | /* basic initialization for all module types */ | ||
1722 | phy->priv = edc_none; | ||
1723 | err = set_phy_regs(phy, regs0); | ||
1724 | if (err) | ||
1725 | return err; | ||
1726 | |||
1727 | /* determine module type and perform appropriate initialization */ | ||
1728 | err = ael2020_get_module_type(phy, 0); | ||
1729 | if (err < 0) | ||
1730 | return err; | ||
1731 | phy->modtype = (u8)err; | ||
1732 | if (err == phy_modtype_twinax || err == phy_modtype_twinax_long) | ||
1733 | err = ael2020_setup_twinax_edc(phy, err); | ||
1734 | else | ||
1735 | err = ael2020_setup_sr_edc(phy); | ||
1736 | if (err) | ||
1737 | return err; | ||
1738 | |||
1739 | /* reset wipes out interrupts, reenable them if they were on */ | ||
1740 | if (lasi_ctrl & 1) | ||
1741 | err = ael2005_intr_enable(phy); | ||
1742 | return err; | ||
1743 | } | ||
1744 | |||
1745 | /* | ||
1746 | * Handle a PHY interrupt. | ||
1747 | */ | ||
1748 | static int ael2020_intr_handler(struct cphy *phy) | ||
1749 | { | ||
1750 | unsigned int stat; | ||
1751 | int ret, edc_needed, cause = 0; | ||
1752 | |||
1753 | ret = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2020_GPIO_INTR, &stat); | ||
1754 | if (ret) | ||
1755 | return ret; | ||
1756 | |||
1757 | if (stat & (0x1 << AEL2020_GPIO_MODDET)) { | ||
1758 | /* modules have max 300 ms init time after hot plug */ | ||
1759 | ret = ael2020_get_module_type(phy, 300); | ||
1760 | if (ret < 0) | ||
1761 | return ret; | ||
1762 | |||
1763 | phy->modtype = (u8)ret; | ||
1764 | if (ret == phy_modtype_none) | ||
1765 | edc_needed = phy->priv; /* on unplug retain EDC */ | ||
1766 | else if (ret == phy_modtype_twinax || | ||
1767 | ret == phy_modtype_twinax_long) | ||
1768 | edc_needed = edc_twinax; | ||
1769 | else | ||
1770 | edc_needed = edc_sr; | ||
1771 | |||
1772 | if (edc_needed != phy->priv) { | ||
1773 | ret = ael2020_reset(phy, 0); | ||
1774 | return ret ? ret : cphy_cause_module_change; | ||
1775 | } | ||
1776 | cause = cphy_cause_module_change; | ||
1777 | } | ||
1778 | |||
1779 | ret = t3_phy_lasi_intr_handler(phy); | ||
1780 | if (ret < 0) | ||
1781 | return ret; | ||
1782 | |||
1783 | ret |= cause; | ||
1784 | return ret ? ret : cphy_cause_link_change; | ||
1785 | } | ||
1786 | |||
1787 | static struct cphy_ops ael2020_ops = { | ||
1788 | .reset = ael2020_reset, | ||
1789 | .intr_enable = ael2020_intr_enable, | ||
1790 | .intr_disable = ael2020_intr_disable, | ||
1791 | .intr_clear = ael2020_intr_clear, | ||
1792 | .intr_handler = ael2020_intr_handler, | ||
1793 | .get_link_status = get_link_status_r, | ||
1794 | .power_down = ael1002_power_down, | ||
1795 | .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, | ||
1796 | }; | ||
1797 | |||
1798 | int t3_ael2020_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, | ||
1799 | const struct mdio_ops *mdio_ops) | ||
1800 | { | ||
1801 | cphy_init(phy, adapter, phy_addr, &ael2020_ops, mdio_ops, | ||
1802 | SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE | | ||
1803 | SUPPORTED_IRQ, "10GBASE-R"); | ||
1804 | msleep(125); | ||
1805 | return 0; | ||
1806 | } | ||
1807 | |||
1808 | /* | ||
1115 | * Get link status for a 10GBASE-X device. | 1809 | * Get link status for a 10GBASE-X device. |
1116 | */ | 1810 | */ |
1117 | static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed, | 1811 | static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed, |
@@ -1119,12 +1813,15 @@ static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed, | |||
1119 | { | 1813 | { |
1120 | if (link_ok) { | 1814 | if (link_ok) { |
1121 | unsigned int stat0, stat1, stat2; | 1815 | unsigned int stat0, stat1, stat2; |
1122 | int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0); | 1816 | int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, |
1817 | MDIO_PMA_RXDET, &stat0); | ||
1123 | 1818 | ||
1124 | if (!err) | 1819 | if (!err) |
1125 | err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_X, &stat1); | 1820 | err = t3_mdio_read(phy, MDIO_MMD_PCS, |
1821 | MDIO_PCS_10GBX_STAT1, &stat1); | ||
1126 | if (!err) | 1822 | if (!err) |
1127 | err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2); | 1823 | err = t3_mdio_read(phy, MDIO_MMD_PHYXS, |
1824 | MDIO_PHYXS_LNSTAT, &stat2); | ||
1128 | if (err) | 1825 | if (err) |
1129 | return err; | 1826 | return err; |
1130 | *link_ok = (stat0 & (stat1 >> 12) & (stat2 >> 12)) & 1; | 1827 | *link_ok = (stat0 & (stat1 >> 12) & (stat2 >> 12)) & 1; |
@@ -1144,6 +1841,7 @@ static struct cphy_ops qt2045_ops = { | |||
1144 | .intr_handler = t3_phy_lasi_intr_handler, | 1841 | .intr_handler = t3_phy_lasi_intr_handler, |
1145 | .get_link_status = get_link_status_x, | 1842 | .get_link_status = get_link_status_x, |
1146 | .power_down = ael1006_power_down, | 1843 | .power_down = ael1006_power_down, |
1844 | .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS, | ||
1147 | }; | 1845 | }; |
1148 | 1846 | ||
1149 | int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, | 1847 | int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, |
@@ -1159,9 +1857,10 @@ int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, | |||
1159 | * Some cards where the PHY is supposed to be at address 0 actually | 1857 | * Some cards where the PHY is supposed to be at address 0 actually |
1160 | * have it at 1. | 1858 | * have it at 1. |
1161 | */ | 1859 | */ |
1162 | if (!phy_addr && !mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &stat) && | 1860 | if (!phy_addr && |
1861 | !t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &stat) && | ||
1163 | stat == 0xffff) | 1862 | stat == 0xffff) |
1164 | phy->addr = 1; | 1863 | phy->mdio.prtad = 1; |
1165 | return 0; | 1864 | return 0; |
1166 | } | 1865 | } |
1167 | 1866 | ||
@@ -1175,15 +1874,16 @@ static int xaui_direct_get_link_status(struct cphy *phy, int *link_ok, | |||
1175 | { | 1874 | { |
1176 | if (link_ok) { | 1875 | if (link_ok) { |
1177 | unsigned int status; | 1876 | unsigned int status; |
1877 | int prtad = phy->mdio.prtad; | ||
1178 | 1878 | ||
1179 | status = t3_read_reg(phy->adapter, | 1879 | status = t3_read_reg(phy->adapter, |
1180 | XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) | | 1880 | XGM_REG(A_XGM_SERDES_STAT0, prtad)) | |
1181 | t3_read_reg(phy->adapter, | 1881 | t3_read_reg(phy->adapter, |
1182 | XGM_REG(A_XGM_SERDES_STAT1, phy->addr)) | | 1882 | XGM_REG(A_XGM_SERDES_STAT1, prtad)) | |
1183 | t3_read_reg(phy->adapter, | 1883 | t3_read_reg(phy->adapter, |
1184 | XGM_REG(A_XGM_SERDES_STAT2, phy->addr)) | | 1884 | XGM_REG(A_XGM_SERDES_STAT2, prtad)) | |
1185 | t3_read_reg(phy->adapter, | 1885 | t3_read_reg(phy->adapter, |
1186 | XGM_REG(A_XGM_SERDES_STAT3, phy->addr)); | 1886 | XGM_REG(A_XGM_SERDES_STAT3, prtad)); |
1187 | *link_ok = !(status & F_LOWSIG0); | 1887 | *link_ok = !(status & F_LOWSIG0); |
1188 | } | 1888 | } |
1189 | if (speed) | 1889 | if (speed) |
@@ -1211,7 +1911,7 @@ static struct cphy_ops xaui_direct_ops = { | |||
1211 | int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter, | 1911 | int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter, |
1212 | int phy_addr, const struct mdio_ops *mdio_ops) | 1912 | int phy_addr, const struct mdio_ops *mdio_ops) |
1213 | { | 1913 | { |
1214 | cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops, | 1914 | cphy_init(phy, adapter, MDIO_PRTAD_NONE, &xaui_direct_ops, mdio_ops, |
1215 | SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP, | 1915 | SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP, |
1216 | "10GBASE-CX4"); | 1916 | "10GBASE-CX4"); |
1217 | return 0; | 1917 | return 0; |