cxgb_ael1002.c revision 197791
1167514Skmacy/**************************************************************************
2167514Skmacy
3189643SgnnCopyright (c) 2007-2009, Chelsio Inc.
4167514SkmacyAll rights reserved.
5167514Skmacy
6167514SkmacyRedistribution and use in source and binary forms, with or without
7167514Skmacymodification, are permitted provided that the following conditions are met:
8167514Skmacy
9167514Skmacy 1. Redistributions of source code must retain the above copyright notice,
10167514Skmacy    this list of conditions and the following disclaimer.
11167514Skmacy
12170076Skmacy 2. Neither the name of the Chelsio Corporation nor the names of its
13167514Skmacy    contributors may be used to endorse or promote products derived from
14167514Skmacy    this software without specific prior written permission.
15167514Skmacy
16167514SkmacyTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17167514SkmacyAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18167514SkmacyIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19167514SkmacyARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20167514SkmacyLIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21167514SkmacyCONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22167514SkmacySUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23167514SkmacyINTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24167514SkmacyCONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25167514SkmacyARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26167514SkmacyPOSSIBILITY OF SUCH DAMAGE.
27167514Skmacy
28167514Skmacy***************************************************************************/
29167514Skmacy
30167514Skmacy#include <sys/cdefs.h>
31167514Skmacy__FBSDID("$FreeBSD: head/sys/dev/cxgb/common/cxgb_ael1002.c 197791 2009-10-05 20:21:41Z np $");
32167514Skmacy
33170076Skmacy#include <cxgb_include.h>
34167514Skmacy
35176472Skmacy#undef msleep
36176472Skmacy#define msleep t3_os_sleep
37176472Skmacy
38167514Skmacyenum {
39181614Skmacy	PMD_RSD     = 10,   /* PMA/PMD receive signal detect register */
40181614Skmacy	PCS_STAT1_X = 24,   /* 10GBASE-X PCS status 1 register */
41181614Skmacy	PCS_STAT1_R = 32,   /* 10GBASE-R PCS status 1 register */
42181614Skmacy	XS_LN_STAT  = 24    /* XS lane status register */
43181614Skmacy};
44181614Skmacy
45181614Skmacyenum {
46167514Skmacy	AEL100X_TX_DISABLE  = 9,
47167514Skmacy	AEL100X_TX_CONFIG1  = 0xc002,
48197791Snp
49167514Skmacy	AEL1002_PWR_DOWN_HI = 0xc011,
50167514Skmacy	AEL1002_PWR_DOWN_LO = 0xc012,
51167514Skmacy	AEL1002_XFI_EQL     = 0xc015,
52167514Skmacy	AEL1002_LB_EN       = 0xc017,
53197791Snp
54180583Skmacy	AEL_OPT_SETTINGS    = 0xc017,
55181614Skmacy	AEL_I2C_CTRL        = 0xc30a,
56181614Skmacy	AEL_I2C_DATA        = 0xc30b,
57181614Skmacy	AEL_I2C_STAT        = 0xc30c,
58197791Snp
59181614Skmacy	AEL2005_GPIO_CTRL   = 0xc214,
60181614Skmacy	AEL2005_GPIO_STAT   = 0xc215,
61197791Snp
62197791Snp	AEL2020_GPIO_INTR   = 0xc103,
63197791Snp	AEL2020_GPIO_CTRL   = 0xc108,
64197791Snp	AEL2020_GPIO_STAT   = 0xc10c,
65197791Snp	AEL2020_GPIO_CFG    = 0xc110,
66197791Snp
67197791Snp	AEL2020_GPIO_SDA    = 0,
68197791Snp	AEL2020_GPIO_MODDET = 1,
69197791Snp	AEL2020_GPIO_0      = 3,
70197791Snp	AEL2020_GPIO_1      = 2,
71197791Snp	AEL2020_GPIO_LSTAT  = AEL2020_GPIO_1,
72180583Skmacy};
73167514Skmacy
74181614Skmacyenum { edc_none, edc_sr, edc_twinax };
75181614Skmacy
76181614Skmacy/* PHY module I2C device address */
77189643Sgnnenum {
78189643Sgnn	MODULE_DEV_ADDR	= 0xa0,
79189643Sgnn	SFF_DEV_ADDR	= 0xa2,
80189643Sgnn};
81181614Skmacy
82189643Sgnn/* PHY transceiver type */
83189643Sgnnenum {
84189643Sgnn	phy_transtype_unknown = 0,
85189643Sgnn	phy_transtype_sfp     = 3,
86189643Sgnn	phy_transtype_xfp     = 6,
87189643Sgnn};
88189643Sgnn
89181614Skmacy#define AEL2005_MODDET_IRQ 4
90181614Skmacy
91180583Skmacystruct reg_val {
92180583Skmacy	unsigned short mmd_addr;
93180583Skmacy	unsigned short reg_addr;
94180583Skmacy	unsigned short clear_bits;
95180583Skmacy	unsigned short set_bits;
96167514Skmacy};
97167514Skmacy
98197791Snpstatic int ael2xxx_get_module_type(struct cphy *phy, int delay_ms);
99186282Sgnn
100180583Skmacystatic int set_phy_regs(struct cphy *phy, const struct reg_val *rv)
101180583Skmacy{
102180583Skmacy	int err;
103180583Skmacy
104180583Skmacy	for (err = 0; rv->mmd_addr && !err; rv++) {
105180583Skmacy		if (rv->clear_bits == 0xffff)
106180583Skmacy			err = mdio_write(phy, rv->mmd_addr, rv->reg_addr,
107180583Skmacy					 rv->set_bits);
108180583Skmacy		else
109180583Skmacy			err = t3_mdio_change_bits(phy, rv->mmd_addr,
110180583Skmacy						  rv->reg_addr, rv->clear_bits,
111180583Skmacy						  rv->set_bits);
112180583Skmacy	}
113180583Skmacy	return err;
114180583Skmacy}
115180583Skmacy
116167514Skmacystatic void ael100x_txon(struct cphy *phy)
117167514Skmacy{
118167514Skmacy	int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL;
119167514Skmacy
120176472Skmacy	msleep(100);
121167514Skmacy	t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN, 0, tx_on_gpio);
122176472Skmacy	msleep(30);
123167514Skmacy}
124167514Skmacy
125197791Snp/*
126197791Snp * Read an 8-bit word from a device attached to the PHY's i2c bus.
127197791Snp */
128189643Sgnnstatic int ael_i2c_rd(struct cphy *phy, int dev_addr, int word_addr)
129189643Sgnn{
130189643Sgnn	int i, err;
131189643Sgnn	unsigned int stat, data;
132189643Sgnn
133189643Sgnn	err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL,
134189643Sgnn			 (dev_addr << 8) | (1 << 8) | word_addr);
135189643Sgnn	if (err)
136189643Sgnn		return err;
137189643Sgnn
138189643Sgnn	for (i = 0; i < 200; i++) {
139189643Sgnn		msleep(1);
140189643Sgnn		err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat);
141189643Sgnn		if (err)
142189643Sgnn			return err;
143189643Sgnn		if ((stat & 3) == 1) {
144189643Sgnn			err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA,
145189643Sgnn					&data);
146189643Sgnn			if (err)
147189643Sgnn				return err;
148189643Sgnn			return data >> 8;
149189643Sgnn		}
150189643Sgnn	}
151197791Snp	CH_WARN(phy->adapter, "PHY %u i2c read of dev.addr %x.%x timed out\n",
152197791Snp		phy->addr, dev_addr, word_addr);
153189643Sgnn	return -ETIMEDOUT;
154189643Sgnn}
155189643Sgnn
156197791Snp/*
157197791Snp * Write an 8-bit word to a device attached to the PHY's i2c bus.
158197791Snp */
159189643Sgnnstatic int ael_i2c_wr(struct cphy *phy, int dev_addr, int word_addr, int data)
160189643Sgnn{
161189643Sgnn	int i, err;
162189643Sgnn	unsigned int stat;
163189643Sgnn
164189643Sgnn	err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA, data);
165189643Sgnn	if (err)
166189643Sgnn		return err;
167189643Sgnn
168189643Sgnn	err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL,
169189643Sgnn			 (dev_addr << 8) | word_addr);
170189643Sgnn	if (err)
171189643Sgnn		return err;
172189643Sgnn
173189643Sgnn	for (i = 0; i < 200; i++) {
174189643Sgnn		msleep(1);
175189643Sgnn		err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat);
176189643Sgnn		if (err)
177189643Sgnn			return err;
178189643Sgnn		if ((stat & 3) == 1)
179189643Sgnn			return 0;
180189643Sgnn	}
181197791Snp	CH_WARN(phy->adapter, "PHY %u i2c Write of dev.addr %x.%x = %#x timed out\n",
182197791Snp		phy->addr, dev_addr, word_addr, data);
183189643Sgnn	return -ETIMEDOUT;
184189643Sgnn}
185189643Sgnn
186189643Sgnnstatic int get_phytrans_type(struct cphy *phy)
187189643Sgnn{
188189643Sgnn	int v;
189189643Sgnn
190189643Sgnn	v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0);
191189643Sgnn	if (v < 0)
192189643Sgnn		return phy_transtype_unknown;
193189643Sgnn
194189643Sgnn	return v;
195189643Sgnn}
196189643Sgnn
197189643Sgnnstatic int ael_laser_down(struct cphy *phy, int enable)
198189643Sgnn{
199189643Sgnn	int v, dev_addr;
200189643Sgnn
201189643Sgnn	v = get_phytrans_type(phy);
202189643Sgnn	if (v < 0)
203189643Sgnn		return v;
204189643Sgnn
205189643Sgnn	if (v == phy_transtype_sfp) {
206189643Sgnn		/* Check SFF Soft TX disable is supported */
207189643Sgnn		v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 93);
208189643Sgnn		if (v < 0)
209189643Sgnn			return v;
210189643Sgnn
211189643Sgnn		v &= 0x40;
212189643Sgnn		if (!v)
213189643Sgnn			return v;
214189643Sgnn
215189643Sgnn		dev_addr = SFF_DEV_ADDR;
216189643Sgnn	} else if (v == phy_transtype_xfp)
217189643Sgnn		dev_addr = MODULE_DEV_ADDR;
218189643Sgnn	else
219189643Sgnn		return v;
220189643Sgnn
221189643Sgnn	v = ael_i2c_rd(phy, dev_addr, 110);
222189643Sgnn	if (v < 0)
223189643Sgnn		return v;
224189643Sgnn
225189643Sgnn	if (enable)
226189643Sgnn		v |= 0x40;
227189643Sgnn	else
228189643Sgnn		v &= ~0x40;
229189643Sgnn
230189643Sgnn	v = ael_i2c_wr(phy, dev_addr, 110, v);
231189643Sgnn
232189643Sgnn	return v;
233189643Sgnn}
234189643Sgnn
235167514Skmacystatic int ael1002_power_down(struct cphy *phy, int enable)
236167514Skmacy{
237167514Skmacy	int err;
238167514Skmacy
239167514Skmacy	err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_DISABLE, !!enable);
240167514Skmacy	if (!err)
241167514Skmacy		err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR,
242167514Skmacy					  BMCR_PDOWN, enable ? BMCR_PDOWN : 0);
243167514Skmacy	return err;
244167514Skmacy}
245167514Skmacy
246186282Sgnnstatic int ael1002_get_module_type(struct cphy *phy, int delay_ms)
247186282Sgnn{
248186282Sgnn	int v;
249186282Sgnn
250186282Sgnn	if (delay_ms)
251186282Sgnn		msleep(delay_ms);
252186282Sgnn
253197791Snp	v = ael2xxx_get_module_type(phy, delay_ms);
254186282Sgnn
255197791Snp	return (v == -ETIMEDOUT ? phy_modtype_none : v);
256186282Sgnn}
257186282Sgnn
258167514Skmacystatic int ael1002_reset(struct cphy *phy, int wait)
259167514Skmacy{
260167514Skmacy	int err;
261167514Skmacy
262167514Skmacy	if ((err = ael1002_power_down(phy, 0)) ||
263167514Skmacy	    (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL100X_TX_CONFIG1, 1)) ||
264167514Skmacy	    (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_HI, 0)) ||
265167514Skmacy	    (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_PWR_DOWN_LO, 0)) ||
266167514Skmacy	    (err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL1002_XFI_EQL, 0x18)) ||
267167514Skmacy	    (err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL1002_LB_EN,
268167514Skmacy				       0, 1 << 5)))
269167514Skmacy		return err;
270186282Sgnn
271186282Sgnn	err = ael1002_get_module_type(phy, 300);
272186282Sgnn	if (err >= 0)
273186282Sgnn		phy->modtype = err;
274186282Sgnn
275167514Skmacy	return 0;
276167514Skmacy}
277167514Skmacy
278167514Skmacystatic int ael1002_intr_noop(struct cphy *phy)
279167514Skmacy{
280167514Skmacy	return 0;
281167514Skmacy}
282167514Skmacy
283181614Skmacy/*
284181614Skmacy * Get link status for a 10GBASE-R device.
285181614Skmacy */
286181614Skmacystatic int get_link_status_r(struct cphy *phy, int *link_ok, int *speed,
287181614Skmacy			     int *duplex, int *fc)
288167514Skmacy{
289167514Skmacy	if (link_ok) {
290181614Skmacy		unsigned int stat0, stat1, stat2;
291181614Skmacy		int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0);
292167514Skmacy
293181614Skmacy		if (!err)
294181614Skmacy			err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_R, &stat1);
295181614Skmacy		if (!err)
296181614Skmacy			err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2);
297167514Skmacy		if (err)
298167514Skmacy			return err;
299181614Skmacy		*link_ok = (stat0 & stat1 & (stat2 >> 12)) & 1;
300167514Skmacy	}
301167514Skmacy	if (speed)
302167514Skmacy		*speed = SPEED_10000;
303167514Skmacy	if (duplex)
304167514Skmacy		*duplex = DUPLEX_FULL;
305167514Skmacy	return 0;
306167514Skmacy}
307167514Skmacy
308167514Skmacy#ifdef C99_NOT_SUPPORTED
309167514Skmacystatic struct cphy_ops ael1002_ops = {
310167514Skmacy	ael1002_reset,
311167514Skmacy	ael1002_intr_noop,
312167514Skmacy	ael1002_intr_noop,
313167514Skmacy	ael1002_intr_noop,
314167514Skmacy	ael1002_intr_noop,
315167514Skmacy	NULL,
316167514Skmacy	NULL,
317167514Skmacy	NULL,
318167514Skmacy	NULL,
319167514Skmacy	NULL,
320181614Skmacy	get_link_status_r,
321167514Skmacy	ael1002_power_down,
322167514Skmacy};
323167514Skmacy#else
324167514Skmacystatic struct cphy_ops ael1002_ops = {
325167514Skmacy	.reset           = ael1002_reset,
326167514Skmacy	.intr_enable     = ael1002_intr_noop,
327167514Skmacy	.intr_disable    = ael1002_intr_noop,
328167514Skmacy	.intr_clear      = ael1002_intr_noop,
329167514Skmacy	.intr_handler    = ael1002_intr_noop,
330181614Skmacy	.get_link_status = get_link_status_r,
331167514Skmacy	.power_down      = ael1002_power_down,
332167514Skmacy};
333167514Skmacy#endif
334167514Skmacy
335197791Snpint t3_ael1002_phy_prep(pinfo_t *pinfo, int phy_addr,
336176472Skmacy			const struct mdio_ops *mdio_ops)
337167514Skmacy{
338186282Sgnn	int err;
339197791Snp	struct cphy *phy = &pinfo->phy;
340186282Sgnn
341197791Snp	cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &ael1002_ops, mdio_ops,
342176472Skmacy		  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE,
343177340Skmacy		  "10GBASE-R");
344167514Skmacy	ael100x_txon(phy);
345189643Sgnn	ael_laser_down(phy, 0);
346186282Sgnn
347186282Sgnn	err = ael1002_get_module_type(phy, 0);
348186282Sgnn	if (err >= 0)
349186282Sgnn		phy->modtype = err;
350186282Sgnn
351176472Skmacy	return 0;
352167514Skmacy}
353167514Skmacy
354167514Skmacystatic int ael1006_reset(struct cphy *phy, int wait)
355167514Skmacy{
356189643Sgnn	int err;
357189643Sgnn
358189643Sgnn	err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait);
359189643Sgnn	if (err)
360189643Sgnn		return err;
361189643Sgnn
362189643Sgnn	t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN,
363189643Sgnn			 F_GPIO6_OUT_VAL, 0);
364189643Sgnn
365185157Sgnn	msleep(125);
366189643Sgnn
367189643Sgnn	t3_set_reg_field(phy->adapter, A_T3DBG_GPIO_EN,
368189643Sgnn			 F_GPIO6_OUT_VAL, F_GPIO6_OUT_VAL);
369189643Sgnn
370185157Sgnn	msleep(125);
371185620Sgnn
372189643Sgnn	err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, wait);
373189643Sgnn	if (err)
374189643Sgnn		return err;
375185620Sgnn
376189643Sgnn	msleep(125);
377189643Sgnn
378189643Sgnn	err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, 1, 1);
379189643Sgnn	if (err)
380189643Sgnn		return err;
381189643Sgnn
382189643Sgnn	msleep(125);
383189643Sgnn
384189643Sgnn	err = t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, MII_BMCR, 1, 0);
385189643Sgnn
386189643Sgnn	return err;
387189643Sgnn
388167514Skmacy}
389167514Skmacy
390167514Skmacy#ifdef C99_NOT_SUPPORTED
391167514Skmacystatic struct cphy_ops ael1006_ops = {
392167514Skmacy	ael1006_reset,
393180583Skmacy	t3_phy_lasi_intr_enable,
394180583Skmacy	t3_phy_lasi_intr_disable,
395180583Skmacy	t3_phy_lasi_intr_clear,
396180583Skmacy	t3_phy_lasi_intr_handler,
397167514Skmacy	NULL,
398167514Skmacy	NULL,
399167514Skmacy	NULL,
400167514Skmacy	NULL,
401167514Skmacy	NULL,
402181614Skmacy	get_link_status_r,
403197791Snp	ael1002_power_down,
404167514Skmacy};
405167514Skmacy#else
406167514Skmacystatic struct cphy_ops ael1006_ops = {
407167514Skmacy	.reset           = ael1006_reset,
408180583Skmacy	.intr_enable     = t3_phy_lasi_intr_enable,
409180583Skmacy	.intr_disable    = t3_phy_lasi_intr_disable,
410180583Skmacy	.intr_clear      = t3_phy_lasi_intr_clear,
411180583Skmacy	.intr_handler    = t3_phy_lasi_intr_handler,
412181614Skmacy	.get_link_status = get_link_status_r,
413197791Snp	.power_down      = ael1002_power_down,
414167514Skmacy};
415167514Skmacy#endif
416167514Skmacy
417197791Snpint t3_ael1006_phy_prep(pinfo_t *pinfo, int phy_addr,
418176472Skmacy			const struct mdio_ops *mdio_ops)
419167514Skmacy{
420197791Snp	struct cphy *phy = &pinfo->phy;
421197791Snp
422197791Snp	cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &ael1006_ops, mdio_ops,
423176472Skmacy		  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE,
424176472Skmacy		  "10GBASE-SR");
425197791Snp	phy->modtype = phy_modtype_sr;
426167514Skmacy	ael100x_txon(phy);
427176472Skmacy	return 0;
428167514Skmacy}
429167514Skmacy
430197791Snp/*
431197791Snp * Decode our module type.
432197791Snp */
433197791Snpstatic int ael2xxx_get_module_type(struct cphy *phy, int delay_ms)
434197791Snp{
435197791Snp	int v;
436197791Snp
437197791Snp	if (delay_ms)
438197791Snp		msleep(delay_ms);
439197791Snp
440197791Snp	v = get_phytrans_type(phy);
441197791Snp	if (v == phy_transtype_sfp) {
442197791Snp		/* SFP: see SFF-8472 for below */
443197791Snp
444197791Snp		v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 3);
445197791Snp		if (v < 0)
446197791Snp			return v;
447197791Snp
448197791Snp		if (v == 0x1)
449197791Snp			return phy_modtype_twinax;
450197791Snp		if (v == 0x10)
451197791Snp			return phy_modtype_sr;
452197791Snp		if (v == 0x20)
453197791Snp			return phy_modtype_lr;
454197791Snp		if (v == 0x40)
455197791Snp			return phy_modtype_lrm;
456197791Snp
457197791Snp		v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 6);
458197791Snp		if (v < 0)
459197791Snp			return v;
460197791Snp		if (v != 4)
461197791Snp			return phy_modtype_unknown;
462197791Snp
463197791Snp		v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 10);
464197791Snp		if (v < 0)
465197791Snp			return v;
466197791Snp
467197791Snp		if (v & 0x80) {
468197791Snp			v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 0x12);
469197791Snp			if (v < 0)
470197791Snp				return v;
471197791Snp			return v > 10 ? phy_modtype_twinax_long :
472197791Snp			    phy_modtype_twinax;
473197791Snp		}
474197791Snp	} else if (v == phy_transtype_xfp) {
475197791Snp		/* XFP: See INF-8077i for details. */
476197791Snp
477197791Snp		v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 127);
478197791Snp		if (v < 0)
479197791Snp			return v;
480197791Snp
481197791Snp		if (v != 1) {
482197791Snp			/* XXX: set page select to table 1 yourself */
483197791Snp			return phy_modtype_unknown;
484197791Snp		}
485197791Snp
486197791Snp		v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 131);
487197791Snp		if (v < 0)
488197791Snp			return v;
489197791Snp		v &= 0xf0;
490197791Snp		if (v == 0x10)
491197791Snp			return phy_modtype_lrm;
492197791Snp		if (v == 0x40)
493197791Snp			return phy_modtype_lr;
494197791Snp		if (v == 0x80)
495197791Snp			return phy_modtype_sr;
496197791Snp	}
497197791Snp
498197791Snp	return phy_modtype_unknown;
499197791Snp}
500197791Snp
501197791Snp/*
502197791Snp * Code to support the Aeluros/NetLogic 2005 10Gb PHY.
503197791Snp */
504180583Skmacystatic int ael2005_setup_sr_edc(struct cphy *phy)
505180583Skmacy{
506181614Skmacy	static struct reg_val regs[] = {
507181614Skmacy		{ MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x181 },
508181614Skmacy		{ MDIO_DEV_PMA_PMD, 0xc010, 0xffff, 0x448a },
509181614Skmacy		{ MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5200 },
510181614Skmacy		{ 0, 0, 0, 0 }
511181614Skmacy	};
512180583Skmacy	static u16 sr_edc[] = {
513180583Skmacy		0xcc00, 0x2ff4,
514180583Skmacy		0xcc01, 0x3cd4,
515180583Skmacy		0xcc02, 0x2015,
516180583Skmacy		0xcc03, 0x3105,
517180583Skmacy		0xcc04, 0x6524,
518180583Skmacy		0xcc05, 0x27ff,
519180583Skmacy		0xcc06, 0x300f,
520180583Skmacy		0xcc07, 0x2c8b,
521180583Skmacy		0xcc08, 0x300b,
522180583Skmacy		0xcc09, 0x4009,
523180583Skmacy		0xcc0a, 0x400e,
524180583Skmacy		0xcc0b, 0x2f72,
525180583Skmacy		0xcc0c, 0x3002,
526180583Skmacy		0xcc0d, 0x1002,
527180583Skmacy		0xcc0e, 0x2172,
528180583Skmacy		0xcc0f, 0x3012,
529180583Skmacy		0xcc10, 0x1002,
530180583Skmacy		0xcc11, 0x25d2,
531180583Skmacy		0xcc12, 0x3012,
532180583Skmacy		0xcc13, 0x1002,
533180583Skmacy		0xcc14, 0xd01e,
534180583Skmacy		0xcc15, 0x27d2,
535180583Skmacy		0xcc16, 0x3012,
536180583Skmacy		0xcc17, 0x1002,
537180583Skmacy		0xcc18, 0x2004,
538180583Skmacy		0xcc19, 0x3c84,
539180583Skmacy		0xcc1a, 0x6436,
540180583Skmacy		0xcc1b, 0x2007,
541180583Skmacy		0xcc1c, 0x3f87,
542180583Skmacy		0xcc1d, 0x8676,
543180583Skmacy		0xcc1e, 0x40b7,
544180583Skmacy		0xcc1f, 0xa746,
545180583Skmacy		0xcc20, 0x4047,
546180583Skmacy		0xcc21, 0x5673,
547180583Skmacy		0xcc22, 0x2982,
548180583Skmacy		0xcc23, 0x3002,
549180583Skmacy		0xcc24, 0x13d2,
550180583Skmacy		0xcc25, 0x8bbd,
551180583Skmacy		0xcc26, 0x2862,
552180583Skmacy		0xcc27, 0x3012,
553180583Skmacy		0xcc28, 0x1002,
554180583Skmacy		0xcc29, 0x2092,
555180583Skmacy		0xcc2a, 0x3012,
556180583Skmacy		0xcc2b, 0x1002,
557180583Skmacy		0xcc2c, 0x5cc3,
558180583Skmacy		0xcc2d, 0x314,
559180583Skmacy		0xcc2e, 0x2942,
560180583Skmacy		0xcc2f, 0x3002,
561180583Skmacy		0xcc30, 0x1002,
562180583Skmacy		0xcc31, 0xd019,
563180583Skmacy		0xcc32, 0x2032,
564180583Skmacy		0xcc33, 0x3012,
565180583Skmacy		0xcc34, 0x1002,
566180583Skmacy		0xcc35, 0x2a04,
567180583Skmacy		0xcc36, 0x3c74,
568180583Skmacy		0xcc37, 0x6435,
569180583Skmacy		0xcc38, 0x2fa4,
570180583Skmacy		0xcc39, 0x3cd4,
571180583Skmacy		0xcc3a, 0x6624,
572180583Skmacy		0xcc3b, 0x5563,
573180583Skmacy		0xcc3c, 0x2d42,
574180583Skmacy		0xcc3d, 0x3002,
575180583Skmacy		0xcc3e, 0x13d2,
576180583Skmacy		0xcc3f, 0x464d,
577180583Skmacy		0xcc40, 0x2862,
578180583Skmacy		0xcc41, 0x3012,
579180583Skmacy		0xcc42, 0x1002,
580180583Skmacy		0xcc43, 0x2032,
581180583Skmacy		0xcc44, 0x3012,
582180583Skmacy		0xcc45, 0x1002,
583180583Skmacy		0xcc46, 0x2fb4,
584180583Skmacy		0xcc47, 0x3cd4,
585180583Skmacy		0xcc48, 0x6624,
586180583Skmacy		0xcc49, 0x5563,
587180583Skmacy		0xcc4a, 0x2d42,
588180583Skmacy		0xcc4b, 0x3002,
589180583Skmacy		0xcc4c, 0x13d2,
590180583Skmacy		0xcc4d, 0x2ed2,
591180583Skmacy		0xcc4e, 0x3002,
592180583Skmacy		0xcc4f, 0x1002,
593180583Skmacy		0xcc50, 0x2fd2,
594180583Skmacy		0xcc51, 0x3002,
595180583Skmacy		0xcc52, 0x1002,
596180583Skmacy		0xcc53, 0x004,
597180583Skmacy		0xcc54, 0x2942,
598180583Skmacy		0xcc55, 0x3002,
599180583Skmacy		0xcc56, 0x1002,
600180583Skmacy		0xcc57, 0x2092,
601180583Skmacy		0xcc58, 0x3012,
602180583Skmacy		0xcc59, 0x1002,
603180583Skmacy		0xcc5a, 0x5cc3,
604180583Skmacy		0xcc5b, 0x317,
605180583Skmacy		0xcc5c, 0x2f72,
606180583Skmacy		0xcc5d, 0x3002,
607180583Skmacy		0xcc5e, 0x1002,
608180583Skmacy		0xcc5f, 0x2942,
609180583Skmacy		0xcc60, 0x3002,
610180583Skmacy		0xcc61, 0x1002,
611180583Skmacy		0xcc62, 0x22cd,
612180583Skmacy		0xcc63, 0x301d,
613180583Skmacy		0xcc64, 0x2862,
614180583Skmacy		0xcc65, 0x3012,
615180583Skmacy		0xcc66, 0x1002,
616180583Skmacy		0xcc67, 0x2ed2,
617180583Skmacy		0xcc68, 0x3002,
618180583Skmacy		0xcc69, 0x1002,
619180583Skmacy		0xcc6a, 0x2d72,
620180583Skmacy		0xcc6b, 0x3002,
621180583Skmacy		0xcc6c, 0x1002,
622180583Skmacy		0xcc6d, 0x628f,
623180583Skmacy		0xcc6e, 0x2112,
624180583Skmacy		0xcc6f, 0x3012,
625180583Skmacy		0xcc70, 0x1002,
626180583Skmacy		0xcc71, 0x5aa3,
627180583Skmacy		0xcc72, 0x2dc2,
628180583Skmacy		0xcc73, 0x3002,
629180583Skmacy		0xcc74, 0x1312,
630180583Skmacy		0xcc75, 0x6f72,
631180583Skmacy		0xcc76, 0x1002,
632180583Skmacy		0xcc77, 0x2807,
633180583Skmacy		0xcc78, 0x31a7,
634180583Skmacy		0xcc79, 0x20c4,
635180583Skmacy		0xcc7a, 0x3c24,
636180583Skmacy		0xcc7b, 0x6724,
637180583Skmacy		0xcc7c, 0x1002,
638180583Skmacy		0xcc7d, 0x2807,
639180583Skmacy		0xcc7e, 0x3187,
640180583Skmacy		0xcc7f, 0x20c4,
641180583Skmacy		0xcc80, 0x3c24,
642180583Skmacy		0xcc81, 0x6724,
643180583Skmacy		0xcc82, 0x1002,
644180583Skmacy		0xcc83, 0x2514,
645180583Skmacy		0xcc84, 0x3c64,
646180583Skmacy		0xcc85, 0x6436,
647180583Skmacy		0xcc86, 0xdff4,
648180583Skmacy		0xcc87, 0x6436,
649180583Skmacy		0xcc88, 0x1002,
650180583Skmacy		0xcc89, 0x40a4,
651180583Skmacy		0xcc8a, 0x643c,
652180583Skmacy		0xcc8b, 0x4016,
653180583Skmacy		0xcc8c, 0x8c6c,
654180583Skmacy		0xcc8d, 0x2b24,
655180583Skmacy		0xcc8e, 0x3c24,
656180583Skmacy		0xcc8f, 0x6435,
657180583Skmacy		0xcc90, 0x1002,
658180583Skmacy		0xcc91, 0x2b24,
659180583Skmacy		0xcc92, 0x3c24,
660180583Skmacy		0xcc93, 0x643a,
661180583Skmacy		0xcc94, 0x4025,
662180583Skmacy		0xcc95, 0x8a5a,
663180583Skmacy		0xcc96, 0x1002,
664180583Skmacy		0xcc97, 0x2731,
665180583Skmacy		0xcc98, 0x3011,
666180583Skmacy		0xcc99, 0x1001,
667180583Skmacy		0xcc9a, 0xc7a0,
668180583Skmacy		0xcc9b, 0x100,
669180583Skmacy		0xcc9c, 0xc502,
670180583Skmacy		0xcc9d, 0x53ac,
671180583Skmacy		0xcc9e, 0xc503,
672180583Skmacy		0xcc9f, 0xd5d5,
673180583Skmacy		0xcca0, 0xc600,
674180583Skmacy		0xcca1, 0x2a6d,
675180583Skmacy		0xcca2, 0xc601,
676180583Skmacy		0xcca3, 0x2a4c,
677180583Skmacy		0xcca4, 0xc602,
678180583Skmacy		0xcca5, 0x111,
679180583Skmacy		0xcca6, 0xc60c,
680180583Skmacy		0xcca7, 0x5900,
681180583Skmacy		0xcca8, 0xc710,
682180583Skmacy		0xcca9, 0x700,
683180583Skmacy		0xccaa, 0xc718,
684180583Skmacy		0xccab, 0x700,
685180583Skmacy		0xccac, 0xc720,
686180583Skmacy		0xccad, 0x4700,
687180583Skmacy		0xccae, 0xc801,
688180583Skmacy		0xccaf, 0x7f50,
689180583Skmacy		0xccb0, 0xc802,
690180583Skmacy		0xccb1, 0x7760,
691180583Skmacy		0xccb2, 0xc803,
692180583Skmacy		0xccb3, 0x7fce,
693180583Skmacy		0xccb4, 0xc804,
694180583Skmacy		0xccb5, 0x5700,
695180583Skmacy		0xccb6, 0xc805,
696180583Skmacy		0xccb7, 0x5f11,
697180583Skmacy		0xccb8, 0xc806,
698180583Skmacy		0xccb9, 0x4751,
699180583Skmacy		0xccba, 0xc807,
700180583Skmacy		0xccbb, 0x57e1,
701180583Skmacy		0xccbc, 0xc808,
702180583Skmacy		0xccbd, 0x2700,
703180583Skmacy		0xccbe, 0xc809,
704180583Skmacy		0xccbf, 0x000,
705180583Skmacy		0xccc0, 0xc821,
706180583Skmacy		0xccc1, 0x002,
707180583Skmacy		0xccc2, 0xc822,
708180583Skmacy		0xccc3, 0x014,
709180583Skmacy		0xccc4, 0xc832,
710180583Skmacy		0xccc5, 0x1186,
711180583Skmacy		0xccc6, 0xc847,
712180583Skmacy		0xccc7, 0x1e02,
713180583Skmacy		0xccc8, 0xc013,
714180583Skmacy		0xccc9, 0xf341,
715180583Skmacy		0xccca, 0xc01a,
716180583Skmacy		0xcccb, 0x446,
717180583Skmacy		0xcccc, 0xc024,
718180583Skmacy		0xcccd, 0x1000,
719180583Skmacy		0xccce, 0xc025,
720180583Skmacy		0xcccf, 0xa00,
721180583Skmacy		0xccd0, 0xc026,
722180583Skmacy		0xccd1, 0xc0c,
723180583Skmacy		0xccd2, 0xc027,
724180583Skmacy		0xccd3, 0xc0c,
725180583Skmacy		0xccd4, 0xc029,
726180583Skmacy		0xccd5, 0x0a0,
727180583Skmacy		0xccd6, 0xc030,
728180583Skmacy		0xccd7, 0xa00,
729180583Skmacy		0xccd8, 0xc03c,
730180583Skmacy		0xccd9, 0x01c,
731180583Skmacy		0xccda, 0xc005,
732180583Skmacy		0xccdb, 0x7a06,
733180583Skmacy		0xccdc, 0x000,
734180583Skmacy		0xccdd, 0x2731,
735180583Skmacy		0xccde, 0x3011,
736180583Skmacy		0xccdf, 0x1001,
737180583Skmacy		0xcce0, 0xc620,
738180583Skmacy		0xcce1, 0x000,
739180583Skmacy		0xcce2, 0xc621,
740180583Skmacy		0xcce3, 0x03f,
741180583Skmacy		0xcce4, 0xc622,
742180583Skmacy		0xcce5, 0x000,
743180583Skmacy		0xcce6, 0xc623,
744180583Skmacy		0xcce7, 0x000,
745180583Skmacy		0xcce8, 0xc624,
746180583Skmacy		0xcce9, 0x000,
747180583Skmacy		0xccea, 0xc625,
748180583Skmacy		0xcceb, 0x000,
749180583Skmacy		0xccec, 0xc627,
750180583Skmacy		0xcced, 0x000,
751180583Skmacy		0xccee, 0xc628,
752180583Skmacy		0xccef, 0x000,
753180583Skmacy		0xccf0, 0xc62c,
754180583Skmacy		0xccf1, 0x000,
755180583Skmacy		0xccf2, 0x000,
756180583Skmacy		0xccf3, 0x2806,
757180583Skmacy		0xccf4, 0x3cb6,
758180583Skmacy		0xccf5, 0xc161,
759180583Skmacy		0xccf6, 0x6134,
760180583Skmacy		0xccf7, 0x6135,
761180583Skmacy		0xccf8, 0x5443,
762180583Skmacy		0xccf9, 0x303,
763180583Skmacy		0xccfa, 0x6524,
764180583Skmacy		0xccfb, 0x00b,
765180583Skmacy		0xccfc, 0x1002,
766180583Skmacy		0xccfd, 0x2104,
767180583Skmacy		0xccfe, 0x3c24,
768180583Skmacy		0xccff, 0x2105,
769180583Skmacy		0xcd00, 0x3805,
770180583Skmacy		0xcd01, 0x6524,
771180583Skmacy		0xcd02, 0xdff4,
772180583Skmacy		0xcd03, 0x4005,
773180583Skmacy		0xcd04, 0x6524,
774180583Skmacy		0xcd05, 0x1002,
775180583Skmacy		0xcd06, 0x5dd3,
776180583Skmacy		0xcd07, 0x306,
777180583Skmacy		0xcd08, 0x2ff7,
778180583Skmacy		0xcd09, 0x38f7,
779180583Skmacy		0xcd0a, 0x60b7,
780180583Skmacy		0xcd0b, 0xdffd,
781180583Skmacy		0xcd0c, 0x00a,
782180583Skmacy		0xcd0d, 0x1002,
783180583Skmacy		0xcd0e, 0
784180583Skmacy	};
785180583Skmacy	int i, err;
786180583Skmacy
787181614Skmacy	err = set_phy_regs(phy, regs);
788181614Skmacy	if (err)
789181614Skmacy		return err;
790181614Skmacy
791181614Skmacy	msleep(50);
792181614Skmacy
793181614Skmacy	for (i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2)
794180583Skmacy		err = mdio_write(phy, MDIO_DEV_PMA_PMD, sr_edc[i],
795180583Skmacy				 sr_edc[i + 1]);
796181614Skmacy	if (!err)
797181614Skmacy		phy->priv = edc_sr;
798180583Skmacy	return err;
799180583Skmacy}
800180583Skmacy
801181614Skmacystatic int ael2005_setup_twinax_edc(struct cphy *phy, int modtype)
802181614Skmacy{
803181614Skmacy	static struct reg_val regs[] = {
804181614Skmacy		{ MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5a00 },
805181614Skmacy		{ 0, 0, 0, 0 }
806181614Skmacy	};
807181614Skmacy	static struct reg_val preemphasis[] = {
808181614Skmacy		{ MDIO_DEV_PMA_PMD, 0xc014, 0xffff, 0xfe16 },
809181614Skmacy		{ MDIO_DEV_PMA_PMD, 0xc015, 0xffff, 0xa000 },
810181614Skmacy		{ 0, 0, 0, 0 }
811181614Skmacy	};
812181614Skmacy	static u16 twinax_edc[] = {
813181614Skmacy		0xcc00, 0x4009,
814181614Skmacy		0xcc01, 0x27ff,
815181614Skmacy		0xcc02, 0x300f,
816181614Skmacy		0xcc03, 0x40aa,
817181614Skmacy		0xcc04, 0x401c,
818181614Skmacy		0xcc05, 0x401e,
819181614Skmacy		0xcc06, 0x2ff4,
820181614Skmacy		0xcc07, 0x3cd4,
821181614Skmacy		0xcc08, 0x2035,
822181614Skmacy		0xcc09, 0x3145,
823181614Skmacy		0xcc0a, 0x6524,
824181614Skmacy		0xcc0b, 0x26a2,
825181614Skmacy		0xcc0c, 0x3012,
826181614Skmacy		0xcc0d, 0x1002,
827181614Skmacy		0xcc0e, 0x29c2,
828181614Skmacy		0xcc0f, 0x3002,
829181614Skmacy		0xcc10, 0x1002,
830181614Skmacy		0xcc11, 0x2072,
831181614Skmacy		0xcc12, 0x3012,
832181614Skmacy		0xcc13, 0x1002,
833181614Skmacy		0xcc14, 0x22cd,
834181614Skmacy		0xcc15, 0x301d,
835181614Skmacy		0xcc16, 0x2e52,
836181614Skmacy		0xcc17, 0x3012,
837181614Skmacy		0xcc18, 0x1002,
838181614Skmacy		0xcc19, 0x28e2,
839181614Skmacy		0xcc1a, 0x3002,
840181614Skmacy		0xcc1b, 0x1002,
841181614Skmacy		0xcc1c, 0x628f,
842181614Skmacy		0xcc1d, 0x2ac2,
843181614Skmacy		0xcc1e, 0x3012,
844181614Skmacy		0xcc1f, 0x1002,
845181614Skmacy		0xcc20, 0x5553,
846181614Skmacy		0xcc21, 0x2ae2,
847181614Skmacy		0xcc22, 0x3002,
848181614Skmacy		0xcc23, 0x1302,
849181614Skmacy		0xcc24, 0x401e,
850181614Skmacy		0xcc25, 0x2be2,
851181614Skmacy		0xcc26, 0x3012,
852181614Skmacy		0xcc27, 0x1002,
853181614Skmacy		0xcc28, 0x2da2,
854181614Skmacy		0xcc29, 0x3012,
855181614Skmacy		0xcc2a, 0x1002,
856181614Skmacy		0xcc2b, 0x2ba2,
857181614Skmacy		0xcc2c, 0x3002,
858181614Skmacy		0xcc2d, 0x1002,
859181614Skmacy		0xcc2e, 0x5ee3,
860181614Skmacy		0xcc2f, 0x305,
861181614Skmacy		0xcc30, 0x400e,
862181614Skmacy		0xcc31, 0x2bc2,
863181614Skmacy		0xcc32, 0x3002,
864181614Skmacy		0xcc33, 0x1002,
865181614Skmacy		0xcc34, 0x2b82,
866181614Skmacy		0xcc35, 0x3012,
867181614Skmacy		0xcc36, 0x1002,
868181614Skmacy		0xcc37, 0x5663,
869181614Skmacy		0xcc38, 0x302,
870181614Skmacy		0xcc39, 0x401e,
871181614Skmacy		0xcc3a, 0x6f72,
872181614Skmacy		0xcc3b, 0x1002,
873181614Skmacy		0xcc3c, 0x628f,
874181614Skmacy		0xcc3d, 0x2be2,
875181614Skmacy		0xcc3e, 0x3012,
876181614Skmacy		0xcc3f, 0x1002,
877181614Skmacy		0xcc40, 0x22cd,
878181614Skmacy		0xcc41, 0x301d,
879181614Skmacy		0xcc42, 0x2e52,
880181614Skmacy		0xcc43, 0x3012,
881181614Skmacy		0xcc44, 0x1002,
882181614Skmacy		0xcc45, 0x2522,
883181614Skmacy		0xcc46, 0x3012,
884181614Skmacy		0xcc47, 0x1002,
885181614Skmacy		0xcc48, 0x2da2,
886181614Skmacy		0xcc49, 0x3012,
887181614Skmacy		0xcc4a, 0x1002,
888181614Skmacy		0xcc4b, 0x2ca2,
889181614Skmacy		0xcc4c, 0x3012,
890181614Skmacy		0xcc4d, 0x1002,
891181614Skmacy		0xcc4e, 0x2fa4,
892181614Skmacy		0xcc4f, 0x3cd4,
893181614Skmacy		0xcc50, 0x6624,
894181614Skmacy		0xcc51, 0x410b,
895181614Skmacy		0xcc52, 0x56b3,
896181614Skmacy		0xcc53, 0x3c4,
897181614Skmacy		0xcc54, 0x2fb2,
898181614Skmacy		0xcc55, 0x3002,
899181614Skmacy		0xcc56, 0x1002,
900181614Skmacy		0xcc57, 0x220b,
901181614Skmacy		0xcc58, 0x303b,
902181614Skmacy		0xcc59, 0x56b3,
903181614Skmacy		0xcc5a, 0x3c3,
904181614Skmacy		0xcc5b, 0x866b,
905181614Skmacy		0xcc5c, 0x400c,
906181614Skmacy		0xcc5d, 0x23a2,
907181614Skmacy		0xcc5e, 0x3012,
908181614Skmacy		0xcc5f, 0x1002,
909181614Skmacy		0xcc60, 0x2da2,
910181614Skmacy		0xcc61, 0x3012,
911181614Skmacy		0xcc62, 0x1002,
912181614Skmacy		0xcc63, 0x2ca2,
913181614Skmacy		0xcc64, 0x3012,
914181614Skmacy		0xcc65, 0x1002,
915181614Skmacy		0xcc66, 0x2fb4,
916181614Skmacy		0xcc67, 0x3cd4,
917181614Skmacy		0xcc68, 0x6624,
918181614Skmacy		0xcc69, 0x56b3,
919181614Skmacy		0xcc6a, 0x3c3,
920181614Skmacy		0xcc6b, 0x866b,
921181614Skmacy		0xcc6c, 0x401c,
922181614Skmacy		0xcc6d, 0x2205,
923181614Skmacy		0xcc6e, 0x3035,
924181614Skmacy		0xcc6f, 0x5b53,
925181614Skmacy		0xcc70, 0x2c52,
926181614Skmacy		0xcc71, 0x3002,
927181614Skmacy		0xcc72, 0x13c2,
928181614Skmacy		0xcc73, 0x5cc3,
929181614Skmacy		0xcc74, 0x317,
930181614Skmacy		0xcc75, 0x2522,
931181614Skmacy		0xcc76, 0x3012,
932181614Skmacy		0xcc77, 0x1002,
933181614Skmacy		0xcc78, 0x2da2,
934181614Skmacy		0xcc79, 0x3012,
935181614Skmacy		0xcc7a, 0x1002,
936181614Skmacy		0xcc7b, 0x2b82,
937181614Skmacy		0xcc7c, 0x3012,
938181614Skmacy		0xcc7d, 0x1002,
939181614Skmacy		0xcc7e, 0x5663,
940181614Skmacy		0xcc7f, 0x303,
941181614Skmacy		0xcc80, 0x401e,
942181614Skmacy		0xcc81, 0x004,
943181614Skmacy		0xcc82, 0x2c42,
944181614Skmacy		0xcc83, 0x3012,
945181614Skmacy		0xcc84, 0x1002,
946181614Skmacy		0xcc85, 0x6f72,
947181614Skmacy		0xcc86, 0x1002,
948181614Skmacy		0xcc87, 0x628f,
949181614Skmacy		0xcc88, 0x2304,
950181614Skmacy		0xcc89, 0x3c84,
951181614Skmacy		0xcc8a, 0x6436,
952181614Skmacy		0xcc8b, 0xdff4,
953181614Skmacy		0xcc8c, 0x6436,
954181614Skmacy		0xcc8d, 0x2ff5,
955181614Skmacy		0xcc8e, 0x3005,
956181614Skmacy		0xcc8f, 0x8656,
957181614Skmacy		0xcc90, 0xdfba,
958181614Skmacy		0xcc91, 0x56a3,
959181614Skmacy		0xcc92, 0xd05a,
960181614Skmacy		0xcc93, 0x21c2,
961181614Skmacy		0xcc94, 0x3012,
962181614Skmacy		0xcc95, 0x1392,
963181614Skmacy		0xcc96, 0xd05a,
964181614Skmacy		0xcc97, 0x56a3,
965181614Skmacy		0xcc98, 0xdfba,
966181614Skmacy		0xcc99, 0x383,
967181614Skmacy		0xcc9a, 0x6f72,
968181614Skmacy		0xcc9b, 0x1002,
969181614Skmacy		0xcc9c, 0x28c5,
970181614Skmacy		0xcc9d, 0x3005,
971181614Skmacy		0xcc9e, 0x4178,
972181614Skmacy		0xcc9f, 0x5653,
973181614Skmacy		0xcca0, 0x384,
974181614Skmacy		0xcca1, 0x22b2,
975181614Skmacy		0xcca2, 0x3012,
976181614Skmacy		0xcca3, 0x1002,
977181614Skmacy		0xcca4, 0x2be5,
978181614Skmacy		0xcca5, 0x3005,
979181614Skmacy		0xcca6, 0x41e8,
980181614Skmacy		0xcca7, 0x5653,
981181614Skmacy		0xcca8, 0x382,
982181614Skmacy		0xcca9, 0x002,
983181614Skmacy		0xccaa, 0x4258,
984181614Skmacy		0xccab, 0x2474,
985181614Skmacy		0xccac, 0x3c84,
986181614Skmacy		0xccad, 0x6437,
987181614Skmacy		0xccae, 0xdff4,
988181614Skmacy		0xccaf, 0x6437,
989181614Skmacy		0xccb0, 0x2ff5,
990181614Skmacy		0xccb1, 0x3c05,
991181614Skmacy		0xccb2, 0x8757,
992181614Skmacy		0xccb3, 0xb888,
993181614Skmacy		0xccb4, 0x9787,
994181614Skmacy		0xccb5, 0xdff4,
995181614Skmacy		0xccb6, 0x6724,
996181614Skmacy		0xccb7, 0x866a,
997181614Skmacy		0xccb8, 0x6f72,
998181614Skmacy		0xccb9, 0x1002,
999181614Skmacy		0xccba, 0x2d01,
1000181614Skmacy		0xccbb, 0x3011,
1001181614Skmacy		0xccbc, 0x1001,
1002181614Skmacy		0xccbd, 0xc620,
1003181614Skmacy		0xccbe, 0x14e5,
1004181614Skmacy		0xccbf, 0xc621,
1005181614Skmacy		0xccc0, 0xc53d,
1006181614Skmacy		0xccc1, 0xc622,
1007181614Skmacy		0xccc2, 0x3cbe,
1008181614Skmacy		0xccc3, 0xc623,
1009181614Skmacy		0xccc4, 0x4452,
1010181614Skmacy		0xccc5, 0xc624,
1011181614Skmacy		0xccc6, 0xc5c5,
1012181614Skmacy		0xccc7, 0xc625,
1013181614Skmacy		0xccc8, 0xe01e,
1014181614Skmacy		0xccc9, 0xc627,
1015181614Skmacy		0xccca, 0x000,
1016181614Skmacy		0xcccb, 0xc628,
1017181614Skmacy		0xcccc, 0x000,
1018181614Skmacy		0xcccd, 0xc62b,
1019181614Skmacy		0xccce, 0x000,
1020181614Skmacy		0xcccf, 0xc62c,
1021181614Skmacy		0xccd0, 0x000,
1022181614Skmacy		0xccd1, 0x000,
1023181614Skmacy		0xccd2, 0x2d01,
1024181614Skmacy		0xccd3, 0x3011,
1025181614Skmacy		0xccd4, 0x1001,
1026181614Skmacy		0xccd5, 0xc620,
1027181614Skmacy		0xccd6, 0x000,
1028181614Skmacy		0xccd7, 0xc621,
1029181614Skmacy		0xccd8, 0x000,
1030181614Skmacy		0xccd9, 0xc622,
1031181614Skmacy		0xccda, 0x0ce,
1032181614Skmacy		0xccdb, 0xc623,
1033181614Skmacy		0xccdc, 0x07f,
1034181614Skmacy		0xccdd, 0xc624,
1035181614Skmacy		0xccde, 0x032,
1036181614Skmacy		0xccdf, 0xc625,
1037181614Skmacy		0xcce0, 0x000,
1038181614Skmacy		0xcce1, 0xc627,
1039181614Skmacy		0xcce2, 0x000,
1040181614Skmacy		0xcce3, 0xc628,
1041181614Skmacy		0xcce4, 0x000,
1042181614Skmacy		0xcce5, 0xc62b,
1043181614Skmacy		0xcce6, 0x000,
1044181614Skmacy		0xcce7, 0xc62c,
1045181614Skmacy		0xcce8, 0x000,
1046181614Skmacy		0xcce9, 0x000,
1047181614Skmacy		0xccea, 0x2d01,
1048181614Skmacy		0xcceb, 0x3011,
1049181614Skmacy		0xccec, 0x1001,
1050181614Skmacy		0xcced, 0xc502,
1051181614Skmacy		0xccee, 0x609f,
1052181614Skmacy		0xccef, 0xc600,
1053181614Skmacy		0xccf0, 0x2a6e,
1054181614Skmacy		0xccf1, 0xc601,
1055181614Skmacy		0xccf2, 0x2a2c,
1056181614Skmacy		0xccf3, 0xc60c,
1057181614Skmacy		0xccf4, 0x5400,
1058181614Skmacy		0xccf5, 0xc710,
1059181614Skmacy		0xccf6, 0x700,
1060181614Skmacy		0xccf7, 0xc718,
1061181614Skmacy		0xccf8, 0x700,
1062181614Skmacy		0xccf9, 0xc720,
1063181614Skmacy		0xccfa, 0x4700,
1064181614Skmacy		0xccfb, 0xc728,
1065181614Skmacy		0xccfc, 0x700,
1066181614Skmacy		0xccfd, 0xc729,
1067181614Skmacy		0xccfe, 0x1207,
1068181614Skmacy		0xccff, 0xc801,
1069181614Skmacy		0xcd00, 0x7f50,
1070181614Skmacy		0xcd01, 0xc802,
1071181614Skmacy		0xcd02, 0x7760,
1072181614Skmacy		0xcd03, 0xc803,
1073181614Skmacy		0xcd04, 0x7fce,
1074181614Skmacy		0xcd05, 0xc804,
1075181614Skmacy		0xcd06, 0x520e,
1076181614Skmacy		0xcd07, 0xc805,
1077181614Skmacy		0xcd08, 0x5c11,
1078181614Skmacy		0xcd09, 0xc806,
1079181614Skmacy		0xcd0a, 0x3c51,
1080181614Skmacy		0xcd0b, 0xc807,
1081181614Skmacy		0xcd0c, 0x4061,
1082181614Skmacy		0xcd0d, 0xc808,
1083181614Skmacy		0xcd0e, 0x49c1,
1084181614Skmacy		0xcd0f, 0xc809,
1085181614Skmacy		0xcd10, 0x3840,
1086181614Skmacy		0xcd11, 0xc80a,
1087181614Skmacy		0xcd12, 0x000,
1088181614Skmacy		0xcd13, 0xc821,
1089181614Skmacy		0xcd14, 0x002,
1090181614Skmacy		0xcd15, 0xc822,
1091181614Skmacy		0xcd16, 0x046,
1092181614Skmacy		0xcd17, 0xc844,
1093181614Skmacy		0xcd18, 0x182f,
1094181614Skmacy		0xcd19, 0xc013,
1095181614Skmacy		0xcd1a, 0xf341,
1096181614Skmacy		0xcd1b, 0xc01a,
1097181614Skmacy		0xcd1c, 0x446,
1098181614Skmacy		0xcd1d, 0xc024,
1099181614Skmacy		0xcd1e, 0x1000,
1100181614Skmacy		0xcd1f, 0xc025,
1101181614Skmacy		0xcd20, 0xa00,
1102181614Skmacy		0xcd21, 0xc026,
1103181614Skmacy		0xcd22, 0xc0c,
1104181614Skmacy		0xcd23, 0xc027,
1105181614Skmacy		0xcd24, 0xc0c,
1106181614Skmacy		0xcd25, 0xc029,
1107181614Skmacy		0xcd26, 0x0a0,
1108181614Skmacy		0xcd27, 0xc030,
1109181614Skmacy		0xcd28, 0xa00,
1110181614Skmacy		0xcd29, 0xc03c,
1111181614Skmacy		0xcd2a, 0x01c,
1112181614Skmacy		0xcd2b, 0x000,
1113181614Skmacy		0xcd2c, 0x2b84,
1114181614Skmacy		0xcd2d, 0x3c74,
1115181614Skmacy		0xcd2e, 0x6435,
1116181614Skmacy		0xcd2f, 0xdff4,
1117181614Skmacy		0xcd30, 0x6435,
1118181614Skmacy		0xcd31, 0x2806,
1119181614Skmacy		0xcd32, 0x3006,
1120181614Skmacy		0xcd33, 0x8565,
1121181614Skmacy		0xcd34, 0x2b24,
1122181614Skmacy		0xcd35, 0x3c24,
1123181614Skmacy		0xcd36, 0x6436,
1124181614Skmacy		0xcd37, 0x1002,
1125181614Skmacy		0xcd38, 0x2b24,
1126181614Skmacy		0xcd39, 0x3c24,
1127181614Skmacy		0xcd3a, 0x6436,
1128181614Skmacy		0xcd3b, 0x4045,
1129181614Skmacy		0xcd3c, 0x8656,
1130181614Skmacy		0xcd3d, 0x1002,
1131181614Skmacy		0xcd3e, 0x2807,
1132181614Skmacy		0xcd3f, 0x31a7,
1133181614Skmacy		0xcd40, 0x20c4,
1134181614Skmacy		0xcd41, 0x3c24,
1135181614Skmacy		0xcd42, 0x6724,
1136181614Skmacy		0xcd43, 0x1002,
1137181614Skmacy		0xcd44, 0x2807,
1138181614Skmacy		0xcd45, 0x3187,
1139181614Skmacy		0xcd46, 0x20c4,
1140181614Skmacy		0xcd47, 0x3c24,
1141181614Skmacy		0xcd48, 0x6724,
1142181614Skmacy		0xcd49, 0x1002,
1143181614Skmacy		0xcd4a, 0x2514,
1144181614Skmacy		0xcd4b, 0x3c64,
1145181614Skmacy		0xcd4c, 0x6436,
1146181614Skmacy		0xcd4d, 0xdff4,
1147181614Skmacy		0xcd4e, 0x6436,
1148181614Skmacy		0xcd4f, 0x1002,
1149181614Skmacy		0xcd50, 0x2806,
1150181614Skmacy		0xcd51, 0x3cb6,
1151181614Skmacy		0xcd52, 0xc161,
1152181614Skmacy		0xcd53, 0x6134,
1153181614Skmacy		0xcd54, 0x6135,
1154181614Skmacy		0xcd55, 0x5443,
1155181614Skmacy		0xcd56, 0x303,
1156181614Skmacy		0xcd57, 0x6524,
1157181614Skmacy		0xcd58, 0x00b,
1158181614Skmacy		0xcd59, 0x1002,
1159181614Skmacy		0xcd5a, 0xd019,
1160181614Skmacy		0xcd5b, 0x2104,
1161181614Skmacy		0xcd5c, 0x3c24,
1162181614Skmacy		0xcd5d, 0x2105,
1163181614Skmacy		0xcd5e, 0x3805,
1164181614Skmacy		0xcd5f, 0x6524,
1165181614Skmacy		0xcd60, 0xdff4,
1166181614Skmacy		0xcd61, 0x4005,
1167181614Skmacy		0xcd62, 0x6524,
1168181614Skmacy		0xcd63, 0x2e8d,
1169181614Skmacy		0xcd64, 0x303d,
1170181614Skmacy		0xcd65, 0x5dd3,
1171181614Skmacy		0xcd66, 0x306,
1172181614Skmacy		0xcd67, 0x2ff7,
1173181614Skmacy		0xcd68, 0x38f7,
1174181614Skmacy		0xcd69, 0x60b7,
1175181614Skmacy		0xcd6a, 0xdffd,
1176181614Skmacy		0xcd6b, 0x00a,
1177181614Skmacy		0xcd6c, 0x1002,
1178181614Skmacy		0xcd6d, 0
1179181614Skmacy	};
1180181614Skmacy	int i, err;
1181181614Skmacy
1182181614Skmacy	err = set_phy_regs(phy, regs);
1183181614Skmacy	if (!err && modtype == phy_modtype_twinax_long)
1184181614Skmacy		err = set_phy_regs(phy, preemphasis);
1185181614Skmacy	if (err)
1186181614Skmacy		return err;
1187181614Skmacy
1188181614Skmacy	msleep(50);
1189181614Skmacy
1190181614Skmacy	for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2)
1191181614Skmacy		err = mdio_write(phy, MDIO_DEV_PMA_PMD, twinax_edc[i],
1192181614Skmacy				 twinax_edc[i + 1]);
1193181614Skmacy	if (!err)
1194181614Skmacy		phy->priv = edc_twinax;
1195181614Skmacy	return err;
1196181614Skmacy}
1197181614Skmacy
1198197791Snpstatic int ael2005_get_module_type(struct cphy *phy, int delay_ms)
1199181614Skmacy{
1200189643Sgnn	int v;
1201197791Snp	unsigned int stat;
1202181614Skmacy
1203197791Snp	v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, &stat);
1204197791Snp	if (v)
1205197791Snp		return v;
1206181614Skmacy
1207197791Snp	if (stat & (1 << 8))			/* module absent */
1208197791Snp		return phy_modtype_none;
1209181614Skmacy
1210197791Snp	return ael2xxx_get_module_type(phy, delay_ms);
1211181614Skmacy}
1212181614Skmacy
1213181614Skmacystatic int ael2005_intr_enable(struct cphy *phy)
1214181614Skmacy{
1215181614Skmacy	int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x200);
1216181614Skmacy	return err ? err : t3_phy_lasi_intr_enable(phy);
1217181614Skmacy}
1218181614Skmacy
1219181614Skmacystatic int ael2005_intr_disable(struct cphy *phy)
1220181614Skmacy{
1221181614Skmacy	int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x100);
1222181614Skmacy	return err ? err : t3_phy_lasi_intr_disable(phy);
1223181614Skmacy}
1224181614Skmacy
1225181614Skmacystatic int ael2005_intr_clear(struct cphy *phy)
1226181614Skmacy{
1227181614Skmacy	int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0xd00);
1228181614Skmacy	return err ? err : t3_phy_lasi_intr_clear(phy);
1229181614Skmacy}
1230181614Skmacy
1231180583Skmacystatic int ael2005_reset(struct cphy *phy, int wait)
1232180583Skmacy{
1233180583Skmacy	static struct reg_val regs0[] = {
1234180583Skmacy		{ MDIO_DEV_PMA_PMD, 0xc001, 0, 1 << 5 },
1235180583Skmacy		{ MDIO_DEV_PMA_PMD, 0xc017, 0, 1 << 5 },
1236180583Skmacy		{ MDIO_DEV_PMA_PMD, 0xc013, 0xffff, 0xf341 },
1237180583Skmacy		{ MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 },
1238180583Skmacy		{ MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8100 },
1239180583Skmacy		{ MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 },
1240180583Skmacy		{ MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0 },
1241180583Skmacy		{ 0, 0, 0, 0 }
1242180583Skmacy	};
1243180583Skmacy	static struct reg_val regs1[] = {
1244180583Skmacy		{ MDIO_DEV_PMA_PMD, 0xca00, 0xffff, 0x0080 },
1245180583Skmacy		{ MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0 },
1246180583Skmacy		{ 0, 0, 0, 0 }
1247180583Skmacy	};
1248180583Skmacy
1249197791Snp	int err;
1250197791Snp	unsigned int lasi_ctrl;
1251180583Skmacy
1252181614Skmacy	err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl);
1253181614Skmacy	if (err)
1254181614Skmacy		return err;
1255181614Skmacy
1256180583Skmacy	err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 0);
1257180583Skmacy	if (err)
1258180583Skmacy		return err;
1259180583Skmacy
1260180583Skmacy	msleep(125);
1261181614Skmacy	phy->priv = edc_none;
1262180583Skmacy	err = set_phy_regs(phy, regs0);
1263180583Skmacy	if (err)
1264180583Skmacy		return err;
1265180583Skmacy
1266180583Skmacy	msleep(50);
1267181614Skmacy
1268186282Sgnn	err = ael2005_get_module_type(phy, 0);
1269181614Skmacy	if (err < 0)
1270181614Skmacy		return err;
1271181614Skmacy	phy->modtype = (u8)err;
1272181614Skmacy
1273192540Sgnn	if (err == phy_modtype_none || err == phy_modtype_unknown)
1274192540Sgnn		err = 0;
1275192540Sgnn	else if (err == phy_modtype_twinax || err == phy_modtype_twinax_long)
1276181614Skmacy		err = ael2005_setup_twinax_edc(phy, err);
1277181614Skmacy	else
1278181614Skmacy		err = ael2005_setup_sr_edc(phy);
1279180583Skmacy	if (err)
1280180583Skmacy		return err;
1281180583Skmacy
1282181614Skmacy	err = set_phy_regs(phy, regs1);
1283180583Skmacy	if (err)
1284180583Skmacy		return err;
1285180583Skmacy
1286181614Skmacy	/* reset wipes out interrupts, reenable them if they were on */
1287181614Skmacy	if (lasi_ctrl & 1)
1288181614Skmacy		err = ael2005_intr_enable(phy);
1289181614Skmacy	return err;
1290180583Skmacy}
1291180583Skmacy
1292181614Skmacystatic int ael2005_intr_handler(struct cphy *phy)
1293181614Skmacy{
1294181614Skmacy	unsigned int stat;
1295181614Skmacy	int ret, edc_needed, cause = 0;
1296181614Skmacy
1297181614Skmacy	ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_STAT, &stat);
1298181614Skmacy	if (ret)
1299181614Skmacy		return ret;
1300181614Skmacy
1301181614Skmacy	if (stat & AEL2005_MODDET_IRQ) {
1302181614Skmacy		ret = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL,
1303181614Skmacy				 0xd00);
1304181614Skmacy		if (ret)
1305181614Skmacy			return ret;
1306181614Skmacy
1307181614Skmacy		/* modules have max 300 ms init time after hot plug */
1308186282Sgnn		ret = ael2005_get_module_type(phy, 300);
1309181614Skmacy		if (ret < 0)
1310181614Skmacy			return ret;
1311181614Skmacy
1312181614Skmacy		phy->modtype = (u8)ret;
1313181614Skmacy		if (ret == phy_modtype_none)
1314181614Skmacy			edc_needed = phy->priv;       /* on unplug retain EDC */
1315181614Skmacy		else if (ret == phy_modtype_twinax ||
1316181614Skmacy			 ret == phy_modtype_twinax_long)
1317181614Skmacy			edc_needed = edc_twinax;
1318181614Skmacy		else
1319181614Skmacy			edc_needed = edc_sr;
1320181614Skmacy
1321181614Skmacy		if (edc_needed != phy->priv) {
1322181614Skmacy			ret = ael2005_reset(phy, 0);
1323181614Skmacy			return ret ? ret : cphy_cause_module_change;
1324181614Skmacy		}
1325181614Skmacy		cause = cphy_cause_module_change;
1326181614Skmacy	}
1327181614Skmacy
1328181614Skmacy	ret = t3_phy_lasi_intr_handler(phy);
1329189643Sgnn	if (ret < 0)
1330189643Sgnn		return ret;
1331189643Sgnn
1332189643Sgnn	ret |= cause;
1333189643Sgnn	if (!ret)
1334189643Sgnn		ret |= cphy_cause_link_change;
1335189643Sgnn	return ret;
1336181614Skmacy}
1337181614Skmacy
1338197791Snpstatic struct cphy_ops ael2005_ops = {
1339167514Skmacy#ifdef C99_NOT_SUPPORTED
1340180583Skmacy	ael2005_reset,
1341181614Skmacy	ael2005_intr_enable,
1342181614Skmacy	ael2005_intr_disable,
1343181614Skmacy	ael2005_intr_clear,
1344181614Skmacy	ael2005_intr_handler,
1345180583Skmacy	NULL,
1346180583Skmacy	NULL,
1347180583Skmacy	NULL,
1348180583Skmacy	NULL,
1349180583Skmacy	NULL,
1350181614Skmacy	get_link_status_r,
1351180583Skmacy	ael1002_power_down,
1352180583Skmacy#else
1353180583Skmacy	.reset           = ael2005_reset,
1354181614Skmacy	.intr_enable     = ael2005_intr_enable,
1355181614Skmacy	.intr_disable    = ael2005_intr_disable,
1356181614Skmacy	.intr_clear      = ael2005_intr_clear,
1357181614Skmacy	.intr_handler    = ael2005_intr_handler,
1358181614Skmacy	.get_link_status = get_link_status_r,
1359180583Skmacy	.power_down      = ael1002_power_down,
1360197791Snp#endif
1361180583Skmacy};
1362180583Skmacy
1363197791Snpint t3_ael2005_phy_prep(pinfo_t *pinfo, int phy_addr,
1364180583Skmacy			const struct mdio_ops *mdio_ops)
1365180583Skmacy{
1366186282Sgnn	int err;
1367197791Snp	struct cphy *phy = &pinfo->phy;
1368197791Snp
1369197791Snp	cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &ael2005_ops, mdio_ops,
1370181614Skmacy		  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE |
1371181614Skmacy		  SUPPORTED_IRQ, "10GBASE-R");
1372180583Skmacy	msleep(125);
1373189643Sgnn	ael_laser_down(phy, 0);
1374186282Sgnn
1375186282Sgnn	err = ael2005_get_module_type(phy, 0);
1376186282Sgnn	if (err >= 0)
1377186282Sgnn		phy->modtype = err;
1378186282Sgnn
1379180583Skmacy	return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL_OPT_SETTINGS, 0,
1380180583Skmacy				   1 << 5);
1381180583Skmacy}
1382180583Skmacy
1383181614Skmacy/*
1384197791Snp * Setup EDC and other parameters for operation with an optical module.
1385197791Snp */
1386197791Snpstatic int ael2020_setup_sr_edc(struct cphy *phy)
1387197791Snp{
1388197791Snp	static struct reg_val regs[] = {
1389197791Snp		{ MDIO_DEV_PMA_PMD, 0xcc01, 0xffff, 0x488a },
1390197791Snp
1391197791Snp		{ MDIO_DEV_PMA_PMD, 0xcb1b, 0xffff, 0x0200 },
1392197791Snp		{ MDIO_DEV_PMA_PMD, 0xcb1c, 0xffff, 0x00f0 },
1393197791Snp		{ MDIO_DEV_PMA_PMD, 0xcc06, 0xffff, 0x00e0 },
1394197791Snp
1395197791Snp		/* end */
1396197791Snp		{ 0, 0, 0, 0 }
1397197791Snp	};
1398197791Snp	int err;
1399197791Snp
1400197791Snp	err = set_phy_regs(phy, regs);
1401197791Snp	msleep(50);
1402197791Snp	if (err)
1403197791Snp		return err;
1404197791Snp
1405197791Snp	phy->priv = edc_sr;
1406197791Snp	return 0;
1407197791Snp}
1408197791Snp
1409197791Snp/*
1410197791Snp * Setup EDC and other parameters for operation with an TWINAX module.
1411197791Snp */
1412197791Snpstatic int ael2020_setup_twinax_edc(struct cphy *phy, int modtype)
1413197791Snp{
1414197791Snp	static struct reg_val uCclock40MHz[] = {
1415197791Snp		{ MDIO_DEV_PMA_PMD, 0xff28, 0xffff, 0x4001 },
1416197791Snp		{ MDIO_DEV_PMA_PMD, 0xff2a, 0xffff, 0x0002 },
1417197791Snp		{ 0, 0, 0, 0 }
1418197791Snp	};
1419197791Snp
1420197791Snp	static struct reg_val uCclockActivate[] = {
1421197791Snp		{ MDIO_DEV_PMA_PMD, 0xd000, 0xffff, 0x5200 },
1422197791Snp		{ 0, 0, 0, 0 }
1423197791Snp	};
1424197791Snp
1425197791Snp	static struct reg_val uCactivate[] = {
1426197791Snp		{ MDIO_DEV_PMA_PMD, 0xd080, 0xffff, 0x0100 },
1427197791Snp		{ MDIO_DEV_PMA_PMD, 0xd092, 0xffff, 0x0000 },
1428197791Snp		{ 0, 0, 0, 0 }
1429197791Snp	};
1430197791Snp
1431197791Snp	static u16 twinax_edc[] = {
1432197791Snp		0xd800, 0x4009,
1433197791Snp		0xd801, 0x2fff,
1434197791Snp		0xd802, 0x300f,
1435197791Snp		0xd803, 0x40aa,
1436197791Snp		0xd804, 0x401c,
1437197791Snp		0xd805, 0x401e,
1438197791Snp		0xd806, 0x2ff4,
1439197791Snp		0xd807, 0x3dc4,
1440197791Snp		0xd808, 0x2035,
1441197791Snp		0xd809, 0x3035,
1442197791Snp		0xd80a, 0x6524,
1443197791Snp		0xd80b, 0x2cb2,
1444197791Snp		0xd80c, 0x3012,
1445197791Snp		0xd80d, 0x1002,
1446197791Snp		0xd80e, 0x26e2,
1447197791Snp		0xd80f, 0x3022,
1448197791Snp		0xd810, 0x1002,
1449197791Snp		0xd811, 0x27d2,
1450197791Snp		0xd812, 0x3022,
1451197791Snp		0xd813, 0x1002,
1452197791Snp		0xd814, 0x2822,
1453197791Snp		0xd815, 0x3012,
1454197791Snp		0xd816, 0x1002,
1455197791Snp		0xd817, 0x2492,
1456197791Snp		0xd818, 0x3022,
1457197791Snp		0xd819, 0x1002,
1458197791Snp		0xd81a, 0x2772,
1459197791Snp		0xd81b, 0x3012,
1460197791Snp		0xd81c, 0x1002,
1461197791Snp		0xd81d, 0x23d2,
1462197791Snp		0xd81e, 0x3022,
1463197791Snp		0xd81f, 0x1002,
1464197791Snp		0xd820, 0x22cd,
1465197791Snp		0xd821, 0x301d,
1466197791Snp		0xd822, 0x27f2,
1467197791Snp		0xd823, 0x3022,
1468197791Snp		0xd824, 0x1002,
1469197791Snp		0xd825, 0x5553,
1470197791Snp		0xd826, 0x0307,
1471197791Snp		0xd827, 0x2522,
1472197791Snp		0xd828, 0x3022,
1473197791Snp		0xd829, 0x1002,
1474197791Snp		0xd82a, 0x2142,
1475197791Snp		0xd82b, 0x3012,
1476197791Snp		0xd82c, 0x1002,
1477197791Snp		0xd82d, 0x4016,
1478197791Snp		0xd82e, 0x5e63,
1479197791Snp		0xd82f, 0x0344,
1480197791Snp		0xd830, 0x2142,
1481197791Snp		0xd831, 0x3012,
1482197791Snp		0xd832, 0x1002,
1483197791Snp		0xd833, 0x400e,
1484197791Snp		0xd834, 0x2522,
1485197791Snp		0xd835, 0x3022,
1486197791Snp		0xd836, 0x1002,
1487197791Snp		0xd837, 0x2b52,
1488197791Snp		0xd838, 0x3012,
1489197791Snp		0xd839, 0x1002,
1490197791Snp		0xd83a, 0x2742,
1491197791Snp		0xd83b, 0x3022,
1492197791Snp		0xd83c, 0x1002,
1493197791Snp		0xd83d, 0x25e2,
1494197791Snp		0xd83e, 0x3022,
1495197791Snp		0xd83f, 0x1002,
1496197791Snp		0xd840, 0x2fa4,
1497197791Snp		0xd841, 0x3dc4,
1498197791Snp		0xd842, 0x6624,
1499197791Snp		0xd843, 0x414b,
1500197791Snp		0xd844, 0x56b3,
1501197791Snp		0xd845, 0x03c6,
1502197791Snp		0xd846, 0x866b,
1503197791Snp		0xd847, 0x400c,
1504197791Snp		0xd848, 0x2712,
1505197791Snp		0xd849, 0x3012,
1506197791Snp		0xd84a, 0x1002,
1507197791Snp		0xd84b, 0x2c4b,
1508197791Snp		0xd84c, 0x309b,
1509197791Snp		0xd84d, 0x56b3,
1510197791Snp		0xd84e, 0x03c3,
1511197791Snp		0xd84f, 0x866b,
1512197791Snp		0xd850, 0x400c,
1513197791Snp		0xd851, 0x2272,
1514197791Snp		0xd852, 0x3022,
1515197791Snp		0xd853, 0x1002,
1516197791Snp		0xd854, 0x2742,
1517197791Snp		0xd855, 0x3022,
1518197791Snp		0xd856, 0x1002,
1519197791Snp		0xd857, 0x25e2,
1520197791Snp		0xd858, 0x3022,
1521197791Snp		0xd859, 0x1002,
1522197791Snp		0xd85a, 0x2fb4,
1523197791Snp		0xd85b, 0x3dc4,
1524197791Snp		0xd85c, 0x6624,
1525197791Snp		0xd85d, 0x56b3,
1526197791Snp		0xd85e, 0x03c3,
1527197791Snp		0xd85f, 0x866b,
1528197791Snp		0xd860, 0x401c,
1529197791Snp		0xd861, 0x2c45,
1530197791Snp		0xd862, 0x3095,
1531197791Snp		0xd863, 0x5b53,
1532197791Snp		0xd864, 0x2372,
1533197791Snp		0xd865, 0x3012,
1534197791Snp		0xd866, 0x13c2,
1535197791Snp		0xd867, 0x5cc3,
1536197791Snp		0xd868, 0x2712,
1537197791Snp		0xd869, 0x3012,
1538197791Snp		0xd86a, 0x1312,
1539197791Snp		0xd86b, 0x2b52,
1540197791Snp		0xd86c, 0x3012,
1541197791Snp		0xd86d, 0x1002,
1542197791Snp		0xd86e, 0x2742,
1543197791Snp		0xd86f, 0x3022,
1544197791Snp		0xd870, 0x1002,
1545197791Snp		0xd871, 0x2582,
1546197791Snp		0xd872, 0x3022,
1547197791Snp		0xd873, 0x1002,
1548197791Snp		0xd874, 0x2142,
1549197791Snp		0xd875, 0x3012,
1550197791Snp		0xd876, 0x1002,
1551197791Snp		0xd877, 0x628f,
1552197791Snp		0xd878, 0x2985,
1553197791Snp		0xd879, 0x33a5,
1554197791Snp		0xd87a, 0x25e2,
1555197791Snp		0xd87b, 0x3022,
1556197791Snp		0xd87c, 0x1002,
1557197791Snp		0xd87d, 0x5653,
1558197791Snp		0xd87e, 0x03d2,
1559197791Snp		0xd87f, 0x401e,
1560197791Snp		0xd880, 0x6f72,
1561197791Snp		0xd881, 0x1002,
1562197791Snp		0xd882, 0x628f,
1563197791Snp		0xd883, 0x2304,
1564197791Snp		0xd884, 0x3c84,
1565197791Snp		0xd885, 0x6436,
1566197791Snp		0xd886, 0xdff4,
1567197791Snp		0xd887, 0x6436,
1568197791Snp		0xd888, 0x2ff5,
1569197791Snp		0xd889, 0x3005,
1570197791Snp		0xd88a, 0x8656,
1571197791Snp		0xd88b, 0xdfba,
1572197791Snp		0xd88c, 0x56a3,
1573197791Snp		0xd88d, 0xd05a,
1574197791Snp		0xd88e, 0x2972,
1575197791Snp		0xd88f, 0x3012,
1576197791Snp		0xd890, 0x1392,
1577197791Snp		0xd891, 0xd05a,
1578197791Snp		0xd892, 0x56a3,
1579197791Snp		0xd893, 0xdfba,
1580197791Snp		0xd894, 0x0383,
1581197791Snp		0xd895, 0x6f72,
1582197791Snp		0xd896, 0x1002,
1583197791Snp		0xd897, 0x2b45,
1584197791Snp		0xd898, 0x3005,
1585197791Snp		0xd899, 0x4178,
1586197791Snp		0xd89a, 0x5653,
1587197791Snp		0xd89b, 0x0384,
1588197791Snp		0xd89c, 0x2a62,
1589197791Snp		0xd89d, 0x3012,
1590197791Snp		0xd89e, 0x1002,
1591197791Snp		0xd89f, 0x2f05,
1592197791Snp		0xd8a0, 0x3005,
1593197791Snp		0xd8a1, 0x41c8,
1594197791Snp		0xd8a2, 0x5653,
1595197791Snp		0xd8a3, 0x0382,
1596197791Snp		0xd8a4, 0x0002,
1597197791Snp		0xd8a5, 0x4218,
1598197791Snp		0xd8a6, 0x2474,
1599197791Snp		0xd8a7, 0x3c84,
1600197791Snp		0xd8a8, 0x6437,
1601197791Snp		0xd8a9, 0xdff4,
1602197791Snp		0xd8aa, 0x6437,
1603197791Snp		0xd8ab, 0x2ff5,
1604197791Snp		0xd8ac, 0x3c05,
1605197791Snp		0xd8ad, 0x8757,
1606197791Snp		0xd8ae, 0xb888,
1607197791Snp		0xd8af, 0x9787,
1608197791Snp		0xd8b0, 0xdff4,
1609197791Snp		0xd8b1, 0x6724,
1610197791Snp		0xd8b2, 0x866a,
1611197791Snp		0xd8b3, 0x6f72,
1612197791Snp		0xd8b4, 0x1002,
1613197791Snp		0xd8b5, 0x2641,
1614197791Snp		0xd8b6, 0x3021,
1615197791Snp		0xd8b7, 0x1001,
1616197791Snp		0xd8b8, 0xc620,
1617197791Snp		0xd8b9, 0x0000,
1618197791Snp		0xd8ba, 0xc621,
1619197791Snp		0xd8bb, 0x0000,
1620197791Snp		0xd8bc, 0xc622,
1621197791Snp		0xd8bd, 0x00ce,
1622197791Snp		0xd8be, 0xc623,
1623197791Snp		0xd8bf, 0x007f,
1624197791Snp		0xd8c0, 0xc624,
1625197791Snp		0xd8c1, 0x0032,
1626197791Snp		0xd8c2, 0xc625,
1627197791Snp		0xd8c3, 0x0000,
1628197791Snp		0xd8c4, 0xc627,
1629197791Snp		0xd8c5, 0x0000,
1630197791Snp		0xd8c6, 0xc628,
1631197791Snp		0xd8c7, 0x0000,
1632197791Snp		0xd8c8, 0xc62c,
1633197791Snp		0xd8c9, 0x0000,
1634197791Snp		0xd8ca, 0x0000,
1635197791Snp		0xd8cb, 0x2641,
1636197791Snp		0xd8cc, 0x3021,
1637197791Snp		0xd8cd, 0x1001,
1638197791Snp		0xd8ce, 0xc502,
1639197791Snp		0xd8cf, 0x53ac,
1640197791Snp		0xd8d0, 0xc503,
1641197791Snp		0xd8d1, 0x2cd3,
1642197791Snp		0xd8d2, 0xc600,
1643197791Snp		0xd8d3, 0x2a6e,
1644197791Snp		0xd8d4, 0xc601,
1645197791Snp		0xd8d5, 0x2a2c,
1646197791Snp		0xd8d6, 0xc605,
1647197791Snp		0xd8d7, 0x5557,
1648197791Snp		0xd8d8, 0xc60c,
1649197791Snp		0xd8d9, 0x5400,
1650197791Snp		0xd8da, 0xc710,
1651197791Snp		0xd8db, 0x0700,
1652197791Snp		0xd8dc, 0xc711,
1653197791Snp		0xd8dd, 0x0f06,
1654197791Snp		0xd8de, 0xc718,
1655197791Snp		0xd8df, 0x0700,
1656197791Snp		0xd8e0, 0xc719,
1657197791Snp		0xd8e1, 0x0f06,
1658197791Snp		0xd8e2, 0xc720,
1659197791Snp		0xd8e3, 0x4700,
1660197791Snp		0xd8e4, 0xc721,
1661197791Snp		0xd8e5, 0x0f06,
1662197791Snp		0xd8e6, 0xc728,
1663197791Snp		0xd8e7, 0x0700,
1664197791Snp		0xd8e8, 0xc729,
1665197791Snp		0xd8e9, 0x1207,
1666197791Snp		0xd8ea, 0xc801,
1667197791Snp		0xd8eb, 0x7f50,
1668197791Snp		0xd8ec, 0xc802,
1669197791Snp		0xd8ed, 0x7760,
1670197791Snp		0xd8ee, 0xc803,
1671197791Snp		0xd8ef, 0x7fce,
1672197791Snp		0xd8f0, 0xc804,
1673197791Snp		0xd8f1, 0x520e,
1674197791Snp		0xd8f2, 0xc805,
1675197791Snp		0xd8f3, 0x5c11,
1676197791Snp		0xd8f4, 0xc806,
1677197791Snp		0xd8f5, 0x3c51,
1678197791Snp		0xd8f6, 0xc807,
1679197791Snp		0xd8f7, 0x4061,
1680197791Snp		0xd8f8, 0xc808,
1681197791Snp		0xd8f9, 0x49c1,
1682197791Snp		0xd8fa, 0xc809,
1683197791Snp		0xd8fb, 0x3840,
1684197791Snp		0xd8fc, 0xc80a,
1685197791Snp		0xd8fd, 0x0000,
1686197791Snp		0xd8fe, 0xc821,
1687197791Snp		0xd8ff, 0x0002,
1688197791Snp		0xd900, 0xc822,
1689197791Snp		0xd901, 0x0046,
1690197791Snp		0xd902, 0xc844,
1691197791Snp		0xd903, 0x182f,
1692197791Snp		0xd904, 0xc013,
1693197791Snp		0xd905, 0xf341,
1694197791Snp		0xd906, 0xc084,
1695197791Snp		0xd907, 0x0030,
1696197791Snp		0xd908, 0xc904,
1697197791Snp		0xd909, 0x1401,
1698197791Snp		0xd90a, 0xcb0c,
1699197791Snp		0xd90b, 0x0004,
1700197791Snp		0xd90c, 0xcb0e,
1701197791Snp		0xd90d, 0xa00a,
1702197791Snp		0xd90e, 0xcb0f,
1703197791Snp		0xd90f, 0xc0c0,
1704197791Snp		0xd910, 0xcb10,
1705197791Snp		0xd911, 0xc0c0,
1706197791Snp		0xd912, 0xcb11,
1707197791Snp		0xd913, 0x00a0,
1708197791Snp		0xd914, 0xcb12,
1709197791Snp		0xd915, 0x0007,
1710197791Snp		0xd916, 0xc241,
1711197791Snp		0xd917, 0xa000,
1712197791Snp		0xd918, 0xc243,
1713197791Snp		0xd919, 0x7fe0,
1714197791Snp		0xd91a, 0xc604,
1715197791Snp		0xd91b, 0x000e,
1716197791Snp		0xd91c, 0xc609,
1717197791Snp		0xd91d, 0x00f5,
1718197791Snp		0xd91e, 0xc611,
1719197791Snp		0xd91f, 0x000e,
1720197791Snp		0xd920, 0xc660,
1721197791Snp		0xd921, 0x9600,
1722197791Snp		0xd922, 0xc687,
1723197791Snp		0xd923, 0x0004,
1724197791Snp		0xd924, 0xc60a,
1725197791Snp		0xd925, 0x04f5,
1726197791Snp		0xd926, 0x0000,
1727197791Snp		0xd927, 0x2641,
1728197791Snp		0xd928, 0x3021,
1729197791Snp		0xd929, 0x1001,
1730197791Snp		0xd92a, 0xc620,
1731197791Snp		0xd92b, 0x14e5,
1732197791Snp		0xd92c, 0xc621,
1733197791Snp		0xd92d, 0xc53d,
1734197791Snp		0xd92e, 0xc622,
1735197791Snp		0xd92f, 0x3cbe,
1736197791Snp		0xd930, 0xc623,
1737197791Snp		0xd931, 0x4452,
1738197791Snp		0xd932, 0xc624,
1739197791Snp		0xd933, 0xc5c5,
1740197791Snp		0xd934, 0xc625,
1741197791Snp		0xd935, 0xe01e,
1742197791Snp		0xd936, 0xc627,
1743197791Snp		0xd937, 0x0000,
1744197791Snp		0xd938, 0xc628,
1745197791Snp		0xd939, 0x0000,
1746197791Snp		0xd93a, 0xc62c,
1747197791Snp		0xd93b, 0x0000,
1748197791Snp		0xd93c, 0x0000,
1749197791Snp		0xd93d, 0x2b84,
1750197791Snp		0xd93e, 0x3c74,
1751197791Snp		0xd93f, 0x6435,
1752197791Snp		0xd940, 0xdff4,
1753197791Snp		0xd941, 0x6435,
1754197791Snp		0xd942, 0x2806,
1755197791Snp		0xd943, 0x3006,
1756197791Snp		0xd944, 0x8565,
1757197791Snp		0xd945, 0x2b24,
1758197791Snp		0xd946, 0x3c24,
1759197791Snp		0xd947, 0x6436,
1760197791Snp		0xd948, 0x1002,
1761197791Snp		0xd949, 0x2b24,
1762197791Snp		0xd94a, 0x3c24,
1763197791Snp		0xd94b, 0x6436,
1764197791Snp		0xd94c, 0x4045,
1765197791Snp		0xd94d, 0x8656,
1766197791Snp		0xd94e, 0x5663,
1767197791Snp		0xd94f, 0x0302,
1768197791Snp		0xd950, 0x401e,
1769197791Snp		0xd951, 0x1002,
1770197791Snp		0xd952, 0x2807,
1771197791Snp		0xd953, 0x31a7,
1772197791Snp		0xd954, 0x20c4,
1773197791Snp		0xd955, 0x3c24,
1774197791Snp		0xd956, 0x6724,
1775197791Snp		0xd957, 0x1002,
1776197791Snp		0xd958, 0x2807,
1777197791Snp		0xd959, 0x3187,
1778197791Snp		0xd95a, 0x20c4,
1779197791Snp		0xd95b, 0x3c24,
1780197791Snp		0xd95c, 0x6724,
1781197791Snp		0xd95d, 0x1002,
1782197791Snp		0xd95e, 0x24f4,
1783197791Snp		0xd95f, 0x3c64,
1784197791Snp		0xd960, 0x6436,
1785197791Snp		0xd961, 0xdff4,
1786197791Snp		0xd962, 0x6436,
1787197791Snp		0xd963, 0x1002,
1788197791Snp		0xd964, 0x2006,
1789197791Snp		0xd965, 0x3d76,
1790197791Snp		0xd966, 0xc161,
1791197791Snp		0xd967, 0x6134,
1792197791Snp		0xd968, 0x6135,
1793197791Snp		0xd969, 0x5443,
1794197791Snp		0xd96a, 0x0303,
1795197791Snp		0xd96b, 0x6524,
1796197791Snp		0xd96c, 0x00fb,
1797197791Snp		0xd96d, 0x1002,
1798197791Snp		0xd96e, 0x20d4,
1799197791Snp		0xd96f, 0x3c24,
1800197791Snp		0xd970, 0x2025,
1801197791Snp		0xd971, 0x3005,
1802197791Snp		0xd972, 0x6524,
1803197791Snp		0xd973, 0x1002,
1804197791Snp		0xd974, 0xd019,
1805197791Snp		0xd975, 0x2104,
1806197791Snp		0xd976, 0x3c24,
1807197791Snp		0xd977, 0x2105,
1808197791Snp		0xd978, 0x3805,
1809197791Snp		0xd979, 0x6524,
1810197791Snp		0xd97a, 0xdff4,
1811197791Snp		0xd97b, 0x4005,
1812197791Snp		0xd97c, 0x6524,
1813197791Snp		0xd97d, 0x2e8d,
1814197791Snp		0xd97e, 0x303d,
1815197791Snp		0xd97f, 0x2408,
1816197791Snp		0xd980, 0x35d8,
1817197791Snp		0xd981, 0x5dd3,
1818197791Snp		0xd982, 0x0307,
1819197791Snp		0xd983, 0x8887,
1820197791Snp		0xd984, 0x63a7,
1821197791Snp		0xd985, 0x8887,
1822197791Snp		0xd986, 0x63a7,
1823197791Snp		0xd987, 0xdffd,
1824197791Snp		0xd988, 0x00f9,
1825197791Snp		0xd989, 0x1002,
1826197791Snp		0xd98a, 0x0000,
1827197791Snp	};
1828197791Snp	int i, err;
1829197791Snp
1830197791Snp	/* set uC clock and activate it */
1831197791Snp	err = set_phy_regs(phy, uCclock40MHz);
1832197791Snp	msleep(500);
1833197791Snp	if (err)
1834197791Snp		return err;
1835197791Snp	err = set_phy_regs(phy, uCclockActivate);
1836197791Snp	msleep(500);
1837197791Snp	if (err)
1838197791Snp		return err;
1839197791Snp
1840197791Snp	for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2)
1841197791Snp		err = mdio_write(phy, MDIO_DEV_PMA_PMD, twinax_edc[i],
1842197791Snp				 twinax_edc[i + 1]);
1843197791Snp	/* activate uC */
1844197791Snp	err = set_phy_regs(phy, uCactivate);
1845197791Snp	if (!err)
1846197791Snp		phy->priv = edc_twinax;
1847197791Snp	return err;
1848197791Snp}
1849197791Snp
1850197791Snp/*
1851197791Snp * Return Module Type.
1852197791Snp */
1853197791Snpstatic int ael2020_get_module_type(struct cphy *phy, int delay_ms)
1854197791Snp{
1855197791Snp	int v;
1856197791Snp	unsigned int stat;
1857197791Snp
1858197791Snp	v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2020_GPIO_STAT, &stat);
1859197791Snp	if (v)
1860197791Snp		return v;
1861197791Snp
1862197791Snp	if (stat & (0x1 << (AEL2020_GPIO_MODDET*4))) {
1863197791Snp		/* module absent */
1864197791Snp		return phy_modtype_none;
1865197791Snp	}
1866197791Snp
1867197791Snp	return ael2xxx_get_module_type(phy, delay_ms);
1868197791Snp}
1869197791Snp
1870197791Snp/*
1871197791Snp * Enable PHY interrupts.  We enable "Module Detection" interrupts (on any
1872197791Snp * state transition) and then generic Link Alarm Status Interrupt (LASI).
1873197791Snp */
1874197791Snpstatic int ael2020_intr_enable(struct cphy *phy)
1875197791Snp{
1876197791Snp	struct reg_val regs[] = {
1877197791Snp		{ MDIO_DEV_PMA_PMD, AEL2020_GPIO_CFG+AEL2020_GPIO_LSTAT,
1878197791Snp			0xffff, 0x4 },
1879197791Snp		{ MDIO_DEV_PMA_PMD, AEL2020_GPIO_CTRL,
1880197791Snp			0xffff, 0x8 << (AEL2020_GPIO_LSTAT*4) },
1881197791Snp
1882197791Snp		{ MDIO_DEV_PMA_PMD, AEL2020_GPIO_CTRL,
1883197791Snp			0xffff, 0x2 << (AEL2020_GPIO_MODDET*4) },
1884197791Snp
1885197791Snp		/* end */
1886197791Snp		{ 0, 0, 0, 0 }
1887197791Snp	};
1888197791Snp	int err;
1889197791Snp
1890197791Snp	err = set_phy_regs(phy, regs);
1891197791Snp	if (err)
1892197791Snp		return err;
1893197791Snp
1894197791Snp	phy->caps |= POLL_LINK_1ST_TIME;
1895197791Snp
1896197791Snp	/* enable standard Link Alarm Status Interrupts */
1897197791Snp	err = t3_phy_lasi_intr_enable(phy);
1898197791Snp	if (err)
1899197791Snp		return err;
1900197791Snp
1901197791Snp	return 0;
1902197791Snp}
1903197791Snp
1904197791Snp/*
1905197791Snp * Disable PHY interrupts.  The mirror of the above ...
1906197791Snp */
1907197791Snpstatic int ael2020_intr_disable(struct cphy *phy)
1908197791Snp{
1909197791Snp	struct reg_val regs[] = {
1910197791Snp		{ MDIO_DEV_PMA_PMD, AEL2020_GPIO_CTRL,
1911197791Snp			0xffff, 0xb << (AEL2020_GPIO_LSTAT*4) },
1912197791Snp
1913197791Snp		{ MDIO_DEV_PMA_PMD, AEL2020_GPIO_CTRL,
1914197791Snp			0xffff, 0x1 << (AEL2020_GPIO_MODDET*4) },
1915197791Snp
1916197791Snp		/* end */
1917197791Snp		{ 0, 0, 0, 0 }
1918197791Snp	};
1919197791Snp	int err;
1920197791Snp
1921197791Snp	err = set_phy_regs(phy, regs);
1922197791Snp	if (err)
1923197791Snp		return err;
1924197791Snp
1925197791Snp	/* disable standard Link Alarm Status Interrupts */
1926197791Snp	return t3_phy_lasi_intr_disable(phy);
1927197791Snp}
1928197791Snp
1929197791Snp/*
1930197791Snp * Clear PHY interrupt state.
1931197791Snp */
1932197791Snpstatic int ael2020_intr_clear(struct cphy *phy)
1933197791Snp{
1934197791Snp	unsigned int stat;
1935197791Snp	int err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2020_GPIO_INTR, &stat);
1936197791Snp	return err ? err : t3_phy_lasi_intr_clear(phy);
1937197791Snp}
1938197791Snp
1939197791Snp/*
1940197791Snp * Common register settings for the AEL2020 when it comes out of reset.
1941197791Snp */
1942197791Snpstatic struct reg_val ael2020_reset_regs[] = {
1943197791Snp	{ MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x3101 },
1944197791Snp
1945197791Snp	{ MDIO_DEV_PMA_PMD, 0xcd40, 0xffff, 0x0001 },
1946197791Snp
1947197791Snp	{ MDIO_DEV_PMA_PMD, 0xff02, 0xffff, 0x0023 },
1948197791Snp	{ MDIO_DEV_PMA_PMD, 0xff03, 0xffff, 0x0000 },
1949197791Snp	{ MDIO_DEV_PMA_PMD, 0xff04, 0xffff, 0x0000 },
1950197791Snp
1951197791Snp	/* end */
1952197791Snp	{ 0, 0, 0, 0 }
1953197791Snp};
1954197791Snp
1955197791Snp/*
1956197791Snp * Reset the PHY and put it into a canonical operating state.
1957197791Snp */
1958197791Snpstatic int ael2020_reset(struct cphy *phy, int wait)
1959197791Snp{
1960197791Snp	int err;
1961197791Snp	unsigned int lasi_ctrl;
1962197791Snp
1963197791Snp	/* grab current interrupt state */
1964197791Snp	err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl);
1965197791Snp	if (err)
1966197791Snp		return err;
1967197791Snp
1968197791Snp	err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 125);
1969197791Snp	if (err)
1970197791Snp		return err;
1971197791Snp	msleep(100);
1972197791Snp
1973197791Snp	/* basic initialization for all module types */
1974197791Snp	phy->priv = edc_none;
1975197791Snp	err = set_phy_regs(phy, ael2020_reset_regs);
1976197791Snp	if (err)
1977197791Snp		return err;
1978197791Snp
1979197791Snp	/* determine module type and perform appropriate initialization */
1980197791Snp	err = ael2020_get_module_type(phy, 0);
1981197791Snp	if (err < 0)
1982197791Snp		return err;
1983197791Snp	phy->modtype = (u8)err;
1984197791Snp	if (err == phy_modtype_none || err == phy_modtype_unknown)
1985197791Snp		err = 0;
1986197791Snp	else if (err == phy_modtype_twinax || err == phy_modtype_twinax_long)
1987197791Snp		err = ael2020_setup_twinax_edc(phy, err);
1988197791Snp	else
1989197791Snp		err = ael2020_setup_sr_edc(phy);
1990197791Snp	if (err)
1991197791Snp		return err;
1992197791Snp
1993197791Snp	/* reset wipes out interrupts, reenable them if they were on */
1994197791Snp	if (lasi_ctrl & 1)
1995197791Snp		err = ael2020_intr_enable(phy);
1996197791Snp	return err;
1997197791Snp}
1998197791Snp
1999197791Snp/*
2000197791Snp * Handle a PHY interrupt.
2001197791Snp */
2002197791Snpstatic int ael2020_intr_handler(struct cphy *phy)
2003197791Snp{
2004197791Snp	unsigned int stat;
2005197791Snp	int ret, edc_needed, cause = 0;
2006197791Snp
2007197791Snp	ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2020_GPIO_INTR, &stat);
2008197791Snp	if (ret)
2009197791Snp		return ret;
2010197791Snp
2011197791Snp	if (stat & (0x1 << AEL2020_GPIO_MODDET)) {
2012197791Snp		/* modules have max 300 ms init time after hot plug */
2013197791Snp		ret = ael2020_get_module_type(phy, 300);
2014197791Snp		if (ret < 0)
2015197791Snp			return ret;
2016197791Snp
2017197791Snp		phy->modtype = (u8)ret;
2018197791Snp		if (ret == phy_modtype_none)
2019197791Snp			edc_needed = phy->priv;       /* on unplug retain EDC */
2020197791Snp		else if (ret == phy_modtype_twinax ||
2021197791Snp			 ret == phy_modtype_twinax_long)
2022197791Snp			edc_needed = edc_twinax;
2023197791Snp		else
2024197791Snp			edc_needed = edc_sr;
2025197791Snp
2026197791Snp		if (edc_needed != phy->priv) {
2027197791Snp			ret = ael2020_reset(phy, 0);
2028197791Snp			return ret ? ret : cphy_cause_module_change;
2029197791Snp		}
2030197791Snp		cause = cphy_cause_module_change;
2031197791Snp	}
2032197791Snp
2033197791Snp	ret = t3_phy_lasi_intr_handler(phy);
2034197791Snp	if (ret < 0)
2035197791Snp		return ret;
2036197791Snp
2037197791Snp	ret |= cause;
2038197791Snp	if (!ret)
2039197791Snp		ret |= cphy_cause_link_change;
2040197791Snp	return ret;
2041197791Snp}
2042197791Snp
2043197791Snpstatic struct cphy_ops ael2020_ops = {
2044197791Snp#ifdef C99_NOT_SUPPORTED
2045197791Snp	ael2020_reset,
2046197791Snp	ael2020_intr_enable,
2047197791Snp	ael2020_intr_disable,
2048197791Snp	ael2020_intr_clear,
2049197791Snp	ael2020_intr_handler,
2050197791Snp	NULL,
2051197791Snp	NULL,
2052197791Snp	NULL,
2053197791Snp	NULL,
2054197791Snp	NULL,
2055197791Snp	get_link_status_r,
2056197791Snp	ael1002_power_down,
2057197791Snp#else
2058197791Snp	.reset           = ael2020_reset,
2059197791Snp	.intr_enable     = ael2020_intr_enable,
2060197791Snp	.intr_disable    = ael2020_intr_disable,
2061197791Snp	.intr_clear      = ael2020_intr_clear,
2062197791Snp	.intr_handler    = ael2020_intr_handler,
2063197791Snp	.get_link_status = get_link_status_r,
2064197791Snp	.power_down      = ael1002_power_down,
2065197791Snp#endif
2066197791Snp};
2067197791Snp
2068197791Snpint t3_ael2020_phy_prep(pinfo_t *pinfo, int phy_addr,
2069197791Snp			const struct mdio_ops *mdio_ops)
2070197791Snp{
2071197791Snp	int err;
2072197791Snp	struct cphy *phy = &pinfo->phy;
2073197791Snp
2074197791Snp	cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &ael2020_ops, mdio_ops,
2075197791Snp		SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE |
2076197791Snp		  SUPPORTED_IRQ, "10GBASE-R");
2077197791Snp	msleep(125);
2078197791Snp
2079197791Snp	err = set_phy_regs(phy, ael2020_reset_regs);
2080197791Snp	if (err)
2081197791Snp		return err;
2082197791Snp	err = ael2020_get_module_type(phy, 0);
2083197791Snp	if (err >= 0)
2084197791Snp		phy->modtype = err;
2085197791Snp
2086197791Snp	ael_laser_down(phy, 0);
2087197791Snp	return 0;
2088197791Snp}
2089197791Snp
2090197791Snp/*
2091181614Skmacy * Get link status for a 10GBASE-X device.
2092181614Skmacy */
2093181614Skmacystatic int get_link_status_x(struct cphy *phy, int *link_ok, int *speed,
2094181614Skmacy			     int *duplex, int *fc)
2095181614Skmacy{
2096181614Skmacy	if (link_ok) {
2097181614Skmacy		unsigned int stat0, stat1, stat2;
2098181614Skmacy		int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0);
2099181614Skmacy
2100181614Skmacy		if (!err)
2101181614Skmacy			err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_X, &stat1);
2102181614Skmacy		if (!err)
2103181614Skmacy			err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2);
2104181614Skmacy		if (err)
2105181614Skmacy			return err;
2106181614Skmacy		*link_ok = (stat0 & (stat1 >> 12) & (stat2 >> 12)) & 1;
2107181614Skmacy	}
2108181614Skmacy	if (speed)
2109181614Skmacy		*speed = SPEED_10000;
2110181614Skmacy	if (duplex)
2111181614Skmacy		*duplex = DUPLEX_FULL;
2112181614Skmacy	return 0;
2113181614Skmacy}
2114181614Skmacy
2115180583Skmacy#ifdef C99_NOT_SUPPORTED
2116167514Skmacystatic struct cphy_ops qt2045_ops = {
2117167514Skmacy	ael1006_reset,
2118180583Skmacy	t3_phy_lasi_intr_enable,
2119180583Skmacy	t3_phy_lasi_intr_disable,
2120180583Skmacy	t3_phy_lasi_intr_clear,
2121180583Skmacy	t3_phy_lasi_intr_handler,
2122167514Skmacy	NULL,
2123167514Skmacy	NULL,
2124167514Skmacy	NULL,
2125167514Skmacy	NULL,
2126167514Skmacy	NULL,
2127181614Skmacy	get_link_status_x,
2128197791Snp	ael1002_power_down,
2129167514Skmacy};
2130167514Skmacy#else
2131167514Skmacystatic struct cphy_ops qt2045_ops = {
2132167514Skmacy	.reset           = ael1006_reset,
2133180583Skmacy	.intr_enable     = t3_phy_lasi_intr_enable,
2134180583Skmacy	.intr_disable    = t3_phy_lasi_intr_disable,
2135180583Skmacy	.intr_clear      = t3_phy_lasi_intr_clear,
2136180583Skmacy	.intr_handler    = t3_phy_lasi_intr_handler,
2137181614Skmacy	.get_link_status = get_link_status_x,
2138197791Snp	.power_down      = ael1002_power_down,
2139167514Skmacy};
2140167514Skmacy#endif
2141167514Skmacy
2142197791Snpint t3_qt2045_phy_prep(pinfo_t *pinfo, int phy_addr,
2143176472Skmacy		       const struct mdio_ops *mdio_ops)
2144167514Skmacy{
2145167514Skmacy	unsigned int stat;
2146197791Snp	struct cphy *phy = &pinfo->phy;
2147167514Skmacy
2148197791Snp	cphy_init(phy, pinfo->adapter, pinfo, phy_addr, &qt2045_ops, mdio_ops,
2149176472Skmacy		  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
2150176472Skmacy		  "10GBASE-CX4");
2151167514Skmacy
2152167514Skmacy	/*
2153167514Skmacy	 * Some cards where the PHY is supposed to be at address 0 actually
2154167514Skmacy	 * have it at 1.
2155167514Skmacy	 */
2156167514Skmacy	if (!phy_addr && !mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &stat) &&
2157167514Skmacy	    stat == 0xffff)
2158167514Skmacy		phy->addr = 1;
2159176472Skmacy	return 0;
2160167514Skmacy}
2161167514Skmacy
2162167514Skmacystatic int xaui_direct_reset(struct cphy *phy, int wait)
2163167514Skmacy{
2164167514Skmacy	return 0;
2165167514Skmacy}
2166167514Skmacy
2167167514Skmacystatic int xaui_direct_get_link_status(struct cphy *phy, int *link_ok,
2168167514Skmacy				       int *speed, int *duplex, int *fc)
2169167514Skmacy{
2170167514Skmacy	if (link_ok) {
2171167514Skmacy		unsigned int status;
2172197791Snp		adapter_t *adapter = phy->adapter;
2173189643Sgnn
2174197791Snp		status = t3_read_reg(adapter,
2175170654Skmacy				     XGM_REG(A_XGM_SERDES_STAT0, phy->addr)) |
2176197791Snp			 t3_read_reg(adapter,
2177170654Skmacy				     XGM_REG(A_XGM_SERDES_STAT1, phy->addr)) |
2178197791Snp			 t3_read_reg(adapter,
2179170654Skmacy				     XGM_REG(A_XGM_SERDES_STAT2, phy->addr)) |
2180197791Snp			 t3_read_reg(adapter,
2181170654Skmacy				     XGM_REG(A_XGM_SERDES_STAT3, phy->addr));
2182167514Skmacy		*link_ok = !(status & F_LOWSIG0);
2183167514Skmacy	}
2184167514Skmacy	if (speed)
2185167514Skmacy		*speed = SPEED_10000;
2186167514Skmacy	if (duplex)
2187167514Skmacy		*duplex = DUPLEX_FULL;
2188167514Skmacy	return 0;
2189167514Skmacy}
2190167514Skmacy
2191167514Skmacystatic int xaui_direct_power_down(struct cphy *phy, int enable)
2192167514Skmacy{
2193167514Skmacy	return 0;
2194167514Skmacy}
2195167514Skmacy
2196167514Skmacy#ifdef C99_NOT_SUPPORTED
2197167514Skmacystatic struct cphy_ops xaui_direct_ops = {
2198167514Skmacy	xaui_direct_reset,
2199167514Skmacy	ael1002_intr_noop,
2200167514Skmacy	ael1002_intr_noop,
2201167514Skmacy	ael1002_intr_noop,
2202167514Skmacy	ael1002_intr_noop,
2203167514Skmacy	NULL,
2204167514Skmacy	NULL,
2205167514Skmacy	NULL,
2206167514Skmacy	NULL,
2207167514Skmacy	NULL,
2208167514Skmacy	xaui_direct_get_link_status,
2209167514Skmacy	xaui_direct_power_down,
2210167514Skmacy};
2211167514Skmacy#else
2212167514Skmacystatic struct cphy_ops xaui_direct_ops = {
2213167514Skmacy	.reset           = xaui_direct_reset,
2214167514Skmacy	.intr_enable     = ael1002_intr_noop,
2215167514Skmacy	.intr_disable    = ael1002_intr_noop,
2216167514Skmacy	.intr_clear      = ael1002_intr_noop,
2217167514Skmacy	.intr_handler    = ael1002_intr_noop,
2218167514Skmacy	.get_link_status = xaui_direct_get_link_status,
2219167514Skmacy	.power_down      = xaui_direct_power_down,
2220167514Skmacy};
2221167514Skmacy#endif
2222167514Skmacy
2223197791Snpint t3_xaui_direct_phy_prep(pinfo_t *pinfo, int phy_addr,
2224176472Skmacy			    const struct mdio_ops *mdio_ops)
2225167514Skmacy{
2226197791Snp	cphy_init(&pinfo->phy, pinfo->adapter, pinfo, phy_addr, &xaui_direct_ops, mdio_ops,
2227176472Skmacy		  SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_TP,
2228176472Skmacy		  "10GBASE-CX4");
2229176472Skmacy	return 0;
2230167514Skmacy}
2231