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