xref: /freebsd/sys/dev/cxgb/common/cxgb_ael1002.c (revision ff0ba87247820afbdfdc1b307c803f7923d0e4d3)
1 /**************************************************************************
2 
3 Copyright (c) 2007-2009, Chelsio Inc.
4 All rights reserved.
5 
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8 
9  1. Redistributions of source code must retain the above copyright notice,
10     this list of conditions and the following disclaimer.
11 
12  2. Neither the name of the Chelsio Corporation nor the names of its
13     contributors may be used to endorse or promote products derived from
14     this software without specific prior written permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 POSSIBILITY OF SUCH DAMAGE.
27 
28 ***************************************************************************/
29 
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32 
33 #include <cxgb_include.h>
34 
35 #undef msleep
36 #define msleep t3_os_sleep
37 
38 enum {
39 	PMD_RSD     = 10,   /* PMA/PMD receive signal detect register */
40 	PCS_STAT1_X = 24,   /* 10GBASE-X PCS status 1 register */
41 	PCS_STAT1_R = 32,   /* 10GBASE-R PCS status 1 register */
42 	XS_LN_STAT  = 24    /* XS lane status register */
43 };
44 
45 enum {
46 	AEL100X_TX_DISABLE  = 9,
47 	AEL100X_TX_CONFIG1  = 0xc002,
48 
49 	AEL1002_PWR_DOWN_HI = 0xc011,
50 	AEL1002_PWR_DOWN_LO = 0xc012,
51 	AEL1002_XFI_EQL     = 0xc015,
52 	AEL1002_LB_EN       = 0xc017,
53 
54 	AEL_OPT_SETTINGS    = 0xc017,
55 	AEL_I2C_CTRL        = 0xc30a,
56 	AEL_I2C_DATA        = 0xc30b,
57 	AEL_I2C_STAT        = 0xc30c,
58 
59 	AEL2005_GPIO_CTRL   = 0xc214,
60 	AEL2005_GPIO_STAT   = 0xc215,
61 
62 	AEL2020_GPIO_INTR   = 0xc103,
63 	AEL2020_GPIO_CTRL   = 0xc108,
64 	AEL2020_GPIO_STAT   = 0xc10c,
65 	AEL2020_GPIO_CFG    = 0xc110,
66 
67 	AEL2020_GPIO_SDA    = 0,
68 	AEL2020_GPIO_MODDET = 1,
69 	AEL2020_GPIO_0      = 3,
70 	AEL2020_GPIO_1      = 2,
71 	AEL2020_GPIO_LSTAT  = AEL2020_GPIO_1,
72 };
73 
74 enum { edc_none, edc_sr, edc_twinax };
75 
76 /* PHY module I2C device address */
77 enum {
78 	MODULE_DEV_ADDR	= 0xa0,
79 	SFF_DEV_ADDR	= 0xa2,
80 };
81 
82 /* PHY transceiver type */
83 enum {
84 	phy_transtype_unknown = 0,
85 	phy_transtype_sfp     = 3,
86 	phy_transtype_xfp     = 6,
87 };
88 
89 #define AEL2005_MODDET_IRQ 4
90 
91 struct reg_val {
92 	unsigned short mmd_addr;
93 	unsigned short reg_addr;
94 	unsigned short clear_bits;
95 	unsigned short set_bits;
96 };
97 
98 static int ael2xxx_get_module_type(struct cphy *phy, int delay_ms);
99 
100 static int set_phy_regs(struct cphy *phy, const struct reg_val *rv)
101 {
102 	int err;
103 
104 	for (err = 0; rv->mmd_addr && !err; rv++) {
105 		if (rv->clear_bits == 0xffff)
106 			err = mdio_write(phy, rv->mmd_addr, rv->reg_addr,
107 					 rv->set_bits);
108 		else
109 			err = t3_mdio_change_bits(phy, rv->mmd_addr,
110 						  rv->reg_addr, rv->clear_bits,
111 						  rv->set_bits);
112 	}
113 	return err;
114 }
115 
116 static void ael100x_txon(struct cphy *phy)
117 {
118 	int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL;
119 
120 	msleep(100);
121 	t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 0, tx_on_gpio);
122 	msleep(30);
123 }
124 
125 /*
126  * Read an 8-bit word from a device attached to the PHY's i2c bus.
127  */
128 static int ael_i2c_rd(struct cphy *phy, int dev_addr, int word_addr)
129 {
130 	int i, err;
131 	unsigned int stat, data;
132 
133 	err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL,
134 			 (dev_addr << 8) | (1 << 8) | word_addr);
135 	if (err)
136 		return err;
137 
138 	for (i = 0; i < 200; i++) {
139 		msleep(1);
140 		err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat);
141 		if (err)
142 			return err;
143 		if ((stat & 3) == 1) {
144 			err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA,
145 					&data);
146 			if (err)
147 				return err;
148 			return data >> 8;
149 		}
150 	}
151 	CH_WARN(phy->adapter, "PHY %u i2c read of dev.addr %x.%x timed out\n",
152 		phy->addr, dev_addr, word_addr);
153 	return -ETIMEDOUT;
154 }
155 
156 /*
157  * Write an 8-bit word to a device attached to the PHY's i2c bus.
158  */
159 static int ael_i2c_wr(struct cphy *phy, int dev_addr, int word_addr, int data)
160 {
161 	int i, err;
162 	unsigned int stat;
163 
164 	err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA, data);
165 	if (err)
166 		return err;
167 
168 	err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL,
169 			 (dev_addr << 8) | word_addr);
170 	if (err)
171 		return err;
172 
173 	for (i = 0; i < 200; i++) {
174 		msleep(1);
175 		err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat);
176 		if (err)
177 			return err;
178 		if ((stat & 3) == 1)
179 			return 0;
180 	}
181 	CH_WARN(phy->adapter, "PHY %u i2c Write of dev.addr %x.%x = %#x timed out\n",
182 		phy->addr, dev_addr, word_addr, data);
183 	return -ETIMEDOUT;
184 }
185 
186 static int get_phytrans_type(struct cphy *phy)
187 {
188 	int v;
189 
190 	v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0);
191 	if (v < 0)
192 		return phy_transtype_unknown;
193 
194 	return v;
195 }
196 
197 static int ael_laser_down(struct cphy *phy, int enable)
198 {
199 	int v, dev_addr;
200 
201 	v = get_phytrans_type(phy);
202 	if (v < 0)
203 		return v;
204 
205 	if (v == phy_transtype_sfp) {
206 		/* Check SFF Soft TX disable is supported */
207 		v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 93);
208 		if (v < 0)
209 			return v;
210 
211 		v &= 0x40;
212 		if (!v)
213 			return v;
214 
215 		dev_addr = SFF_DEV_ADDR;
216 	} else if (v == phy_transtype_xfp)
217 		dev_addr = MODULE_DEV_ADDR;
218 	else
219 		return v;
220 
221 	v = ael_i2c_rd(phy, dev_addr, 110);
222 	if (v < 0)
223 		return v;
224 
225 	if (enable)
226 		v |= 0x40;
227 	else
228 		v &= ~0x40;
229 
230 	v = ael_i2c_wr(phy, dev_addr, 110, v);
231 
232 	return v;
233 }
234 
235 static int ael1002_power_down(struct cphy *phy, int enable)
236 {
237 	int err;
238 
239 	err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_DISABLE, !!enable);
240 	if (!err)
241 		err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR,
242 					  BMCR_PDOWN, enable ? BMCR_PDOWN : 0);
243 	return err;
244 }
245 
246 static int ael1002_get_module_type(struct cphy *phy, int delay_ms)
247 {
248 	int v;
249 
250 	if (delay_ms)
251 		msleep(delay_ms);
252 
253 	v = ael2xxx_get_module_type(phy, delay_ms);
254 
255 	return (v == -ETIMEDOUT ? phy_modtype_none : v);
256 }
257 
258 static int ael1002_reset(struct cphy *phy, int wait)
259 {
260 	int err;
261 
262 	if ((err = ael1002_power_down(phy, 0)) ||
263 	    (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_CONFIG1, 1)) ||
264 	    (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_HI, 0)) ||
265 	    (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_LO, 0)) ||
266 	    (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_XFI_EQL, 0x18)) ||
267 	    (err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL1002_LB_EN,
268 				       0, 1 << 5)))
269 		return err;
270 
271 	err = ael1002_get_module_type(phy, 300);
272 	if (err >= 0)
273 		phy->modtype = err;
274 
275 	return 0;
276 }
277 
278 static int ael1002_intr_noop(struct cphy *phy)
279 {
280 	return 0;
281 }
282 
283 /*
284  * Get link status for a 10GBASE-R device.
285  */
286 static int get_link_status_r(struct cphy *phy, int *link_ok, int *speed,
287 			     int *duplex, int *fc)
288 {
289 	if (link_ok) {
290 		unsigned int stat0, stat1, stat2;
291 		int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0);
292 
293 		if (!err)
294 			err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_R, &stat1);
295 		if (!err)
296 			err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2);
297 		if (err)
298 			return err;
299 		*link_ok = (stat0 & stat1 & (stat2 >> 12)) & 1;
300 
301 		if (*link_ok == 0)
302 			return (0);
303 	}
304 	if (speed)
305 		*speed = SPEED_10000;
306 	if (duplex)
307 		*duplex = DUPLEX_FULL;
308 	return 0;
309 }
310 
311 #ifdef C99_NOT_SUPPORTED
312 static struct cphy_ops ael1002_ops = {
313 	ael1002_reset,
314 	ael1002_intr_noop,
315 	ael1002_intr_noop,
316 	ael1002_intr_noop,
317 	ael1002_intr_noop,
318 	NULL,
319 	NULL,
320 	NULL,
321 	NULL,
322 	NULL,
323 	get_link_status_r,
324 	ael1002_power_down,
325 };
326 #else
327 static struct cphy_ops ael1002_ops = {
328 	.reset           = ael1002_reset,
329 	.intr_enable     = ael1002_intr_noop,
330 	.intr_disable    = ael1002_intr_noop,
331 	.intr_clear      = ael1002_intr_noop,
332 	.intr_handler    = ael1002_intr_noop,
333 	.get_link_status = get_link_status_r,
334 	.power_down      = ael1002_power_down,
335 };
336 #endif
337 
338 int t3_ael1002_phy_prep(pinfo_t *pinfo, int phy_addr,
339 			const struct mdio_ops *mdio_ops)
340 {
341 	int err;
342 	struct cphy *phy = &pinfo->phy;
343 
344 	cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &ael1002_ops, mdio_ops,
345 		  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE,
346 		  "10GBASE-R");
347 	ael100x_txon(phy);
348 	ael_laser_down(phy, 0);
349 
350 	err = ael1002_get_module_type(phy, 0);
351 	if (err >= 0)
352 		phy->modtype = err;
353 
354 	return 0;
355 }
356 
357 static int ael1006_reset(struct cphy *phy, int wait)
358 {
359 	int err;
360 
361 	err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait);
362 	if (err)
363 		return err;
364 
365 	t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN,
366 			 F_GPIO6_OUT_VAL, 0);
367 
368 	msleep(125);
369 
370 	t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN,
371 			 F_GPIO6_OUT_VAL, F_GPIO6_OUT_VAL);
372 
373 	msleep(125);
374 
375 	err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait);
376 	if (err)
377 		return err;
378 
379 	msleep(125);
380 
381 	err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, 1, 1);
382 	if (err)
383 		return err;
384 
385 	msleep(125);
386 
387 	err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, 1, 0);
388 
389 	return err;
390 
391 }
392 
393 #ifdef C99_NOT_SUPPORTED
394 static struct cphy_ops ael1006_ops = {
395 	ael1006_reset,
396 	t3_phy_lasi_intr_enable,
397 	t3_phy_lasi_intr_disable,
398 	t3_phy_lasi_intr_clear,
399 	t3_phy_lasi_intr_handler,
400 	NULL,
401 	NULL,
402 	NULL,
403 	NULL,
404 	NULL,
405 	get_link_status_r,
406 	ael1002_power_down,
407 };
408 #else
409 static struct cphy_ops ael1006_ops = {
410 	.reset           = ael1006_reset,
411 	.intr_enable     = t3_phy_lasi_intr_enable,
412 	.intr_disable    = t3_phy_lasi_intr_disable,
413 	.intr_clear      = t3_phy_lasi_intr_clear,
414 	.intr_handler    = t3_phy_lasi_intr_handler,
415 	.get_link_status = get_link_status_r,
416 	.power_down      = ael1002_power_down,
417 };
418 #endif
419 
420 int t3_ael1006_phy_prep(pinfo_t *pinfo, int phy_addr,
421 			const struct mdio_ops *mdio_ops)
422 {
423 	struct cphy *phy = &pinfo->phy;
424 
425 	cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &ael1006_ops, mdio_ops,
426 		  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE,
427 		  "10GBASE-SR");
428 	phy->modtype = phy_modtype_sr;
429 	ael100x_txon(phy);
430 	return 0;
431 }
432 
433 /*
434  * Decode our module type.
435  */
436 static int ael2xxx_get_module_type(struct cphy *phy, int delay_ms)
437 {
438 	int v;
439 
440 	if (delay_ms)
441 		msleep(delay_ms);
442 
443 	v = get_phytrans_type(phy);
444 	if (v == phy_transtype_sfp) {
445 		/* SFP: see SFF-8472 for below */
446 
447 		v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 3);
448 		if (v < 0)
449 			return v;
450 
451 		if (v == 0x1)
452 			goto twinax;
453 		if (v == 0x10)
454 			return phy_modtype_sr;
455 		if (v == 0x20)
456 			return phy_modtype_lr;
457 		if (v == 0x40)
458 			return phy_modtype_lrm;
459 
460 		v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 8);
461 		if (v < 0)
462 			return v;
463 		if (v == 4) {
464 			v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 60);
465 			if (v < 0)
466 				return v;
467 			if (v & 0x1)
468 				goto twinax;
469 		}
470 
471 		v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 6);
472 		if (v < 0)
473 			return v;
474 		if (v != 4)
475 			return phy_modtype_unknown;
476 
477 		v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 10);
478 		if (v < 0)
479 			return v;
480 
481 		if (v & 0x80) {
482 twinax:
483 			v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0x12);
484 			if (v < 0)
485 				return v;
486 			return v > 10 ? phy_modtype_twinax_long :
487 			    phy_modtype_twinax;
488 		}
489 	} else if (v == phy_transtype_xfp) {
490 		/* XFP: See INF-8077i for details. */
491 
492 		v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 127);
493 		if (v < 0)
494 			return v;
495 
496 		if (v != 1) {
497 			/* XXX: set page select to table 1 yourself */
498 			return phy_modtype_unknown;
499 		}
500 
501 		v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 131);
502 		if (v < 0)
503 			return v;
504 		v &= 0xf0;
505 		if (v == 0x10)
506 			return phy_modtype_lrm;
507 		if (v == 0x40)
508 			return phy_modtype_lr;
509 		if (v == 0x80)
510 			return phy_modtype_sr;
511 	}
512 
513 	return phy_modtype_unknown;
514 }
515 
516 /*
517  * Code to support the Aeluros/NetLogic 2005 10Gb PHY.
518  */
519 static int ael2005_setup_sr_edc(struct cphy *phy)
520 {
521 	static struct reg_val regs[] = {
522 		{ MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x181 },
523 		{ MDIO_DEV_PMA_PMD, 0xc010, 0xffff, 0x448a },
524 		{ MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5200 },
525 		{ 0, 0, 0, 0 }
526 	};
527 	static u16 sr_edc[] = {
528 		0xcc00, 0x2ff4,
529 		0xcc01, 0x3cd4,
530 		0xcc02, 0x2015,
531 		0xcc03, 0x3105,
532 		0xcc04, 0x6524,
533 		0xcc05, 0x27ff,
534 		0xcc06, 0x300f,
535 		0xcc07, 0x2c8b,
536 		0xcc08, 0x300b,
537 		0xcc09, 0x4009,
538 		0xcc0a, 0x400e,
539 		0xcc0b, 0x2f72,
540 		0xcc0c, 0x3002,
541 		0xcc0d, 0x1002,
542 		0xcc0e, 0x2172,
543 		0xcc0f, 0x3012,
544 		0xcc10, 0x1002,
545 		0xcc11, 0x25d2,
546 		0xcc12, 0x3012,
547 		0xcc13, 0x1002,
548 		0xcc14, 0xd01e,
549 		0xcc15, 0x27d2,
550 		0xcc16, 0x3012,
551 		0xcc17, 0x1002,
552 		0xcc18, 0x2004,
553 		0xcc19, 0x3c84,
554 		0xcc1a, 0x6436,
555 		0xcc1b, 0x2007,
556 		0xcc1c, 0x3f87,
557 		0xcc1d, 0x8676,
558 		0xcc1e, 0x40b7,
559 		0xcc1f, 0xa746,
560 		0xcc20, 0x4047,
561 		0xcc21, 0x5673,
562 		0xcc22, 0x2982,
563 		0xcc23, 0x3002,
564 		0xcc24, 0x13d2,
565 		0xcc25, 0x8bbd,
566 		0xcc26, 0x2862,
567 		0xcc27, 0x3012,
568 		0xcc28, 0x1002,
569 		0xcc29, 0x2092,
570 		0xcc2a, 0x3012,
571 		0xcc2b, 0x1002,
572 		0xcc2c, 0x5cc3,
573 		0xcc2d, 0x314,
574 		0xcc2e, 0x2942,
575 		0xcc2f, 0x3002,
576 		0xcc30, 0x1002,
577 		0xcc31, 0xd019,
578 		0xcc32, 0x2032,
579 		0xcc33, 0x3012,
580 		0xcc34, 0x1002,
581 		0xcc35, 0x2a04,
582 		0xcc36, 0x3c74,
583 		0xcc37, 0x6435,
584 		0xcc38, 0x2fa4,
585 		0xcc39, 0x3cd4,
586 		0xcc3a, 0x6624,
587 		0xcc3b, 0x5563,
588 		0xcc3c, 0x2d42,
589 		0xcc3d, 0x3002,
590 		0xcc3e, 0x13d2,
591 		0xcc3f, 0x464d,
592 		0xcc40, 0x2862,
593 		0xcc41, 0x3012,
594 		0xcc42, 0x1002,
595 		0xcc43, 0x2032,
596 		0xcc44, 0x3012,
597 		0xcc45, 0x1002,
598 		0xcc46, 0x2fb4,
599 		0xcc47, 0x3cd4,
600 		0xcc48, 0x6624,
601 		0xcc49, 0x5563,
602 		0xcc4a, 0x2d42,
603 		0xcc4b, 0x3002,
604 		0xcc4c, 0x13d2,
605 		0xcc4d, 0x2ed2,
606 		0xcc4e, 0x3002,
607 		0xcc4f, 0x1002,
608 		0xcc50, 0x2fd2,
609 		0xcc51, 0x3002,
610 		0xcc52, 0x1002,
611 		0xcc53, 0x004,
612 		0xcc54, 0x2942,
613 		0xcc55, 0x3002,
614 		0xcc56, 0x1002,
615 		0xcc57, 0x2092,
616 		0xcc58, 0x3012,
617 		0xcc59, 0x1002,
618 		0xcc5a, 0x5cc3,
619 		0xcc5b, 0x317,
620 		0xcc5c, 0x2f72,
621 		0xcc5d, 0x3002,
622 		0xcc5e, 0x1002,
623 		0xcc5f, 0x2942,
624 		0xcc60, 0x3002,
625 		0xcc61, 0x1002,
626 		0xcc62, 0x22cd,
627 		0xcc63, 0x301d,
628 		0xcc64, 0x2862,
629 		0xcc65, 0x3012,
630 		0xcc66, 0x1002,
631 		0xcc67, 0x2ed2,
632 		0xcc68, 0x3002,
633 		0xcc69, 0x1002,
634 		0xcc6a, 0x2d72,
635 		0xcc6b, 0x3002,
636 		0xcc6c, 0x1002,
637 		0xcc6d, 0x628f,
638 		0xcc6e, 0x2112,
639 		0xcc6f, 0x3012,
640 		0xcc70, 0x1002,
641 		0xcc71, 0x5aa3,
642 		0xcc72, 0x2dc2,
643 		0xcc73, 0x3002,
644 		0xcc74, 0x1312,
645 		0xcc75, 0x6f72,
646 		0xcc76, 0x1002,
647 		0xcc77, 0x2807,
648 		0xcc78, 0x31a7,
649 		0xcc79, 0x20c4,
650 		0xcc7a, 0x3c24,
651 		0xcc7b, 0x6724,
652 		0xcc7c, 0x1002,
653 		0xcc7d, 0x2807,
654 		0xcc7e, 0x3187,
655 		0xcc7f, 0x20c4,
656 		0xcc80, 0x3c24,
657 		0xcc81, 0x6724,
658 		0xcc82, 0x1002,
659 		0xcc83, 0x2514,
660 		0xcc84, 0x3c64,
661 		0xcc85, 0x6436,
662 		0xcc86, 0xdff4,
663 		0xcc87, 0x6436,
664 		0xcc88, 0x1002,
665 		0xcc89, 0x40a4,
666 		0xcc8a, 0x643c,
667 		0xcc8b, 0x4016,
668 		0xcc8c, 0x8c6c,
669 		0xcc8d, 0x2b24,
670 		0xcc8e, 0x3c24,
671 		0xcc8f, 0x6435,
672 		0xcc90, 0x1002,
673 		0xcc91, 0x2b24,
674 		0xcc92, 0x3c24,
675 		0xcc93, 0x643a,
676 		0xcc94, 0x4025,
677 		0xcc95, 0x8a5a,
678 		0xcc96, 0x1002,
679 		0xcc97, 0x2731,
680 		0xcc98, 0x3011,
681 		0xcc99, 0x1001,
682 		0xcc9a, 0xc7a0,
683 		0xcc9b, 0x100,
684 		0xcc9c, 0xc502,
685 		0xcc9d, 0x53ac,
686 		0xcc9e, 0xc503,
687 		0xcc9f, 0xd5d5,
688 		0xcca0, 0xc600,
689 		0xcca1, 0x2a6d,
690 		0xcca2, 0xc601,
691 		0xcca3, 0x2a4c,
692 		0xcca4, 0xc602,
693 		0xcca5, 0x111,
694 		0xcca6, 0xc60c,
695 		0xcca7, 0x5900,
696 		0xcca8, 0xc710,
697 		0xcca9, 0x700,
698 		0xccaa, 0xc718,
699 		0xccab, 0x700,
700 		0xccac, 0xc720,
701 		0xccad, 0x4700,
702 		0xccae, 0xc801,
703 		0xccaf, 0x7f50,
704 		0xccb0, 0xc802,
705 		0xccb1, 0x7760,
706 		0xccb2, 0xc803,
707 		0xccb3, 0x7fce,
708 		0xccb4, 0xc804,
709 		0xccb5, 0x5700,
710 		0xccb6, 0xc805,
711 		0xccb7, 0x5f11,
712 		0xccb8, 0xc806,
713 		0xccb9, 0x4751,
714 		0xccba, 0xc807,
715 		0xccbb, 0x57e1,
716 		0xccbc, 0xc808,
717 		0xccbd, 0x2700,
718 		0xccbe, 0xc809,
719 		0xccbf, 0x000,
720 		0xccc0, 0xc821,
721 		0xccc1, 0x002,
722 		0xccc2, 0xc822,
723 		0xccc3, 0x014,
724 		0xccc4, 0xc832,
725 		0xccc5, 0x1186,
726 		0xccc6, 0xc847,
727 		0xccc7, 0x1e02,
728 		0xccc8, 0xc013,
729 		0xccc9, 0xf341,
730 		0xccca, 0xc01a,
731 		0xcccb, 0x446,
732 		0xcccc, 0xc024,
733 		0xcccd, 0x1000,
734 		0xccce, 0xc025,
735 		0xcccf, 0xa00,
736 		0xccd0, 0xc026,
737 		0xccd1, 0xc0c,
738 		0xccd2, 0xc027,
739 		0xccd3, 0xc0c,
740 		0xccd4, 0xc029,
741 		0xccd5, 0x0a0,
742 		0xccd6, 0xc030,
743 		0xccd7, 0xa00,
744 		0xccd8, 0xc03c,
745 		0xccd9, 0x01c,
746 		0xccda, 0xc005,
747 		0xccdb, 0x7a06,
748 		0xccdc, 0x000,
749 		0xccdd, 0x2731,
750 		0xccde, 0x3011,
751 		0xccdf, 0x1001,
752 		0xcce0, 0xc620,
753 		0xcce1, 0x000,
754 		0xcce2, 0xc621,
755 		0xcce3, 0x03f,
756 		0xcce4, 0xc622,
757 		0xcce5, 0x000,
758 		0xcce6, 0xc623,
759 		0xcce7, 0x000,
760 		0xcce8, 0xc624,
761 		0xcce9, 0x000,
762 		0xccea, 0xc625,
763 		0xcceb, 0x000,
764 		0xccec, 0xc627,
765 		0xcced, 0x000,
766 		0xccee, 0xc628,
767 		0xccef, 0x000,
768 		0xccf0, 0xc62c,
769 		0xccf1, 0x000,
770 		0xccf2, 0x000,
771 		0xccf3, 0x2806,
772 		0xccf4, 0x3cb6,
773 		0xccf5, 0xc161,
774 		0xccf6, 0x6134,
775 		0xccf7, 0x6135,
776 		0xccf8, 0x5443,
777 		0xccf9, 0x303,
778 		0xccfa, 0x6524,
779 		0xccfb, 0x00b,
780 		0xccfc, 0x1002,
781 		0xccfd, 0x2104,
782 		0xccfe, 0x3c24,
783 		0xccff, 0x2105,
784 		0xcd00, 0x3805,
785 		0xcd01, 0x6524,
786 		0xcd02, 0xdff4,
787 		0xcd03, 0x4005,
788 		0xcd04, 0x6524,
789 		0xcd05, 0x1002,
790 		0xcd06, 0x5dd3,
791 		0xcd07, 0x306,
792 		0xcd08, 0x2ff7,
793 		0xcd09, 0x38f7,
794 		0xcd0a, 0x60b7,
795 		0xcd0b, 0xdffd,
796 		0xcd0c, 0x00a,
797 		0xcd0d, 0x1002,
798 		0xcd0e, 0
799 	};
800 	int i, err;
801 
802 	err = set_phy_regs(phy, regs);
803 	if (err)
804 		return err;
805 
806 	msleep(50);
807 
808 	for (i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2)
809 		err = mdio_write(phy, MDIO_DEV_PMA_PMD, sr_edc[i],
810 				 sr_edc[i + 1]);
811 	if (!err)
812 		phy->priv = edc_sr;
813 	return err;
814 }
815 
816 static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
817 {
818 	static struct reg_val regs[] = {
819 		{ MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5a00 },
820 		{ 0, 0, 0, 0 }
821 	};
822 	static struct reg_val preemphasis[] = {
823 		{ MDIO_DEV_PMA_PMD, 0xc014, 0xffff, 0xfe16 },
824 		{ MDIO_DEV_PMA_PMD, 0xc015, 0xffff, 0xa000 },
825 		{ 0, 0, 0, 0 }
826 	};
827 	static u16 twinax_edc[] = {
828 		0xcc00, 0x4009,
829 		0xcc01, 0x27ff,
830 		0xcc02, 0x300f,
831 		0xcc03, 0x40aa,
832 		0xcc04, 0x401c,
833 		0xcc05, 0x401e,
834 		0xcc06, 0x2ff4,
835 		0xcc07, 0x3cd4,
836 		0xcc08, 0x2035,
837 		0xcc09, 0x3145,
838 		0xcc0a, 0x6524,
839 		0xcc0b, 0x26a2,
840 		0xcc0c, 0x3012,
841 		0xcc0d, 0x1002,
842 		0xcc0e, 0x29c2,
843 		0xcc0f, 0x3002,
844 		0xcc10, 0x1002,
845 		0xcc11, 0x2072,
846 		0xcc12, 0x3012,
847 		0xcc13, 0x1002,
848 		0xcc14, 0x22cd,
849 		0xcc15, 0x301d,
850 		0xcc16, 0x2e52,
851 		0xcc17, 0x3012,
852 		0xcc18, 0x1002,
853 		0xcc19, 0x28e2,
854 		0xcc1a, 0x3002,
855 		0xcc1b, 0x1002,
856 		0xcc1c, 0x628f,
857 		0xcc1d, 0x2ac2,
858 		0xcc1e, 0x3012,
859 		0xcc1f, 0x1002,
860 		0xcc20, 0x5553,
861 		0xcc21, 0x2ae2,
862 		0xcc22, 0x3002,
863 		0xcc23, 0x1302,
864 		0xcc24, 0x401e,
865 		0xcc25, 0x2be2,
866 		0xcc26, 0x3012,
867 		0xcc27, 0x1002,
868 		0xcc28, 0x2da2,
869 		0xcc29, 0x3012,
870 		0xcc2a, 0x1002,
871 		0xcc2b, 0x2ba2,
872 		0xcc2c, 0x3002,
873 		0xcc2d, 0x1002,
874 		0xcc2e, 0x5ee3,
875 		0xcc2f, 0x305,
876 		0xcc30, 0x400e,
877 		0xcc31, 0x2bc2,
878 		0xcc32, 0x3002,
879 		0xcc33, 0x1002,
880 		0xcc34, 0x2b82,
881 		0xcc35, 0x3012,
882 		0xcc36, 0x1002,
883 		0xcc37, 0x5663,
884 		0xcc38, 0x302,
885 		0xcc39, 0x401e,
886 		0xcc3a, 0x6f72,
887 		0xcc3b, 0x1002,
888 		0xcc3c, 0x628f,
889 		0xcc3d, 0x2be2,
890 		0xcc3e, 0x3012,
891 		0xcc3f, 0x1002,
892 		0xcc40, 0x22cd,
893 		0xcc41, 0x301d,
894 		0xcc42, 0x2e52,
895 		0xcc43, 0x3012,
896 		0xcc44, 0x1002,
897 		0xcc45, 0x2522,
898 		0xcc46, 0x3012,
899 		0xcc47, 0x1002,
900 		0xcc48, 0x2da2,
901 		0xcc49, 0x3012,
902 		0xcc4a, 0x1002,
903 		0xcc4b, 0x2ca2,
904 		0xcc4c, 0x3012,
905 		0xcc4d, 0x1002,
906 		0xcc4e, 0x2fa4,
907 		0xcc4f, 0x3cd4,
908 		0xcc50, 0x6624,
909 		0xcc51, 0x410b,
910 		0xcc52, 0x56b3,
911 		0xcc53, 0x3c4,
912 		0xcc54, 0x2fb2,
913 		0xcc55, 0x3002,
914 		0xcc56, 0x1002,
915 		0xcc57, 0x220b,
916 		0xcc58, 0x303b,
917 		0xcc59, 0x56b3,
918 		0xcc5a, 0x3c3,
919 		0xcc5b, 0x866b,
920 		0xcc5c, 0x400c,
921 		0xcc5d, 0x23a2,
922 		0xcc5e, 0x3012,
923 		0xcc5f, 0x1002,
924 		0xcc60, 0x2da2,
925 		0xcc61, 0x3012,
926 		0xcc62, 0x1002,
927 		0xcc63, 0x2ca2,
928 		0xcc64, 0x3012,
929 		0xcc65, 0x1002,
930 		0xcc66, 0x2fb4,
931 		0xcc67, 0x3cd4,
932 		0xcc68, 0x6624,
933 		0xcc69, 0x56b3,
934 		0xcc6a, 0x3c3,
935 		0xcc6b, 0x866b,
936 		0xcc6c, 0x401c,
937 		0xcc6d, 0x2205,
938 		0xcc6e, 0x3035,
939 		0xcc6f, 0x5b53,
940 		0xcc70, 0x2c52,
941 		0xcc71, 0x3002,
942 		0xcc72, 0x13c2,
943 		0xcc73, 0x5cc3,
944 		0xcc74, 0x317,
945 		0xcc75, 0x2522,
946 		0xcc76, 0x3012,
947 		0xcc77, 0x1002,
948 		0xcc78, 0x2da2,
949 		0xcc79, 0x3012,
950 		0xcc7a, 0x1002,
951 		0xcc7b, 0x2b82,
952 		0xcc7c, 0x3012,
953 		0xcc7d, 0x1002,
954 		0xcc7e, 0x5663,
955 		0xcc7f, 0x303,
956 		0xcc80, 0x401e,
957 		0xcc81, 0x004,
958 		0xcc82, 0x2c42,
959 		0xcc83, 0x3012,
960 		0xcc84, 0x1002,
961 		0xcc85, 0x6f72,
962 		0xcc86, 0x1002,
963 		0xcc87, 0x628f,
964 		0xcc88, 0x2304,
965 		0xcc89, 0x3c84,
966 		0xcc8a, 0x6436,
967 		0xcc8b, 0xdff4,
968 		0xcc8c, 0x6436,
969 		0xcc8d, 0x2ff5,
970 		0xcc8e, 0x3005,
971 		0xcc8f, 0x8656,
972 		0xcc90, 0xdfba,
973 		0xcc91, 0x56a3,
974 		0xcc92, 0xd05a,
975 		0xcc93, 0x21c2,
976 		0xcc94, 0x3012,
977 		0xcc95, 0x1392,
978 		0xcc96, 0xd05a,
979 		0xcc97, 0x56a3,
980 		0xcc98, 0xdfba,
981 		0xcc99, 0x383,
982 		0xcc9a, 0x6f72,
983 		0xcc9b, 0x1002,
984 		0xcc9c, 0x28c5,
985 		0xcc9d, 0x3005,
986 		0xcc9e, 0x4178,
987 		0xcc9f, 0x5653,
988 		0xcca0, 0x384,
989 		0xcca1, 0x22b2,
990 		0xcca2, 0x3012,
991 		0xcca3, 0x1002,
992 		0xcca4, 0x2be5,
993 		0xcca5, 0x3005,
994 		0xcca6, 0x41e8,
995 		0xcca7, 0x5653,
996 		0xcca8, 0x382,
997 		0xcca9, 0x002,
998 		0xccaa, 0x4258,
999 		0xccab, 0x2474,
1000 		0xccac, 0x3c84,
1001 		0xccad, 0x6437,
1002 		0xccae, 0xdff4,
1003 		0xccaf, 0x6437,
1004 		0xccb0, 0x2ff5,
1005 		0xccb1, 0x3c05,
1006 		0xccb2, 0x8757,
1007 		0xccb3, 0xb888,
1008 		0xccb4, 0x9787,
1009 		0xccb5, 0xdff4,
1010 		0xccb6, 0x6724,
1011 		0xccb7, 0x866a,
1012 		0xccb8, 0x6f72,
1013 		0xccb9, 0x1002,
1014 		0xccba, 0x2d01,
1015 		0xccbb, 0x3011,
1016 		0xccbc, 0x1001,
1017 		0xccbd, 0xc620,
1018 		0xccbe, 0x14e5,
1019 		0xccbf, 0xc621,
1020 		0xccc0, 0xc53d,
1021 		0xccc1, 0xc622,
1022 		0xccc2, 0x3cbe,
1023 		0xccc3, 0xc623,
1024 		0xccc4, 0x4452,
1025 		0xccc5, 0xc624,
1026 		0xccc6, 0xc5c5,
1027 		0xccc7, 0xc625,
1028 		0xccc8, 0xe01e,
1029 		0xccc9, 0xc627,
1030 		0xccca, 0x000,
1031 		0xcccb, 0xc628,
1032 		0xcccc, 0x000,
1033 		0xcccd, 0xc62b,
1034 		0xccce, 0x000,
1035 		0xcccf, 0xc62c,
1036 		0xccd0, 0x000,
1037 		0xccd1, 0x000,
1038 		0xccd2, 0x2d01,
1039 		0xccd3, 0x3011,
1040 		0xccd4, 0x1001,
1041 		0xccd5, 0xc620,
1042 		0xccd6, 0x000,
1043 		0xccd7, 0xc621,
1044 		0xccd8, 0x000,
1045 		0xccd9, 0xc622,
1046 		0xccda, 0x0ce,
1047 		0xccdb, 0xc623,
1048 		0xccdc, 0x07f,
1049 		0xccdd, 0xc624,
1050 		0xccde, 0x032,
1051 		0xccdf, 0xc625,
1052 		0xcce0, 0x000,
1053 		0xcce1, 0xc627,
1054 		0xcce2, 0x000,
1055 		0xcce3, 0xc628,
1056 		0xcce4, 0x000,
1057 		0xcce5, 0xc62b,
1058 		0xcce6, 0x000,
1059 		0xcce7, 0xc62c,
1060 		0xcce8, 0x000,
1061 		0xcce9, 0x000,
1062 		0xccea, 0x2d01,
1063 		0xcceb, 0x3011,
1064 		0xccec, 0x1001,
1065 		0xcced, 0xc502,
1066 		0xccee, 0x609f,
1067 		0xccef, 0xc600,
1068 		0xccf0, 0x2a6e,
1069 		0xccf1, 0xc601,
1070 		0xccf2, 0x2a2c,
1071 		0xccf3, 0xc60c,
1072 		0xccf4, 0x5400,
1073 		0xccf5, 0xc710,
1074 		0xccf6, 0x700,
1075 		0xccf7, 0xc718,
1076 		0xccf8, 0x700,
1077 		0xccf9, 0xc720,
1078 		0xccfa, 0x4700,
1079 		0xccfb, 0xc728,
1080 		0xccfc, 0x700,
1081 		0xccfd, 0xc729,
1082 		0xccfe, 0x1207,
1083 		0xccff, 0xc801,
1084 		0xcd00, 0x7f50,
1085 		0xcd01, 0xc802,
1086 		0xcd02, 0x7760,
1087 		0xcd03, 0xc803,
1088 		0xcd04, 0x7fce,
1089 		0xcd05, 0xc804,
1090 		0xcd06, 0x520e,
1091 		0xcd07, 0xc805,
1092 		0xcd08, 0x5c11,
1093 		0xcd09, 0xc806,
1094 		0xcd0a, 0x3c51,
1095 		0xcd0b, 0xc807,
1096 		0xcd0c, 0x4061,
1097 		0xcd0d, 0xc808,
1098 		0xcd0e, 0x49c1,
1099 		0xcd0f, 0xc809,
1100 		0xcd10, 0x3840,
1101 		0xcd11, 0xc80a,
1102 		0xcd12, 0x000,
1103 		0xcd13, 0xc821,
1104 		0xcd14, 0x002,
1105 		0xcd15, 0xc822,
1106 		0xcd16, 0x046,
1107 		0xcd17, 0xc844,
1108 		0xcd18, 0x182f,
1109 		0xcd19, 0xc013,
1110 		0xcd1a, 0xf341,
1111 		0xcd1b, 0xc01a,
1112 		0xcd1c, 0x446,
1113 		0xcd1d, 0xc024,
1114 		0xcd1e, 0x1000,
1115 		0xcd1f, 0xc025,
1116 		0xcd20, 0xa00,
1117 		0xcd21, 0xc026,
1118 		0xcd22, 0xc0c,
1119 		0xcd23, 0xc027,
1120 		0xcd24, 0xc0c,
1121 		0xcd25, 0xc029,
1122 		0xcd26, 0x0a0,
1123 		0xcd27, 0xc030,
1124 		0xcd28, 0xa00,
1125 		0xcd29, 0xc03c,
1126 		0xcd2a, 0x01c,
1127 		0xcd2b, 0x000,
1128 		0xcd2c, 0x2b84,
1129 		0xcd2d, 0x3c74,
1130 		0xcd2e, 0x6435,
1131 		0xcd2f, 0xdff4,
1132 		0xcd30, 0x6435,
1133 		0xcd31, 0x2806,
1134 		0xcd32, 0x3006,
1135 		0xcd33, 0x8565,
1136 		0xcd34, 0x2b24,
1137 		0xcd35, 0x3c24,
1138 		0xcd36, 0x6436,
1139 		0xcd37, 0x1002,
1140 		0xcd38, 0x2b24,
1141 		0xcd39, 0x3c24,
1142 		0xcd3a, 0x6436,
1143 		0xcd3b, 0x4045,
1144 		0xcd3c, 0x8656,
1145 		0xcd3d, 0x1002,
1146 		0xcd3e, 0x2807,
1147 		0xcd3f, 0x31a7,
1148 		0xcd40, 0x20c4,
1149 		0xcd41, 0x3c24,
1150 		0xcd42, 0x6724,
1151 		0xcd43, 0x1002,
1152 		0xcd44, 0x2807,
1153 		0xcd45, 0x3187,
1154 		0xcd46, 0x20c4,
1155 		0xcd47, 0x3c24,
1156 		0xcd48, 0x6724,
1157 		0xcd49, 0x1002,
1158 		0xcd4a, 0x2514,
1159 		0xcd4b, 0x3c64,
1160 		0xcd4c, 0x6436,
1161 		0xcd4d, 0xdff4,
1162 		0xcd4e, 0x6436,
1163 		0xcd4f, 0x1002,
1164 		0xcd50, 0x2806,
1165 		0xcd51, 0x3cb6,
1166 		0xcd52, 0xc161,
1167 		0xcd53, 0x6134,
1168 		0xcd54, 0x6135,
1169 		0xcd55, 0x5443,
1170 		0xcd56, 0x303,
1171 		0xcd57, 0x6524,
1172 		0xcd58, 0x00b,
1173 		0xcd59, 0x1002,
1174 		0xcd5a, 0xd019,
1175 		0xcd5b, 0x2104,
1176 		0xcd5c, 0x3c24,
1177 		0xcd5d, 0x2105,
1178 		0xcd5e, 0x3805,
1179 		0xcd5f, 0x6524,
1180 		0xcd60, 0xdff4,
1181 		0xcd61, 0x4005,
1182 		0xcd62, 0x6524,
1183 		0xcd63, 0x2e8d,
1184 		0xcd64, 0x303d,
1185 		0xcd65, 0x5dd3,
1186 		0xcd66, 0x306,
1187 		0xcd67, 0x2ff7,
1188 		0xcd68, 0x38f7,
1189 		0xcd69, 0x60b7,
1190 		0xcd6a, 0xdffd,
1191 		0xcd6b, 0x00a,
1192 		0xcd6c, 0x1002,
1193 		0xcd6d, 0
1194 	};
1195 	int i, err;
1196 
1197 	err = set_phy_regs(phy, regs);
1198 	if (!err && modtype == phy_modtype_twinax_long)
1199 		err = set_phy_regs(phy, preemphasis);
1200 	if (err)
1201 		return err;
1202 
1203 	msleep(50);
1204 
1205 	for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2)
1206 		err = mdio_write(phy, MDIO_DEV_PMA_PMD, twinax_edc[i],
1207 				 twinax_edc[i + 1]);
1208 	if (!err)
1209 		phy->priv = edc_twinax;
1210 	return err;
1211 }
1212 
1213 static int ael2005_get_module_type(struct cphy *phy, int delay_ms)
1214 {
1215 	int v;
1216 	unsigned int stat;
1217 
1218 	v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, &stat);
1219 	if (v)
1220 		return v;
1221 
1222 	if (stat & (1 << 8))			/* module absent */
1223 		return phy_modtype_none;
1224 
1225 	return ael2xxx_get_module_type(phy, delay_ms);
1226 }
1227 
1228 static int ael2005_intr_enable(struct cphy *phy)
1229 {
1230 	int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x200);
1231 	return err ? err : t3_phy_lasi_intr_enable(phy);
1232 }
1233 
1234 static int ael2005_intr_disable(struct cphy *phy)
1235 {
1236 	int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x100);
1237 	return err ? err : t3_phy_lasi_intr_disable(phy);
1238 }
1239 
1240 static int ael2005_intr_clear(struct cphy *phy)
1241 {
1242 	int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0xd00);
1243 	return err ? err : t3_phy_lasi_intr_clear(phy);
1244 }
1245 
1246 static int ael2005_reset(struct cphy *phy, int wait)
1247 {
1248 	static struct reg_val regs0[] = {
1249 		{ MDIO_DEV_PMA_PMD, 0xc001, 0, 1 << 5 },
1250 		{ MDIO_DEV_PMA_PMD, 0xc017, 0, 1 << 5 },
1251 		{ MDIO_DEV_PMA_PMD, 0xc013, 0xffff, 0xf341 },
1252 		{ MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 },
1253 		{ MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8100 },
1254 		{ MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 },
1255 		{ MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0 },
1256 		{ 0, 0, 0, 0 }
1257 	};
1258 	static struct reg_val regs1[] = {
1259 		{ MDIO_DEV_PMA_PMD, 0xca00, 0xffff, 0x0080 },
1260 		{ MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0 },
1261 		{ 0, 0, 0, 0 }
1262 	};
1263 
1264 	int err;
1265 	unsigned int lasi_ctrl;
1266 
1267 	err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl);
1268 	if (err)
1269 		return err;
1270 
1271 	err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 0);
1272 	if (err)
1273 		return err;
1274 
1275 	msleep(125);
1276 	phy->priv = edc_none;
1277 	err = set_phy_regs(phy, regs0);
1278 	if (err)
1279 		return err;
1280 
1281 	msleep(50);
1282 
1283 	err = ael2005_get_module_type(phy, 0);
1284 	if (err < 0)
1285 		return err;
1286 	phy->modtype = (u8)err;
1287 
1288 	if (err == phy_modtype_none)
1289 		err = 0;
1290 	else if (err == phy_modtype_twinax || err == phy_modtype_twinax_long)
1291 		err = ael2005_setup_twinax_edc(phy, err);
1292 	else
1293 		err = ael2005_setup_sr_edc(phy);
1294 	if (err)
1295 		return err;
1296 
1297 	err = set_phy_regs(phy, regs1);
1298 	if (err)
1299 		return err;
1300 
1301 	/* reset wipes out interrupts, reenable them if they were on */
1302 	if (lasi_ctrl & 1)
1303 		err = ael2005_intr_enable(phy);
1304 	return err;
1305 }
1306 
1307 static int ael2005_intr_handler(struct cphy *phy)
1308 {
1309 	unsigned int stat;
1310 	int ret, edc_needed, cause = 0;
1311 
1312 	ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_STAT, &stat);
1313 	if (ret)
1314 		return ret;
1315 
1316 	if (stat & AEL2005_MODDET_IRQ) {
1317 		ret = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL,
1318 				 0xd00);
1319 		if (ret)
1320 			return ret;
1321 
1322 		/* modules have max 300 ms init time after hot plug */
1323 		ret = ael2005_get_module_type(phy, 300);
1324 		if (ret < 0)
1325 			return ret;
1326 
1327 		phy->modtype = (u8)ret;
1328 		if (ret == phy_modtype_none)
1329 			edc_needed = phy->priv;       /* on unplug retain EDC */
1330 		else if (ret == phy_modtype_twinax ||
1331 			 ret == phy_modtype_twinax_long)
1332 			edc_needed = edc_twinax;
1333 		else
1334 			edc_needed = edc_sr;
1335 
1336 		if (edc_needed != phy->priv) {
1337 			ret = ael2005_reset(phy, 0);
1338 			return ret ? ret : cphy_cause_module_change;
1339 		}
1340 		cause = cphy_cause_module_change;
1341 	}
1342 
1343 	ret = t3_phy_lasi_intr_handler(phy);
1344 	if (ret < 0)
1345 		return ret;
1346 
1347 	ret |= cause;
1348 	if (!ret) {
1349 		(void) ael2005_reset(phy, 0);
1350 		ret |= cphy_cause_link_change;
1351 	}
1352 	return ret;
1353 }
1354 
1355 static struct cphy_ops ael2005_ops = {
1356 #ifdef C99_NOT_SUPPORTED
1357 	ael2005_reset,
1358 	ael2005_intr_enable,
1359 	ael2005_intr_disable,
1360 	ael2005_intr_clear,
1361 	ael2005_intr_handler,
1362 	NULL,
1363 	NULL,
1364 	NULL,
1365 	NULL,
1366 	NULL,
1367 	get_link_status_r,
1368 	ael1002_power_down,
1369 #else
1370 	.reset           = ael2005_reset,
1371 	.intr_enable     = ael2005_intr_enable,
1372 	.intr_disable    = ael2005_intr_disable,
1373 	.intr_clear      = ael2005_intr_clear,
1374 	.intr_handler    = ael2005_intr_handler,
1375 	.get_link_status = get_link_status_r,
1376 	.power_down      = ael1002_power_down,
1377 #endif
1378 };
1379 
1380 int t3_ael2005_phy_prep(pinfo_t *pinfo, int phy_addr,
1381 			const struct mdio_ops *mdio_ops)
1382 {
1383 	int err;
1384 	struct cphy *phy = &pinfo->phy;
1385 
1386 	cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &ael2005_ops, mdio_ops,
1387 		  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE |
1388 		  SUPPORTED_IRQ, "10GBASE-R");
1389 	msleep(125);
1390 	ael_laser_down(phy, 0);
1391 
1392 	err = ael2005_get_module_type(phy, 0);
1393 	if (err >= 0)
1394 		phy->modtype = err;
1395 
1396 	return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL_OPT_SETTINGS, 0,
1397 				   1 << 5);
1398 }
1399 
1400 /*
1401  * Setup EDC and other parameters for operation with an optical module.
1402  */
1403 static int ael2020_setup_sr_edc(struct cphy *phy)
1404 {
1405 	static struct reg_val regs[] = {
1406 		{ MDIO_DEV_PMA_PMD, 0xcc01, 0xffff, 0x488a },
1407 
1408 		{ MDIO_DEV_PMA_PMD, 0xcb1b, 0xffff, 0x0200 },
1409 		{ MDIO_DEV_PMA_PMD, 0xcb1c, 0xffff, 0x00f0 },
1410 		{ MDIO_DEV_PMA_PMD, 0xcc06, 0xffff, 0x00e0 },
1411 
1412 		/* end */
1413 		{ 0, 0, 0, 0 }
1414 	};
1415 	int err;
1416 
1417 	err = set_phy_regs(phy, regs);
1418 	msleep(50);
1419 	if (err)
1420 		return err;
1421 
1422 	phy->priv = edc_sr;
1423 	return 0;
1424 }
1425 
1426 /*
1427  * Setup EDC and other parameters for operation with an TWINAX module.
1428  */
1429 static int ael2020_setup_twinax_edc(struct cphy *phy, int modtype)
1430 {
1431 	static struct reg_val uCclock40MHz[] = {
1432 		{ MDIO_DEV_PMA_PMD, 0xff28, 0xffff, 0x4001 },
1433 		{ MDIO_DEV_PMA_PMD, 0xff2a, 0xffff, 0x0002 },
1434 		{ 0, 0, 0, 0 }
1435 	};
1436 
1437 	static struct reg_val uCclockActivate[] = {
1438 		{ MDIO_DEV_PMA_PMD, 0xd000, 0xffff, 0x5200 },
1439 		{ 0, 0, 0, 0 }
1440 	};
1441 
1442 	static struct reg_val uCactivate[] = {
1443 		{ MDIO_DEV_PMA_PMD, 0xd080, 0xffff, 0x0100 },
1444 		{ MDIO_DEV_PMA_PMD, 0xd092, 0xffff, 0x0000 },
1445 		{ 0, 0, 0, 0 }
1446 	};
1447 
1448 	static u16 twinax_edc[] = {
1449 		0xd800, 0x4009,
1450 		0xd801, 0x2fff,
1451 		0xd802, 0x300f,
1452 		0xd803, 0x40aa,
1453 		0xd804, 0x401c,
1454 		0xd805, 0x401e,
1455 		0xd806, 0x20c5,
1456 		0xd807, 0x3c05,
1457 		0xd808, 0x6536,
1458 		0xd809, 0x2fe4,
1459 		0xd80a, 0x3dc4,
1460 		0xd80b, 0x6624,
1461 		0xd80c, 0x2ff4,
1462 		0xd80d, 0x3dc4,
1463 		0xd80e, 0x2035,
1464 		0xd80f, 0x30a5,
1465 		0xd810, 0x6524,
1466 		0xd811, 0x2ca2,
1467 		0xd812, 0x3012,
1468 		0xd813, 0x1002,
1469 		0xd814, 0x27e2,
1470 		0xd815, 0x3022,
1471 		0xd816, 0x1002,
1472 		0xd817, 0x28d2,
1473 		0xd818, 0x3022,
1474 		0xd819, 0x1002,
1475 		0xd81a, 0x2892,
1476 		0xd81b, 0x3012,
1477 		0xd81c, 0x1002,
1478 		0xd81d, 0x24e2,
1479 		0xd81e, 0x3022,
1480 		0xd81f, 0x1002,
1481 		0xd820, 0x27e2,
1482 		0xd821, 0x3012,
1483 		0xd822, 0x1002,
1484 		0xd823, 0x2422,
1485 		0xd824, 0x3022,
1486 		0xd825, 0x1002,
1487 		0xd826, 0x22cd,
1488 		0xd827, 0x301d,
1489 		0xd828, 0x28f2,
1490 		0xd829, 0x3022,
1491 		0xd82a, 0x1002,
1492 		0xd82b, 0x5553,
1493 		0xd82c, 0x0307,
1494 		0xd82d, 0x2572,
1495 		0xd82e, 0x3022,
1496 		0xd82f, 0x1002,
1497 		0xd830, 0x21a2,
1498 		0xd831, 0x3012,
1499 		0xd832, 0x1002,
1500 		0xd833, 0x4016,
1501 		0xd834, 0x5e63,
1502 		0xd835, 0x0344,
1503 		0xd836, 0x21a2,
1504 		0xd837, 0x3012,
1505 		0xd838, 0x1002,
1506 		0xd839, 0x400e,
1507 		0xd83a, 0x2572,
1508 		0xd83b, 0x3022,
1509 		0xd83c, 0x1002,
1510 		0xd83d, 0x2b22,
1511 		0xd83e, 0x3012,
1512 		0xd83f, 0x1002,
1513 		0xd840, 0x2842,
1514 		0xd841, 0x3022,
1515 		0xd842, 0x1002,
1516 		0xd843, 0x26e2,
1517 		0xd844, 0x3022,
1518 		0xd845, 0x1002,
1519 		0xd846, 0x2fa4,
1520 		0xd847, 0x3dc4,
1521 		0xd848, 0x6624,
1522 		0xd849, 0x2e8b,
1523 		0xd84a, 0x303b,
1524 		0xd84b, 0x56b3,
1525 		0xd84c, 0x03c6,
1526 		0xd84d, 0x866b,
1527 		0xd84e, 0x400c,
1528 		0xd84f, 0x2782,
1529 		0xd850, 0x3012,
1530 		0xd851, 0x1002,
1531 		0xd852, 0x2c4b,
1532 		0xd853, 0x309b,
1533 		0xd854, 0x56b3,
1534 		0xd855, 0x03c3,
1535 		0xd856, 0x866b,
1536 		0xd857, 0x400c,
1537 		0xd858, 0x22a2,
1538 		0xd859, 0x3022,
1539 		0xd85a, 0x1002,
1540 		0xd85b, 0x2842,
1541 		0xd85c, 0x3022,
1542 		0xd85d, 0x1002,
1543 		0xd85e, 0x26e2,
1544 		0xd85f, 0x3022,
1545 		0xd860, 0x1002,
1546 		0xd861, 0x2fb4,
1547 		0xd862, 0x3dc4,
1548 		0xd863, 0x6624,
1549 		0xd864, 0x56b3,
1550 		0xd865, 0x03c3,
1551 		0xd866, 0x866b,
1552 		0xd867, 0x401c,
1553 		0xd868, 0x2c45,
1554 		0xd869, 0x3095,
1555 		0xd86a, 0x5b53,
1556 		0xd86b, 0x23d2,
1557 		0xd86c, 0x3012,
1558 		0xd86d, 0x13c2,
1559 		0xd86e, 0x5cc3,
1560 		0xd86f, 0x2782,
1561 		0xd870, 0x3012,
1562 		0xd871, 0x1312,
1563 		0xd872, 0x2b22,
1564 		0xd873, 0x3012,
1565 		0xd874, 0x1002,
1566 		0xd875, 0x2842,
1567 		0xd876, 0x3022,
1568 		0xd877, 0x1002,
1569 		0xd878, 0x2622,
1570 		0xd879, 0x3022,
1571 		0xd87a, 0x1002,
1572 		0xd87b, 0x21a2,
1573 		0xd87c, 0x3012,
1574 		0xd87d, 0x1002,
1575 		0xd87e, 0x628f,
1576 		0xd87f, 0x2985,
1577 		0xd880, 0x33a5,
1578 		0xd881, 0x26e2,
1579 		0xd882, 0x3022,
1580 		0xd883, 0x1002,
1581 		0xd884, 0x5653,
1582 		0xd885, 0x03d2,
1583 		0xd886, 0x401e,
1584 		0xd887, 0x6f72,
1585 		0xd888, 0x1002,
1586 		0xd889, 0x628f,
1587 		0xd88a, 0x2304,
1588 		0xd88b, 0x3c84,
1589 		0xd88c, 0x6436,
1590 		0xd88d, 0xdff4,
1591 		0xd88e, 0x6436,
1592 		0xd88f, 0x2ff5,
1593 		0xd890, 0x3005,
1594 		0xd891, 0x8656,
1595 		0xd892, 0xdfba,
1596 		0xd893, 0x56a3,
1597 		0xd894, 0xd05a,
1598 		0xd895, 0x29e2,
1599 		0xd896, 0x3012,
1600 		0xd897, 0x1392,
1601 		0xd898, 0xd05a,
1602 		0xd899, 0x56a3,
1603 		0xd89a, 0xdfba,
1604 		0xd89b, 0x0383,
1605 		0xd89c, 0x6f72,
1606 		0xd89d, 0x1002,
1607 		0xd89e, 0x2a64,
1608 		0xd89f, 0x3014,
1609 		0xd8a0, 0x2005,
1610 		0xd8a1, 0x3d75,
1611 		0xd8a2, 0xc451,
1612 		0xd8a3, 0x29a2,
1613 		0xd8a4, 0x3022,
1614 		0xd8a5, 0x1002,
1615 		0xd8a6, 0x178c,
1616 		0xd8a7, 0x1898,
1617 		0xd8a8, 0x19a4,
1618 		0xd8a9, 0x1ab0,
1619 		0xd8aa, 0x1bbc,
1620 		0xd8ab, 0x1cc8,
1621 		0xd8ac, 0x1dd3,
1622 		0xd8ad, 0x1ede,
1623 		0xd8ae, 0x1fe9,
1624 		0xd8af, 0x20f4,
1625 		0xd8b0, 0x21ff,
1626 		0xd8b1, 0x0000,
1627 		0xd8b2, 0x2741,
1628 		0xd8b3, 0x3021,
1629 		0xd8b4, 0x1001,
1630 		0xd8b5, 0xc620,
1631 		0xd8b6, 0x0000,
1632 		0xd8b7, 0xc621,
1633 		0xd8b8, 0x0000,
1634 		0xd8b9, 0xc622,
1635 		0xd8ba, 0x00e2,
1636 		0xd8bb, 0xc623,
1637 		0xd8bc, 0x007f,
1638 		0xd8bd, 0xc624,
1639 		0xd8be, 0x00ce,
1640 		0xd8bf, 0xc625,
1641 		0xd8c0, 0x0000,
1642 		0xd8c1, 0xc627,
1643 		0xd8c2, 0x0000,
1644 		0xd8c3, 0xc628,
1645 		0xd8c4, 0x0000,
1646 		0xd8c5, 0xc90a,
1647 		0xd8c6, 0x3a7c,
1648 		0xd8c7, 0xc62c,
1649 		0xd8c8, 0x0000,
1650 		0xd8c9, 0x0000,
1651 		0xd8ca, 0x2741,
1652 		0xd8cb, 0x3021,
1653 		0xd8cc, 0x1001,
1654 		0xd8cd, 0xc502,
1655 		0xd8ce, 0x53ac,
1656 		0xd8cf, 0xc503,
1657 		0xd8d0, 0x2cd3,
1658 		0xd8d1, 0xc600,
1659 		0xd8d2, 0x2a6e,
1660 		0xd8d3, 0xc601,
1661 		0xd8d4, 0x2a2c,
1662 		0xd8d5, 0xc605,
1663 		0xd8d6, 0x5557,
1664 		0xd8d7, 0xc60c,
1665 		0xd8d8, 0x5400,
1666 		0xd8d9, 0xc710,
1667 		0xd8da, 0x0700,
1668 		0xd8db, 0xc711,
1669 		0xd8dc, 0x0f06,
1670 		0xd8dd, 0xc718,
1671 		0xd8de, 0x700,
1672 		0xd8df, 0xc719,
1673 		0xd8e0, 0x0f06,
1674 		0xd8e1, 0xc720,
1675 		0xd8e2, 0x4700,
1676 		0xd8e3, 0xc721,
1677 		0xd8e4, 0x0f06,
1678 		0xd8e5, 0xc728,
1679 		0xd8e6, 0x0700,
1680 		0xd8e7, 0xc729,
1681 		0xd8e8, 0x1207,
1682 		0xd8e9, 0xc801,
1683 		0xd8ea, 0x7f50,
1684 		0xd8eb, 0xc802,
1685 		0xd8ec, 0x7760,
1686 		0xd8ed, 0xc803,
1687 		0xd8ee, 0x7fce,
1688 		0xd8ef, 0xc804,
1689 		0xd8f0, 0x520e,
1690 		0xd8f1, 0xc805,
1691 		0xd8f2, 0x5c11,
1692 		0xd8f3, 0xc806,
1693 		0xd8f4, 0x3c51,
1694 		0xd8f5, 0xc807,
1695 		0xd8f6, 0x4061,
1696 		0xd8f7, 0xc808,
1697 		0xd8f8, 0x49c1,
1698 		0xd8f9, 0xc809,
1699 		0xd8fa, 0x3840,
1700 		0xd8fb, 0xc80a,
1701 		0xd8fc, 0x0000,
1702 		0xd8fd, 0xc821,
1703 		0xd8fe, 0x0002,
1704 		0xd8ff, 0xc822,
1705 		0xd900, 0x0046,
1706 		0xd901, 0xc844,
1707 		0xd902, 0x182f,
1708 		0xd903, 0xc849,
1709 		0xd904, 0x0400,
1710 		0xd905, 0xc84a,
1711 		0xd906, 0x0002,
1712 		0xd907, 0xc013,
1713 		0xd908, 0xf341,
1714 		0xd909, 0xc084,
1715 		0xd90a, 0x0030,
1716 		0xd90b, 0xc904,
1717 		0xd90c, 0x1401,
1718 		0xd90d, 0xcb0c,
1719 		0xd90e, 0x0004,
1720 		0xd90f, 0xcb0e,
1721 		0xd910, 0xa00a,
1722 		0xd911, 0xcb0f,
1723 		0xd912, 0xc0c0,
1724 		0xd913, 0xcb10,
1725 		0xd914, 0xc0c0,
1726 		0xd915, 0xcb11,
1727 		0xd916, 0x00a0,
1728 		0xd917, 0xcb12,
1729 		0xd918, 0x0007,
1730 		0xd919, 0xc241,
1731 		0xd91a, 0xa000,
1732 		0xd91b, 0xc243,
1733 		0xd91c, 0x7fe0,
1734 		0xd91d, 0xc604,
1735 		0xd91e, 0x000e,
1736 		0xd91f, 0xc609,
1737 		0xd920, 0x00f5,
1738 		0xd921, 0xc611,
1739 		0xd922, 0x000e,
1740 		0xd923, 0xc660,
1741 		0xd924, 0x9600,
1742 		0xd925, 0xc687,
1743 		0xd926, 0x0004,
1744 		0xd927, 0xc60a,
1745 		0xd928, 0x04f5,
1746 		0xd929, 0x0000,
1747 		0xd92a, 0x2741,
1748 		0xd92b, 0x3021,
1749 		0xd92c, 0x1001,
1750 		0xd92d, 0xc620,
1751 		0xd92e, 0x14e5,
1752 		0xd92f, 0xc621,
1753 		0xd930, 0xc53d,
1754 		0xd931, 0xc622,
1755 		0xd932, 0x3cbe,
1756 		0xd933, 0xc623,
1757 		0xd934, 0x4452,
1758 		0xd935, 0xc624,
1759 		0xd936, 0xc5c5,
1760 		0xd937, 0xc625,
1761 		0xd938, 0xe01e,
1762 		0xd939, 0xc627,
1763 		0xd93a, 0x0000,
1764 		0xd93b, 0xc628,
1765 		0xd93c, 0x0000,
1766 		0xd93d, 0xc62c,
1767 		0xd93e, 0x0000,
1768 		0xd93f, 0xc90a,
1769 		0xd940, 0x3a7c,
1770 		0xd941, 0x0000,
1771 		0xd942, 0x2b84,
1772 		0xd943, 0x3c74,
1773 		0xd944, 0x6435,
1774 		0xd945, 0xdff4,
1775 		0xd946, 0x6435,
1776 		0xd947, 0x2806,
1777 		0xd948, 0x3006,
1778 		0xd949, 0x8565,
1779 		0xd94a, 0x2b24,
1780 		0xd94b, 0x3c24,
1781 		0xd94c, 0x6436,
1782 		0xd94d, 0x1002,
1783 		0xd94e, 0x2b24,
1784 		0xd94f, 0x3c24,
1785 		0xd950, 0x6436,
1786 		0xd951, 0x4045,
1787 		0xd952, 0x8656,
1788 		0xd953, 0x5663,
1789 		0xd954, 0x0302,
1790 		0xd955, 0x401e,
1791 		0xd956, 0x1002,
1792 		0xd957, 0x2807,
1793 		0xd958, 0x31a7,
1794 		0xd959, 0x20c4,
1795 		0xd95a, 0x3c24,
1796 		0xd95b, 0x6724,
1797 		0xd95c, 0x2ff7,
1798 		0xd95d, 0x30f7,
1799 		0xd95e, 0x20c4,
1800 		0xd95f, 0x3c04,
1801 		0xd960, 0x6724,
1802 		0xd961, 0x1002,
1803 		0xd962, 0x2807,
1804 		0xd963, 0x3187,
1805 		0xd964, 0x20c4,
1806 		0xd965, 0x3c24,
1807 		0xd966, 0x6724,
1808 		0xd967, 0x2fe4,
1809 		0xd968, 0x3dc4,
1810 		0xd969, 0x6437,
1811 		0xd96a, 0x20c4,
1812 		0xd96b, 0x3c04,
1813 		0xd96c, 0x6724,
1814 		0xd96d, 0x1002,
1815 		0xd96e, 0x24f4,
1816 		0xd96f, 0x3c64,
1817 		0xd970, 0x6436,
1818 		0xd971, 0xdff4,
1819 		0xd972, 0x6436,
1820 		0xd973, 0x1002,
1821 		0xd974, 0x2006,
1822 		0xd975, 0x3d76,
1823 		0xd976, 0xc161,
1824 		0xd977, 0x6134,
1825 		0xd978, 0x6135,
1826 		0xd979, 0x5443,
1827 		0xd97a, 0x0303,
1828 		0xd97b, 0x6524,
1829 		0xd97c, 0x00fb,
1830 		0xd97d, 0x1002,
1831 		0xd97e, 0x20d4,
1832 		0xd97f, 0x3c24,
1833 		0xd980, 0x2025,
1834 		0xd981, 0x3005,
1835 		0xd982, 0x6524,
1836 		0xd983, 0x1002,
1837 		0xd984, 0xd019,
1838 		0xd985, 0x2104,
1839 		0xd986, 0x3c24,
1840 		0xd987, 0x2105,
1841 		0xd988, 0x3805,
1842 		0xd989, 0x6524,
1843 		0xd98a, 0xdff4,
1844 		0xd98b, 0x4005,
1845 		0xd98c, 0x6524,
1846 		0xd98d, 0x2e8d,
1847 		0xd98e, 0x303d,
1848 		0xd98f, 0x2408,
1849 		0xd990, 0x35d8,
1850 		0xd991, 0x5dd3,
1851 		0xd992, 0x0307,
1852 		0xd993, 0x8887,
1853 		0xd994, 0x63a7,
1854 		0xd995, 0x8887,
1855 		0xd996, 0x63a7,
1856 		0xd997, 0xdffd,
1857 		0xd998, 0x00f9,
1858 		0xd999, 0x1002,
1859 		0xd99a, 0x866a,
1860 		0xd99b, 0x6138,
1861 		0xd99c, 0x5883,
1862 		0xd99d, 0x2aa2,
1863 		0xd99e, 0x3022,
1864 		0xd99f, 0x1302,
1865 		0xd9a0, 0x2ff7,
1866 		0xd9a1, 0x3007,
1867 		0xd9a2, 0x8785,
1868 		0xd9a3, 0xb887,
1869 		0xd9a4, 0x8786,
1870 		0xd9a5, 0xb8c6,
1871 		0xd9a6, 0x5a53,
1872 		0xd9a7, 0x29b2,
1873 		0xd9a8, 0x3022,
1874 		0xd9a9, 0x13c2,
1875 		0xd9aa, 0x2474,
1876 		0xd9ab, 0x3c84,
1877 		0xd9ac, 0x64d7,
1878 		0xd9ad, 0x64d7,
1879 		0xd9ae, 0x2ff5,
1880 		0xd9af, 0x3c05,
1881 		0xd9b0, 0x8757,
1882 		0xd9b1, 0xb886,
1883 		0xd9b2, 0x9767,
1884 		0xd9b3, 0x67c4,
1885 		0xd9b4, 0x6f72,
1886 		0xd9b5, 0x1002,
1887 		0xd9b6, 0x0000,
1888 	};
1889 	int i, err;
1890 
1891 	/* set uC clock and activate it */
1892 	err = set_phy_regs(phy, uCclock40MHz);
1893 	msleep(500);
1894 	if (err)
1895 		return err;
1896 	err = set_phy_regs(phy, uCclockActivate);
1897 	msleep(500);
1898 	if (err)
1899 		return err;
1900 
1901 	for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2)
1902 		err = mdio_write(phy, MDIO_DEV_PMA_PMD, twinax_edc[i],
1903 				 twinax_edc[i + 1]);
1904 	/* activate uC */
1905 	err = set_phy_regs(phy, uCactivate);
1906 	if (!err)
1907 		phy->priv = edc_twinax;
1908 	return err;
1909 }
1910 
1911 /*
1912  * Return Module Type.
1913  */
1914 static int ael2020_get_module_type(struct cphy *phy, int delay_ms)
1915 {
1916 	int v;
1917 	unsigned int stat;
1918 
1919 	v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2020_GPIO_STAT, &stat);
1920 	if (v)
1921 		return v;
1922 
1923 	if (stat & (0x1 << (AEL2020_GPIO_MODDET*4))) {
1924 		/* module absent */
1925 		return phy_modtype_none;
1926 	}
1927 
1928 	return ael2xxx_get_module_type(phy, delay_ms);
1929 }
1930 
1931 /*
1932  * Enable PHY interrupts.  We enable "Module Detection" interrupts (on any
1933  * state transition) and then generic Link Alarm Status Interrupt (LASI).
1934  */
1935 static int ael2020_intr_enable(struct cphy *phy)
1936 {
1937 	struct reg_val regs[] = {
1938 		{ MDIO_DEV_PMA_PMD, AEL2020_GPIO_CFG+AEL2020_GPIO_LSTAT,
1939 			0xffff, 0x4 },
1940 		{ MDIO_DEV_PMA_PMD, AEL2020_GPIO_CTRL,
1941 			0xffff, 0x8 << (AEL2020_GPIO_LSTAT*4) },
1942 
1943 		{ MDIO_DEV_PMA_PMD, AEL2020_GPIO_CTRL,
1944 			0xffff, 0x2 << (AEL2020_GPIO_MODDET*4) },
1945 
1946 		/* end */
1947 		{ 0, 0, 0, 0 }
1948 	};
1949 	int err;
1950 
1951 	err = set_phy_regs(phy, regs);
1952 	if (err)
1953 		return err;
1954 
1955 	/* enable standard Link Alarm Status Interrupts */
1956 	err = t3_phy_lasi_intr_enable(phy);
1957 	if (err)
1958 		return err;
1959 
1960 	return 0;
1961 }
1962 
1963 /*
1964  * Disable PHY interrupts.  The mirror of the above ...
1965  */
1966 static int ael2020_intr_disable(struct cphy *phy)
1967 {
1968 	struct reg_val regs[] = {
1969 		{ MDIO_DEV_PMA_PMD, AEL2020_GPIO_CTRL,
1970 			0xffff, 0xb << (AEL2020_GPIO_LSTAT*4) },
1971 
1972 		{ MDIO_DEV_PMA_PMD, AEL2020_GPIO_CTRL,
1973 			0xffff, 0x1 << (AEL2020_GPIO_MODDET*4) },
1974 
1975 		/* end */
1976 		{ 0, 0, 0, 0 }
1977 	};
1978 	int err;
1979 
1980 	err = set_phy_regs(phy, regs);
1981 	if (err)
1982 		return err;
1983 
1984 	/* disable standard Link Alarm Status Interrupts */
1985 	return t3_phy_lasi_intr_disable(phy);
1986 }
1987 
1988 /*
1989  * Clear PHY interrupt state.
1990  */
1991 static int ael2020_intr_clear(struct cphy *phy)
1992 {
1993 	unsigned int stat;
1994 	int err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2020_GPIO_INTR, &stat);
1995 	return err ? err : t3_phy_lasi_intr_clear(phy);
1996 }
1997 
1998 /*
1999  * Common register settings for the AEL2020 when it comes out of reset.
2000  */
2001 static struct reg_val ael2020_reset_regs[] = {
2002 	{ MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x3101 },
2003 
2004 	{ MDIO_DEV_PMA_PMD, 0xcd40, 0xffff, 0x0001 },
2005 
2006 	{ MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0x0100 },
2007 	{ MDIO_DEV_PMA_PMD, 0xca22, 0xffff, 0x0100 },
2008 	{ MDIO_DEV_PMA_PMD, 0xca42, 0xffff, 0x0100 },
2009 	{ MDIO_DEV_PMA_PMD, 0xff02, 0xffff, 0x0023 },
2010 	{ MDIO_DEV_PMA_PMD, 0xff03, 0xffff, 0x0000 },
2011 	{ MDIO_DEV_PMA_PMD, 0xff04, 0xffff, 0x0000 },
2012 
2013 	{ MDIO_DEV_PMA_PMD, 0xc20d, 0xffff, 0x0002 },
2014 	/* end */
2015 	{ 0, 0, 0, 0 }
2016 };
2017 
2018 /*
2019  * Reset the PHY and put it into a canonical operating state.
2020  */
2021 static int ael2020_reset(struct cphy *phy, int wait)
2022 {
2023 	int err;
2024 	unsigned int lasi_ctrl;
2025 
2026 	/* grab current interrupt state */
2027 	err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl);
2028 	if (err)
2029 		return err;
2030 
2031 	err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 125);
2032 	if (err)
2033 		return err;
2034 	msleep(100);
2035 
2036 	/* basic initialization for all module types */
2037 	phy->priv = edc_none;
2038 	err = set_phy_regs(phy, ael2020_reset_regs);
2039 	if (err)
2040 		return err;
2041 	msleep(100);
2042 
2043 	/* determine module type and perform appropriate initialization */
2044 	err = ael2020_get_module_type(phy, 0);
2045 	if (err < 0)
2046 		return err;
2047 	phy->modtype = (u8)err;
2048 	if (err == phy_modtype_none)
2049 		err = 0;
2050 	else if (err == phy_modtype_twinax || err == phy_modtype_twinax_long)
2051 		err = ael2020_setup_twinax_edc(phy, err);
2052 	else
2053 		err = ael2020_setup_sr_edc(phy);
2054 	if (err)
2055 		return err;
2056 
2057 	/* reset wipes out interrupts, reenable them if they were on */
2058 	if (lasi_ctrl & 1)
2059 		err = ael2020_intr_enable(phy);
2060 	return err;
2061 }
2062 
2063 /*
2064  * Handle a PHY interrupt.
2065  */
2066 static int ael2020_intr_handler(struct cphy *phy)
2067 {
2068 	unsigned int stat;
2069 	int ret, edc_needed, cause = 0;
2070 
2071 	ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2020_GPIO_INTR, &stat);
2072 	if (ret)
2073 		return ret;
2074 
2075 	if (stat & (0x1 << AEL2020_GPIO_MODDET)) {
2076 		/* modules have max 300 ms init time after hot plug */
2077 		ret = ael2020_get_module_type(phy, 300);
2078 		if (ret < 0)
2079 			return ret;
2080 
2081 		phy->modtype = (u8)ret;
2082 		if (ret == phy_modtype_none)
2083 			edc_needed = phy->priv;       /* on unplug retain EDC */
2084 		else if (ret == phy_modtype_twinax ||
2085 			 ret == phy_modtype_twinax_long)
2086 			edc_needed = edc_twinax;
2087 		else
2088 			edc_needed = edc_sr;
2089 
2090 		if (edc_needed != phy->priv) {
2091 			ret = ael2020_reset(phy, 0);
2092 			return ret ? ret : cphy_cause_module_change;
2093 		}
2094 		cause = cphy_cause_module_change;
2095 	}
2096 
2097 	ret = t3_phy_lasi_intr_handler(phy);
2098 	if (ret < 0)
2099 		return ret;
2100 
2101 	ret |= cause;
2102 	if (!ret)
2103 		ret |= cphy_cause_link_change;
2104 	return ret;
2105 }
2106 
2107 static struct cphy_ops ael2020_ops = {
2108 #ifdef C99_NOT_SUPPORTED
2109 	ael2020_reset,
2110 	ael2020_intr_enable,
2111 	ael2020_intr_disable,
2112 	ael2020_intr_clear,
2113 	ael2020_intr_handler,
2114 	NULL,
2115 	NULL,
2116 	NULL,
2117 	NULL,
2118 	NULL,
2119 	get_link_status_r,
2120 	ael1002_power_down,
2121 #else
2122 	.reset           = ael2020_reset,
2123 	.intr_enable     = ael2020_intr_enable,
2124 	.intr_disable    = ael2020_intr_disable,
2125 	.intr_clear      = ael2020_intr_clear,
2126 	.intr_handler    = ael2020_intr_handler,
2127 	.get_link_status = get_link_status_r,
2128 	.power_down      = ael1002_power_down,
2129 #endif
2130 };
2131 
2132 int t3_ael2020_phy_prep(pinfo_t *pinfo, int phy_addr,
2133 			const struct mdio_ops *mdio_ops)
2134 {
2135 	int err;
2136 	struct cphy *phy = &pinfo->phy;
2137 
2138 	cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &ael2020_ops, mdio_ops,
2139 		SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE |
2140 		  SUPPORTED_IRQ, "10GBASE-R");
2141 	msleep(125);
2142 
2143 	err = set_phy_regs(phy, ael2020_reset_regs);
2144 	if (err)
2145 		return err;
2146 	msleep(100);
2147 
2148 	err = ael2020_get_module_type(phy, 0);
2149 	if (err >= 0)
2150 		phy->modtype = err;
2151 
2152 	ael_laser_down(phy, 0);
2153 	return 0;
2154 }
2155 
2156 /*
2157  * Get link status for a 10GBASE-X device.
2158  */
2159 static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed,
2160 			     int *duplex, int *fc)
2161 {
2162 	if (link_ok) {
2163 		unsigned int stat0, stat1, stat2;
2164 		int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0);
2165 
2166 		if (!err)
2167 			err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_X, &stat1);
2168 		if (!err)
2169 			err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2);
2170 		if (err)
2171 			return err;
2172 		*link_ok = (stat0 & (stat1 >> 12) & (stat2 >> 12)) & 1;
2173 	}
2174 	if (speed)
2175 		*speed = SPEED_10000;
2176 	if (duplex)
2177 		*duplex = DUPLEX_FULL;
2178 	return 0;
2179 }
2180 
2181 #ifdef C99_NOT_SUPPORTED
2182 static struct cphy_ops qt2045_ops = {
2183 	ael1006_reset,
2184 	t3_phy_lasi_intr_enable,
2185 	t3_phy_lasi_intr_disable,
2186 	t3_phy_lasi_intr_clear,
2187 	t3_phy_lasi_intr_handler,
2188 	NULL,
2189 	NULL,
2190 	NULL,
2191 	NULL,
2192 	NULL,
2193 	get_link_status_x,
2194 	ael1002_power_down,
2195 };
2196 #else
2197 static struct cphy_ops qt2045_ops = {
2198 	.reset           = ael1006_reset,
2199 	.intr_enable     = t3_phy_lasi_intr_enable,
2200 	.intr_disable    = t3_phy_lasi_intr_disable,
2201 	.intr_clear      = t3_phy_lasi_intr_clear,
2202 	.intr_handler    = t3_phy_lasi_intr_handler,
2203 	.get_link_status = get_link_status_x,
2204 	.power_down      = ael1002_power_down,
2205 };
2206 #endif
2207 
2208 int t3_qt2045_phy_prep(pinfo_t *pinfo, int phy_addr,
2209 		       const struct mdio_ops *mdio_ops)
2210 {
2211 	unsigned int stat;
2212 	struct cphy *phy = &pinfo->phy;
2213 
2214 	cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &qt2045_ops, mdio_ops,
2215 		  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
2216 		  "10GBASE-CX4");
2217 
2218 	/*
2219 	 * Some cards where the PHY is supposed to be at address 0 actually
2220 	 * have it at 1.
2221 	 */
2222 	if (!phy_addr && !mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &stat) &&
2223 	    stat == 0xffff)
2224 		phy->addr = 1;
2225 	return 0;
2226 }
2227 
2228 static int xaui_direct_reset(struct cphy *phy, int wait)
2229 {
2230 	return 0;
2231 }
2232 
2233 static int xaui_direct_get_link_status(struct cphy *phy, int *link_ok,
2234 				       int *speed, int *duplex, int *fc)
2235 {
2236 	if (link_ok) {
2237 		unsigned int status;
2238 		adapter_t *adapter = phy->adapter;
2239 
2240 		status = t3_read_reg(adapter,
2241 				     XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) |
2242 			 t3_read_reg(adapter,
2243 				     XGM_REG(A_XGM_SERDES_STAT1, phy->addr)) |
2244 			 t3_read_reg(adapter,
2245 				     XGM_REG(A_XGM_SERDES_STAT2, phy->addr)) |
2246 			 t3_read_reg(adapter,
2247 				     XGM_REG(A_XGM_SERDES_STAT3, phy->addr));
2248 		*link_ok = !(status & F_LOWSIG0);
2249 	}
2250 	if (speed)
2251 		*speed = SPEED_10000;
2252 	if (duplex)
2253 		*duplex = DUPLEX_FULL;
2254 	return 0;
2255 }
2256 
2257 static int xaui_direct_power_down(struct cphy *phy, int enable)
2258 {
2259 	return 0;
2260 }
2261 
2262 #ifdef C99_NOT_SUPPORTED
2263 static struct cphy_ops xaui_direct_ops = {
2264 	xaui_direct_reset,
2265 	ael1002_intr_noop,
2266 	ael1002_intr_noop,
2267 	ael1002_intr_noop,
2268 	ael1002_intr_noop,
2269 	NULL,
2270 	NULL,
2271 	NULL,
2272 	NULL,
2273 	NULL,
2274 	xaui_direct_get_link_status,
2275 	xaui_direct_power_down,
2276 };
2277 #else
2278 static struct cphy_ops xaui_direct_ops = {
2279 	.reset           = xaui_direct_reset,
2280 	.intr_enable     = ael1002_intr_noop,
2281 	.intr_disable    = ael1002_intr_noop,
2282 	.intr_clear      = ael1002_intr_noop,
2283 	.intr_handler    = ael1002_intr_noop,
2284 	.get_link_status = xaui_direct_get_link_status,
2285 	.power_down      = xaui_direct_power_down,
2286 };
2287 #endif
2288 
2289 int t3_xaui_direct_phy_prep(pinfo_t *pinfo, int phy_addr,
2290 			    const struct mdio_ops *mdio_ops)
2291 {
2292 	cphy_init(&pinfo->phy, pinfo->adapter, pinfo, phy_addr, &xaui_direct_ops, mdio_ops,
2293 		  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
2294 		  "10GBASE-CX4");
2295 	return 0;
2296 }
2297