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