Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[linux-2.6] / drivers / net / cxgb3 / ael1002.c
1 /*
2  * Copyright (c) 2005-2008 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;
1009         unsigned int lasi_ctrl;
1010
1011         err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl);
1012         if (err)
1013                 return err;
1014
1015         err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 0);
1016         if (err)
1017                 return err;
1018
1019         msleep(125);
1020         phy->priv = edc_none;
1021         err = set_phy_regs(phy, regs0);
1022         if (err)
1023                 return err;
1024
1025         msleep(50);
1026
1027         err = get_module_type(phy, 0);
1028         if (err < 0)
1029                 return err;
1030         phy->modtype = err;
1031
1032         if (err == phy_modtype_twinax || err == phy_modtype_twinax_long)
1033                 err = ael2005_setup_twinax_edc(phy, err);
1034         else
1035                 err = ael2005_setup_sr_edc(phy);
1036         if (err)
1037                 return err;
1038
1039         err = set_phy_regs(phy, regs1);
1040         if (err)
1041                 return err;
1042
1043         /* reset wipes out interrupts, reenable them if they were on */
1044         if (lasi_ctrl & 1)
1045                 err = ael2005_intr_enable(phy);
1046         return err;
1047 }
1048
1049 static int ael2005_intr_handler(struct cphy *phy)
1050 {
1051         unsigned int stat;
1052         int ret, edc_needed, cause = 0;
1053
1054         ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_STAT, &stat);
1055         if (ret)
1056                 return ret;
1057
1058         if (stat & AEL2005_MODDET_IRQ) {
1059                 ret = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL,
1060                                  0xd00);
1061                 if (ret)
1062                         return ret;
1063
1064                 /* modules have max 300 ms init time after hot plug */
1065                 ret = get_module_type(phy, 300);
1066                 if (ret < 0)
1067                         return ret;
1068
1069                 phy->modtype = ret;
1070                 if (ret == phy_modtype_none)
1071                         edc_needed = phy->priv;       /* on unplug retain EDC */
1072                 else if (ret == phy_modtype_twinax ||
1073                          ret == phy_modtype_twinax_long)
1074                         edc_needed = edc_twinax;
1075                 else
1076                         edc_needed = edc_sr;
1077
1078                 if (edc_needed != phy->priv) {
1079                         ret = ael2005_reset(phy, 0);
1080                         return ret ? ret : cphy_cause_module_change;
1081                 }
1082                 cause = cphy_cause_module_change;
1083         }
1084
1085         ret = t3_phy_lasi_intr_handler(phy);
1086         if (ret < 0)
1087                 return ret;
1088
1089         ret |= cause;
1090         return ret ? ret : cphy_cause_link_change;
1091 }
1092
1093 static struct cphy_ops ael2005_ops = {
1094         .reset           = ael2005_reset,
1095         .intr_enable     = ael2005_intr_enable,
1096         .intr_disable    = ael2005_intr_disable,
1097         .intr_clear      = ael2005_intr_clear,
1098         .intr_handler    = ael2005_intr_handler,
1099         .get_link_status = get_link_status_r,
1100         .power_down      = ael1002_power_down,
1101 };
1102
1103 int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter,
1104                         int phy_addr, const struct mdio_ops *mdio_ops)
1105 {
1106         cphy_init(phy, adapter, phy_addr, &ael2005_ops, mdio_ops,
1107                   SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE |
1108                   SUPPORTED_IRQ, "10GBASE-R");
1109         msleep(125);
1110         return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL_OPT_SETTINGS, 0,
1111                                    1 << 5);
1112 }
1113
1114 /*
1115  * Get link status for a 10GBASE-X device.
1116  */
1117 static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed,
1118                              int *duplex, int *fc)
1119 {
1120         if (link_ok) {
1121                 unsigned int stat0, stat1, stat2;
1122                 int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0);
1123
1124                 if (!err)
1125                         err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_X, &stat1);
1126                 if (!err)
1127                         err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2);
1128                 if (err)
1129                         return err;
1130                 *link_ok = (stat0 & (stat1 >> 12) & (stat2 >> 12)) & 1;
1131         }
1132         if (speed)
1133                 *speed = SPEED_10000;
1134         if (duplex)
1135                 *duplex = DUPLEX_FULL;
1136         return 0;
1137 }
1138
1139 static struct cphy_ops qt2045_ops = {
1140         .reset = ael1006_reset,
1141         .intr_enable = t3_phy_lasi_intr_enable,
1142         .intr_disable = t3_phy_lasi_intr_disable,
1143         .intr_clear = t3_phy_lasi_intr_clear,
1144         .intr_handler = t3_phy_lasi_intr_handler,
1145         .get_link_status = get_link_status_x,
1146         .power_down = ael1006_power_down,
1147 };
1148
1149 int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter,
1150                        int phy_addr, const struct mdio_ops *mdio_ops)
1151 {
1152         unsigned int stat;
1153
1154         cphy_init(phy, adapter, phy_addr, &qt2045_ops, mdio_ops,
1155                   SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
1156                   "10GBASE-CX4");
1157
1158         /*
1159          * Some cards where the PHY is supposed to be at address 0 actually
1160          * have it at 1.
1161          */
1162         if (!phy_addr && !mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &stat) &&
1163             stat == 0xffff)
1164                 phy->addr = 1;
1165         return 0;
1166 }
1167
1168 static int xaui_direct_reset(struct cphy *phy, int wait)
1169 {
1170         return 0;
1171 }
1172
1173 static int xaui_direct_get_link_status(struct cphy *phy, int *link_ok,
1174                                        int *speed, int *duplex, int *fc)
1175 {
1176         if (link_ok) {
1177                 unsigned int status;
1178
1179                 status = t3_read_reg(phy->adapter,
1180                                      XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) |
1181                     t3_read_reg(phy->adapter,
1182                                 XGM_REG(A_XGM_SERDES_STAT1, phy->addr)) |
1183                     t3_read_reg(phy->adapter,
1184                                 XGM_REG(A_XGM_SERDES_STAT2, phy->addr)) |
1185                     t3_read_reg(phy->adapter,
1186                                 XGM_REG(A_XGM_SERDES_STAT3, phy->addr));
1187                 *link_ok = !(status & F_LOWSIG0);
1188         }
1189         if (speed)
1190                 *speed = SPEED_10000;
1191         if (duplex)
1192                 *duplex = DUPLEX_FULL;
1193         return 0;
1194 }
1195
1196 static int xaui_direct_power_down(struct cphy *phy, int enable)
1197 {
1198         return 0;
1199 }
1200
1201 static struct cphy_ops xaui_direct_ops = {
1202         .reset = xaui_direct_reset,
1203         .intr_enable = ael1002_intr_noop,
1204         .intr_disable = ael1002_intr_noop,
1205         .intr_clear = ael1002_intr_noop,
1206         .intr_handler = ael1002_intr_noop,
1207         .get_link_status = xaui_direct_get_link_status,
1208         .power_down = xaui_direct_power_down,
1209 };
1210
1211 int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter,
1212                             int phy_addr, const struct mdio_ops *mdio_ops)
1213 {
1214         cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops,
1215                   SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
1216                   "10GBASE-CX4");
1217         return 0;
1218 }