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