]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/dev/cxgb/common/cxgb_ael1002.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / dev / cxgb / common / cxgb_ael1002.c
1 /**************************************************************************
2
3 Copyright (c) 2007-2008, 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 #ifdef CONFIG_DEFINED
34 #include <cxgb_include.h>
35 #else
36 #include <dev/cxgb/cxgb_include.h>
37 #endif
38
39 #undef msleep
40 #define msleep t3_os_sleep
41
42 enum {
43         PMD_RSD     = 10,   /* PMA/PMD receive signal detect register */
44         PCS_STAT1_X = 24,   /* 10GBASE-X PCS status 1 register */
45         PCS_STAT1_R = 32,   /* 10GBASE-R PCS status 1 register */
46         XS_LN_STAT  = 24    /* XS lane status register */
47 };
48
49 enum {
50         AEL100X_TX_DISABLE  = 9,
51         AEL100X_TX_CONFIG1  = 0xc002,
52         AEL1002_PWR_DOWN_HI = 0xc011,
53         AEL1002_PWR_DOWN_LO = 0xc012,
54         AEL1002_XFI_EQL     = 0xc015,
55         AEL1002_LB_EN       = 0xc017,
56         AEL_OPT_SETTINGS    = 0xc017,
57         AEL_I2C_CTRL        = 0xc30a,
58         AEL_I2C_DATA        = 0xc30b,
59         AEL_I2C_STAT        = 0xc30c,
60         AEL2005_GPIO_CTRL   = 0xc214,
61         AEL2005_GPIO_STAT   = 0xc215,
62 };
63
64 enum { edc_none, edc_sr, edc_twinax };
65
66 /* PHY module I2C device address */
67 #define MODULE_DEV_ADDR 0xa0
68
69 #define AEL2005_MODDET_IRQ 4
70
71 struct reg_val {
72         unsigned short mmd_addr;
73         unsigned short reg_addr;
74         unsigned short clear_bits;
75         unsigned short set_bits;
76 };
77
78 static int set_phy_regs(struct cphy *phy, const struct reg_val *rv)
79 {
80         int err;
81
82         for (err = 0; rv->mmd_addr && !err; rv++) {
83                 if (rv->clear_bits == 0xffff)
84                         err = mdio_write(phy, rv->mmd_addr, rv->reg_addr,
85                                          rv->set_bits);
86                 else
87                         err = t3_mdio_change_bits(phy, rv->mmd_addr,
88                                                   rv->reg_addr, rv->clear_bits,
89                                                   rv->set_bits);
90         }
91         return err;
92 }
93
94 static void ael100x_txon(struct cphy *phy)
95 {
96         int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL;
97
98         msleep(100);
99         t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 0, tx_on_gpio);
100         msleep(30);
101 }
102
103 static int ael1002_power_down(struct cphy *phy, int enable)
104 {
105         int err;
106
107         err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_DISABLE, !!enable);
108         if (!err)
109                 err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR,
110                                           BMCR_PDOWN, enable ? BMCR_PDOWN : 0);
111         return err;
112 }
113
114 static int ael1002_reset(struct cphy *phy, int wait)
115 {
116         int err;
117
118         if ((err = ael1002_power_down(phy, 0)) ||
119             (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_CONFIG1, 1)) ||
120             (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_HI, 0)) ||
121             (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_LO, 0)) ||
122             (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_XFI_EQL, 0x18)) ||
123             (err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL1002_LB_EN,
124                                        0, 1 << 5)))
125                 return err;
126         return 0;
127 }
128
129 static int ael1002_intr_noop(struct cphy *phy)
130 {
131         return 0;
132 }
133
134 /*
135  * Get link status for a 10GBASE-R device.
136  */
137 static int get_link_status_r(struct cphy *phy, int *link_ok, int *speed,
138                              int *duplex, int *fc)
139 {
140         if (link_ok) {
141                 unsigned int stat0, stat1, stat2;
142                 int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0);
143
144                 if (!err)
145                         err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_R, &stat1);
146                 if (!err)
147                         err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2);
148                 if (err)
149                         return err;
150                 *link_ok = (stat0 & stat1 & (stat2 >> 12)) & 1;
151         }
152         if (speed)
153                 *speed = SPEED_10000;
154         if (duplex)
155                 *duplex = DUPLEX_FULL;
156         return 0;
157 }
158
159 #ifdef C99_NOT_SUPPORTED
160 static struct cphy_ops ael1002_ops = {
161         ael1002_reset,
162         ael1002_intr_noop,
163         ael1002_intr_noop,
164         ael1002_intr_noop,
165         ael1002_intr_noop,
166         NULL,
167         NULL,
168         NULL,
169         NULL,
170         NULL,
171         get_link_status_r,
172         ael1002_power_down,
173 };
174 #else
175 static struct cphy_ops ael1002_ops = {
176         .reset           = ael1002_reset,
177         .intr_enable     = ael1002_intr_noop,
178         .intr_disable    = ael1002_intr_noop,
179         .intr_clear      = ael1002_intr_noop,
180         .intr_handler    = ael1002_intr_noop,
181         .get_link_status = get_link_status_r,
182         .power_down      = ael1002_power_down,
183 };
184 #endif
185
186 int t3_ael1002_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr,
187                         const struct mdio_ops *mdio_ops)
188 {
189         cphy_init(phy, adapter, phy_addr, &ael1002_ops, mdio_ops,
190                   SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE,
191                   "10GBASE-R");
192         ael100x_txon(phy);
193         return 0;
194 }
195
196 static int ael1006_reset(struct cphy *phy, int wait)
197 {
198         u32 gpio_out;
199         t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait);
200         /* Hack to reset the phy correctly */
201         /* Read out the current value */
202         gpio_out = t3_read_reg(phy->adapter, A_T3DBG_GPIO_EN);
203         /* Reset the phy */
204         gpio_out &= ~F_GPIO6_OUT_VAL;
205         t3_write_reg(phy->adapter, A_T3DBG_GPIO_EN, gpio_out); 
206         msleep(125);
207         /* Take the phy out of reset */
208         gpio_out |= F_GPIO6_OUT_VAL;
209         t3_write_reg(phy->adapter, A_T3DBG_GPIO_EN, gpio_out);
210         msleep(125);
211         t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait);
212
213        /* Phy loopback work around for ael1006 */
214        /* Soft reset phy by toggling loopback  */
215        msleep(125);
216        /* Put phy into local loopback */
217        t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, 0, 1);
218        msleep(125);
219        /* Take phy out of local loopback */
220        t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, 1, 0);
221
222         return 0;
223 }
224
225 static int ael1006_power_down(struct cphy *phy, int enable)
226 {
227         return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR,
228                                    BMCR_PDOWN, enable ? BMCR_PDOWN : 0);
229 }
230
231 #ifdef C99_NOT_SUPPORTED
232 static struct cphy_ops ael1006_ops = {
233         ael1006_reset,
234         t3_phy_lasi_intr_enable,
235         t3_phy_lasi_intr_disable,
236         t3_phy_lasi_intr_clear,
237         t3_phy_lasi_intr_handler,
238         NULL,
239         NULL,
240         NULL,
241         NULL,
242         NULL,
243         get_link_status_r,
244         ael1006_power_down,
245 };
246 #else
247 static struct cphy_ops ael1006_ops = {
248         .reset           = ael1006_reset,
249         .intr_enable     = t3_phy_lasi_intr_enable,
250         .intr_disable    = t3_phy_lasi_intr_disable,
251         .intr_clear      = t3_phy_lasi_intr_clear,
252         .intr_handler    = t3_phy_lasi_intr_handler,
253         .get_link_status = get_link_status_r,
254         .power_down      = ael1006_power_down,
255 };
256 #endif
257
258 int t3_ael1006_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr,
259                         const struct mdio_ops *mdio_ops)
260 {
261         cphy_init(phy, adapter, phy_addr, &ael1006_ops, mdio_ops,
262                   SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE,
263                   "10GBASE-SR");
264         ael100x_txon(phy);
265         return 0;
266 }
267
268 static int ael2005_setup_sr_edc(struct cphy *phy)
269 {
270         static struct reg_val regs[] = {
271                 { MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x181 },
272                 { MDIO_DEV_PMA_PMD, 0xc010, 0xffff, 0x448a },
273                 { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5200 },
274                 { 0, 0, 0, 0 }
275         };
276         static u16 sr_edc[] = {
277                 0xcc00, 0x2ff4,
278                 0xcc01, 0x3cd4,
279                 0xcc02, 0x2015,
280                 0xcc03, 0x3105,
281                 0xcc04, 0x6524,
282                 0xcc05, 0x27ff,
283                 0xcc06, 0x300f,
284                 0xcc07, 0x2c8b,
285                 0xcc08, 0x300b,
286                 0xcc09, 0x4009,
287                 0xcc0a, 0x400e,
288                 0xcc0b, 0x2f72,
289                 0xcc0c, 0x3002,
290                 0xcc0d, 0x1002,
291                 0xcc0e, 0x2172,
292                 0xcc0f, 0x3012,
293                 0xcc10, 0x1002,
294                 0xcc11, 0x25d2,
295                 0xcc12, 0x3012,
296                 0xcc13, 0x1002,
297                 0xcc14, 0xd01e,
298                 0xcc15, 0x27d2,
299                 0xcc16, 0x3012,
300                 0xcc17, 0x1002,
301                 0xcc18, 0x2004,
302                 0xcc19, 0x3c84,
303                 0xcc1a, 0x6436,
304                 0xcc1b, 0x2007,
305                 0xcc1c, 0x3f87,
306                 0xcc1d, 0x8676,
307                 0xcc1e, 0x40b7,
308                 0xcc1f, 0xa746,
309                 0xcc20, 0x4047,
310                 0xcc21, 0x5673,
311                 0xcc22, 0x2982,
312                 0xcc23, 0x3002,
313                 0xcc24, 0x13d2,
314                 0xcc25, 0x8bbd,
315                 0xcc26, 0x2862,
316                 0xcc27, 0x3012,
317                 0xcc28, 0x1002,
318                 0xcc29, 0x2092,
319                 0xcc2a, 0x3012,
320                 0xcc2b, 0x1002,
321                 0xcc2c, 0x5cc3,
322                 0xcc2d, 0x314,
323                 0xcc2e, 0x2942,
324                 0xcc2f, 0x3002,
325                 0xcc30, 0x1002,
326                 0xcc31, 0xd019,
327                 0xcc32, 0x2032,
328                 0xcc33, 0x3012,
329                 0xcc34, 0x1002,
330                 0xcc35, 0x2a04,
331                 0xcc36, 0x3c74,
332                 0xcc37, 0x6435,
333                 0xcc38, 0x2fa4,
334                 0xcc39, 0x3cd4,
335                 0xcc3a, 0x6624,
336                 0xcc3b, 0x5563,
337                 0xcc3c, 0x2d42,
338                 0xcc3d, 0x3002,
339                 0xcc3e, 0x13d2,
340                 0xcc3f, 0x464d,
341                 0xcc40, 0x2862,
342                 0xcc41, 0x3012,
343                 0xcc42, 0x1002,
344                 0xcc43, 0x2032,
345                 0xcc44, 0x3012,
346                 0xcc45, 0x1002,
347                 0xcc46, 0x2fb4,
348                 0xcc47, 0x3cd4,
349                 0xcc48, 0x6624,
350                 0xcc49, 0x5563,
351                 0xcc4a, 0x2d42,
352                 0xcc4b, 0x3002,
353                 0xcc4c, 0x13d2,
354                 0xcc4d, 0x2ed2,
355                 0xcc4e, 0x3002,
356                 0xcc4f, 0x1002,
357                 0xcc50, 0x2fd2,
358                 0xcc51, 0x3002,
359                 0xcc52, 0x1002,
360                 0xcc53, 0x004,
361                 0xcc54, 0x2942,
362                 0xcc55, 0x3002,
363                 0xcc56, 0x1002,
364                 0xcc57, 0x2092,
365                 0xcc58, 0x3012,
366                 0xcc59, 0x1002,
367                 0xcc5a, 0x5cc3,
368                 0xcc5b, 0x317,
369                 0xcc5c, 0x2f72,
370                 0xcc5d, 0x3002,
371                 0xcc5e, 0x1002,
372                 0xcc5f, 0x2942,
373                 0xcc60, 0x3002,
374                 0xcc61, 0x1002,
375                 0xcc62, 0x22cd,
376                 0xcc63, 0x301d,
377                 0xcc64, 0x2862,
378                 0xcc65, 0x3012,
379                 0xcc66, 0x1002,
380                 0xcc67, 0x2ed2,
381                 0xcc68, 0x3002,
382                 0xcc69, 0x1002,
383                 0xcc6a, 0x2d72,
384                 0xcc6b, 0x3002,
385                 0xcc6c, 0x1002,
386                 0xcc6d, 0x628f,
387                 0xcc6e, 0x2112,
388                 0xcc6f, 0x3012,
389                 0xcc70, 0x1002,
390                 0xcc71, 0x5aa3,
391                 0xcc72, 0x2dc2,
392                 0xcc73, 0x3002,
393                 0xcc74, 0x1312,
394                 0xcc75, 0x6f72,
395                 0xcc76, 0x1002,
396                 0xcc77, 0x2807,
397                 0xcc78, 0x31a7,
398                 0xcc79, 0x20c4,
399                 0xcc7a, 0x3c24,
400                 0xcc7b, 0x6724,
401                 0xcc7c, 0x1002,
402                 0xcc7d, 0x2807,
403                 0xcc7e, 0x3187,
404                 0xcc7f, 0x20c4,
405                 0xcc80, 0x3c24,
406                 0xcc81, 0x6724,
407                 0xcc82, 0x1002,
408                 0xcc83, 0x2514,
409                 0xcc84, 0x3c64,
410                 0xcc85, 0x6436,
411                 0xcc86, 0xdff4,
412                 0xcc87, 0x6436,
413                 0xcc88, 0x1002,
414                 0xcc89, 0x40a4,
415                 0xcc8a, 0x643c,
416                 0xcc8b, 0x4016,
417                 0xcc8c, 0x8c6c,
418                 0xcc8d, 0x2b24,
419                 0xcc8e, 0x3c24,
420                 0xcc8f, 0x6435,
421                 0xcc90, 0x1002,
422                 0xcc91, 0x2b24,
423                 0xcc92, 0x3c24,
424                 0xcc93, 0x643a,
425                 0xcc94, 0x4025,
426                 0xcc95, 0x8a5a,
427                 0xcc96, 0x1002,
428                 0xcc97, 0x2731,
429                 0xcc98, 0x3011,
430                 0xcc99, 0x1001,
431                 0xcc9a, 0xc7a0,
432                 0xcc9b, 0x100,
433                 0xcc9c, 0xc502,
434                 0xcc9d, 0x53ac,
435                 0xcc9e, 0xc503,
436                 0xcc9f, 0xd5d5,
437                 0xcca0, 0xc600,
438                 0xcca1, 0x2a6d,
439                 0xcca2, 0xc601,
440                 0xcca3, 0x2a4c,
441                 0xcca4, 0xc602,
442                 0xcca5, 0x111,
443                 0xcca6, 0xc60c,
444                 0xcca7, 0x5900,
445                 0xcca8, 0xc710,
446                 0xcca9, 0x700,
447                 0xccaa, 0xc718,
448                 0xccab, 0x700,
449                 0xccac, 0xc720,
450                 0xccad, 0x4700,
451                 0xccae, 0xc801,
452                 0xccaf, 0x7f50,
453                 0xccb0, 0xc802,
454                 0xccb1, 0x7760,
455                 0xccb2, 0xc803,
456                 0xccb3, 0x7fce,
457                 0xccb4, 0xc804,
458                 0xccb5, 0x5700,
459                 0xccb6, 0xc805,
460                 0xccb7, 0x5f11,
461                 0xccb8, 0xc806,
462                 0xccb9, 0x4751,
463                 0xccba, 0xc807,
464                 0xccbb, 0x57e1,
465                 0xccbc, 0xc808,
466                 0xccbd, 0x2700,
467                 0xccbe, 0xc809,
468                 0xccbf, 0x000,
469                 0xccc0, 0xc821,
470                 0xccc1, 0x002,
471                 0xccc2, 0xc822,
472                 0xccc3, 0x014,
473                 0xccc4, 0xc832,
474                 0xccc5, 0x1186,
475                 0xccc6, 0xc847,
476                 0xccc7, 0x1e02,
477                 0xccc8, 0xc013,
478                 0xccc9, 0xf341,
479                 0xccca, 0xc01a,
480                 0xcccb, 0x446,
481                 0xcccc, 0xc024,
482                 0xcccd, 0x1000,
483                 0xccce, 0xc025,
484                 0xcccf, 0xa00,
485                 0xccd0, 0xc026,
486                 0xccd1, 0xc0c,
487                 0xccd2, 0xc027,
488                 0xccd3, 0xc0c,
489                 0xccd4, 0xc029,
490                 0xccd5, 0x0a0,
491                 0xccd6, 0xc030,
492                 0xccd7, 0xa00,
493                 0xccd8, 0xc03c,
494                 0xccd9, 0x01c,
495                 0xccda, 0xc005,
496                 0xccdb, 0x7a06,
497                 0xccdc, 0x000,
498                 0xccdd, 0x2731,
499                 0xccde, 0x3011,
500                 0xccdf, 0x1001,
501                 0xcce0, 0xc620,
502                 0xcce1, 0x000,
503                 0xcce2, 0xc621,
504                 0xcce3, 0x03f,
505                 0xcce4, 0xc622,
506                 0xcce5, 0x000,
507                 0xcce6, 0xc623,
508                 0xcce7, 0x000,
509                 0xcce8, 0xc624,
510                 0xcce9, 0x000,
511                 0xccea, 0xc625,
512                 0xcceb, 0x000,
513                 0xccec, 0xc627,
514                 0xcced, 0x000,
515                 0xccee, 0xc628,
516                 0xccef, 0x000,
517                 0xccf0, 0xc62c,
518                 0xccf1, 0x000,
519                 0xccf2, 0x000,
520                 0xccf3, 0x2806,
521                 0xccf4, 0x3cb6,
522                 0xccf5, 0xc161,
523                 0xccf6, 0x6134,
524                 0xccf7, 0x6135,
525                 0xccf8, 0x5443,
526                 0xccf9, 0x303,
527                 0xccfa, 0x6524,
528                 0xccfb, 0x00b,
529                 0xccfc, 0x1002,
530                 0xccfd, 0x2104,
531                 0xccfe, 0x3c24,
532                 0xccff, 0x2105,
533                 0xcd00, 0x3805,
534                 0xcd01, 0x6524,
535                 0xcd02, 0xdff4,
536                 0xcd03, 0x4005,
537                 0xcd04, 0x6524,
538                 0xcd05, 0x1002,
539                 0xcd06, 0x5dd3,
540                 0xcd07, 0x306,
541                 0xcd08, 0x2ff7,
542                 0xcd09, 0x38f7,
543                 0xcd0a, 0x60b7,
544                 0xcd0b, 0xdffd,
545                 0xcd0c, 0x00a,
546                 0xcd0d, 0x1002,
547                 0xcd0e, 0
548         };
549         int i, err;
550
551         err = set_phy_regs(phy, regs);
552         if (err)
553                 return err;
554
555         msleep(50);
556
557         for (i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2)
558                 err = mdio_write(phy, MDIO_DEV_PMA_PMD, sr_edc[i],
559                                  sr_edc[i + 1]);
560         if (!err)
561                 phy->priv = edc_sr;
562         return err;
563 }
564
565 static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
566 {
567         static struct reg_val regs[] = {
568                 { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5a00 },
569                 { 0, 0, 0, 0 }
570         };
571         static struct reg_val preemphasis[] = {
572                 { MDIO_DEV_PMA_PMD, 0xc014, 0xffff, 0xfe16 },
573                 { MDIO_DEV_PMA_PMD, 0xc015, 0xffff, 0xa000 },
574                 { 0, 0, 0, 0 }
575         };
576         static u16 twinax_edc[] = {
577                 0xcc00, 0x4009,
578                 0xcc01, 0x27ff,
579                 0xcc02, 0x300f,
580                 0xcc03, 0x40aa,
581                 0xcc04, 0x401c,
582                 0xcc05, 0x401e,
583                 0xcc06, 0x2ff4,
584                 0xcc07, 0x3cd4,
585                 0xcc08, 0x2035,
586                 0xcc09, 0x3145,
587                 0xcc0a, 0x6524,
588                 0xcc0b, 0x26a2,
589                 0xcc0c, 0x3012,
590                 0xcc0d, 0x1002,
591                 0xcc0e, 0x29c2,
592                 0xcc0f, 0x3002,
593                 0xcc10, 0x1002,
594                 0xcc11, 0x2072,
595                 0xcc12, 0x3012,
596                 0xcc13, 0x1002,
597                 0xcc14, 0x22cd,
598                 0xcc15, 0x301d,
599                 0xcc16, 0x2e52,
600                 0xcc17, 0x3012,
601                 0xcc18, 0x1002,
602                 0xcc19, 0x28e2,
603                 0xcc1a, 0x3002,
604                 0xcc1b, 0x1002,
605                 0xcc1c, 0x628f,
606                 0xcc1d, 0x2ac2,
607                 0xcc1e, 0x3012,
608                 0xcc1f, 0x1002,
609                 0xcc20, 0x5553,
610                 0xcc21, 0x2ae2,
611                 0xcc22, 0x3002,
612                 0xcc23, 0x1302,
613                 0xcc24, 0x401e,
614                 0xcc25, 0x2be2,
615                 0xcc26, 0x3012,
616                 0xcc27, 0x1002,
617                 0xcc28, 0x2da2,
618                 0xcc29, 0x3012,
619                 0xcc2a, 0x1002,
620                 0xcc2b, 0x2ba2,
621                 0xcc2c, 0x3002,
622                 0xcc2d, 0x1002,
623                 0xcc2e, 0x5ee3,
624                 0xcc2f, 0x305,
625                 0xcc30, 0x400e,
626                 0xcc31, 0x2bc2,
627                 0xcc32, 0x3002,
628                 0xcc33, 0x1002,
629                 0xcc34, 0x2b82,
630                 0xcc35, 0x3012,
631                 0xcc36, 0x1002,
632                 0xcc37, 0x5663,
633                 0xcc38, 0x302,
634                 0xcc39, 0x401e,
635                 0xcc3a, 0x6f72,
636                 0xcc3b, 0x1002,
637                 0xcc3c, 0x628f,
638                 0xcc3d, 0x2be2,
639                 0xcc3e, 0x3012,
640                 0xcc3f, 0x1002,
641                 0xcc40, 0x22cd,
642                 0xcc41, 0x301d,
643                 0xcc42, 0x2e52,
644                 0xcc43, 0x3012,
645                 0xcc44, 0x1002,
646                 0xcc45, 0x2522,
647                 0xcc46, 0x3012,
648                 0xcc47, 0x1002,
649                 0xcc48, 0x2da2,
650                 0xcc49, 0x3012,
651                 0xcc4a, 0x1002,
652                 0xcc4b, 0x2ca2,
653                 0xcc4c, 0x3012,
654                 0xcc4d, 0x1002,
655                 0xcc4e, 0x2fa4,
656                 0xcc4f, 0x3cd4,
657                 0xcc50, 0x6624,
658                 0xcc51, 0x410b,
659                 0xcc52, 0x56b3,
660                 0xcc53, 0x3c4,
661                 0xcc54, 0x2fb2,
662                 0xcc55, 0x3002,
663                 0xcc56, 0x1002,
664                 0xcc57, 0x220b,
665                 0xcc58, 0x303b,
666                 0xcc59, 0x56b3,
667                 0xcc5a, 0x3c3,
668                 0xcc5b, 0x866b,
669                 0xcc5c, 0x400c,
670                 0xcc5d, 0x23a2,
671                 0xcc5e, 0x3012,
672                 0xcc5f, 0x1002,
673                 0xcc60, 0x2da2,
674                 0xcc61, 0x3012,
675                 0xcc62, 0x1002,
676                 0xcc63, 0x2ca2,
677                 0xcc64, 0x3012,
678                 0xcc65, 0x1002,
679                 0xcc66, 0x2fb4,
680                 0xcc67, 0x3cd4,
681                 0xcc68, 0x6624,
682                 0xcc69, 0x56b3,
683                 0xcc6a, 0x3c3,
684                 0xcc6b, 0x866b,
685                 0xcc6c, 0x401c,
686                 0xcc6d, 0x2205,
687                 0xcc6e, 0x3035,
688                 0xcc6f, 0x5b53,
689                 0xcc70, 0x2c52,
690                 0xcc71, 0x3002,
691                 0xcc72, 0x13c2,
692                 0xcc73, 0x5cc3,
693                 0xcc74, 0x317,
694                 0xcc75, 0x2522,
695                 0xcc76, 0x3012,
696                 0xcc77, 0x1002,
697                 0xcc78, 0x2da2,
698                 0xcc79, 0x3012,
699                 0xcc7a, 0x1002,
700                 0xcc7b, 0x2b82,
701                 0xcc7c, 0x3012,
702                 0xcc7d, 0x1002,
703                 0xcc7e, 0x5663,
704                 0xcc7f, 0x303,
705                 0xcc80, 0x401e,
706                 0xcc81, 0x004,
707                 0xcc82, 0x2c42,
708                 0xcc83, 0x3012,
709                 0xcc84, 0x1002,
710                 0xcc85, 0x6f72,
711                 0xcc86, 0x1002,
712                 0xcc87, 0x628f,
713                 0xcc88, 0x2304,
714                 0xcc89, 0x3c84,
715                 0xcc8a, 0x6436,
716                 0xcc8b, 0xdff4,
717                 0xcc8c, 0x6436,
718                 0xcc8d, 0x2ff5,
719                 0xcc8e, 0x3005,
720                 0xcc8f, 0x8656,
721                 0xcc90, 0xdfba,
722                 0xcc91, 0x56a3,
723                 0xcc92, 0xd05a,
724                 0xcc93, 0x21c2,
725                 0xcc94, 0x3012,
726                 0xcc95, 0x1392,
727                 0xcc96, 0xd05a,
728                 0xcc97, 0x56a3,
729                 0xcc98, 0xdfba,
730                 0xcc99, 0x383,
731                 0xcc9a, 0x6f72,
732                 0xcc9b, 0x1002,
733                 0xcc9c, 0x28c5,
734                 0xcc9d, 0x3005,
735                 0xcc9e, 0x4178,
736                 0xcc9f, 0x5653,
737                 0xcca0, 0x384,
738                 0xcca1, 0x22b2,
739                 0xcca2, 0x3012,
740                 0xcca3, 0x1002,
741                 0xcca4, 0x2be5,
742                 0xcca5, 0x3005,
743                 0xcca6, 0x41e8,
744                 0xcca7, 0x5653,
745                 0xcca8, 0x382,
746                 0xcca9, 0x002,
747                 0xccaa, 0x4258,
748                 0xccab, 0x2474,
749                 0xccac, 0x3c84,
750                 0xccad, 0x6437,
751                 0xccae, 0xdff4,
752                 0xccaf, 0x6437,
753                 0xccb0, 0x2ff5,
754                 0xccb1, 0x3c05,
755                 0xccb2, 0x8757,
756                 0xccb3, 0xb888,
757                 0xccb4, 0x9787,
758                 0xccb5, 0xdff4,
759                 0xccb6, 0x6724,
760                 0xccb7, 0x866a,
761                 0xccb8, 0x6f72,
762                 0xccb9, 0x1002,
763                 0xccba, 0x2d01,
764                 0xccbb, 0x3011,
765                 0xccbc, 0x1001,
766                 0xccbd, 0xc620,
767                 0xccbe, 0x14e5,
768                 0xccbf, 0xc621,
769                 0xccc0, 0xc53d,
770                 0xccc1, 0xc622,
771                 0xccc2, 0x3cbe,
772                 0xccc3, 0xc623,
773                 0xccc4, 0x4452,
774                 0xccc5, 0xc624,
775                 0xccc6, 0xc5c5,
776                 0xccc7, 0xc625,
777                 0xccc8, 0xe01e,
778                 0xccc9, 0xc627,
779                 0xccca, 0x000,
780                 0xcccb, 0xc628,
781                 0xcccc, 0x000,
782                 0xcccd, 0xc62b,
783                 0xccce, 0x000,
784                 0xcccf, 0xc62c,
785                 0xccd0, 0x000,
786                 0xccd1, 0x000,
787                 0xccd2, 0x2d01,
788                 0xccd3, 0x3011,
789                 0xccd4, 0x1001,
790                 0xccd5, 0xc620,
791                 0xccd6, 0x000,
792                 0xccd7, 0xc621,
793                 0xccd8, 0x000,
794                 0xccd9, 0xc622,
795                 0xccda, 0x0ce,
796                 0xccdb, 0xc623,
797                 0xccdc, 0x07f,
798                 0xccdd, 0xc624,
799                 0xccde, 0x032,
800                 0xccdf, 0xc625,
801                 0xcce0, 0x000,
802                 0xcce1, 0xc627,
803                 0xcce2, 0x000,
804                 0xcce3, 0xc628,
805                 0xcce4, 0x000,
806                 0xcce5, 0xc62b,
807                 0xcce6, 0x000,
808                 0xcce7, 0xc62c,
809                 0xcce8, 0x000,
810                 0xcce9, 0x000,
811                 0xccea, 0x2d01,
812                 0xcceb, 0x3011,
813                 0xccec, 0x1001,
814                 0xcced, 0xc502,
815                 0xccee, 0x609f,
816                 0xccef, 0xc600,
817                 0xccf0, 0x2a6e,
818                 0xccf1, 0xc601,
819                 0xccf2, 0x2a2c,
820                 0xccf3, 0xc60c,
821                 0xccf4, 0x5400,
822                 0xccf5, 0xc710,
823                 0xccf6, 0x700,
824                 0xccf7, 0xc718,
825                 0xccf8, 0x700,
826                 0xccf9, 0xc720,
827                 0xccfa, 0x4700,
828                 0xccfb, 0xc728,
829                 0xccfc, 0x700,
830                 0xccfd, 0xc729,
831                 0xccfe, 0x1207,
832                 0xccff, 0xc801,
833                 0xcd00, 0x7f50,
834                 0xcd01, 0xc802,
835                 0xcd02, 0x7760,
836                 0xcd03, 0xc803,
837                 0xcd04, 0x7fce,
838                 0xcd05, 0xc804,
839                 0xcd06, 0x520e,
840                 0xcd07, 0xc805,
841                 0xcd08, 0x5c11,
842                 0xcd09, 0xc806,
843                 0xcd0a, 0x3c51,
844                 0xcd0b, 0xc807,
845                 0xcd0c, 0x4061,
846                 0xcd0d, 0xc808,
847                 0xcd0e, 0x49c1,
848                 0xcd0f, 0xc809,
849                 0xcd10, 0x3840,
850                 0xcd11, 0xc80a,
851                 0xcd12, 0x000,
852                 0xcd13, 0xc821,
853                 0xcd14, 0x002,
854                 0xcd15, 0xc822,
855                 0xcd16, 0x046,
856                 0xcd17, 0xc844,
857                 0xcd18, 0x182f,
858                 0xcd19, 0xc013,
859                 0xcd1a, 0xf341,
860                 0xcd1b, 0xc01a,
861                 0xcd1c, 0x446,
862                 0xcd1d, 0xc024,
863                 0xcd1e, 0x1000,
864                 0xcd1f, 0xc025,
865                 0xcd20, 0xa00,
866                 0xcd21, 0xc026,
867                 0xcd22, 0xc0c,
868                 0xcd23, 0xc027,
869                 0xcd24, 0xc0c,
870                 0xcd25, 0xc029,
871                 0xcd26, 0x0a0,
872                 0xcd27, 0xc030,
873                 0xcd28, 0xa00,
874                 0xcd29, 0xc03c,
875                 0xcd2a, 0x01c,
876                 0xcd2b, 0x000,
877                 0xcd2c, 0x2b84,
878                 0xcd2d, 0x3c74,
879                 0xcd2e, 0x6435,
880                 0xcd2f, 0xdff4,
881                 0xcd30, 0x6435,
882                 0xcd31, 0x2806,
883                 0xcd32, 0x3006,
884                 0xcd33, 0x8565,
885                 0xcd34, 0x2b24,
886                 0xcd35, 0x3c24,
887                 0xcd36, 0x6436,
888                 0xcd37, 0x1002,
889                 0xcd38, 0x2b24,
890                 0xcd39, 0x3c24,
891                 0xcd3a, 0x6436,
892                 0xcd3b, 0x4045,
893                 0xcd3c, 0x8656,
894                 0xcd3d, 0x1002,
895                 0xcd3e, 0x2807,
896                 0xcd3f, 0x31a7,
897                 0xcd40, 0x20c4,
898                 0xcd41, 0x3c24,
899                 0xcd42, 0x6724,
900                 0xcd43, 0x1002,
901                 0xcd44, 0x2807,
902                 0xcd45, 0x3187,
903                 0xcd46, 0x20c4,
904                 0xcd47, 0x3c24,
905                 0xcd48, 0x6724,
906                 0xcd49, 0x1002,
907                 0xcd4a, 0x2514,
908                 0xcd4b, 0x3c64,
909                 0xcd4c, 0x6436,
910                 0xcd4d, 0xdff4,
911                 0xcd4e, 0x6436,
912                 0xcd4f, 0x1002,
913                 0xcd50, 0x2806,
914                 0xcd51, 0x3cb6,
915                 0xcd52, 0xc161,
916                 0xcd53, 0x6134,
917                 0xcd54, 0x6135,
918                 0xcd55, 0x5443,
919                 0xcd56, 0x303,
920                 0xcd57, 0x6524,
921                 0xcd58, 0x00b,
922                 0xcd59, 0x1002,
923                 0xcd5a, 0xd019,
924                 0xcd5b, 0x2104,
925                 0xcd5c, 0x3c24,
926                 0xcd5d, 0x2105,
927                 0xcd5e, 0x3805,
928                 0xcd5f, 0x6524,
929                 0xcd60, 0xdff4,
930                 0xcd61, 0x4005,
931                 0xcd62, 0x6524,
932                 0xcd63, 0x2e8d,
933                 0xcd64, 0x303d,
934                 0xcd65, 0x5dd3,
935                 0xcd66, 0x306,
936                 0xcd67, 0x2ff7,
937                 0xcd68, 0x38f7,
938                 0xcd69, 0x60b7,
939                 0xcd6a, 0xdffd,
940                 0xcd6b, 0x00a,
941                 0xcd6c, 0x1002,
942                 0xcd6d, 0
943         };
944         int i, err;
945
946         err = set_phy_regs(phy, regs);
947         if (!err && modtype == phy_modtype_twinax_long)
948                 err = set_phy_regs(phy, preemphasis);
949         if (err)
950                 return err;
951
952         msleep(50);
953
954         for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2)
955                 err = mdio_write(phy, MDIO_DEV_PMA_PMD, twinax_edc[i],
956                                  twinax_edc[i + 1]);
957         if (!err)
958                 phy->priv = edc_twinax;
959         return err;
960 }
961
962 static int ael2005_i2c_rd(struct cphy *phy, int dev_addr, int word_addr)
963 {
964         int i, err;
965         unsigned int stat, data;
966
967         err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL,
968                          (dev_addr << 8) | (1 << 8) | word_addr);
969         if (err)
970                 return err;
971
972         for (i = 0; i < 5; i++) {
973                 msleep(1);
974                 err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat);
975                 if (err)
976                         return err;
977                 if ((stat & 3) == 1) {
978                         err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA,
979                                         &data);
980                         if (err)
981                                 return err;
982                         return data >> 8;
983                 }
984         }
985         CH_WARN(phy->adapter, "PHY %u I2C read of addr %u timed out\n",
986                 phy->addr, word_addr);
987         return -ETIMEDOUT;
988 }
989
990 static int get_module_type(struct cphy *phy, int delay_ms)
991 {
992         int v;
993         unsigned int stat;
994
995         v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, &stat);
996         if (v)
997                 return v;
998
999         if (stat & (1 << 8))                    /* module absent */
1000                 return phy_modtype_none;
1001
1002         if (delay_ms)
1003                 msleep(delay_ms);
1004
1005         /* see SFF-8472 for below */
1006         v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 3);
1007         if (v < 0)
1008                 return v;
1009
1010         if (v == 0x10)
1011                 return phy_modtype_sr;
1012         if (v == 0x20)
1013                 return phy_modtype_lr;
1014         if (v == 0x40)
1015                 return phy_modtype_lrm;
1016
1017         v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 6);
1018         if (v < 0)
1019                 return v;
1020         if (v != 4)
1021                 goto unknown;
1022
1023         v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 10);
1024         if (v < 0)
1025                 return v;
1026
1027         if (v & 0x80) {
1028                 v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 0x12);
1029                 if (v < 0)
1030                         return v;
1031                 return v > 10 ? phy_modtype_twinax_long : phy_modtype_twinax;
1032         }
1033 unknown:
1034         return phy_modtype_unknown;
1035 }
1036
1037 static int ael2005_intr_enable(struct cphy *phy)
1038 {
1039         int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x200);
1040         return err ? err : t3_phy_lasi_intr_enable(phy);
1041 }
1042
1043 static int ael2005_intr_disable(struct cphy *phy)
1044 {
1045         int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x100);
1046         return err ? err : t3_phy_lasi_intr_disable(phy);
1047 }
1048
1049 static int ael2005_intr_clear(struct cphy *phy)
1050 {
1051         int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0xd00);
1052         return err ? err : t3_phy_lasi_intr_clear(phy);
1053 }
1054
1055 static int ael2005_reset(struct cphy *phy, int wait)
1056 {
1057         static struct reg_val regs0[] = {
1058                 { MDIO_DEV_PMA_PMD, 0xc001, 0, 1 << 5 },
1059                 { MDIO_DEV_PMA_PMD, 0xc017, 0, 1 << 5 },
1060                 { MDIO_DEV_PMA_PMD, 0xc013, 0xffff, 0xf341 },
1061                 { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 },
1062                 { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8100 },
1063                 { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 },
1064                 { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0 },
1065                 { 0, 0, 0, 0 }
1066         };
1067         static struct reg_val regs1[] = {
1068                 { MDIO_DEV_PMA_PMD, 0xca00, 0xffff, 0x0080 },
1069                 { MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0 },
1070                 { 0, 0, 0, 0 }
1071         };
1072
1073         int err, lasi_ctrl;
1074
1075         err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl);
1076         if (err)
1077                 return err;
1078
1079         err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 0);
1080         if (err)
1081                 return err;
1082
1083         msleep(125);
1084         phy->priv = edc_none;
1085         err = set_phy_regs(phy, regs0);
1086         if (err)
1087                 return err;
1088
1089         msleep(50);
1090
1091         err = get_module_type(phy, 0);
1092         if (err < 0)
1093                 return err;
1094         phy->modtype = (u8)err;
1095
1096         if (err == phy_modtype_twinax || err == phy_modtype_twinax_long)
1097                 err = ael2005_setup_twinax_edc(phy, err);
1098         else
1099                 err = ael2005_setup_sr_edc(phy);
1100         if (err)
1101                 return err;
1102
1103         err = set_phy_regs(phy, regs1);
1104         if (err)
1105                 return err;
1106
1107         /* reset wipes out interrupts, reenable them if they were on */
1108         if (lasi_ctrl & 1)
1109                 err = ael2005_intr_enable(phy);
1110         return err;
1111 }
1112
1113 static int ael2005_intr_handler(struct cphy *phy)
1114 {
1115         unsigned int stat;
1116         int ret, edc_needed, cause = 0;
1117
1118         ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_STAT, &stat);
1119         if (ret)
1120                 return ret;
1121
1122         if (stat & AEL2005_MODDET_IRQ) {
1123                 ret = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL,
1124                                  0xd00);
1125                 if (ret)
1126                         return ret;
1127
1128                 /* modules have max 300 ms init time after hot plug */
1129                 ret = get_module_type(phy, 300);
1130                 if (ret < 0)
1131                         return ret;
1132
1133                 phy->modtype = (u8)ret;
1134                 if (ret == phy_modtype_none)
1135                         edc_needed = phy->priv;       /* on unplug retain EDC */
1136                 else if (ret == phy_modtype_twinax ||
1137                          ret == phy_modtype_twinax_long)
1138                         edc_needed = edc_twinax;
1139                 else
1140                         edc_needed = edc_sr;
1141
1142                 if (edc_needed != phy->priv) {
1143                         ret = ael2005_reset(phy, 0);
1144                         return ret ? ret : cphy_cause_module_change;
1145                 }
1146                 cause = cphy_cause_module_change;
1147         }
1148
1149         ret = t3_phy_lasi_intr_handler(phy);
1150         return ret < 0 ? ret : ret + cause;
1151 }
1152
1153 #ifdef C99_NOT_SUPPORTED
1154 static struct cphy_ops ael2005_ops = {
1155         ael2005_reset,
1156         ael2005_intr_enable,
1157         ael2005_intr_disable,
1158         ael2005_intr_clear,
1159         ael2005_intr_handler,
1160         NULL,
1161         NULL,
1162         NULL,
1163         NULL,
1164         NULL,
1165         get_link_status_r,
1166         ael1002_power_down,
1167 };
1168 #else
1169 static struct cphy_ops ael2005_ops = {
1170         .reset           = ael2005_reset,
1171         .intr_enable     = ael2005_intr_enable,
1172         .intr_disable    = ael2005_intr_disable,
1173         .intr_clear      = ael2005_intr_clear,
1174         .intr_handler    = ael2005_intr_handler,
1175         .get_link_status = get_link_status_r,
1176         .power_down      = ael1002_power_down,
1177 };
1178 #endif
1179
1180 int t3_ael2005_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr,
1181                         const struct mdio_ops *mdio_ops)
1182 {
1183         cphy_init(phy, adapter, phy_addr, &ael2005_ops, mdio_ops,
1184                   SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE |
1185                   SUPPORTED_IRQ, "10GBASE-R");
1186         msleep(125);
1187         return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL_OPT_SETTINGS, 0,
1188                                    1 << 5);
1189 }
1190
1191 /*
1192  * Get link status for a 10GBASE-X device.
1193  */
1194 static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed,
1195                              int *duplex, int *fc)
1196 {
1197         if (link_ok) {
1198                 unsigned int stat0, stat1, stat2;
1199                 int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0);
1200
1201                 if (!err)
1202                         err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_X, &stat1);
1203                 if (!err)
1204                         err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2);
1205                 if (err)
1206                         return err;
1207                 *link_ok = (stat0 & (stat1 >> 12) & (stat2 >> 12)) & 1;
1208         }
1209         if (speed)
1210                 *speed = SPEED_10000;
1211         if (duplex)
1212                 *duplex = DUPLEX_FULL;
1213         return 0;
1214 }
1215
1216 #ifdef C99_NOT_SUPPORTED
1217 static struct cphy_ops qt2045_ops = {
1218         ael1006_reset,
1219         t3_phy_lasi_intr_enable,
1220         t3_phy_lasi_intr_disable,
1221         t3_phy_lasi_intr_clear,
1222         t3_phy_lasi_intr_handler,
1223         NULL,
1224         NULL,
1225         NULL,
1226         NULL,
1227         NULL,
1228         get_link_status_x,
1229         ael1006_power_down,
1230 };
1231 #else
1232 static struct cphy_ops qt2045_ops = {
1233         .reset           = ael1006_reset,
1234         .intr_enable     = t3_phy_lasi_intr_enable,
1235         .intr_disable    = t3_phy_lasi_intr_disable,
1236         .intr_clear      = t3_phy_lasi_intr_clear,
1237         .intr_handler    = t3_phy_lasi_intr_handler,
1238         .get_link_status = get_link_status_x,
1239         .power_down      = ael1006_power_down,
1240 };
1241 #endif
1242
1243 int t3_qt2045_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr,
1244                        const struct mdio_ops *mdio_ops)
1245 {
1246         unsigned int stat;
1247
1248         cphy_init(phy, adapter, phy_addr, &qt2045_ops, mdio_ops,
1249                   SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
1250                   "10GBASE-CX4");
1251
1252         /*
1253          * Some cards where the PHY is supposed to be at address 0 actually
1254          * have it at 1.
1255          */
1256         if (!phy_addr && !mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &stat) &&
1257             stat == 0xffff)
1258                 phy->addr = 1;
1259         return 0;
1260 }
1261
1262 static int xaui_direct_reset(struct cphy *phy, int wait)
1263 {
1264         return 0;
1265 }
1266
1267 static int xaui_direct_get_link_status(struct cphy *phy, int *link_ok,
1268                                        int *speed, int *duplex, int *fc)
1269 {
1270         if (link_ok) {
1271                 unsigned int status;
1272                 
1273                 status = t3_read_reg(phy->adapter,
1274                                      XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) |
1275                          t3_read_reg(phy->adapter,
1276                                      XGM_REG(A_XGM_SERDES_STAT1, phy->addr)) |
1277                          t3_read_reg(phy->adapter,
1278                                      XGM_REG(A_XGM_SERDES_STAT2, phy->addr)) |
1279                          t3_read_reg(phy->adapter,
1280                                      XGM_REG(A_XGM_SERDES_STAT3, phy->addr));
1281                 *link_ok = !(status & F_LOWSIG0);
1282         }
1283         if (speed)
1284                 *speed = SPEED_10000;
1285         if (duplex)
1286                 *duplex = DUPLEX_FULL;
1287         return 0;
1288 }
1289
1290 static int xaui_direct_power_down(struct cphy *phy, int enable)
1291 {
1292         return 0;
1293 }
1294
1295 #ifdef C99_NOT_SUPPORTED
1296 static struct cphy_ops xaui_direct_ops = {
1297         xaui_direct_reset,
1298         ael1002_intr_noop,
1299         ael1002_intr_noop,
1300         ael1002_intr_noop,
1301         ael1002_intr_noop,
1302         NULL,
1303         NULL,
1304         NULL,
1305         NULL,
1306         NULL,
1307         xaui_direct_get_link_status,
1308         xaui_direct_power_down,
1309 };
1310 #else
1311 static struct cphy_ops xaui_direct_ops = {
1312         .reset           = xaui_direct_reset,
1313         .intr_enable     = ael1002_intr_noop,
1314         .intr_disable    = ael1002_intr_noop,
1315         .intr_clear      = ael1002_intr_noop,
1316         .intr_handler    = ael1002_intr_noop,
1317         .get_link_status = xaui_direct_get_link_status,
1318         .power_down      = xaui_direct_power_down,
1319 };
1320 #endif
1321
1322 int t3_xaui_direct_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr,
1323                             const struct mdio_ops *mdio_ops)
1324 {
1325         cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops,
1326                   SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
1327                   "10GBASE-CX4");
1328         return 0;
1329 }