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.c823
1 files changed, 758 insertions, 65 deletions
diff --git a/drivers/net/cxgb3/ael1002.c b/drivers/net/cxgb3/ael1002.c
index df1f58576689..9fe008ec9ba5 100644
--- a/drivers/net/cxgb3/ael1002.c
+++ b/drivers/net/cxgb3/ael1002.c
@@ -44,12 +44,33 @@ enum {
44 AEL_I2C_STAT = 0xc30c, 44 AEL_I2C_STAT = 0xc30c,
45 AEL2005_GPIO_CTRL = 0xc214, 45 AEL2005_GPIO_CTRL = 0xc214,
46 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 */
47}; 58};
48 59
49enum { edc_none, edc_sr, edc_twinax }; 60enum { edc_none, edc_sr, edc_twinax };
50 61
51/* PHY module I2C device address */ 62/* PHY module I2C device address */
52#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};
53 74
54#define AEL2005_MODDET_IRQ 4 75#define AEL2005_MODDET_IRQ 4
55 76
@@ -86,6 +107,37 @@ static void ael100x_txon(struct cphy *phy)
86 msleep(30); 107 msleep(30);
87} 108}
88 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
89static int ael1002_power_down(struct cphy *phy, int enable) 141static int ael1002_power_down(struct cphy *phy, int enable)
90{ 142{
91 int err; 143 int err;
@@ -199,6 +251,51 @@ int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter,
199 return 0; 251 return 0;
200} 252}
201 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 */
202static int ael2005_setup_sr_edc(struct cphy *phy) 299static int ael2005_setup_sr_edc(struct cphy *phy)
203{ 300{
204 static struct reg_val regs[] = { 301 static struct reg_val regs[] = {
@@ -893,35 +990,7 @@ static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
893 return err; 990 return err;
894} 991}
895 992
896static 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)
897{
898 int i, err;
899 unsigned int stat, data;
900
901 err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL_I2C_CTRL,
902 (dev_addr << 8) | (1 << 8) | word_addr);
903 if (err)
904 return err;
905
906 for (i = 0; i < 5; i++) {
907 msleep(1);
908 err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_STAT, &stat);
909 if (err)
910 return err;
911 if ((stat & 3) == 1) {
912 err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_DATA,
913 &data);
914 if (err)
915 return err;
916 return data >> 8;
917 }
918 }
919 CH_WARN(phy->adapter, "PHY %u I2C read of addr %u timed out\n",
920 phy->mdio.prtad, word_addr);
921 return -ETIMEDOUT;
922}
923
924static int get_module_type(struct cphy *phy, int delay_ms)
925{ 994{
926 int v; 995 int v;
927 unsigned int stat; 996 unsigned int stat;
@@ -933,39 +1002,7 @@ static int get_module_type(struct cphy *phy, int delay_ms)
933 if (stat & (1 << 8)) /* module absent */ 1002 if (stat & (1 << 8)) /* module absent */
934 return phy_modtype_none; 1003 return phy_modtype_none;
935 1004
936 if (delay_ms) 1005 return ael2xxx_get_module_type(phy, delay_ms);
937 msleep(delay_ms);
938
939 /* see SFF-8472 for below */
940 v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 3);
941 if (v < 0)
942 return v;
943
944 if (v == 0x10)
945 return phy_modtype_sr;
946 if (v == 0x20)
947 return phy_modtype_lr;
948 if (v == 0x40)
949 return phy_modtype_lrm;
950
951 v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 6);
952 if (v < 0)
953 return v;
954 if (v != 4)
955 goto unknown;
956
957 v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 10);
958 if (v < 0)
959 return v;
960
961 if (v & 0x80) {
962 v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 0x12);
963 if (v < 0)
964 return v;
965 return v > 10 ? phy_modtype_twinax_long : phy_modtype_twinax;
966 }
967unknown:
968 return phy_modtype_unknown;
969} 1006}
970 1007
971static int ael2005_intr_enable(struct cphy *phy) 1008static int ael2005_intr_enable(struct cphy *phy)
@@ -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;
@@ -1062,7 +1099,7 @@ static int ael2005_intr_handler(struct cphy *phy)
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
@@ -1113,6 +1150,662 @@ int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter,
1113} 1150}
1114 1151
1115/* 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/*
1116 * Get link status for a 10GBASE-X device. 1809 * Get link status for a 10GBASE-X device.
1117 */ 1810 */
1118static 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,