blob: df1f58576689908450098ae58b9267c81fc74fc2 [file] [log] [blame]
Divy Le Ray4d22de32007-01-18 22:04:14 -05001/*
Divy Le Raya02d44a2008-10-13 18:47:30 -07002 * Copyright (c) 2005-2008 Chelsio, Inc. All rights reserved.
Divy Le Ray4d22de32007-01-18 22:04:14 -05003 *
Divy Le Ray1d68e932007-01-30 19:44:35 -08004 * 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:
Divy Le Ray4d22de32007-01-18 22:04:14 -05009 *
Divy Le Ray1d68e932007-01-30 19:44:35 -080010 * 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.
Divy Le Ray4d22de32007-01-18 22:04:14 -050031 */
Divy Le Ray4d22de32007-01-18 22:04:14 -050032#include "common.h"
33#include "regs.h"
34
35enum {
Divy Le Ray4d22de32007-01-18 22:04:14 -050036 AEL100X_TX_CONFIG1 = 0xc002,
37 AEL1002_PWR_DOWN_HI = 0xc011,
38 AEL1002_PWR_DOWN_LO = 0xc012,
39 AEL1002_XFI_EQL = 0xc015,
40 AEL1002_LB_EN = 0xc017,
Divy Le Ray1e882022008-10-08 17:40:07 -070041 AEL_OPT_SETTINGS = 0xc017,
42 AEL_I2C_CTRL = 0xc30a,
43 AEL_I2C_DATA = 0xc30b,
44 AEL_I2C_STAT = 0xc30c,
45 AEL2005_GPIO_CTRL = 0xc214,
46 AEL2005_GPIO_STAT = 0xc215,
Divy Le Ray4d22de32007-01-18 22:04:14 -050047};
48
Divy Le Ray1e882022008-10-08 17:40:07 -070049enum { edc_none, edc_sr, edc_twinax };
50
51/* PHY module I2C device address */
52#define MODULE_DEV_ADDR 0xa0
53
54#define AEL2005_MODDET_IRQ 4
55
56struct reg_val {
57 unsigned short mmd_addr;
58 unsigned short reg_addr;
59 unsigned short clear_bits;
60 unsigned short set_bits;
61};
62
63static int set_phy_regs(struct cphy *phy, const struct reg_val *rv)
64{
65 int err;
66
67 for (err = 0; rv->mmd_addr && !err; rv++) {
68 if (rv->clear_bits == 0xffff)
Ben Hutchings0f07c4e2009-04-29 08:07:20 +000069 err = t3_mdio_write(phy, rv->mmd_addr, rv->reg_addr,
70 rv->set_bits);
Divy Le Ray1e882022008-10-08 17:40:07 -070071 else
72 err = t3_mdio_change_bits(phy, rv->mmd_addr,
73 rv->reg_addr, rv->clear_bits,
74 rv->set_bits);
75 }
76 return err;
77}
78
Divy Le Ray4d22de32007-01-18 22:04:14 -050079static void ael100x_txon(struct cphy *phy)
80{
Ben Hutchings0f07c4e2009-04-29 08:07:20 +000081 int tx_on_gpio =
82 phy->mdio.prtad == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL;
Divy Le Ray4d22de32007-01-18 22:04:14 -050083
84 msleep(100);
85 t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 0, tx_on_gpio);
86 msleep(30);
87}
88
89static int ael1002_power_down(struct cphy *phy, int enable)
90{
91 int err;
92
Ben Hutchings0f07c4e2009-04-29 08:07:20 +000093 err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, MDIO_PMA_TXDIS, !!enable);
Divy Le Ray4d22de32007-01-18 22:04:14 -050094 if (!err)
Ben Hutchings0f07c4e2009-04-29 08:07:20 +000095 err = mdio_set_flag(&phy->mdio, phy->mdio.prtad,
96 MDIO_MMD_PMAPMD, MDIO_CTRL1,
97 MDIO_CTRL1_LPOWER, enable);
Divy Le Ray4d22de32007-01-18 22:04:14 -050098 return err;
99}
100
101static int ael1002_reset(struct cphy *phy, int wait)
102{
103 int err;
104
105 if ((err = ael1002_power_down(phy, 0)) ||
Ben Hutchings0f07c4e2009-04-29 08:07:20 +0000106 (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL100X_TX_CONFIG1, 1)) ||
107 (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_PWR_DOWN_HI, 0)) ||
108 (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_PWR_DOWN_LO, 0)) ||
109 (err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL1002_XFI_EQL, 0x18)) ||
110 (err = t3_mdio_change_bits(phy, MDIO_MMD_PMAPMD, AEL1002_LB_EN,
Divy Le Ray4d22de32007-01-18 22:04:14 -0500111 0, 1 << 5)))
112 return err;
113 return 0;
114}
115
116static int ael1002_intr_noop(struct cphy *phy)
117{
118 return 0;
119}
120
Divy Le Ray1e882022008-10-08 17:40:07 -0700121/*
122 * Get link status for a 10GBASE-R device.
123 */
124static int get_link_status_r(struct cphy *phy, int *link_ok, int *speed,
125 int *duplex, int *fc)
Divy Le Ray4d22de32007-01-18 22:04:14 -0500126{
127 if (link_ok) {
Divy Le Ray1e882022008-10-08 17:40:07 -0700128 unsigned int stat0, stat1, stat2;
Ben Hutchings0f07c4e2009-04-29 08:07:20 +0000129 int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD,
130 MDIO_PMA_RXDET, &stat0);
Divy Le Ray4d22de32007-01-18 22:04:14 -0500131
Divy Le Ray1e882022008-10-08 17:40:07 -0700132 if (!err)
Ben Hutchings0f07c4e2009-04-29 08:07:20 +0000133 err = t3_mdio_read(phy, MDIO_MMD_PCS,
134 MDIO_PCS_10GBRT_STAT1, &stat1);
Divy Le Ray1e882022008-10-08 17:40:07 -0700135 if (!err)
Ben Hutchings0f07c4e2009-04-29 08:07:20 +0000136 err = t3_mdio_read(phy, MDIO_MMD_PHYXS,
137 MDIO_PHYXS_LNSTAT, &stat2);
Divy Le Ray4d22de32007-01-18 22:04:14 -0500138 if (err)
139 return err;
Divy Le Ray1e882022008-10-08 17:40:07 -0700140 *link_ok = (stat0 & stat1 & (stat2 >> 12)) & 1;
Divy Le Ray4d22de32007-01-18 22:04:14 -0500141 }
142 if (speed)
143 *speed = SPEED_10000;
144 if (duplex)
145 *duplex = DUPLEX_FULL;
146 return 0;
147}
148
149static struct cphy_ops ael1002_ops = {
150 .reset = ael1002_reset,
151 .intr_enable = ael1002_intr_noop,
152 .intr_disable = ael1002_intr_noop,
153 .intr_clear = ael1002_intr_noop,
154 .intr_handler = ael1002_intr_noop,
Divy Le Ray1e882022008-10-08 17:40:07 -0700155 .get_link_status = get_link_status_r,
Divy Le Ray4d22de32007-01-18 22:04:14 -0500156 .power_down = ael1002_power_down,
Ben Hutchings0f07c4e2009-04-29 08:07:20 +0000157 .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
Divy Le Ray4d22de32007-01-18 22:04:14 -0500158};
159
Divy Le Ray78e46892008-10-08 17:38:01 -0700160int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter,
161 int phy_addr, const struct mdio_ops *mdio_ops)
Divy Le Ray4d22de32007-01-18 22:04:14 -0500162{
Divy Le Ray04497982008-10-08 17:38:29 -0700163 cphy_init(phy, adapter, phy_addr, &ael1002_ops, mdio_ops,
164 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE,
165 "10GBASE-R");
Divy Le Ray4d22de32007-01-18 22:04:14 -0500166 ael100x_txon(phy);
Divy Le Ray78e46892008-10-08 17:38:01 -0700167 return 0;
Divy Le Ray4d22de32007-01-18 22:04:14 -0500168}
169
170static int ael1006_reset(struct cphy *phy, int wait)
171{
Ben Hutchings0f07c4e2009-04-29 08:07:20 +0000172 return t3_phy_reset(phy, MDIO_MMD_PMAPMD, wait);
Divy Le Ray4d22de32007-01-18 22:04:14 -0500173}
174
Divy Le Ray4d22de32007-01-18 22:04:14 -0500175static int ael1006_power_down(struct cphy *phy, int enable)
176{
Ben Hutchings0f07c4e2009-04-29 08:07:20 +0000177 return mdio_set_flag(&phy->mdio, phy->mdio.prtad, MDIO_MMD_PMAPMD,
178 MDIO_CTRL1, MDIO_CTRL1_LPOWER, enable);
Divy Le Ray4d22de32007-01-18 22:04:14 -0500179}
180
181static struct cphy_ops ael1006_ops = {
182 .reset = ael1006_reset,
Divy Le Ray9b1e3652008-10-08 17:39:31 -0700183 .intr_enable = t3_phy_lasi_intr_enable,
184 .intr_disable = t3_phy_lasi_intr_disable,
185 .intr_clear = t3_phy_lasi_intr_clear,
186 .intr_handler = t3_phy_lasi_intr_handler,
Divy Le Ray1e882022008-10-08 17:40:07 -0700187 .get_link_status = get_link_status_r,
Divy Le Ray4d22de32007-01-18 22:04:14 -0500188 .power_down = ael1006_power_down,
Ben Hutchings0f07c4e2009-04-29 08:07:20 +0000189 .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
Divy Le Ray4d22de32007-01-18 22:04:14 -0500190};
191
Divy Le Ray78e46892008-10-08 17:38:01 -0700192int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter,
193 int phy_addr, const struct mdio_ops *mdio_ops)
Divy Le Ray4d22de32007-01-18 22:04:14 -0500194{
Divy Le Ray04497982008-10-08 17:38:29 -0700195 cphy_init(phy, adapter, phy_addr, &ael1006_ops, mdio_ops,
196 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE,
197 "10GBASE-SR");
Divy Le Ray4d22de32007-01-18 22:04:14 -0500198 ael100x_txon(phy);
Divy Le Ray78e46892008-10-08 17:38:01 -0700199 return 0;
Divy Le Ray4d22de32007-01-18 22:04:14 -0500200}
201
Divy Le Ray1e882022008-10-08 17:40:07 -0700202static int ael2005_setup_sr_edc(struct cphy *phy)
203{
204 static struct reg_val regs[] = {
Ben Hutchings0f07c4e2009-04-29 08:07:20 +0000205 { MDIO_MMD_PMAPMD, 0xc003, 0xffff, 0x181 },
206 { MDIO_MMD_PMAPMD, 0xc010, 0xffff, 0x448a },
207 { MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5200 },
Divy Le Ray1e882022008-10-08 17:40:07 -0700208 { 0, 0, 0, 0 }
209 };
210 static u16 sr_edc[] = {
211 0xcc00, 0x2ff4,
212 0xcc01, 0x3cd4,
213 0xcc02, 0x2015,
214 0xcc03, 0x3105,
215 0xcc04, 0x6524,
216 0xcc05, 0x27ff,
217 0xcc06, 0x300f,
218 0xcc07, 0x2c8b,
219 0xcc08, 0x300b,
220 0xcc09, 0x4009,
221 0xcc0a, 0x400e,
222 0xcc0b, 0x2f72,
223 0xcc0c, 0x3002,
224 0xcc0d, 0x1002,
225 0xcc0e, 0x2172,
226 0xcc0f, 0x3012,
227 0xcc10, 0x1002,
228 0xcc11, 0x25d2,
229 0xcc12, 0x3012,
230 0xcc13, 0x1002,
231 0xcc14, 0xd01e,
232 0xcc15, 0x27d2,
233 0xcc16, 0x3012,
234 0xcc17, 0x1002,
235 0xcc18, 0x2004,
236 0xcc19, 0x3c84,
237 0xcc1a, 0x6436,
238 0xcc1b, 0x2007,
239 0xcc1c, 0x3f87,
240 0xcc1d, 0x8676,
241 0xcc1e, 0x40b7,
242 0xcc1f, 0xa746,
243 0xcc20, 0x4047,
244 0xcc21, 0x5673,
245 0xcc22, 0x2982,
246 0xcc23, 0x3002,
247 0xcc24, 0x13d2,
248 0xcc25, 0x8bbd,
249 0xcc26, 0x2862,
250 0xcc27, 0x3012,
251 0xcc28, 0x1002,
252 0xcc29, 0x2092,
253 0xcc2a, 0x3012,
254 0xcc2b, 0x1002,
255 0xcc2c, 0x5cc3,
256 0xcc2d, 0x314,
257 0xcc2e, 0x2942,
258 0xcc2f, 0x3002,
259 0xcc30, 0x1002,
260 0xcc31, 0xd019,
261 0xcc32, 0x2032,
262 0xcc33, 0x3012,
263 0xcc34, 0x1002,
264 0xcc35, 0x2a04,
265 0xcc36, 0x3c74,
266 0xcc37, 0x6435,
267 0xcc38, 0x2fa4,
268 0xcc39, 0x3cd4,
269 0xcc3a, 0x6624,
270 0xcc3b, 0x5563,
271 0xcc3c, 0x2d42,
272 0xcc3d, 0x3002,
273 0xcc3e, 0x13d2,
274 0xcc3f, 0x464d,
275 0xcc40, 0x2862,
276 0xcc41, 0x3012,
277 0xcc42, 0x1002,
278 0xcc43, 0x2032,
279 0xcc44, 0x3012,
280 0xcc45, 0x1002,
281 0xcc46, 0x2fb4,
282 0xcc47, 0x3cd4,
283 0xcc48, 0x6624,
284 0xcc49, 0x5563,
285 0xcc4a, 0x2d42,
286 0xcc4b, 0x3002,
287 0xcc4c, 0x13d2,
288 0xcc4d, 0x2ed2,
289 0xcc4e, 0x3002,
290 0xcc4f, 0x1002,
291 0xcc50, 0x2fd2,
292 0xcc51, 0x3002,
293 0xcc52, 0x1002,
294 0xcc53, 0x004,
295 0xcc54, 0x2942,
296 0xcc55, 0x3002,
297 0xcc56, 0x1002,
298 0xcc57, 0x2092,
299 0xcc58, 0x3012,
300 0xcc59, 0x1002,
301 0xcc5a, 0x5cc3,
302 0xcc5b, 0x317,
303 0xcc5c, 0x2f72,
304 0xcc5d, 0x3002,
305 0xcc5e, 0x1002,
306 0xcc5f, 0x2942,
307 0xcc60, 0x3002,
308 0xcc61, 0x1002,
309 0xcc62, 0x22cd,
310 0xcc63, 0x301d,
311 0xcc64, 0x2862,
312 0xcc65, 0x3012,
313 0xcc66, 0x1002,
314 0xcc67, 0x2ed2,
315 0xcc68, 0x3002,
316 0xcc69, 0x1002,
317 0xcc6a, 0x2d72,
318 0xcc6b, 0x3002,
319 0xcc6c, 0x1002,
320 0xcc6d, 0x628f,
321 0xcc6e, 0x2112,
322 0xcc6f, 0x3012,
323 0xcc70, 0x1002,
324 0xcc71, 0x5aa3,
325 0xcc72, 0x2dc2,
326 0xcc73, 0x3002,
327 0xcc74, 0x1312,
328 0xcc75, 0x6f72,
329 0xcc76, 0x1002,
330 0xcc77, 0x2807,
331 0xcc78, 0x31a7,
332 0xcc79, 0x20c4,
333 0xcc7a, 0x3c24,
334 0xcc7b, 0x6724,
335 0xcc7c, 0x1002,
336 0xcc7d, 0x2807,
337 0xcc7e, 0x3187,
338 0xcc7f, 0x20c4,
339 0xcc80, 0x3c24,
340 0xcc81, 0x6724,
341 0xcc82, 0x1002,
342 0xcc83, 0x2514,
343 0xcc84, 0x3c64,
344 0xcc85, 0x6436,
345 0xcc86, 0xdff4,
346 0xcc87, 0x6436,
347 0xcc88, 0x1002,
348 0xcc89, 0x40a4,
349 0xcc8a, 0x643c,
350 0xcc8b, 0x4016,
351 0xcc8c, 0x8c6c,
352 0xcc8d, 0x2b24,
353 0xcc8e, 0x3c24,
354 0xcc8f, 0x6435,
355 0xcc90, 0x1002,
356 0xcc91, 0x2b24,
357 0xcc92, 0x3c24,
358 0xcc93, 0x643a,
359 0xcc94, 0x4025,
360 0xcc95, 0x8a5a,
361 0xcc96, 0x1002,
362 0xcc97, 0x2731,
363 0xcc98, 0x3011,
364 0xcc99, 0x1001,
365 0xcc9a, 0xc7a0,
366 0xcc9b, 0x100,
367 0xcc9c, 0xc502,
368 0xcc9d, 0x53ac,
369 0xcc9e, 0xc503,
370 0xcc9f, 0xd5d5,
371 0xcca0, 0xc600,
372 0xcca1, 0x2a6d,
373 0xcca2, 0xc601,
374 0xcca3, 0x2a4c,
375 0xcca4, 0xc602,
376 0xcca5, 0x111,
377 0xcca6, 0xc60c,
378 0xcca7, 0x5900,
379 0xcca8, 0xc710,
380 0xcca9, 0x700,
381 0xccaa, 0xc718,
382 0xccab, 0x700,
383 0xccac, 0xc720,
384 0xccad, 0x4700,
385 0xccae, 0xc801,
386 0xccaf, 0x7f50,
387 0xccb0, 0xc802,
388 0xccb1, 0x7760,
389 0xccb2, 0xc803,
390 0xccb3, 0x7fce,
391 0xccb4, 0xc804,
392 0xccb5, 0x5700,
393 0xccb6, 0xc805,
394 0xccb7, 0x5f11,
395 0xccb8, 0xc806,
396 0xccb9, 0x4751,
397 0xccba, 0xc807,
398 0xccbb, 0x57e1,
399 0xccbc, 0xc808,
400 0xccbd, 0x2700,
401 0xccbe, 0xc809,
402 0xccbf, 0x000,
403 0xccc0, 0xc821,
404 0xccc1, 0x002,
405 0xccc2, 0xc822,
406 0xccc3, 0x014,
407 0xccc4, 0xc832,
408 0xccc5, 0x1186,
409 0xccc6, 0xc847,
410 0xccc7, 0x1e02,
411 0xccc8, 0xc013,
412 0xccc9, 0xf341,
413 0xccca, 0xc01a,
414 0xcccb, 0x446,
415 0xcccc, 0xc024,
416 0xcccd, 0x1000,
417 0xccce, 0xc025,
418 0xcccf, 0xa00,
419 0xccd0, 0xc026,
420 0xccd1, 0xc0c,
421 0xccd2, 0xc027,
422 0xccd3, 0xc0c,
423 0xccd4, 0xc029,
424 0xccd5, 0x0a0,
425 0xccd6, 0xc030,
426 0xccd7, 0xa00,
427 0xccd8, 0xc03c,
428 0xccd9, 0x01c,
429 0xccda, 0xc005,
430 0xccdb, 0x7a06,
431 0xccdc, 0x000,
432 0xccdd, 0x2731,
433 0xccde, 0x3011,
434 0xccdf, 0x1001,
435 0xcce0, 0xc620,
436 0xcce1, 0x000,
437 0xcce2, 0xc621,
438 0xcce3, 0x03f,
439 0xcce4, 0xc622,
440 0xcce5, 0x000,
441 0xcce6, 0xc623,
442 0xcce7, 0x000,
443 0xcce8, 0xc624,
444 0xcce9, 0x000,
445 0xccea, 0xc625,
446 0xcceb, 0x000,
447 0xccec, 0xc627,
448 0xcced, 0x000,
449 0xccee, 0xc628,
450 0xccef, 0x000,
451 0xccf0, 0xc62c,
452 0xccf1, 0x000,
453 0xccf2, 0x000,
454 0xccf3, 0x2806,
455 0xccf4, 0x3cb6,
456 0xccf5, 0xc161,
457 0xccf6, 0x6134,
458 0xccf7, 0x6135,
459 0xccf8, 0x5443,
460 0xccf9, 0x303,
461 0xccfa, 0x6524,
462 0xccfb, 0x00b,
463 0xccfc, 0x1002,
464 0xccfd, 0x2104,
465 0xccfe, 0x3c24,
466 0xccff, 0x2105,
467 0xcd00, 0x3805,
468 0xcd01, 0x6524,
469 0xcd02, 0xdff4,
470 0xcd03, 0x4005,
471 0xcd04, 0x6524,
472 0xcd05, 0x1002,
473 0xcd06, 0x5dd3,
474 0xcd07, 0x306,
475 0xcd08, 0x2ff7,
476 0xcd09, 0x38f7,
477 0xcd0a, 0x60b7,
478 0xcd0b, 0xdffd,
479 0xcd0c, 0x00a,
480 0xcd0d, 0x1002,
481 0xcd0e, 0
482 };
483 int i, err;
484
485 err = set_phy_regs(phy, regs);
486 if (err)
487 return err;
488
489 msleep(50);
490
491 for (i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2)
Ben Hutchings0f07c4e2009-04-29 08:07:20 +0000492 err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, sr_edc[i],
493 sr_edc[i + 1]);
Divy Le Ray1e882022008-10-08 17:40:07 -0700494 if (!err)
495 phy->priv = edc_sr;
496 return err;
497}
498
499static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
500{
501 static struct reg_val regs[] = {
Ben Hutchings0f07c4e2009-04-29 08:07:20 +0000502 { MDIO_MMD_PMAPMD, 0xc04a, 0xffff, 0x5a00 },
Divy Le Ray1e882022008-10-08 17:40:07 -0700503 { 0, 0, 0, 0 }
504 };
505 static struct reg_val preemphasis[] = {
Ben Hutchings0f07c4e2009-04-29 08:07:20 +0000506 { MDIO_MMD_PMAPMD, 0xc014, 0xffff, 0xfe16 },
507 { MDIO_MMD_PMAPMD, 0xc015, 0xffff, 0xa000 },
Divy Le Ray1e882022008-10-08 17:40:07 -0700508 { 0, 0, 0, 0 }
509 };
510 static u16 twinax_edc[] = {
511 0xcc00, 0x4009,
512 0xcc01, 0x27ff,
513 0xcc02, 0x300f,
514 0xcc03, 0x40aa,
515 0xcc04, 0x401c,
516 0xcc05, 0x401e,
517 0xcc06, 0x2ff4,
518 0xcc07, 0x3cd4,
519 0xcc08, 0x2035,
520 0xcc09, 0x3145,
521 0xcc0a, 0x6524,
522 0xcc0b, 0x26a2,
523 0xcc0c, 0x3012,
524 0xcc0d, 0x1002,
525 0xcc0e, 0x29c2,
526 0xcc0f, 0x3002,
527 0xcc10, 0x1002,
528 0xcc11, 0x2072,
529 0xcc12, 0x3012,
530 0xcc13, 0x1002,
531 0xcc14, 0x22cd,
532 0xcc15, 0x301d,
533 0xcc16, 0x2e52,
534 0xcc17, 0x3012,
535 0xcc18, 0x1002,
536 0xcc19, 0x28e2,
537 0xcc1a, 0x3002,
538 0xcc1b, 0x1002,
539 0xcc1c, 0x628f,
540 0xcc1d, 0x2ac2,
541 0xcc1e, 0x3012,
542 0xcc1f, 0x1002,
543 0xcc20, 0x5553,
544 0xcc21, 0x2ae2,
545 0xcc22, 0x3002,
546 0xcc23, 0x1302,
547 0xcc24, 0x401e,
548 0xcc25, 0x2be2,
549 0xcc26, 0x3012,
550 0xcc27, 0x1002,
551 0xcc28, 0x2da2,
552 0xcc29, 0x3012,
553 0xcc2a, 0x1002,
554 0xcc2b, 0x2ba2,
555 0xcc2c, 0x3002,
556 0xcc2d, 0x1002,
557 0xcc2e, 0x5ee3,
558 0xcc2f, 0x305,
559 0xcc30, 0x400e,
560 0xcc31, 0x2bc2,
561 0xcc32, 0x3002,
562 0xcc33, 0x1002,
563 0xcc34, 0x2b82,
564 0xcc35, 0x3012,
565 0xcc36, 0x1002,
566 0xcc37, 0x5663,
567 0xcc38, 0x302,
568 0xcc39, 0x401e,
569 0xcc3a, 0x6f72,
570 0xcc3b, 0x1002,
571 0xcc3c, 0x628f,
572 0xcc3d, 0x2be2,
573 0xcc3e, 0x3012,
574 0xcc3f, 0x1002,
575 0xcc40, 0x22cd,
576 0xcc41, 0x301d,
577 0xcc42, 0x2e52,
578 0xcc43, 0x3012,
579 0xcc44, 0x1002,
580 0xcc45, 0x2522,
581 0xcc46, 0x3012,
582 0xcc47, 0x1002,
583 0xcc48, 0x2da2,
584 0xcc49, 0x3012,
585 0xcc4a, 0x1002,
586 0xcc4b, 0x2ca2,
587 0xcc4c, 0x3012,
588 0xcc4d, 0x1002,
589 0xcc4e, 0x2fa4,
590 0xcc4f, 0x3cd4,
591 0xcc50, 0x6624,
592 0xcc51, 0x410b,
593 0xcc52, 0x56b3,
594 0xcc53, 0x3c4,
595 0xcc54, 0x2fb2,
596 0xcc55, 0x3002,
597 0xcc56, 0x1002,
598 0xcc57, 0x220b,
599 0xcc58, 0x303b,
600 0xcc59, 0x56b3,
601 0xcc5a, 0x3c3,
602 0xcc5b, 0x866b,
603 0xcc5c, 0x400c,
604 0xcc5d, 0x23a2,
605 0xcc5e, 0x3012,
606 0xcc5f, 0x1002,
607 0xcc60, 0x2da2,
608 0xcc61, 0x3012,
609 0xcc62, 0x1002,
610 0xcc63, 0x2ca2,
611 0xcc64, 0x3012,
612 0xcc65, 0x1002,
613 0xcc66, 0x2fb4,
614 0xcc67, 0x3cd4,
615 0xcc68, 0x6624,
616 0xcc69, 0x56b3,
617 0xcc6a, 0x3c3,
618 0xcc6b, 0x866b,
619 0xcc6c, 0x401c,
620 0xcc6d, 0x2205,
621 0xcc6e, 0x3035,
622 0xcc6f, 0x5b53,
623 0xcc70, 0x2c52,
624 0xcc71, 0x3002,
625 0xcc72, 0x13c2,
626 0xcc73, 0x5cc3,
627 0xcc74, 0x317,
628 0xcc75, 0x2522,
629 0xcc76, 0x3012,
630 0xcc77, 0x1002,
631 0xcc78, 0x2da2,
632 0xcc79, 0x3012,
633 0xcc7a, 0x1002,
634 0xcc7b, 0x2b82,
635 0xcc7c, 0x3012,
636 0xcc7d, 0x1002,
637 0xcc7e, 0x5663,
638 0xcc7f, 0x303,
639 0xcc80, 0x401e,
640 0xcc81, 0x004,
641 0xcc82, 0x2c42,
642 0xcc83, 0x3012,
643 0xcc84, 0x1002,
644 0xcc85, 0x6f72,
645 0xcc86, 0x1002,
646 0xcc87, 0x628f,
647 0xcc88, 0x2304,
648 0xcc89, 0x3c84,
649 0xcc8a, 0x6436,
650 0xcc8b, 0xdff4,
651 0xcc8c, 0x6436,
652 0xcc8d, 0x2ff5,
653 0xcc8e, 0x3005,
654 0xcc8f, 0x8656,
655 0xcc90, 0xdfba,
656 0xcc91, 0x56a3,
657 0xcc92, 0xd05a,
658 0xcc93, 0x21c2,
659 0xcc94, 0x3012,
660 0xcc95, 0x1392,
661 0xcc96, 0xd05a,
662 0xcc97, 0x56a3,
663 0xcc98, 0xdfba,
664 0xcc99, 0x383,
665 0xcc9a, 0x6f72,
666 0xcc9b, 0x1002,
667 0xcc9c, 0x28c5,
668 0xcc9d, 0x3005,
669 0xcc9e, 0x4178,
670 0xcc9f, 0x5653,
671 0xcca0, 0x384,
672 0xcca1, 0x22b2,
673 0xcca2, 0x3012,
674 0xcca3, 0x1002,
675 0xcca4, 0x2be5,
676 0xcca5, 0x3005,
677 0xcca6, 0x41e8,
678 0xcca7, 0x5653,
679 0xcca8, 0x382,
680 0xcca9, 0x002,
681 0xccaa, 0x4258,
682 0xccab, 0x2474,
683 0xccac, 0x3c84,
684 0xccad, 0x6437,
685 0xccae, 0xdff4,
686 0xccaf, 0x6437,
687 0xccb0, 0x2ff5,
688 0xccb1, 0x3c05,
689 0xccb2, 0x8757,
690 0xccb3, 0xb888,
691 0xccb4, 0x9787,
692 0xccb5, 0xdff4,
693 0xccb6, 0x6724,
694 0xccb7, 0x866a,
695 0xccb8, 0x6f72,
696 0xccb9, 0x1002,
697 0xccba, 0x2d01,
698 0xccbb, 0x3011,
699 0xccbc, 0x1001,
700 0xccbd, 0xc620,
701 0xccbe, 0x14e5,
702 0xccbf, 0xc621,
703 0xccc0, 0xc53d,
704 0xccc1, 0xc622,
705 0xccc2, 0x3cbe,
706 0xccc3, 0xc623,
707 0xccc4, 0x4452,
708 0xccc5, 0xc624,
709 0xccc6, 0xc5c5,
710 0xccc7, 0xc625,
711 0xccc8, 0xe01e,
712 0xccc9, 0xc627,
713 0xccca, 0x000,
714 0xcccb, 0xc628,
715 0xcccc, 0x000,
716 0xcccd, 0xc62b,
717 0xccce, 0x000,
718 0xcccf, 0xc62c,
719 0xccd0, 0x000,
720 0xccd1, 0x000,
721 0xccd2, 0x2d01,
722 0xccd3, 0x3011,
723 0xccd4, 0x1001,
724 0xccd5, 0xc620,
725 0xccd6, 0x000,
726 0xccd7, 0xc621,
727 0xccd8, 0x000,
728 0xccd9, 0xc622,
729 0xccda, 0x0ce,
730 0xccdb, 0xc623,
731 0xccdc, 0x07f,
732 0xccdd, 0xc624,
733 0xccde, 0x032,
734 0xccdf, 0xc625,
735 0xcce0, 0x000,
736 0xcce1, 0xc627,
737 0xcce2, 0x000,
738 0xcce3, 0xc628,
739 0xcce4, 0x000,
740 0xcce5, 0xc62b,
741 0xcce6, 0x000,
742 0xcce7, 0xc62c,
743 0xcce8, 0x000,
744 0xcce9, 0x000,
745 0xccea, 0x2d01,
746 0xcceb, 0x3011,
747 0xccec, 0x1001,
748 0xcced, 0xc502,
749 0xccee, 0x609f,
750 0xccef, 0xc600,
751 0xccf0, 0x2a6e,
752 0xccf1, 0xc601,
753 0xccf2, 0x2a2c,
754 0xccf3, 0xc60c,
755 0xccf4, 0x5400,
756 0xccf5, 0xc710,
757 0xccf6, 0x700,
758 0xccf7, 0xc718,
759 0xccf8, 0x700,
760 0xccf9, 0xc720,
761 0xccfa, 0x4700,
762 0xccfb, 0xc728,
763 0xccfc, 0x700,
764 0xccfd, 0xc729,
765 0xccfe, 0x1207,
766 0xccff, 0xc801,
767 0xcd00, 0x7f50,
768 0xcd01, 0xc802,
769 0xcd02, 0x7760,
770 0xcd03, 0xc803,
771 0xcd04, 0x7fce,
772 0xcd05, 0xc804,
773 0xcd06, 0x520e,
774 0xcd07, 0xc805,
775 0xcd08, 0x5c11,
776 0xcd09, 0xc806,
777 0xcd0a, 0x3c51,
778 0xcd0b, 0xc807,
779 0xcd0c, 0x4061,
780 0xcd0d, 0xc808,
781 0xcd0e, 0x49c1,
782 0xcd0f, 0xc809,
783 0xcd10, 0x3840,
784 0xcd11, 0xc80a,
785 0xcd12, 0x000,
786 0xcd13, 0xc821,
787 0xcd14, 0x002,
788 0xcd15, 0xc822,
789 0xcd16, 0x046,
790 0xcd17, 0xc844,
791 0xcd18, 0x182f,
792 0xcd19, 0xc013,
793 0xcd1a, 0xf341,
794 0xcd1b, 0xc01a,
795 0xcd1c, 0x446,
796 0xcd1d, 0xc024,
797 0xcd1e, 0x1000,
798 0xcd1f, 0xc025,
799 0xcd20, 0xa00,
800 0xcd21, 0xc026,
801 0xcd22, 0xc0c,
802 0xcd23, 0xc027,
803 0xcd24, 0xc0c,
804 0xcd25, 0xc029,
805 0xcd26, 0x0a0,
806 0xcd27, 0xc030,
807 0xcd28, 0xa00,
808 0xcd29, 0xc03c,
809 0xcd2a, 0x01c,
810 0xcd2b, 0x000,
811 0xcd2c, 0x2b84,
812 0xcd2d, 0x3c74,
813 0xcd2e, 0x6435,
814 0xcd2f, 0xdff4,
815 0xcd30, 0x6435,
816 0xcd31, 0x2806,
817 0xcd32, 0x3006,
818 0xcd33, 0x8565,
819 0xcd34, 0x2b24,
820 0xcd35, 0x3c24,
821 0xcd36, 0x6436,
822 0xcd37, 0x1002,
823 0xcd38, 0x2b24,
824 0xcd39, 0x3c24,
825 0xcd3a, 0x6436,
826 0xcd3b, 0x4045,
827 0xcd3c, 0x8656,
828 0xcd3d, 0x1002,
829 0xcd3e, 0x2807,
830 0xcd3f, 0x31a7,
831 0xcd40, 0x20c4,
832 0xcd41, 0x3c24,
833 0xcd42, 0x6724,
834 0xcd43, 0x1002,
835 0xcd44, 0x2807,
836 0xcd45, 0x3187,
837 0xcd46, 0x20c4,
838 0xcd47, 0x3c24,
839 0xcd48, 0x6724,
840 0xcd49, 0x1002,
841 0xcd4a, 0x2514,
842 0xcd4b, 0x3c64,
843 0xcd4c, 0x6436,
844 0xcd4d, 0xdff4,
845 0xcd4e, 0x6436,
846 0xcd4f, 0x1002,
847 0xcd50, 0x2806,
848 0xcd51, 0x3cb6,
849 0xcd52, 0xc161,
850 0xcd53, 0x6134,
851 0xcd54, 0x6135,
852 0xcd55, 0x5443,
853 0xcd56, 0x303,
854 0xcd57, 0x6524,
855 0xcd58, 0x00b,
856 0xcd59, 0x1002,
857 0xcd5a, 0xd019,
858 0xcd5b, 0x2104,
859 0xcd5c, 0x3c24,
860 0xcd5d, 0x2105,
861 0xcd5e, 0x3805,
862 0xcd5f, 0x6524,
863 0xcd60, 0xdff4,
864 0xcd61, 0x4005,
865 0xcd62, 0x6524,
866 0xcd63, 0x2e8d,
867 0xcd64, 0x303d,
868 0xcd65, 0x5dd3,
869 0xcd66, 0x306,
870 0xcd67, 0x2ff7,
871 0xcd68, 0x38f7,
872 0xcd69, 0x60b7,
873 0xcd6a, 0xdffd,
874 0xcd6b, 0x00a,
875 0xcd6c, 0x1002,
876 0xcd6d, 0
877 };
878 int i, err;
879
880 err = set_phy_regs(phy, regs);
881 if (!err && modtype == phy_modtype_twinax_long)
882 err = set_phy_regs(phy, preemphasis);
883 if (err)
884 return err;
885
886 msleep(50);
887
888 for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2)
Ben Hutchings0f07c4e2009-04-29 08:07:20 +0000889 err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, twinax_edc[i],
890 twinax_edc[i + 1]);
Divy Le Ray1e882022008-10-08 17:40:07 -0700891 if (!err)
892 phy->priv = edc_twinax;
893 return err;
894}
895
896static int ael2005_i2c_rd(struct cphy *phy, int dev_addr, int word_addr)
897{
898 int i, err;
899 unsigned int stat, data;
900
Ben Hutchings0f07c4e2009-04-29 08:07:20 +0000901 err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL_I2C_CTRL,
902 (dev_addr << 8) | (1 << 8) | word_addr);
Divy Le Ray1e882022008-10-08 17:40:07 -0700903 if (err)
904 return err;
905
906 for (i = 0; i < 5; i++) {
907 msleep(1);
Ben Hutchings0f07c4e2009-04-29 08:07:20 +0000908 err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_STAT, &stat);
Divy Le Ray1e882022008-10-08 17:40:07 -0700909 if (err)
910 return err;
911 if ((stat & 3) == 1) {
Ben Hutchings0f07c4e2009-04-29 08:07:20 +0000912 err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL_I2C_DATA,
913 &data);
Divy Le Ray1e882022008-10-08 17:40:07 -0700914 if (err)
915 return err;
916 return data >> 8;
917 }
918 }
919 CH_WARN(phy->adapter, "PHY %u I2C read of addr %u timed out\n",
Ben Hutchings0f07c4e2009-04-29 08:07:20 +0000920 phy->mdio.prtad, word_addr);
Divy Le Ray1e882022008-10-08 17:40:07 -0700921 return -ETIMEDOUT;
922}
923
924static int get_module_type(struct cphy *phy, int delay_ms)
925{
926 int v;
927 unsigned int stat;
928
Ben Hutchings0f07c4e2009-04-29 08:07:20 +0000929 v = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, &stat);
Divy Le Ray1e882022008-10-08 17:40:07 -0700930 if (v)
931 return v;
932
933 if (stat & (1 << 8)) /* module absent */
934 return phy_modtype_none;
935
936 if (delay_ms)
937 msleep(delay_ms);
938
939 /* see SFF-8472 for below */
940 v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 3);
941 if (v < 0)
942 return v;
943
944 if (v == 0x10)
945 return phy_modtype_sr;
946 if (v == 0x20)
947 return phy_modtype_lr;
948 if (v == 0x40)
949 return phy_modtype_lrm;
950
951 v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 6);
952 if (v < 0)
953 return v;
954 if (v != 4)
955 goto unknown;
956
957 v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 10);
958 if (v < 0)
959 return v;
960
961 if (v & 0x80) {
962 v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 0x12);
963 if (v < 0)
964 return v;
965 return v > 10 ? phy_modtype_twinax_long : phy_modtype_twinax;
966 }
967unknown:
968 return phy_modtype_unknown;
969}
970
971static int ael2005_intr_enable(struct cphy *phy)
972{
Ben Hutchings0f07c4e2009-04-29 08:07:20 +0000973 int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0x200);
Divy Le Ray1e882022008-10-08 17:40:07 -0700974 return err ? err : t3_phy_lasi_intr_enable(phy);
975}
976
977static int ael2005_intr_disable(struct cphy *phy)
978{
Ben Hutchings0f07c4e2009-04-29 08:07:20 +0000979 int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0x100);
Divy Le Ray1e882022008-10-08 17:40:07 -0700980 return err ? err : t3_phy_lasi_intr_disable(phy);
981}
982
983static int ael2005_intr_clear(struct cphy *phy)
984{
Ben Hutchings0f07c4e2009-04-29 08:07:20 +0000985 int err = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL, 0xd00);
Divy Le Ray1e882022008-10-08 17:40:07 -0700986 return err ? err : t3_phy_lasi_intr_clear(phy);
987}
988
989static int ael2005_reset(struct cphy *phy, int wait)
990{
991 static struct reg_val regs0[] = {
Ben Hutchings0f07c4e2009-04-29 08:07:20 +0000992 { MDIO_MMD_PMAPMD, 0xc001, 0, 1 << 5 },
993 { MDIO_MMD_PMAPMD, 0xc017, 0, 1 << 5 },
994 { MDIO_MMD_PMAPMD, 0xc013, 0xffff, 0xf341 },
995 { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8000 },
996 { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8100 },
997 { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0x8000 },
998 { MDIO_MMD_PMAPMD, 0xc210, 0xffff, 0 },
Divy Le Ray1e882022008-10-08 17:40:07 -0700999 { 0, 0, 0, 0 }
1000 };
1001 static struct reg_val regs1[] = {
Ben Hutchings0f07c4e2009-04-29 08:07:20 +00001002 { MDIO_MMD_PMAPMD, 0xca00, 0xffff, 0x0080 },
1003 { MDIO_MMD_PMAPMD, 0xca12, 0xffff, 0 },
Divy Le Ray1e882022008-10-08 17:40:07 -07001004 { 0, 0, 0, 0 }
1005 };
1006
Hannes Edera243f842009-02-14 11:16:19 +00001007 int err;
1008 unsigned int lasi_ctrl;
Divy Le Ray1e882022008-10-08 17:40:07 -07001009
Ben Hutchings64318332009-05-19 13:22:30 +00001010 err = t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_PMA_LASI_CTRL,
1011 &lasi_ctrl);
Divy Le Ray1e882022008-10-08 17:40:07 -07001012 if (err)
1013 return err;
1014
Ben Hutchings0f07c4e2009-04-29 08:07:20 +00001015 err = t3_phy_reset(phy, MDIO_MMD_PMAPMD, 0);
Divy Le Ray1e882022008-10-08 17:40:07 -07001016 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
1049static int ael2005_intr_handler(struct cphy *phy)
1050{
1051 unsigned int stat;
1052 int ret, edc_needed, cause = 0;
1053
Ben Hutchings0f07c4e2009-04-29 08:07:20 +00001054 ret = t3_mdio_read(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_STAT, &stat);
Divy Le Ray1e882022008-10-08 17:40:07 -07001055 if (ret)
1056 return ret;
1057
1058 if (stat & AEL2005_MODDET_IRQ) {
Ben Hutchings0f07c4e2009-04-29 08:07:20 +00001059 ret = t3_mdio_write(phy, MDIO_MMD_PMAPMD, AEL2005_GPIO_CTRL,
1060 0xd00);
Divy Le Ray1e882022008-10-08 17:40:07 -07001061 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
1093static 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,
Ben Hutchings0f07c4e2009-04-29 08:07:20 +00001101 .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
Divy Le Ray1e882022008-10-08 17:40:07 -07001102};
1103
1104int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter,
1105 int phy_addr, const struct mdio_ops *mdio_ops)
1106{
1107 cphy_init(phy, adapter, phy_addr, &ael2005_ops, mdio_ops,
1108 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE |
1109 SUPPORTED_IRQ, "10GBASE-R");
1110 msleep(125);
Ben Hutchings0f07c4e2009-04-29 08:07:20 +00001111 return t3_mdio_change_bits(phy, MDIO_MMD_PMAPMD, AEL_OPT_SETTINGS, 0,
Divy Le Ray1e882022008-10-08 17:40:07 -07001112 1 << 5);
1113}
1114
1115/*
1116 * Get link status for a 10GBASE-X device.
1117 */
1118static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed,
1119 int *duplex, int *fc)
1120{
1121 if (link_ok) {
1122 unsigned int stat0, stat1, stat2;
Ben Hutchings0f07c4e2009-04-29 08:07:20 +00001123 int err = t3_mdio_read(phy, MDIO_MMD_PMAPMD,
1124 MDIO_PMA_RXDET, &stat0);
Divy Le Ray1e882022008-10-08 17:40:07 -07001125
1126 if (!err)
Ben Hutchings0f07c4e2009-04-29 08:07:20 +00001127 err = t3_mdio_read(phy, MDIO_MMD_PCS,
1128 MDIO_PCS_10GBX_STAT1, &stat1);
Divy Le Ray1e882022008-10-08 17:40:07 -07001129 if (!err)
Ben Hutchings0f07c4e2009-04-29 08:07:20 +00001130 err = t3_mdio_read(phy, MDIO_MMD_PHYXS,
1131 MDIO_PHYXS_LNSTAT, &stat2);
Divy Le Ray1e882022008-10-08 17:40:07 -07001132 if (err)
1133 return err;
1134 *link_ok = (stat0 & (stat1 >> 12) & (stat2 >> 12)) & 1;
1135 }
1136 if (speed)
1137 *speed = SPEED_10000;
1138 if (duplex)
1139 *duplex = DUPLEX_FULL;
1140 return 0;
1141}
1142
Divy Le Ray4d22de32007-01-18 22:04:14 -05001143static struct cphy_ops qt2045_ops = {
1144 .reset = ael1006_reset,
Divy Le Ray9b1e3652008-10-08 17:39:31 -07001145 .intr_enable = t3_phy_lasi_intr_enable,
1146 .intr_disable = t3_phy_lasi_intr_disable,
1147 .intr_clear = t3_phy_lasi_intr_clear,
1148 .intr_handler = t3_phy_lasi_intr_handler,
Divy Le Ray1e882022008-10-08 17:40:07 -07001149 .get_link_status = get_link_status_x,
Divy Le Ray4d22de32007-01-18 22:04:14 -05001150 .power_down = ael1006_power_down,
Ben Hutchings0f07c4e2009-04-29 08:07:20 +00001151 .mmds = MDIO_DEVS_PMAPMD | MDIO_DEVS_PCS | MDIO_DEVS_PHYXS,
Divy Le Ray4d22de32007-01-18 22:04:14 -05001152};
1153
Divy Le Ray78e46892008-10-08 17:38:01 -07001154int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter,
1155 int phy_addr, const struct mdio_ops *mdio_ops)
Divy Le Ray4d22de32007-01-18 22:04:14 -05001156{
1157 unsigned int stat;
1158
Divy Le Ray04497982008-10-08 17:38:29 -07001159 cphy_init(phy, adapter, phy_addr, &qt2045_ops, mdio_ops,
1160 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
1161 "10GBASE-CX4");
Divy Le Ray4d22de32007-01-18 22:04:14 -05001162
1163 /*
1164 * Some cards where the PHY is supposed to be at address 0 actually
1165 * have it at 1.
1166 */
Ben Hutchings0f07c4e2009-04-29 08:07:20 +00001167 if (!phy_addr &&
1168 !t3_mdio_read(phy, MDIO_MMD_PMAPMD, MDIO_STAT1, &stat) &&
Divy Le Ray4d22de32007-01-18 22:04:14 -05001169 stat == 0xffff)
Ben Hutchings0f07c4e2009-04-29 08:07:20 +00001170 phy->mdio.prtad = 1;
Divy Le Ray78e46892008-10-08 17:38:01 -07001171 return 0;
Divy Le Ray4d22de32007-01-18 22:04:14 -05001172}
1173
1174static int xaui_direct_reset(struct cphy *phy, int wait)
1175{
1176 return 0;
1177}
1178
1179static int xaui_direct_get_link_status(struct cphy *phy, int *link_ok,
1180 int *speed, int *duplex, int *fc)
1181{
1182 if (link_ok) {
1183 unsigned int status;
Ben Hutchings0f07c4e2009-04-29 08:07:20 +00001184 int prtad = phy->mdio.prtad;
Divy Le Ray4d22de32007-01-18 22:04:14 -05001185
1186 status = t3_read_reg(phy->adapter,
Ben Hutchings0f07c4e2009-04-29 08:07:20 +00001187 XGM_REG(A_XGM_SERDES_STAT0, prtad)) |
Divy Le Rayc706bfb2007-05-30 10:01:39 -07001188 t3_read_reg(phy->adapter,
Ben Hutchings0f07c4e2009-04-29 08:07:20 +00001189 XGM_REG(A_XGM_SERDES_STAT1, prtad)) |
Divy Le Rayc706bfb2007-05-30 10:01:39 -07001190 t3_read_reg(phy->adapter,
Ben Hutchings0f07c4e2009-04-29 08:07:20 +00001191 XGM_REG(A_XGM_SERDES_STAT2, prtad)) |
Divy Le Rayc706bfb2007-05-30 10:01:39 -07001192 t3_read_reg(phy->adapter,
Ben Hutchings0f07c4e2009-04-29 08:07:20 +00001193 XGM_REG(A_XGM_SERDES_STAT3, prtad));
Divy Le Ray4d22de32007-01-18 22:04:14 -05001194 *link_ok = !(status & F_LOWSIG0);
1195 }
1196 if (speed)
1197 *speed = SPEED_10000;
1198 if (duplex)
1199 *duplex = DUPLEX_FULL;
1200 return 0;
1201}
1202
1203static int xaui_direct_power_down(struct cphy *phy, int enable)
1204{
1205 return 0;
1206}
1207
1208static struct cphy_ops xaui_direct_ops = {
1209 .reset = xaui_direct_reset,
1210 .intr_enable = ael1002_intr_noop,
1211 .intr_disable = ael1002_intr_noop,
1212 .intr_clear = ael1002_intr_noop,
1213 .intr_handler = ael1002_intr_noop,
1214 .get_link_status = xaui_direct_get_link_status,
1215 .power_down = xaui_direct_power_down,
1216};
1217
Divy Le Ray78e46892008-10-08 17:38:01 -07001218int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter,
1219 int phy_addr, const struct mdio_ops *mdio_ops)
Divy Le Ray4d22de32007-01-18 22:04:14 -05001220{
Ben Hutchings0f07c4e2009-04-29 08:07:20 +00001221 cphy_init(phy, adapter, MDIO_PRTAD_NONE, &xaui_direct_ops, mdio_ops,
Divy Le Ray04497982008-10-08 17:38:29 -07001222 SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
1223 "10GBASE-CX4");
Divy Le Ray78e46892008-10-08 17:38:01 -07001224 return 0;
Divy Le Ray4d22de32007-01-18 22:04:14 -05001225}