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