drivers/net/cxgb3: fix sparse warnings: fix signedness
[linux-2.6/kvm.git] / drivers / net / cxgb3 / ael1002.c
blobe1b22490ff597e439bbb1deb90b3638d59dfdb6f
1 /*
2 * Copyright (c) 2005-2008 Chelsio, Inc. All rights reserved.
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
32 #include "common.h"
33 #include "regs.h"
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 */
42 enum {
43 AEL100X_TX_DISABLE = 9,
44 AEL100X_TX_CONFIG1 = 0xc002,
45 AEL1002_PWR_DOWN_HI = 0xc011,
46 AEL1002_PWR_DOWN_LO = 0xc012,
47 AEL1002_XFI_EQL = 0xc015,
48 AEL1002_LB_EN = 0xc017,
49 AEL_OPT_SETTINGS = 0xc017,
50 AEL_I2C_CTRL = 0xc30a,
51 AEL_I2C_DATA = 0xc30b,
52 AEL_I2C_STAT = 0xc30c,
53 AEL2005_GPIO_CTRL = 0xc214,
54 AEL2005_GPIO_STAT = 0xc215,
57 enum { edc_none, edc_sr, edc_twinax };
59 /* PHY module I2C device address */
60 #define MODULE_DEV_ADDR 0xa0
62 #define AEL2005_MODDET_IRQ 4
64 struct reg_val {
65 unsigned short mmd_addr;
66 unsigned short reg_addr;
67 unsigned short clear_bits;
68 unsigned short set_bits;
71 static int set_phy_regs(struct cphy *phy, const struct reg_val *rv)
73 int err;
75 for (err = 0; rv->mmd_addr && !err; rv++) {
76 if (rv->clear_bits == 0xffff)
77 err = mdio_write(phy, rv->mmd_addr, rv->reg_addr,
78 rv->set_bits);
79 else
80 err = t3_mdio_change_bits(phy, rv->mmd_addr,
81 rv->reg_addr, rv->clear_bits,
82 rv->set_bits);
84 return err;
87 static void ael100x_txon(struct cphy *phy)
89 int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL;
91 msleep(100);
92 t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 0, tx_on_gpio);
93 msleep(30);
96 static int ael1002_power_down(struct cphy *phy, int enable)
98 int err;
100 err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_DISABLE, !!enable);
101 if (!err)
102 err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR,
103 BMCR_PDOWN, enable ? BMCR_PDOWN : 0);
104 return err;
107 static int ael1002_reset(struct cphy *phy, int wait)
109 int err;
111 if ((err = ael1002_power_down(phy, 0)) ||
112 (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_CONFIG1, 1)) ||
113 (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_HI, 0)) ||
114 (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_LO, 0)) ||
115 (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_XFI_EQL, 0x18)) ||
116 (err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL1002_LB_EN,
117 0, 1 << 5)))
118 return err;
119 return 0;
122 static int ael1002_intr_noop(struct cphy *phy)
124 return 0;
128 * Get link status for a 10GBASE-R device.
130 static int get_link_status_r(struct cphy *phy, int *link_ok, int *speed,
131 int *duplex, int *fc)
133 if (link_ok) {
134 unsigned int stat0, stat1, stat2;
135 int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0);
137 if (!err)
138 err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_R, &stat1);
139 if (!err)
140 err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2);
141 if (err)
142 return err;
143 *link_ok = (stat0 & stat1 & (stat2 >> 12)) & 1;
145 if (speed)
146 *speed = SPEED_10000;
147 if (duplex)
148 *duplex = DUPLEX_FULL;
149 return 0;
152 static struct cphy_ops ael1002_ops = {
153 .reset = ael1002_reset,
154 .intr_enable = ael1002_intr_noop,
155 .intr_disable = ael1002_intr_noop,
156 .intr_clear = ael1002_intr_noop,
157 .intr_handler = ael1002_intr_noop,
158 .get_link_status = get_link_status_r,
159 .power_down = ael1002_power_down,
162 int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter,
163 int phy_addr, const struct mdio_ops *mdio_ops)
165 cphy_init(phy, adapter, phy_addr, &ael1002_ops, mdio_ops,
166 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE,
167 "10GBASE-R");
168 ael100x_txon(phy);
169 return 0;
172 static int ael1006_reset(struct cphy *phy, int wait)
174 return t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait);
177 static int ael1006_power_down(struct cphy *phy, int enable)
179 return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR,
180 BMCR_PDOWN, enable ? BMCR_PDOWN : 0);
183 static struct cphy_ops ael1006_ops = {
184 .reset = ael1006_reset,
185 .intr_enable = t3_phy_lasi_intr_enable,
186 .intr_disable = t3_phy_lasi_intr_disable,
187 .intr_clear = t3_phy_lasi_intr_clear,
188 .intr_handler = t3_phy_lasi_intr_handler,
189 .get_link_status = get_link_status_r,
190 .power_down = ael1006_power_down,
193 int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter,
194 int phy_addr, const struct mdio_ops *mdio_ops)
196 cphy_init(phy, adapter, phy_addr, &ael1006_ops, mdio_ops,
197 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE,
198 "10GBASE-SR");
199 ael100x_txon(phy);
200 return 0;
203 static int ael2005_setup_sr_edc(struct cphy *phy)
205 static struct reg_val regs[] = {
206 { MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x181 },
207 { MDIO_DEV_PMA_PMD, 0xc010, 0xffff, 0x448a },
208 { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5200 },
209 { 0, 0, 0, 0 }
211 static u16 sr_edc[] = {
212 0xcc00, 0x2ff4,
213 0xcc01, 0x3cd4,
214 0xcc02, 0x2015,
215 0xcc03, 0x3105,
216 0xcc04, 0x6524,
217 0xcc05, 0x27ff,
218 0xcc06, 0x300f,
219 0xcc07, 0x2c8b,
220 0xcc08, 0x300b,
221 0xcc09, 0x4009,
222 0xcc0a, 0x400e,
223 0xcc0b, 0x2f72,
224 0xcc0c, 0x3002,
225 0xcc0d, 0x1002,
226 0xcc0e, 0x2172,
227 0xcc0f, 0x3012,
228 0xcc10, 0x1002,
229 0xcc11, 0x25d2,
230 0xcc12, 0x3012,
231 0xcc13, 0x1002,
232 0xcc14, 0xd01e,
233 0xcc15, 0x27d2,
234 0xcc16, 0x3012,
235 0xcc17, 0x1002,
236 0xcc18, 0x2004,
237 0xcc19, 0x3c84,
238 0xcc1a, 0x6436,
239 0xcc1b, 0x2007,
240 0xcc1c, 0x3f87,
241 0xcc1d, 0x8676,
242 0xcc1e, 0x40b7,
243 0xcc1f, 0xa746,
244 0xcc20, 0x4047,
245 0xcc21, 0x5673,
246 0xcc22, 0x2982,
247 0xcc23, 0x3002,
248 0xcc24, 0x13d2,
249 0xcc25, 0x8bbd,
250 0xcc26, 0x2862,
251 0xcc27, 0x3012,
252 0xcc28, 0x1002,
253 0xcc29, 0x2092,
254 0xcc2a, 0x3012,
255 0xcc2b, 0x1002,
256 0xcc2c, 0x5cc3,
257 0xcc2d, 0x314,
258 0xcc2e, 0x2942,
259 0xcc2f, 0x3002,
260 0xcc30, 0x1002,
261 0xcc31, 0xd019,
262 0xcc32, 0x2032,
263 0xcc33, 0x3012,
264 0xcc34, 0x1002,
265 0xcc35, 0x2a04,
266 0xcc36, 0x3c74,
267 0xcc37, 0x6435,
268 0xcc38, 0x2fa4,
269 0xcc39, 0x3cd4,
270 0xcc3a, 0x6624,
271 0xcc3b, 0x5563,
272 0xcc3c, 0x2d42,
273 0xcc3d, 0x3002,
274 0xcc3e, 0x13d2,
275 0xcc3f, 0x464d,
276 0xcc40, 0x2862,
277 0xcc41, 0x3012,
278 0xcc42, 0x1002,
279 0xcc43, 0x2032,
280 0xcc44, 0x3012,
281 0xcc45, 0x1002,
282 0xcc46, 0x2fb4,
283 0xcc47, 0x3cd4,
284 0xcc48, 0x6624,
285 0xcc49, 0x5563,
286 0xcc4a, 0x2d42,
287 0xcc4b, 0x3002,
288 0xcc4c, 0x13d2,
289 0xcc4d, 0x2ed2,
290 0xcc4e, 0x3002,
291 0xcc4f, 0x1002,
292 0xcc50, 0x2fd2,
293 0xcc51, 0x3002,
294 0xcc52, 0x1002,
295 0xcc53, 0x004,
296 0xcc54, 0x2942,
297 0xcc55, 0x3002,
298 0xcc56, 0x1002,
299 0xcc57, 0x2092,
300 0xcc58, 0x3012,
301 0xcc59, 0x1002,
302 0xcc5a, 0x5cc3,
303 0xcc5b, 0x317,
304 0xcc5c, 0x2f72,
305 0xcc5d, 0x3002,
306 0xcc5e, 0x1002,
307 0xcc5f, 0x2942,
308 0xcc60, 0x3002,
309 0xcc61, 0x1002,
310 0xcc62, 0x22cd,
311 0xcc63, 0x301d,
312 0xcc64, 0x2862,
313 0xcc65, 0x3012,
314 0xcc66, 0x1002,
315 0xcc67, 0x2ed2,
316 0xcc68, 0x3002,
317 0xcc69, 0x1002,
318 0xcc6a, 0x2d72,
319 0xcc6b, 0x3002,
320 0xcc6c, 0x1002,
321 0xcc6d, 0x628f,
322 0xcc6e, 0x2112,
323 0xcc6f, 0x3012,
324 0xcc70, 0x1002,
325 0xcc71, 0x5aa3,
326 0xcc72, 0x2dc2,
327 0xcc73, 0x3002,
328 0xcc74, 0x1312,
329 0xcc75, 0x6f72,
330 0xcc76, 0x1002,
331 0xcc77, 0x2807,
332 0xcc78, 0x31a7,
333 0xcc79, 0x20c4,
334 0xcc7a, 0x3c24,
335 0xcc7b, 0x6724,
336 0xcc7c, 0x1002,
337 0xcc7d, 0x2807,
338 0xcc7e, 0x3187,
339 0xcc7f, 0x20c4,
340 0xcc80, 0x3c24,
341 0xcc81, 0x6724,
342 0xcc82, 0x1002,
343 0xcc83, 0x2514,
344 0xcc84, 0x3c64,
345 0xcc85, 0x6436,
346 0xcc86, 0xdff4,
347 0xcc87, 0x6436,
348 0xcc88, 0x1002,
349 0xcc89, 0x40a4,
350 0xcc8a, 0x643c,
351 0xcc8b, 0x4016,
352 0xcc8c, 0x8c6c,
353 0xcc8d, 0x2b24,
354 0xcc8e, 0x3c24,
355 0xcc8f, 0x6435,
356 0xcc90, 0x1002,
357 0xcc91, 0x2b24,
358 0xcc92, 0x3c24,
359 0xcc93, 0x643a,
360 0xcc94, 0x4025,
361 0xcc95, 0x8a5a,
362 0xcc96, 0x1002,
363 0xcc97, 0x2731,
364 0xcc98, 0x3011,
365 0xcc99, 0x1001,
366 0xcc9a, 0xc7a0,
367 0xcc9b, 0x100,
368 0xcc9c, 0xc502,
369 0xcc9d, 0x53ac,
370 0xcc9e, 0xc503,
371 0xcc9f, 0xd5d5,
372 0xcca0, 0xc600,
373 0xcca1, 0x2a6d,
374 0xcca2, 0xc601,
375 0xcca3, 0x2a4c,
376 0xcca4, 0xc602,
377 0xcca5, 0x111,
378 0xcca6, 0xc60c,
379 0xcca7, 0x5900,
380 0xcca8, 0xc710,
381 0xcca9, 0x700,
382 0xccaa, 0xc718,
383 0xccab, 0x700,
384 0xccac, 0xc720,
385 0xccad, 0x4700,
386 0xccae, 0xc801,
387 0xccaf, 0x7f50,
388 0xccb0, 0xc802,
389 0xccb1, 0x7760,
390 0xccb2, 0xc803,
391 0xccb3, 0x7fce,
392 0xccb4, 0xc804,
393 0xccb5, 0x5700,
394 0xccb6, 0xc805,
395 0xccb7, 0x5f11,
396 0xccb8, 0xc806,
397 0xccb9, 0x4751,
398 0xccba, 0xc807,
399 0xccbb, 0x57e1,
400 0xccbc, 0xc808,
401 0xccbd, 0x2700,
402 0xccbe, 0xc809,
403 0xccbf, 0x000,
404 0xccc0, 0xc821,
405 0xccc1, 0x002,
406 0xccc2, 0xc822,
407 0xccc3, 0x014,
408 0xccc4, 0xc832,
409 0xccc5, 0x1186,
410 0xccc6, 0xc847,
411 0xccc7, 0x1e02,
412 0xccc8, 0xc013,
413 0xccc9, 0xf341,
414 0xccca, 0xc01a,
415 0xcccb, 0x446,
416 0xcccc, 0xc024,
417 0xcccd, 0x1000,
418 0xccce, 0xc025,
419 0xcccf, 0xa00,
420 0xccd0, 0xc026,
421 0xccd1, 0xc0c,
422 0xccd2, 0xc027,
423 0xccd3, 0xc0c,
424 0xccd4, 0xc029,
425 0xccd5, 0x0a0,
426 0xccd6, 0xc030,
427 0xccd7, 0xa00,
428 0xccd8, 0xc03c,
429 0xccd9, 0x01c,
430 0xccda, 0xc005,
431 0xccdb, 0x7a06,
432 0xccdc, 0x000,
433 0xccdd, 0x2731,
434 0xccde, 0x3011,
435 0xccdf, 0x1001,
436 0xcce0, 0xc620,
437 0xcce1, 0x000,
438 0xcce2, 0xc621,
439 0xcce3, 0x03f,
440 0xcce4, 0xc622,
441 0xcce5, 0x000,
442 0xcce6, 0xc623,
443 0xcce7, 0x000,
444 0xcce8, 0xc624,
445 0xcce9, 0x000,
446 0xccea, 0xc625,
447 0xcceb, 0x000,
448 0xccec, 0xc627,
449 0xcced, 0x000,
450 0xccee, 0xc628,
451 0xccef, 0x000,
452 0xccf0, 0xc62c,
453 0xccf1, 0x000,
454 0xccf2, 0x000,
455 0xccf3, 0x2806,
456 0xccf4, 0x3cb6,
457 0xccf5, 0xc161,
458 0xccf6, 0x6134,
459 0xccf7, 0x6135,
460 0xccf8, 0x5443,
461 0xccf9, 0x303,
462 0xccfa, 0x6524,
463 0xccfb, 0x00b,
464 0xccfc, 0x1002,
465 0xccfd, 0x2104,
466 0xccfe, 0x3c24,
467 0xccff, 0x2105,
468 0xcd00, 0x3805,
469 0xcd01, 0x6524,
470 0xcd02, 0xdff4,
471 0xcd03, 0x4005,
472 0xcd04, 0x6524,
473 0xcd05, 0x1002,
474 0xcd06, 0x5dd3,
475 0xcd07, 0x306,
476 0xcd08, 0x2ff7,
477 0xcd09, 0x38f7,
478 0xcd0a, 0x60b7,
479 0xcd0b, 0xdffd,
480 0xcd0c, 0x00a,
481 0xcd0d, 0x1002,
482 0xcd0e, 0
484 int i, err;
486 err = set_phy_regs(phy, regs);
487 if (err)
488 return err;
490 msleep(50);
492 for (i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2)
493 err = mdio_write(phy, MDIO_DEV_PMA_PMD, sr_edc[i],
494 sr_edc[i + 1]);
495 if (!err)
496 phy->priv = edc_sr;
497 return err;
500 static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
502 static struct reg_val regs[] = {
503 { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5a00 },
504 { 0, 0, 0, 0 }
506 static struct reg_val preemphasis[] = {
507 { MDIO_DEV_PMA_PMD, 0xc014, 0xffff, 0xfe16 },
508 { MDIO_DEV_PMA_PMD, 0xc015, 0xffff, 0xa000 },
509 { 0, 0, 0, 0 }
511 static u16 twinax_edc[] = {
512 0xcc00, 0x4009,
513 0xcc01, 0x27ff,
514 0xcc02, 0x300f,
515 0xcc03, 0x40aa,
516 0xcc04, 0x401c,
517 0xcc05, 0x401e,
518 0xcc06, 0x2ff4,
519 0xcc07, 0x3cd4,
520 0xcc08, 0x2035,
521 0xcc09, 0x3145,
522 0xcc0a, 0x6524,
523 0xcc0b, 0x26a2,
524 0xcc0c, 0x3012,
525 0xcc0d, 0x1002,
526 0xcc0e, 0x29c2,
527 0xcc0f, 0x3002,
528 0xcc10, 0x1002,
529 0xcc11, 0x2072,
530 0xcc12, 0x3012,
531 0xcc13, 0x1002,
532 0xcc14, 0x22cd,
533 0xcc15, 0x301d,
534 0xcc16, 0x2e52,
535 0xcc17, 0x3012,
536 0xcc18, 0x1002,
537 0xcc19, 0x28e2,
538 0xcc1a, 0x3002,
539 0xcc1b, 0x1002,
540 0xcc1c, 0x628f,
541 0xcc1d, 0x2ac2,
542 0xcc1e, 0x3012,
543 0xcc1f, 0x1002,
544 0xcc20, 0x5553,
545 0xcc21, 0x2ae2,
546 0xcc22, 0x3002,
547 0xcc23, 0x1302,
548 0xcc24, 0x401e,
549 0xcc25, 0x2be2,
550 0xcc26, 0x3012,
551 0xcc27, 0x1002,
552 0xcc28, 0x2da2,
553 0xcc29, 0x3012,
554 0xcc2a, 0x1002,
555 0xcc2b, 0x2ba2,
556 0xcc2c, 0x3002,
557 0xcc2d, 0x1002,
558 0xcc2e, 0x5ee3,
559 0xcc2f, 0x305,
560 0xcc30, 0x400e,
561 0xcc31, 0x2bc2,
562 0xcc32, 0x3002,
563 0xcc33, 0x1002,
564 0xcc34, 0x2b82,
565 0xcc35, 0x3012,
566 0xcc36, 0x1002,
567 0xcc37, 0x5663,
568 0xcc38, 0x302,
569 0xcc39, 0x401e,
570 0xcc3a, 0x6f72,
571 0xcc3b, 0x1002,
572 0xcc3c, 0x628f,
573 0xcc3d, 0x2be2,
574 0xcc3e, 0x3012,
575 0xcc3f, 0x1002,
576 0xcc40, 0x22cd,
577 0xcc41, 0x301d,
578 0xcc42, 0x2e52,
579 0xcc43, 0x3012,
580 0xcc44, 0x1002,
581 0xcc45, 0x2522,
582 0xcc46, 0x3012,
583 0xcc47, 0x1002,
584 0xcc48, 0x2da2,
585 0xcc49, 0x3012,
586 0xcc4a, 0x1002,
587 0xcc4b, 0x2ca2,
588 0xcc4c, 0x3012,
589 0xcc4d, 0x1002,
590 0xcc4e, 0x2fa4,
591 0xcc4f, 0x3cd4,
592 0xcc50, 0x6624,
593 0xcc51, 0x410b,
594 0xcc52, 0x56b3,
595 0xcc53, 0x3c4,
596 0xcc54, 0x2fb2,
597 0xcc55, 0x3002,
598 0xcc56, 0x1002,
599 0xcc57, 0x220b,
600 0xcc58, 0x303b,
601 0xcc59, 0x56b3,
602 0xcc5a, 0x3c3,
603 0xcc5b, 0x866b,
604 0xcc5c, 0x400c,
605 0xcc5d, 0x23a2,
606 0xcc5e, 0x3012,
607 0xcc5f, 0x1002,
608 0xcc60, 0x2da2,
609 0xcc61, 0x3012,
610 0xcc62, 0x1002,
611 0xcc63, 0x2ca2,
612 0xcc64, 0x3012,
613 0xcc65, 0x1002,
614 0xcc66, 0x2fb4,
615 0xcc67, 0x3cd4,
616 0xcc68, 0x6624,
617 0xcc69, 0x56b3,
618 0xcc6a, 0x3c3,
619 0xcc6b, 0x866b,
620 0xcc6c, 0x401c,
621 0xcc6d, 0x2205,
622 0xcc6e, 0x3035,
623 0xcc6f, 0x5b53,
624 0xcc70, 0x2c52,
625 0xcc71, 0x3002,
626 0xcc72, 0x13c2,
627 0xcc73, 0x5cc3,
628 0xcc74, 0x317,
629 0xcc75, 0x2522,
630 0xcc76, 0x3012,
631 0xcc77, 0x1002,
632 0xcc78, 0x2da2,
633 0xcc79, 0x3012,
634 0xcc7a, 0x1002,
635 0xcc7b, 0x2b82,
636 0xcc7c, 0x3012,
637 0xcc7d, 0x1002,
638 0xcc7e, 0x5663,
639 0xcc7f, 0x303,
640 0xcc80, 0x401e,
641 0xcc81, 0x004,
642 0xcc82, 0x2c42,
643 0xcc83, 0x3012,
644 0xcc84, 0x1002,
645 0xcc85, 0x6f72,
646 0xcc86, 0x1002,
647 0xcc87, 0x628f,
648 0xcc88, 0x2304,
649 0xcc89, 0x3c84,
650 0xcc8a, 0x6436,
651 0xcc8b, 0xdff4,
652 0xcc8c, 0x6436,
653 0xcc8d, 0x2ff5,
654 0xcc8e, 0x3005,
655 0xcc8f, 0x8656,
656 0xcc90, 0xdfba,
657 0xcc91, 0x56a3,
658 0xcc92, 0xd05a,
659 0xcc93, 0x21c2,
660 0xcc94, 0x3012,
661 0xcc95, 0x1392,
662 0xcc96, 0xd05a,
663 0xcc97, 0x56a3,
664 0xcc98, 0xdfba,
665 0xcc99, 0x383,
666 0xcc9a, 0x6f72,
667 0xcc9b, 0x1002,
668 0xcc9c, 0x28c5,
669 0xcc9d, 0x3005,
670 0xcc9e, 0x4178,
671 0xcc9f, 0x5653,
672 0xcca0, 0x384,
673 0xcca1, 0x22b2,
674 0xcca2, 0x3012,
675 0xcca3, 0x1002,
676 0xcca4, 0x2be5,
677 0xcca5, 0x3005,
678 0xcca6, 0x41e8,
679 0xcca7, 0x5653,
680 0xcca8, 0x382,
681 0xcca9, 0x002,
682 0xccaa, 0x4258,
683 0xccab, 0x2474,
684 0xccac, 0x3c84,
685 0xccad, 0x6437,
686 0xccae, 0xdff4,
687 0xccaf, 0x6437,
688 0xccb0, 0x2ff5,
689 0xccb1, 0x3c05,
690 0xccb2, 0x8757,
691 0xccb3, 0xb888,
692 0xccb4, 0x9787,
693 0xccb5, 0xdff4,
694 0xccb6, 0x6724,
695 0xccb7, 0x866a,
696 0xccb8, 0x6f72,
697 0xccb9, 0x1002,
698 0xccba, 0x2d01,
699 0xccbb, 0x3011,
700 0xccbc, 0x1001,
701 0xccbd, 0xc620,
702 0xccbe, 0x14e5,
703 0xccbf, 0xc621,
704 0xccc0, 0xc53d,
705 0xccc1, 0xc622,
706 0xccc2, 0x3cbe,
707 0xccc3, 0xc623,
708 0xccc4, 0x4452,
709 0xccc5, 0xc624,
710 0xccc6, 0xc5c5,
711 0xccc7, 0xc625,
712 0xccc8, 0xe01e,
713 0xccc9, 0xc627,
714 0xccca, 0x000,
715 0xcccb, 0xc628,
716 0xcccc, 0x000,
717 0xcccd, 0xc62b,
718 0xccce, 0x000,
719 0xcccf, 0xc62c,
720 0xccd0, 0x000,
721 0xccd1, 0x000,
722 0xccd2, 0x2d01,
723 0xccd3, 0x3011,
724 0xccd4, 0x1001,
725 0xccd5, 0xc620,
726 0xccd6, 0x000,
727 0xccd7, 0xc621,
728 0xccd8, 0x000,
729 0xccd9, 0xc622,
730 0xccda, 0x0ce,
731 0xccdb, 0xc623,
732 0xccdc, 0x07f,
733 0xccdd, 0xc624,
734 0xccde, 0x032,
735 0xccdf, 0xc625,
736 0xcce0, 0x000,
737 0xcce1, 0xc627,
738 0xcce2, 0x000,
739 0xcce3, 0xc628,
740 0xcce4, 0x000,
741 0xcce5, 0xc62b,
742 0xcce6, 0x000,
743 0xcce7, 0xc62c,
744 0xcce8, 0x000,
745 0xcce9, 0x000,
746 0xccea, 0x2d01,
747 0xcceb, 0x3011,
748 0xccec, 0x1001,
749 0xcced, 0xc502,
750 0xccee, 0x609f,
751 0xccef, 0xc600,
752 0xccf0, 0x2a6e,
753 0xccf1, 0xc601,
754 0xccf2, 0x2a2c,
755 0xccf3, 0xc60c,
756 0xccf4, 0x5400,
757 0xccf5, 0xc710,
758 0xccf6, 0x700,
759 0xccf7, 0xc718,
760 0xccf8, 0x700,
761 0xccf9, 0xc720,
762 0xccfa, 0x4700,
763 0xccfb, 0xc728,
764 0xccfc, 0x700,
765 0xccfd, 0xc729,
766 0xccfe, 0x1207,
767 0xccff, 0xc801,
768 0xcd00, 0x7f50,
769 0xcd01, 0xc802,
770 0xcd02, 0x7760,
771 0xcd03, 0xc803,
772 0xcd04, 0x7fce,
773 0xcd05, 0xc804,
774 0xcd06, 0x520e,
775 0xcd07, 0xc805,
776 0xcd08, 0x5c11,
777 0xcd09, 0xc806,
778 0xcd0a, 0x3c51,
779 0xcd0b, 0xc807,
780 0xcd0c, 0x4061,
781 0xcd0d, 0xc808,
782 0xcd0e, 0x49c1,
783 0xcd0f, 0xc809,
784 0xcd10, 0x3840,
785 0xcd11, 0xc80a,
786 0xcd12, 0x000,
787 0xcd13, 0xc821,
788 0xcd14, 0x002,
789 0xcd15, 0xc822,
790 0xcd16, 0x046,
791 0xcd17, 0xc844,
792 0xcd18, 0x182f,
793 0xcd19, 0xc013,
794 0xcd1a, 0xf341,
795 0xcd1b, 0xc01a,
796 0xcd1c, 0x446,
797 0xcd1d, 0xc024,
798 0xcd1e, 0x1000,
799 0xcd1f, 0xc025,
800 0xcd20, 0xa00,
801 0xcd21, 0xc026,
802 0xcd22, 0xc0c,
803 0xcd23, 0xc027,
804 0xcd24, 0xc0c,
805 0xcd25, 0xc029,
806 0xcd26, 0x0a0,
807 0xcd27, 0xc030,
808 0xcd28, 0xa00,
809 0xcd29, 0xc03c,
810 0xcd2a, 0x01c,
811 0xcd2b, 0x000,
812 0xcd2c, 0x2b84,
813 0xcd2d, 0x3c74,
814 0xcd2e, 0x6435,
815 0xcd2f, 0xdff4,
816 0xcd30, 0x6435,
817 0xcd31, 0x2806,
818 0xcd32, 0x3006,
819 0xcd33, 0x8565,
820 0xcd34, 0x2b24,
821 0xcd35, 0x3c24,
822 0xcd36, 0x6436,
823 0xcd37, 0x1002,
824 0xcd38, 0x2b24,
825 0xcd39, 0x3c24,
826 0xcd3a, 0x6436,
827 0xcd3b, 0x4045,
828 0xcd3c, 0x8656,
829 0xcd3d, 0x1002,
830 0xcd3e, 0x2807,
831 0xcd3f, 0x31a7,
832 0xcd40, 0x20c4,
833 0xcd41, 0x3c24,
834 0xcd42, 0x6724,
835 0xcd43, 0x1002,
836 0xcd44, 0x2807,
837 0xcd45, 0x3187,
838 0xcd46, 0x20c4,
839 0xcd47, 0x3c24,
840 0xcd48, 0x6724,
841 0xcd49, 0x1002,
842 0xcd4a, 0x2514,
843 0xcd4b, 0x3c64,
844 0xcd4c, 0x6436,
845 0xcd4d, 0xdff4,
846 0xcd4e, 0x6436,
847 0xcd4f, 0x1002,
848 0xcd50, 0x2806,
849 0xcd51, 0x3cb6,
850 0xcd52, 0xc161,
851 0xcd53, 0x6134,
852 0xcd54, 0x6135,
853 0xcd55, 0x5443,
854 0xcd56, 0x303,
855 0xcd57, 0x6524,
856 0xcd58, 0x00b,
857 0xcd59, 0x1002,
858 0xcd5a, 0xd019,
859 0xcd5b, 0x2104,
860 0xcd5c, 0x3c24,
861 0xcd5d, 0x2105,
862 0xcd5e, 0x3805,
863 0xcd5f, 0x6524,
864 0xcd60, 0xdff4,
865 0xcd61, 0x4005,
866 0xcd62, 0x6524,
867 0xcd63, 0x2e8d,
868 0xcd64, 0x303d,
869 0xcd65, 0x5dd3,
870 0xcd66, 0x306,
871 0xcd67, 0x2ff7,
872 0xcd68, 0x38f7,
873 0xcd69, 0x60b7,
874 0xcd6a, 0xdffd,
875 0xcd6b, 0x00a,
876 0xcd6c, 0x1002,
877 0xcd6d, 0
879 int i, err;
881 err = set_phy_regs(phy, regs);
882 if (!err && modtype == phy_modtype_twinax_long)
883 err = set_phy_regs(phy, preemphasis);
884 if (err)
885 return err;
887 msleep(50);
889 for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2)
890 err = mdio_write(phy, MDIO_DEV_PMA_PMD, twinax_edc[i],
891 twinax_edc[i + 1]);
892 if (!err)
893 phy->priv = edc_twinax;
894 return err;
897 static int ael2005_i2c_rd(struct cphy *phy, int dev_addr, int word_addr)
899 int i, err;
900 unsigned int stat, data;
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;
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;
920 CH_WARN(phy->adapter, "PHY %u I2C read of addr %u timed out\n",
921 phy->addr, word_addr);
922 return -ETIMEDOUT;
925 static int get_module_type(struct cphy *phy, int delay_ms)
927 int v;
928 unsigned int stat;
930 v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, &stat);
931 if (v)
932 return v;
934 if (stat & (1 << 8)) /* module absent */
935 return phy_modtype_none;
937 if (delay_ms)
938 msleep(delay_ms);
940 /* see SFF-8472 for below */
941 v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 3);
942 if (v < 0)
943 return v;
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;
952 v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 6);
953 if (v < 0)
954 return v;
955 if (v != 4)
956 goto unknown;
958 v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 10);
959 if (v < 0)
960 return v;
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;
968 unknown:
969 return phy_modtype_unknown;
972 static int ael2005_intr_enable(struct cphy *phy)
974 int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x200);
975 return err ? err : t3_phy_lasi_intr_enable(phy);
978 static int ael2005_intr_disable(struct cphy *phy)
980 int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x100);
981 return err ? err : t3_phy_lasi_intr_disable(phy);
984 static int ael2005_intr_clear(struct cphy *phy)
986 int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0xd00);
987 return err ? err : t3_phy_lasi_intr_clear(phy);
990 static int ael2005_reset(struct cphy *phy, int wait)
992 static struct reg_val regs0[] = {
993 { MDIO_DEV_PMA_PMD, 0xc001, 0, 1 << 5 },
994 { MDIO_DEV_PMA_PMD, 0xc017, 0, 1 << 5 },
995 { MDIO_DEV_PMA_PMD, 0xc013, 0xffff, 0xf341 },
996 { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 },
997 { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8100 },
998 { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 },
999 { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0 },
1000 { 0, 0, 0, 0 }
1002 static struct reg_val regs1[] = {
1003 { MDIO_DEV_PMA_PMD, 0xca00, 0xffff, 0x0080 },
1004 { MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0 },
1005 { 0, 0, 0, 0 }
1008 int err;
1009 unsigned int lasi_ctrl;
1011 err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl);
1012 if (err)
1013 return err;
1015 err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 0);
1016 if (err)
1017 return err;
1019 msleep(125);
1020 phy->priv = edc_none;
1021 err = set_phy_regs(phy, regs0);
1022 if (err)
1023 return err;
1025 msleep(50);
1027 err = get_module_type(phy, 0);
1028 if (err < 0)
1029 return err;
1030 phy->modtype = err;
1032 if (err == phy_modtype_twinax || err == phy_modtype_twinax_long)
1033 err = ael2005_setup_twinax_edc(phy, err);
1034 else
1035 err = ael2005_setup_sr_edc(phy);
1036 if (err)
1037 return err;
1039 err = set_phy_regs(phy, regs1);
1040 if (err)
1041 return err;
1043 /* reset wipes out interrupts, reenable them if they were on */
1044 if (lasi_ctrl & 1)
1045 err = ael2005_intr_enable(phy);
1046 return err;
1049 static int ael2005_intr_handler(struct cphy *phy)
1051 unsigned int stat;
1052 int ret, edc_needed, cause = 0;
1054 ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_STAT, &stat);
1055 if (ret)
1056 return ret;
1058 if (stat & AEL2005_MODDET_IRQ) {
1059 ret = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL,
1060 0xd00);
1061 if (ret)
1062 return ret;
1064 /* modules have max 300 ms init time after hot plug */
1065 ret = get_module_type(phy, 300);
1066 if (ret < 0)
1067 return ret;
1069 phy->modtype = ret;
1070 if (ret == phy_modtype_none)
1071 edc_needed = phy->priv; /* on unplug retain EDC */
1072 else if (ret == phy_modtype_twinax ||
1073 ret == phy_modtype_twinax_long)
1074 edc_needed = edc_twinax;
1075 else
1076 edc_needed = edc_sr;
1078 if (edc_needed != phy->priv) {
1079 ret = ael2005_reset(phy, 0);
1080 return ret ? ret : cphy_cause_module_change;
1082 cause = cphy_cause_module_change;
1085 ret = t3_phy_lasi_intr_handler(phy);
1086 if (ret < 0)
1087 return ret;
1089 ret |= cause;
1090 return ret ? ret : cphy_cause_link_change;
1093 static struct cphy_ops ael2005_ops = {
1094 .reset = ael2005_reset,
1095 .intr_enable = ael2005_intr_enable,
1096 .intr_disable = ael2005_intr_disable,
1097 .intr_clear = ael2005_intr_clear,
1098 .intr_handler = ael2005_intr_handler,
1099 .get_link_status = get_link_status_r,
1100 .power_down = ael1002_power_down,
1103 int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter,
1104 int phy_addr, const struct mdio_ops *mdio_ops)
1106 cphy_init(phy, adapter, phy_addr, &ael2005_ops, mdio_ops,
1107 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE |
1108 SUPPORTED_IRQ, "10GBASE-R");
1109 msleep(125);
1110 return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL_OPT_SETTINGS, 0,
1111 1 << 5);
1115 * Get link status for a 10GBASE-X device.
1117 static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed,
1118 int *duplex, int *fc)
1120 if (link_ok) {
1121 unsigned int stat0, stat1, stat2;
1122 int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0);
1124 if (!err)
1125 err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_X, &stat1);
1126 if (!err)
1127 err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2);
1128 if (err)
1129 return err;
1130 *link_ok = (stat0 & (stat1 >> 12) & (stat2 >> 12)) & 1;
1132 if (speed)
1133 *speed = SPEED_10000;
1134 if (duplex)
1135 *duplex = DUPLEX_FULL;
1136 return 0;
1139 static struct cphy_ops qt2045_ops = {
1140 .reset = ael1006_reset,
1141 .intr_enable = t3_phy_lasi_intr_enable,
1142 .intr_disable = t3_phy_lasi_intr_disable,
1143 .intr_clear = t3_phy_lasi_intr_clear,
1144 .intr_handler = t3_phy_lasi_intr_handler,
1145 .get_link_status = get_link_status_x,
1146 .power_down = ael1006_power_down,
1149 int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter,
1150 int phy_addr, const struct mdio_ops *mdio_ops)
1152 unsigned int stat;
1154 cphy_init(phy, adapter, phy_addr, &qt2045_ops, mdio_ops,
1155 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
1156 "10GBASE-CX4");
1159 * Some cards where the PHY is supposed to be at address 0 actually
1160 * have it at 1.
1162 if (!phy_addr && !mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &stat) &&
1163 stat == 0xffff)
1164 phy->addr = 1;
1165 return 0;
1168 static int xaui_direct_reset(struct cphy *phy, int wait)
1170 return 0;
1173 static int xaui_direct_get_link_status(struct cphy *phy, int *link_ok,
1174 int *speed, int *duplex, int *fc)
1176 if (link_ok) {
1177 unsigned int status;
1179 status = t3_read_reg(phy->adapter,
1180 XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) |
1181 t3_read_reg(phy->adapter,
1182 XGM_REG(A_XGM_SERDES_STAT1, phy->addr)) |
1183 t3_read_reg(phy->adapter,
1184 XGM_REG(A_XGM_SERDES_STAT2, phy->addr)) |
1185 t3_read_reg(phy->adapter,
1186 XGM_REG(A_XGM_SERDES_STAT3, phy->addr));
1187 *link_ok = !(status & F_LOWSIG0);
1189 if (speed)
1190 *speed = SPEED_10000;
1191 if (duplex)
1192 *duplex = DUPLEX_FULL;
1193 return 0;
1196 static int xaui_direct_power_down(struct cphy *phy, int enable)
1198 return 0;
1201 static struct cphy_ops xaui_direct_ops = {
1202 .reset = xaui_direct_reset,
1203 .intr_enable = ael1002_intr_noop,
1204 .intr_disable = ael1002_intr_noop,
1205 .intr_clear = ael1002_intr_noop,
1206 .intr_handler = ael1002_intr_noop,
1207 .get_link_status = xaui_direct_get_link_status,
1208 .power_down = xaui_direct_power_down,
1211 int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter,
1212 int phy_addr, const struct mdio_ops *mdio_ops)
1214 cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops,
1215 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
1216 "10GBASE-CX4");
1217 return 0;