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