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