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