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