xref: /freebsd/sys/dev/cxgb/common/cxgb_ael1002.c (revision f7c4bd95ba735bd6a5454b4953945a99cefbb80c)
1 /**************************************************************************
2 
3 Copyright (c) 2007-2008, Chelsio Inc.
4 All rights reserved.
5 
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
8 
9  1. Redistributions of source code must retain the above copyright notice,
10     this list of conditions and the following disclaimer.
11 
12  2. Neither the name of the Chelsio Corporation nor the names of its
13     contributors may be used to endorse or promote products derived from
14     this software without specific prior written permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 POSSIBILITY OF SUCH DAMAGE.
27 
28 ***************************************************************************/
29 
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32 
33 #ifdef CONFIG_DEFINED
34 #include <cxgb_include.h>
35 #else
36 #include <dev/cxgb/cxgb_include.h>
37 #endif
38 
39 #undef msleep
40 #define msleep t3_os_sleep
41 
42 enum {
43 	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 };
51 
52 struct reg_val {
53 	unsigned short mmd_addr;
54 	unsigned short reg_addr;
55 	unsigned short clear_bits;
56 	unsigned short set_bits;
57 };
58 
59 static int set_phy_regs(struct cphy *phy, const struct reg_val *rv)
60 {
61 	int err;
62 
63 	for (err = 0; rv->mmd_addr && !err; rv++) {
64 		if (rv->clear_bits == 0xffff)
65 			err = mdio_write(phy, rv->mmd_addr, rv->reg_addr,
66 					 rv->set_bits);
67 		else
68 			err = t3_mdio_change_bits(phy, rv->mmd_addr,
69 						  rv->reg_addr, rv->clear_bits,
70 						  rv->set_bits);
71 	}
72 	return err;
73 }
74 
75 static void ael100x_txon(struct cphy *phy)
76 {
77 	int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL;
78 
79 	msleep(100);
80 	t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 0, tx_on_gpio);
81 	msleep(30);
82 }
83 
84 static int ael1002_power_down(struct cphy *phy, int enable)
85 {
86 	int err;
87 
88 	err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_DISABLE, !!enable);
89 	if (!err)
90 		err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR,
91 					  BMCR_PDOWN, enable ? BMCR_PDOWN : 0);
92 	return err;
93 }
94 
95 static int ael1002_reset(struct cphy *phy, int wait)
96 {
97 	int err;
98 
99 	if ((err = ael1002_power_down(phy, 0)) ||
100 	    (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_CONFIG1, 1)) ||
101 	    (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_HI, 0)) ||
102 	    (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_LO, 0)) ||
103 	    (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_XFI_EQL, 0x18)) ||
104 	    (err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL1002_LB_EN,
105 				       0, 1 << 5)))
106 		return err;
107 	return 0;
108 }
109 
110 static int ael1002_intr_noop(struct cphy *phy)
111 {
112 	return 0;
113 }
114 
115 static int ael100x_get_link_status(struct cphy *phy, int *link_ok,
116 				   int *speed, int *duplex, int *fc)
117 {
118 	if (link_ok) {
119 		unsigned int status;
120 		int err = mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &status);
121 
122 		/*
123 		 * BMSR_LSTATUS is latch-low, so if it is 0 we need to read it
124 		 * once more to get the current link state.
125 		 */
126 		if (!err && !(status & BMSR_LSTATUS))
127 			err = mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR,
128 					&status);
129 		if (err)
130 			return err;
131 		*link_ok = !!(status & BMSR_LSTATUS);
132 	}
133 	if (speed)
134 		*speed = SPEED_10000;
135 	if (duplex)
136 		*duplex = DUPLEX_FULL;
137 	return 0;
138 }
139 
140 #ifdef C99_NOT_SUPPORTED
141 static struct cphy_ops ael1002_ops = {
142 	ael1002_reset,
143 	ael1002_intr_noop,
144 	ael1002_intr_noop,
145 	ael1002_intr_noop,
146 	ael1002_intr_noop,
147 	NULL,
148 	NULL,
149 	NULL,
150 	NULL,
151 	NULL,
152 	ael100x_get_link_status,
153 	ael1002_power_down,
154 };
155 #else
156 static struct cphy_ops ael1002_ops = {
157 	.reset           = ael1002_reset,
158 	.intr_enable     = ael1002_intr_noop,
159 	.intr_disable    = ael1002_intr_noop,
160 	.intr_clear      = ael1002_intr_noop,
161 	.intr_handler    = ael1002_intr_noop,
162 	.get_link_status = ael100x_get_link_status,
163 	.power_down      = ael1002_power_down,
164 };
165 #endif
166 
167 int t3_ael1002_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr,
168 			const struct mdio_ops *mdio_ops)
169 {
170 	cphy_init(phy, adapter, phy_addr, &ael1002_ops, mdio_ops,
171 		  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE,
172 		  "10GBASE-R");
173 	ael100x_txon(phy);
174 	return 0;
175 }
176 
177 static int ael1006_reset(struct cphy *phy, int wait)
178 {
179 	return t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait);
180 }
181 
182 static int ael1006_power_down(struct cphy *phy, int enable)
183 {
184 	return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR,
185 				   BMCR_PDOWN, enable ? BMCR_PDOWN : 0);
186 }
187 
188 #ifdef C99_NOT_SUPPORTED
189 static struct cphy_ops ael1006_ops = {
190 	ael1006_reset,
191 	t3_phy_lasi_intr_enable,
192 	t3_phy_lasi_intr_disable,
193 	t3_phy_lasi_intr_clear,
194 	t3_phy_lasi_intr_handler,
195 	NULL,
196 	NULL,
197 	NULL,
198 	NULL,
199 	NULL,
200 	ael100x_get_link_status,
201 	ael1006_power_down,
202 };
203 #else
204 static struct cphy_ops ael1006_ops = {
205 	.reset           = ael1006_reset,
206 	.intr_enable     = t3_phy_lasi_intr_enable,
207 	.intr_disable    = t3_phy_lasi_intr_disable,
208 	.intr_clear      = t3_phy_lasi_intr_clear,
209 	.intr_handler    = t3_phy_lasi_intr_handler,
210 	.get_link_status = ael100x_get_link_status,
211 	.power_down      = ael1006_power_down,
212 };
213 #endif
214 
215 int t3_ael1006_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr,
216 			const struct mdio_ops *mdio_ops)
217 {
218 	cphy_init(phy, adapter, phy_addr, &ael1006_ops, mdio_ops,
219 		  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE,
220 		  "10GBASE-SR");
221 	ael100x_txon(phy);
222 	return 0;
223 }
224 
225 static int ael2005_setup_sr_edc(struct cphy *phy)
226 {
227 	static u16 sr_edc[] = {
228 		0xcc00, 0x2ff4,
229 		0xcc01, 0x3cd4,
230 		0xcc02, 0x2015,
231 		0xcc03, 0x3105,
232 		0xcc04, 0x6524,
233 		0xcc05, 0x27ff,
234 		0xcc06, 0x300f,
235 		0xcc07, 0x2c8b,
236 		0xcc08, 0x300b,
237 		0xcc09, 0x4009,
238 		0xcc0a, 0x400e,
239 		0xcc0b, 0x2f72,
240 		0xcc0c, 0x3002,
241 		0xcc0d, 0x1002,
242 		0xcc0e, 0x2172,
243 		0xcc0f, 0x3012,
244 		0xcc10, 0x1002,
245 		0xcc11, 0x25d2,
246 		0xcc12, 0x3012,
247 		0xcc13, 0x1002,
248 		0xcc14, 0xd01e,
249 		0xcc15, 0x27d2,
250 		0xcc16, 0x3012,
251 		0xcc17, 0x1002,
252 		0xcc18, 0x2004,
253 		0xcc19, 0x3c84,
254 		0xcc1a, 0x6436,
255 		0xcc1b, 0x2007,
256 		0xcc1c, 0x3f87,
257 		0xcc1d, 0x8676,
258 		0xcc1e, 0x40b7,
259 		0xcc1f, 0xa746,
260 		0xcc20, 0x4047,
261 		0xcc21, 0x5673,
262 		0xcc22, 0x2982,
263 		0xcc23, 0x3002,
264 		0xcc24, 0x13d2,
265 		0xcc25, 0x8bbd,
266 		0xcc26, 0x2862,
267 		0xcc27, 0x3012,
268 		0xcc28, 0x1002,
269 		0xcc29, 0x2092,
270 		0xcc2a, 0x3012,
271 		0xcc2b, 0x1002,
272 		0xcc2c, 0x5cc3,
273 		0xcc2d, 0x314,
274 		0xcc2e, 0x2942,
275 		0xcc2f, 0x3002,
276 		0xcc30, 0x1002,
277 		0xcc31, 0xd019,
278 		0xcc32, 0x2032,
279 		0xcc33, 0x3012,
280 		0xcc34, 0x1002,
281 		0xcc35, 0x2a04,
282 		0xcc36, 0x3c74,
283 		0xcc37, 0x6435,
284 		0xcc38, 0x2fa4,
285 		0xcc39, 0x3cd4,
286 		0xcc3a, 0x6624,
287 		0xcc3b, 0x5563,
288 		0xcc3c, 0x2d42,
289 		0xcc3d, 0x3002,
290 		0xcc3e, 0x13d2,
291 		0xcc3f, 0x464d,
292 		0xcc40, 0x2862,
293 		0xcc41, 0x3012,
294 		0xcc42, 0x1002,
295 		0xcc43, 0x2032,
296 		0xcc44, 0x3012,
297 		0xcc45, 0x1002,
298 		0xcc46, 0x2fb4,
299 		0xcc47, 0x3cd4,
300 		0xcc48, 0x6624,
301 		0xcc49, 0x5563,
302 		0xcc4a, 0x2d42,
303 		0xcc4b, 0x3002,
304 		0xcc4c, 0x13d2,
305 		0xcc4d, 0x2ed2,
306 		0xcc4e, 0x3002,
307 		0xcc4f, 0x1002,
308 		0xcc50, 0x2fd2,
309 		0xcc51, 0x3002,
310 		0xcc52, 0x1002,
311 		0xcc53, 0x004,
312 		0xcc54, 0x2942,
313 		0xcc55, 0x3002,
314 		0xcc56, 0x1002,
315 		0xcc57, 0x2092,
316 		0xcc58, 0x3012,
317 		0xcc59, 0x1002,
318 		0xcc5a, 0x5cc3,
319 		0xcc5b, 0x317,
320 		0xcc5c, 0x2f72,
321 		0xcc5d, 0x3002,
322 		0xcc5e, 0x1002,
323 		0xcc5f, 0x2942,
324 		0xcc60, 0x3002,
325 		0xcc61, 0x1002,
326 		0xcc62, 0x22cd,
327 		0xcc63, 0x301d,
328 		0xcc64, 0x2862,
329 		0xcc65, 0x3012,
330 		0xcc66, 0x1002,
331 		0xcc67, 0x2ed2,
332 		0xcc68, 0x3002,
333 		0xcc69, 0x1002,
334 		0xcc6a, 0x2d72,
335 		0xcc6b, 0x3002,
336 		0xcc6c, 0x1002,
337 		0xcc6d, 0x628f,
338 		0xcc6e, 0x2112,
339 		0xcc6f, 0x3012,
340 		0xcc70, 0x1002,
341 		0xcc71, 0x5aa3,
342 		0xcc72, 0x2dc2,
343 		0xcc73, 0x3002,
344 		0xcc74, 0x1312,
345 		0xcc75, 0x6f72,
346 		0xcc76, 0x1002,
347 		0xcc77, 0x2807,
348 		0xcc78, 0x31a7,
349 		0xcc79, 0x20c4,
350 		0xcc7a, 0x3c24,
351 		0xcc7b, 0x6724,
352 		0xcc7c, 0x1002,
353 		0xcc7d, 0x2807,
354 		0xcc7e, 0x3187,
355 		0xcc7f, 0x20c4,
356 		0xcc80, 0x3c24,
357 		0xcc81, 0x6724,
358 		0xcc82, 0x1002,
359 		0xcc83, 0x2514,
360 		0xcc84, 0x3c64,
361 		0xcc85, 0x6436,
362 		0xcc86, 0xdff4,
363 		0xcc87, 0x6436,
364 		0xcc88, 0x1002,
365 		0xcc89, 0x40a4,
366 		0xcc8a, 0x643c,
367 		0xcc8b, 0x4016,
368 		0xcc8c, 0x8c6c,
369 		0xcc8d, 0x2b24,
370 		0xcc8e, 0x3c24,
371 		0xcc8f, 0x6435,
372 		0xcc90, 0x1002,
373 		0xcc91, 0x2b24,
374 		0xcc92, 0x3c24,
375 		0xcc93, 0x643a,
376 		0xcc94, 0x4025,
377 		0xcc95, 0x8a5a,
378 		0xcc96, 0x1002,
379 		0xcc97, 0x2731,
380 		0xcc98, 0x3011,
381 		0xcc99, 0x1001,
382 		0xcc9a, 0xc7a0,
383 		0xcc9b, 0x100,
384 		0xcc9c, 0xc502,
385 		0xcc9d, 0x53ac,
386 		0xcc9e, 0xc503,
387 		0xcc9f, 0xd5d5,
388 		0xcca0, 0xc600,
389 		0xcca1, 0x2a6d,
390 		0xcca2, 0xc601,
391 		0xcca3, 0x2a4c,
392 		0xcca4, 0xc602,
393 		0xcca5, 0x111,
394 		0xcca6, 0xc60c,
395 		0xcca7, 0x5900,
396 		0xcca8, 0xc710,
397 		0xcca9, 0x700,
398 		0xccaa, 0xc718,
399 		0xccab, 0x700,
400 		0xccac, 0xc720,
401 		0xccad, 0x4700,
402 		0xccae, 0xc801,
403 		0xccaf, 0x7f50,
404 		0xccb0, 0xc802,
405 		0xccb1, 0x7760,
406 		0xccb2, 0xc803,
407 		0xccb3, 0x7fce,
408 		0xccb4, 0xc804,
409 		0xccb5, 0x5700,
410 		0xccb6, 0xc805,
411 		0xccb7, 0x5f11,
412 		0xccb8, 0xc806,
413 		0xccb9, 0x4751,
414 		0xccba, 0xc807,
415 		0xccbb, 0x57e1,
416 		0xccbc, 0xc808,
417 		0xccbd, 0x2700,
418 		0xccbe, 0xc809,
419 		0xccbf, 0x000,
420 		0xccc0, 0xc821,
421 		0xccc1, 0x002,
422 		0xccc2, 0xc822,
423 		0xccc3, 0x014,
424 		0xccc4, 0xc832,
425 		0xccc5, 0x1186,
426 		0xccc6, 0xc847,
427 		0xccc7, 0x1e02,
428 		0xccc8, 0xc013,
429 		0xccc9, 0xf341,
430 		0xccca, 0xc01a,
431 		0xcccb, 0x446,
432 		0xcccc, 0xc024,
433 		0xcccd, 0x1000,
434 		0xccce, 0xc025,
435 		0xcccf, 0xa00,
436 		0xccd0, 0xc026,
437 		0xccd1, 0xc0c,
438 		0xccd2, 0xc027,
439 		0xccd3, 0xc0c,
440 		0xccd4, 0xc029,
441 		0xccd5, 0x0a0,
442 		0xccd6, 0xc030,
443 		0xccd7, 0xa00,
444 		0xccd8, 0xc03c,
445 		0xccd9, 0x01c,
446 		0xccda, 0xc005,
447 		0xccdb, 0x7a06,
448 		0xccdc, 0x000,
449 		0xccdd, 0x2731,
450 		0xccde, 0x3011,
451 		0xccdf, 0x1001,
452 		0xcce0, 0xc620,
453 		0xcce1, 0x000,
454 		0xcce2, 0xc621,
455 		0xcce3, 0x03f,
456 		0xcce4, 0xc622,
457 		0xcce5, 0x000,
458 		0xcce6, 0xc623,
459 		0xcce7, 0x000,
460 		0xcce8, 0xc624,
461 		0xcce9, 0x000,
462 		0xccea, 0xc625,
463 		0xcceb, 0x000,
464 		0xccec, 0xc627,
465 		0xcced, 0x000,
466 		0xccee, 0xc628,
467 		0xccef, 0x000,
468 		0xccf0, 0xc62c,
469 		0xccf1, 0x000,
470 		0xccf2, 0x000,
471 		0xccf3, 0x2806,
472 		0xccf4, 0x3cb6,
473 		0xccf5, 0xc161,
474 		0xccf6, 0x6134,
475 		0xccf7, 0x6135,
476 		0xccf8, 0x5443,
477 		0xccf9, 0x303,
478 		0xccfa, 0x6524,
479 		0xccfb, 0x00b,
480 		0xccfc, 0x1002,
481 		0xccfd, 0x2104,
482 		0xccfe, 0x3c24,
483 		0xccff, 0x2105,
484 		0xcd00, 0x3805,
485 		0xcd01, 0x6524,
486 		0xcd02, 0xdff4,
487 		0xcd03, 0x4005,
488 		0xcd04, 0x6524,
489 		0xcd05, 0x1002,
490 		0xcd06, 0x5dd3,
491 		0xcd07, 0x306,
492 		0xcd08, 0x2ff7,
493 		0xcd09, 0x38f7,
494 		0xcd0a, 0x60b7,
495 		0xcd0b, 0xdffd,
496 		0xcd0c, 0x00a,
497 		0xcd0d, 0x1002,
498 		0xcd0e, 0
499 	};
500 	int i, err;
501 
502 	for (err = i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2)
503 		err = mdio_write(phy, MDIO_DEV_PMA_PMD, sr_edc[i],
504 				 sr_edc[i + 1]);
505 	return err;
506 }
507 
508 static int ael2005_reset(struct cphy *phy, int wait)
509 {
510 	static struct reg_val regs0[] = {
511 		{ MDIO_DEV_PMA_PMD, 0xc001, 0, 1 << 5 },
512 		{ MDIO_DEV_PMA_PMD, 0xc017, 0, 1 << 5 },
513 		{ MDIO_DEV_PMA_PMD, 0xc013, 0xffff, 0xf341 },
514 		{ MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 },
515 		{ MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8100 },
516 		{ MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 },
517 		{ MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0 },
518 		{ 0, 0, 0, 0 }
519 	};
520 	static struct reg_val regs1[] = {
521 		{ MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x181 },
522 		{ MDIO_DEV_PMA_PMD, 0xc010, 0xffff, 0x448a },
523 		{ MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5200 },
524 		{ 0, 0, 0, 0 }
525 	};
526 	static struct reg_val regs2[] = {
527 		{ MDIO_DEV_PMA_PMD, 0xca00, 0xffff, 0x0080 },
528 		{ MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0 },
529 		{ 0, 0, 0, 0 }
530 	};
531 
532 	int err;
533 
534 	err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 0);
535 	if (err)
536 		return err;
537 
538 	msleep(125);
539 	err = set_phy_regs(phy, regs0);
540 	if (err)
541 		return err;
542 
543 	msleep(50);
544 	err = set_phy_regs(phy, regs1);
545 	if (err)
546 		return err;
547 
548 	msleep(50);
549 	err = ael2005_setup_sr_edc(phy);
550 	if (err)
551 		return err;
552 
553 	return set_phy_regs(phy, regs2);
554 }
555 
556 #ifdef C99_NOT_SUPPORTED
557 static struct cphy_ops ael2005_ops = {
558 	ael2005_reset,
559 	t3_phy_lasi_intr_enable,
560 	t3_phy_lasi_intr_disable,
561 	t3_phy_lasi_intr_clear,
562 	t3_phy_lasi_intr_handler,
563 	NULL,
564 	NULL,
565 	NULL,
566 	NULL,
567 	NULL,
568 	ael100x_get_link_status,
569 	ael1002_power_down,
570 };
571 #else
572 static struct cphy_ops ael2005_ops = {
573 	.reset           = ael2005_reset,
574 	.intr_enable     = t3_phy_lasi_intr_enable,
575 	.intr_disable    = t3_phy_lasi_intr_disable,
576 	.intr_clear      = t3_phy_lasi_intr_clear,
577 	.intr_handler    = t3_phy_lasi_intr_handler,
578 	.get_link_status = ael100x_get_link_status,
579 	.power_down      = ael1002_power_down,
580 };
581 #endif
582 
583 int t3_ael2005_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr,
584 			const struct mdio_ops *mdio_ops)
585 {
586 	cphy_init(phy, adapter, phy_addr, &ael2005_ops, mdio_ops,
587 		  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE,
588 		  "10GBASE-R");
589 	msleep(125);
590 	return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL_OPT_SETTINGS, 0,
591 				   1 << 5);
592 }
593 
594 #ifdef C99_NOT_SUPPORTED
595 static struct cphy_ops qt2045_ops = {
596 	ael1006_reset,
597 	t3_phy_lasi_intr_enable,
598 	t3_phy_lasi_intr_disable,
599 	t3_phy_lasi_intr_clear,
600 	t3_phy_lasi_intr_handler,
601 	NULL,
602 	NULL,
603 	NULL,
604 	NULL,
605 	NULL,
606 	ael100x_get_link_status,
607 	ael1006_power_down,
608 };
609 #else
610 static struct cphy_ops qt2045_ops = {
611 	.reset           = ael1006_reset,
612 	.intr_enable     = t3_phy_lasi_intr_enable,
613 	.intr_disable    = t3_phy_lasi_intr_disable,
614 	.intr_clear      = t3_phy_lasi_intr_clear,
615 	.intr_handler    = t3_phy_lasi_intr_handler,
616 	.get_link_status = ael100x_get_link_status,
617 	.power_down      = ael1006_power_down,
618 };
619 #endif
620 
621 int t3_qt2045_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr,
622 		       const struct mdio_ops *mdio_ops)
623 {
624 	unsigned int stat;
625 
626 	cphy_init(phy, adapter, phy_addr, &qt2045_ops, mdio_ops,
627 		  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
628 		  "10GBASE-CX4");
629 
630 	/*
631 	 * Some cards where the PHY is supposed to be at address 0 actually
632 	 * have it at 1.
633 	 */
634 	if (!phy_addr && !mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &stat) &&
635 	    stat == 0xffff)
636 		phy->addr = 1;
637 	return 0;
638 }
639 
640 static int xaui_direct_reset(struct cphy *phy, int wait)
641 {
642 	return 0;
643 }
644 
645 static int xaui_direct_get_link_status(struct cphy *phy, int *link_ok,
646 				       int *speed, int *duplex, int *fc)
647 {
648 	if (link_ok) {
649 		unsigned int status;
650 
651 		status = t3_read_reg(phy->adapter,
652 				     XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) |
653 			 t3_read_reg(phy->adapter,
654 				     XGM_REG(A_XGM_SERDES_STAT1, phy->addr)) |
655 			 t3_read_reg(phy->adapter,
656 				     XGM_REG(A_XGM_SERDES_STAT2, phy->addr)) |
657 			 t3_read_reg(phy->adapter,
658 				     XGM_REG(A_XGM_SERDES_STAT3, phy->addr));
659 		*link_ok = !(status & F_LOWSIG0);
660 	}
661 	if (speed)
662 		*speed = SPEED_10000;
663 	if (duplex)
664 		*duplex = DUPLEX_FULL;
665 	return 0;
666 }
667 
668 static int xaui_direct_power_down(struct cphy *phy, int enable)
669 {
670 	return 0;
671 }
672 
673 #ifdef C99_NOT_SUPPORTED
674 static struct cphy_ops xaui_direct_ops = {
675 	xaui_direct_reset,
676 	ael1002_intr_noop,
677 	ael1002_intr_noop,
678 	ael1002_intr_noop,
679 	ael1002_intr_noop,
680 	NULL,
681 	NULL,
682 	NULL,
683 	NULL,
684 	NULL,
685 	xaui_direct_get_link_status,
686 	xaui_direct_power_down,
687 };
688 #else
689 static struct cphy_ops xaui_direct_ops = {
690 	.reset           = xaui_direct_reset,
691 	.intr_enable     = ael1002_intr_noop,
692 	.intr_disable    = ael1002_intr_noop,
693 	.intr_clear      = ael1002_intr_noop,
694 	.intr_handler    = ael1002_intr_noop,
695 	.get_link_status = xaui_direct_get_link_status,
696 	.power_down      = xaui_direct_power_down,
697 };
698 #endif
699 
700 int t3_xaui_direct_phy_prep(struct cphy *phy, adapter_t *adapter, int phy_addr,
701 			    const struct mdio_ops *mdio_ops)
702 {
703 	cphy_init(phy, adapter, phy_addr, &xaui_direct_ops, mdio_ops,
704 		  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
705 		  "10GBASE-CX4");
706 	return 0;
707 }
708