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