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