aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/cxgb3/ael1002.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/cxgb3/ael1002.c')
-rw-r--r--drivers/net/cxgb3/ael1002.c958
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
35enum { 35enum {
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
42enum {
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
57enum { edc_none, edc_sr, edc_twinax }; 60enum { 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 63enum {
64 MODULE_DEV_ADDR = 0xa0,
65 SFF_DEV_ADDR = 0xa2,
66};
67
68/* PHY transceiver type */
69enum {
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
87static void ael100x_txon(struct cphy *phy) 100static 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 */
113static 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
96static int ael1002_power_down(struct cphy *phy, int enable) 141static 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
162int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter, 212int 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
172static int ael1006_reset(struct cphy *phy, int wait) 222static 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
177static int ael1006_power_down(struct cphy *phy, int enable) 227static 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
183static struct cphy_ops ael1006_ops = { 233static 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
193int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, 244int 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 */
257static 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 }
292unknown:
293 return phy_modtype_unknown;
294}
295
296/*
297 * Code to support the Aeluros/NetLogic 2005 10Gb PHY.
298 */
203static int ael2005_setup_sr_edc(struct cphy *phy) 299static 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)
500static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype) 596static 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
897static int ael2005_i2c_rd(struct cphy *phy, int dev_addr, int word_addr) 993static 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
925static 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 }
968unknown:
969 return phy_modtype_unknown;
970} 1006}
971 1007
972static int ael2005_intr_enable(struct cphy *phy) 1008static 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
978static int ael2005_intr_disable(struct cphy *phy) 1014static 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
984static int ael2005_intr_clear(struct cphy *phy) 1020static 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
990static int ael2005_reset(struct cphy *phy, int wait) 1026static 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
1103int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter, 1141int 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 */
1155static 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 */
1183static 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 */
1629static 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 */
1650static 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 */
1660static 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 */
1670static 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 */
1685static 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 */
1748static 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
1787static 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
1798int 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 */
1117static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed, 1811static 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
1149int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, 1847int 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 = {
1211int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter, 1911int 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;