Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * Driver for Aquantia PHY
  4 *
  5 * Author: Shaohui Xie <Shaohui.Xie@freescale.com>
  6 *
  7 * Copyright 2015 Freescale Semiconductor, Inc.
  8 */
  9
 10#include <linux/kernel.h>
 11#include <linux/module.h>
 12#include <linux/delay.h>
 13#include <linux/bitfield.h>
 14#include <linux/phy.h>
 15
 16#include "aquantia.h"
 17
 18#define PHY_ID_AQ1202	0x03a1b445
 19#define PHY_ID_AQ2104	0x03a1b460
 20#define PHY_ID_AQR105	0x03a1b4a2
 21#define PHY_ID_AQR106	0x03a1b4d0
 22#define PHY_ID_AQR107	0x03a1b4e0
 23#define PHY_ID_AQCS109	0x03a1b5c2
 24#define PHY_ID_AQR405	0x03a1b4b0
 25
 26#define MDIO_PHYXS_VEND_IF_STATUS		0xe812
 27#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK	GENMASK(7, 3)
 28#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR	0
 29#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI	2
 30#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII	3
 31#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII	6
 32#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII	10
 33
 34#define MDIO_AN_VEND_PROV			0xc400
 35#define MDIO_AN_VEND_PROV_1000BASET_FULL	BIT(15)
 36#define MDIO_AN_VEND_PROV_1000BASET_HALF	BIT(14)
 37#define MDIO_AN_VEND_PROV_DOWNSHIFT_EN		BIT(4)
 38#define MDIO_AN_VEND_PROV_DOWNSHIFT_MASK	GENMASK(3, 0)
 39#define MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT	4
 40
 41#define MDIO_AN_TX_VEND_STATUS1			0xc800
 42#define MDIO_AN_TX_VEND_STATUS1_RATE_MASK	GENMASK(3, 1)
 43#define MDIO_AN_TX_VEND_STATUS1_10BASET		0
 44#define MDIO_AN_TX_VEND_STATUS1_100BASETX	1
 45#define MDIO_AN_TX_VEND_STATUS1_1000BASET	2
 46#define MDIO_AN_TX_VEND_STATUS1_10GBASET	3
 47#define MDIO_AN_TX_VEND_STATUS1_2500BASET	4
 48#define MDIO_AN_TX_VEND_STATUS1_5000BASET	5
 49#define MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX	BIT(0)
 50
 51#define MDIO_AN_TX_VEND_INT_STATUS1		0xcc00
 52#define MDIO_AN_TX_VEND_INT_STATUS1_DOWNSHIFT	BIT(1)
 53
 54#define MDIO_AN_TX_VEND_INT_STATUS2		0xcc01
 55#define MDIO_AN_TX_VEND_INT_STATUS2_MASK	BIT(0)
 56
 57#define MDIO_AN_TX_VEND_INT_MASK2		0xd401
 58#define MDIO_AN_TX_VEND_INT_MASK2_LINK		BIT(0)
 59
 60#define MDIO_AN_RX_LP_STAT1			0xe820
 61#define MDIO_AN_RX_LP_STAT1_1000BASET_FULL	BIT(15)
 62#define MDIO_AN_RX_LP_STAT1_1000BASET_HALF	BIT(14)
 63#define MDIO_AN_RX_LP_STAT1_SHORT_REACH		BIT(13)
 64#define MDIO_AN_RX_LP_STAT1_AQRATE_DOWNSHIFT	BIT(12)
 65#define MDIO_AN_RX_LP_STAT1_AQ_PHY		BIT(2)
 66
 67#define MDIO_AN_RX_LP_STAT4			0xe823
 68#define MDIO_AN_RX_LP_STAT4_FW_MAJOR		GENMASK(15, 8)
 69#define MDIO_AN_RX_LP_STAT4_FW_MINOR		GENMASK(7, 0)
 70
 71#define MDIO_AN_RX_VEND_STAT3			0xe832
 72#define MDIO_AN_RX_VEND_STAT3_AFR		BIT(0)
 73
 74/* MDIO_MMD_C22EXT */
 75#define MDIO_C22EXT_STAT_SGMII_RX_GOOD_FRAMES		0xd292
 76#define MDIO_C22EXT_STAT_SGMII_RX_BAD_FRAMES		0xd294
 77#define MDIO_C22EXT_STAT_SGMII_RX_FALSE_CARRIER		0xd297
 78#define MDIO_C22EXT_STAT_SGMII_TX_GOOD_FRAMES		0xd313
 79#define MDIO_C22EXT_STAT_SGMII_TX_BAD_FRAMES		0xd315
 80#define MDIO_C22EXT_STAT_SGMII_TX_FALSE_CARRIER		0xd317
 81#define MDIO_C22EXT_STAT_SGMII_TX_COLLISIONS		0xd318
 82#define MDIO_C22EXT_STAT_SGMII_TX_LINE_COLLISIONS	0xd319
 83#define MDIO_C22EXT_STAT_SGMII_TX_FRAME_ALIGN_ERR	0xd31a
 84#define MDIO_C22EXT_STAT_SGMII_TX_RUNT_FRAMES		0xd31b
 85
 86/* Vendor specific 1, MDIO_MMD_VEND1 */
 87#define VEND1_GLOBAL_FW_ID			0x0020
 88#define VEND1_GLOBAL_FW_ID_MAJOR		GENMASK(15, 8)
 89#define VEND1_GLOBAL_FW_ID_MINOR		GENMASK(7, 0)
 90
 91#define VEND1_GLOBAL_RSVD_STAT1			0xc885
 92#define VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID	GENMASK(7, 4)
 93#define VEND1_GLOBAL_RSVD_STAT1_PROV_ID		GENMASK(3, 0)
 94
 95#define VEND1_GLOBAL_RSVD_STAT9			0xc88d
 96#define VEND1_GLOBAL_RSVD_STAT9_MODE		GENMASK(7, 0)
 97#define VEND1_GLOBAL_RSVD_STAT9_1000BT2		0x23
 98
 99#define VEND1_GLOBAL_INT_STD_STATUS		0xfc00
100#define VEND1_GLOBAL_INT_VEND_STATUS		0xfc01
101
102#define VEND1_GLOBAL_INT_STD_MASK		0xff00
103#define VEND1_GLOBAL_INT_STD_MASK_PMA1		BIT(15)
104#define VEND1_GLOBAL_INT_STD_MASK_PMA2		BIT(14)
105#define VEND1_GLOBAL_INT_STD_MASK_PCS1		BIT(13)
106#define VEND1_GLOBAL_INT_STD_MASK_PCS2		BIT(12)
107#define VEND1_GLOBAL_INT_STD_MASK_PCS3		BIT(11)
108#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS1	BIT(10)
109#define VEND1_GLOBAL_INT_STD_MASK_PHY_XS2	BIT(9)
110#define VEND1_GLOBAL_INT_STD_MASK_AN1		BIT(8)
111#define VEND1_GLOBAL_INT_STD_MASK_AN2		BIT(7)
112#define VEND1_GLOBAL_INT_STD_MASK_GBE		BIT(6)
113#define VEND1_GLOBAL_INT_STD_MASK_ALL		BIT(0)
114
115#define VEND1_GLOBAL_INT_VEND_MASK		0xff01
116#define VEND1_GLOBAL_INT_VEND_MASK_PMA		BIT(15)
117#define VEND1_GLOBAL_INT_VEND_MASK_PCS		BIT(14)
118#define VEND1_GLOBAL_INT_VEND_MASK_PHY_XS	BIT(13)
119#define VEND1_GLOBAL_INT_VEND_MASK_AN		BIT(12)
120#define VEND1_GLOBAL_INT_VEND_MASK_GBE		BIT(11)
121#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL1	BIT(2)
122#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL2	BIT(1)
123#define VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3	BIT(0)
124
125struct aqr107_hw_stat {
126	const char *name;
127	int reg;
128	int size;
129};
130
131#define SGMII_STAT(n, r, s) { n, MDIO_C22EXT_STAT_SGMII_ ## r, s }
132static const struct aqr107_hw_stat aqr107_hw_stats[] = {
133	SGMII_STAT("sgmii_rx_good_frames",	    RX_GOOD_FRAMES,	26),
134	SGMII_STAT("sgmii_rx_bad_frames",	    RX_BAD_FRAMES,	26),
135	SGMII_STAT("sgmii_rx_false_carrier_events", RX_FALSE_CARRIER,	 8),
136	SGMII_STAT("sgmii_tx_good_frames",	    TX_GOOD_FRAMES,	26),
137	SGMII_STAT("sgmii_tx_bad_frames",	    TX_BAD_FRAMES,	26),
138	SGMII_STAT("sgmii_tx_false_carrier_events", TX_FALSE_CARRIER,	 8),
139	SGMII_STAT("sgmii_tx_collisions",	    TX_COLLISIONS,	 8),
140	SGMII_STAT("sgmii_tx_line_collisions",	    TX_LINE_COLLISIONS,	 8),
141	SGMII_STAT("sgmii_tx_frame_alignment_err",  TX_FRAME_ALIGN_ERR,	16),
142	SGMII_STAT("sgmii_tx_runt_frames",	    TX_RUNT_FRAMES,	22),
143};
144#define AQR107_SGMII_STAT_SZ ARRAY_SIZE(aqr107_hw_stats)
145
146struct aqr107_priv {
147	u64 sgmii_stats[AQR107_SGMII_STAT_SZ];
148};
149
150static int aqr107_get_sset_count(struct phy_device *phydev)
151{
152	return AQR107_SGMII_STAT_SZ;
153}
154
155static void aqr107_get_strings(struct phy_device *phydev, u8 *data)
156{
157	int i;
158
159	for (i = 0; i < AQR107_SGMII_STAT_SZ; i++)
160		strscpy(data + i * ETH_GSTRING_LEN, aqr107_hw_stats[i].name,
161			ETH_GSTRING_LEN);
162}
163
164static u64 aqr107_get_stat(struct phy_device *phydev, int index)
165{
166	const struct aqr107_hw_stat *stat = aqr107_hw_stats + index;
167	int len_l = min(stat->size, 16);
168	int len_h = stat->size - len_l;
169	u64 ret;
170	int val;
171
172	val = phy_read_mmd(phydev, MDIO_MMD_C22EXT, stat->reg);
173	if (val < 0)
174		return U64_MAX;
175
176	ret = val & GENMASK(len_l - 1, 0);
177	if (len_h) {
178		val = phy_read_mmd(phydev, MDIO_MMD_C22EXT, stat->reg + 1);
179		if (val < 0)
180			return U64_MAX;
181
182		ret += (val & GENMASK(len_h - 1, 0)) << 16;
183	}
184
185	return ret;
186}
187
188static void aqr107_get_stats(struct phy_device *phydev,
189			     struct ethtool_stats *stats, u64 *data)
190{
191	struct aqr107_priv *priv = phydev->priv;
192	u64 val;
193	int i;
194
195	for (i = 0; i < AQR107_SGMII_STAT_SZ; i++) {
196		val = aqr107_get_stat(phydev, i);
197		if (val == U64_MAX)
198			phydev_err(phydev, "Reading HW Statistics failed for %s\n",
199				   aqr107_hw_stats[i].name);
200		else
201			priv->sgmii_stats[i] += val;
202
203		data[i] = priv->sgmii_stats[i];
204	}
205}
206
207static int aqr_config_aneg(struct phy_device *phydev)
208{
209	bool changed = false;
210	u16 reg;
211	int ret;
212
213	if (phydev->autoneg == AUTONEG_DISABLE)
214		return genphy_c45_pma_setup_forced(phydev);
215
216	ret = genphy_c45_an_config_aneg(phydev);
217	if (ret < 0)
218		return ret;
219	if (ret > 0)
220		changed = true;
221
222	/* Clause 45 has no standardized support for 1000BaseT, therefore
223	 * use vendor registers for this mode.
224	 */
225	reg = 0;
226	if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
227			      phydev->advertising))
228		reg |= MDIO_AN_VEND_PROV_1000BASET_FULL;
229
230	if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
231			      phydev->advertising))
232		reg |= MDIO_AN_VEND_PROV_1000BASET_HALF;
233
234	ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV,
235				     MDIO_AN_VEND_PROV_1000BASET_HALF |
236				     MDIO_AN_VEND_PROV_1000BASET_FULL, reg);
237	if (ret < 0)
238		return ret;
239	if (ret > 0)
240		changed = true;
241
242	return genphy_c45_check_and_restart_aneg(phydev, changed);
243}
244
245static int aqr_config_intr(struct phy_device *phydev)
246{
247	bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED;
248	int err;
249
250	if (en) {
251		/* Clear any pending interrupts before enabling them */
252		err = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS2);
253		if (err < 0)
254			return err;
255	}
256
257	err = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_MASK2,
258			    en ? MDIO_AN_TX_VEND_INT_MASK2_LINK : 0);
259	if (err < 0)
260		return err;
261
262	err = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_STD_MASK,
263			    en ? VEND1_GLOBAL_INT_STD_MASK_ALL : 0);
264	if (err < 0)
265		return err;
266
267	err = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_VEND_MASK,
268			    en ? VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 |
269			    VEND1_GLOBAL_INT_VEND_MASK_AN : 0);
270	if (err < 0)
271		return err;
272
273	if (!en) {
274		/* Clear any pending interrupts after we have disabled them */
275		err = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS2);
276		if (err < 0)
277			return err;
278	}
279
280	return 0;
281}
282
283static irqreturn_t aqr_handle_interrupt(struct phy_device *phydev)
284{
285	int irq_status;
286
287	irq_status = phy_read_mmd(phydev, MDIO_MMD_AN,
288				  MDIO_AN_TX_VEND_INT_STATUS2);
289	if (irq_status < 0) {
290		phy_error(phydev);
291		return IRQ_NONE;
292	}
293
294	if (!(irq_status & MDIO_AN_TX_VEND_INT_STATUS2_MASK))
295		return IRQ_NONE;
296
297	phy_trigger_machine(phydev);
298
299	return IRQ_HANDLED;
300}
301
302static int aqr_read_status(struct phy_device *phydev)
303{
304	int val;
305
306	if (phydev->autoneg == AUTONEG_ENABLE) {
307		val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT1);
308		if (val < 0)
309			return val;
310
311		linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
312				 phydev->lp_advertising,
313				 val & MDIO_AN_RX_LP_STAT1_1000BASET_FULL);
314		linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
315				 phydev->lp_advertising,
316				 val & MDIO_AN_RX_LP_STAT1_1000BASET_HALF);
317	}
318
319	return genphy_c45_read_status(phydev);
320}
321
322static int aqr107_read_rate(struct phy_device *phydev)
323{
324	int val;
325
326	val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_STATUS1);
327	if (val < 0)
328		return val;
329
330	switch (FIELD_GET(MDIO_AN_TX_VEND_STATUS1_RATE_MASK, val)) {
331	case MDIO_AN_TX_VEND_STATUS1_10BASET:
332		phydev->speed = SPEED_10;
333		break;
334	case MDIO_AN_TX_VEND_STATUS1_100BASETX:
335		phydev->speed = SPEED_100;
336		break;
337	case MDIO_AN_TX_VEND_STATUS1_1000BASET:
338		phydev->speed = SPEED_1000;
339		break;
340	case MDIO_AN_TX_VEND_STATUS1_2500BASET:
341		phydev->speed = SPEED_2500;
342		break;
343	case MDIO_AN_TX_VEND_STATUS1_5000BASET:
344		phydev->speed = SPEED_5000;
345		break;
346	case MDIO_AN_TX_VEND_STATUS1_10GBASET:
347		phydev->speed = SPEED_10000;
348		break;
349	default:
350		phydev->speed = SPEED_UNKNOWN;
351		break;
352	}
353
354	if (val & MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX)
355		phydev->duplex = DUPLEX_FULL;
356	else
357		phydev->duplex = DUPLEX_HALF;
358
359	return 0;
360}
361
362static int aqr107_read_status(struct phy_device *phydev)
363{
364	int val, ret;
365
366	ret = aqr_read_status(phydev);
367	if (ret)
368		return ret;
369
370	if (!phydev->link || phydev->autoneg == AUTONEG_DISABLE)
371		return 0;
372
373	val = phy_read_mmd(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_VEND_IF_STATUS);
374	if (val < 0)
375		return val;
376
377	switch (FIELD_GET(MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK, val)) {
378	case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR:
379		phydev->interface = PHY_INTERFACE_MODE_10GKR;
380		break;
381	case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI:
382		phydev->interface = PHY_INTERFACE_MODE_10GBASER;
383		break;
384	case MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII:
385		phydev->interface = PHY_INTERFACE_MODE_USXGMII;
386		break;
387	case MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII:
388		phydev->interface = PHY_INTERFACE_MODE_SGMII;
389		break;
390	case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII:
391		phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
392		break;
393	default:
394		phydev->interface = PHY_INTERFACE_MODE_NA;
395		break;
396	}
397
398	/* Read possibly downshifted rate from vendor register */
399	return aqr107_read_rate(phydev);
400}
401
402static int aqr107_get_downshift(struct phy_device *phydev, u8 *data)
403{
404	int val, cnt, enable;
405
406	val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV);
407	if (val < 0)
408		return val;
409
410	enable = FIELD_GET(MDIO_AN_VEND_PROV_DOWNSHIFT_EN, val);
411	cnt = FIELD_GET(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, val);
412
413	*data = enable && cnt ? cnt : DOWNSHIFT_DEV_DISABLE;
414
415	return 0;
416}
417
418static int aqr107_set_downshift(struct phy_device *phydev, u8 cnt)
419{
420	int val = 0;
421
422	if (!FIELD_FIT(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, cnt))
423		return -E2BIG;
424
425	if (cnt != DOWNSHIFT_DEV_DISABLE) {
426		val = MDIO_AN_VEND_PROV_DOWNSHIFT_EN;
427		val |= FIELD_PREP(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, cnt);
428	}
429
430	return phy_modify_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV,
431			      MDIO_AN_VEND_PROV_DOWNSHIFT_EN |
432			      MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, val);
433}
434
435static int aqr107_get_tunable(struct phy_device *phydev,
436			      struct ethtool_tunable *tuna, void *data)
437{
438	switch (tuna->id) {
439	case ETHTOOL_PHY_DOWNSHIFT:
440		return aqr107_get_downshift(phydev, data);
441	default:
442		return -EOPNOTSUPP;
443	}
444}
445
446static int aqr107_set_tunable(struct phy_device *phydev,
447			      struct ethtool_tunable *tuna, const void *data)
448{
449	switch (tuna->id) {
450	case ETHTOOL_PHY_DOWNSHIFT:
451		return aqr107_set_downshift(phydev, *(const u8 *)data);
452	default:
453		return -EOPNOTSUPP;
454	}
455}
456
457/* If we configure settings whilst firmware is still initializing the chip,
458 * then these settings may be overwritten. Therefore make sure chip
459 * initialization has completed. Use presence of the firmware ID as
460 * indicator for initialization having completed.
461 * The chip also provides a "reset completed" bit, but it's cleared after
462 * read. Therefore function would time out if called again.
463 */
464static int aqr107_wait_reset_complete(struct phy_device *phydev)
465{
466	int val;
467
468	return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
469					 VEND1_GLOBAL_FW_ID, val, val != 0,
470					 20000, 2000000, false);
471}
472
473static void aqr107_chip_info(struct phy_device *phydev)
474{
475	u8 fw_major, fw_minor, build_id, prov_id;
476	int val;
477
478	val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_FW_ID);
479	if (val < 0)
480		return;
481
482	fw_major = FIELD_GET(VEND1_GLOBAL_FW_ID_MAJOR, val);
483	fw_minor = FIELD_GET(VEND1_GLOBAL_FW_ID_MINOR, val);
484
485	val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_RSVD_STAT1);
486	if (val < 0)
487		return;
488
489	build_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID, val);
490	prov_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_PROV_ID, val);
491
492	phydev_dbg(phydev, "FW %u.%u, Build %u, Provisioning %u\n",
493		   fw_major, fw_minor, build_id, prov_id);
494}
495
496static int aqr107_config_init(struct phy_device *phydev)
497{
498	int ret;
499
500	/* Check that the PHY interface type is compatible */
501	if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
502	    phydev->interface != PHY_INTERFACE_MODE_2500BASEX &&
503	    phydev->interface != PHY_INTERFACE_MODE_XGMII &&
504	    phydev->interface != PHY_INTERFACE_MODE_USXGMII &&
505	    phydev->interface != PHY_INTERFACE_MODE_10GKR &&
506	    phydev->interface != PHY_INTERFACE_MODE_10GBASER)
507		return -ENODEV;
508
509	WARN(phydev->interface == PHY_INTERFACE_MODE_XGMII,
510	     "Your devicetree is out of date, please update it. The AQR107 family doesn't support XGMII, maybe you mean USXGMII.\n");
511
512	ret = aqr107_wait_reset_complete(phydev);
513	if (!ret)
514		aqr107_chip_info(phydev);
515
516	return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
517}
518
519static int aqcs109_config_init(struct phy_device *phydev)
520{
521	int ret;
522
523	/* Check that the PHY interface type is compatible */
524	if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
525	    phydev->interface != PHY_INTERFACE_MODE_2500BASEX)
526		return -ENODEV;
527
528	ret = aqr107_wait_reset_complete(phydev);
529	if (!ret)
530		aqr107_chip_info(phydev);
531
532	/* AQCS109 belongs to a chip family partially supporting 10G and 5G.
533	 * PMA speed ability bits are the same for all members of the family,
534	 * AQCS109 however supports speeds up to 2.5G only.
535	 */
536	ret = phy_set_max_speed(phydev, SPEED_2500);
537	if (ret)
538		return ret;
539
540	return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);
541}
542
543static void aqr107_link_change_notify(struct phy_device *phydev)
544{
545	u8 fw_major, fw_minor;
546	bool downshift, short_reach, afr;
547	int mode, val;
548
549	if (phydev->state != PHY_RUNNING || phydev->autoneg == AUTONEG_DISABLE)
550		return;
551
552	val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT1);
553	/* call failed or link partner is no Aquantia PHY */
554	if (val < 0 || !(val & MDIO_AN_RX_LP_STAT1_AQ_PHY))
555		return;
556
557	short_reach = val & MDIO_AN_RX_LP_STAT1_SHORT_REACH;
558	downshift = val & MDIO_AN_RX_LP_STAT1_AQRATE_DOWNSHIFT;
559
560	val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT4);
561	if (val < 0)
562		return;
563
564	fw_major = FIELD_GET(MDIO_AN_RX_LP_STAT4_FW_MAJOR, val);
565	fw_minor = FIELD_GET(MDIO_AN_RX_LP_STAT4_FW_MINOR, val);
566
567	val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_VEND_STAT3);
568	if (val < 0)
569		return;
570
571	afr = val & MDIO_AN_RX_VEND_STAT3_AFR;
572
573	phydev_dbg(phydev, "Link partner is Aquantia PHY, FW %u.%u%s%s%s\n",
574		   fw_major, fw_minor,
575		   short_reach ? ", short reach mode" : "",
576		   downshift ? ", fast-retrain downshift advertised" : "",
577		   afr ? ", fast reframe advertised" : "");
578
579	val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_RSVD_STAT9);
580	if (val < 0)
581		return;
582
583	mode = FIELD_GET(VEND1_GLOBAL_RSVD_STAT9_MODE, val);
584	if (mode == VEND1_GLOBAL_RSVD_STAT9_1000BT2)
585		phydev_info(phydev, "Aquantia 1000Base-T2 mode active\n");
586}
587
588static int aqr107_suspend(struct phy_device *phydev)
589{
590	return phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,
591				MDIO_CTRL1_LPOWER);
592}
593
594static int aqr107_resume(struct phy_device *phydev)
595{
596	return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,
597				  MDIO_CTRL1_LPOWER);
598}
599
600static int aqr107_probe(struct phy_device *phydev)
601{
602	phydev->priv = devm_kzalloc(&phydev->mdio.dev,
603				    sizeof(struct aqr107_priv), GFP_KERNEL);
604	if (!phydev->priv)
605		return -ENOMEM;
606
607	return aqr_hwmon_probe(phydev);
608}
609
610static struct phy_driver aqr_driver[] = {
611{
612	PHY_ID_MATCH_MODEL(PHY_ID_AQ1202),
613	.name		= "Aquantia AQ1202",
614	.config_aneg    = aqr_config_aneg,
615	.config_intr	= aqr_config_intr,
616	.handle_interrupt = aqr_handle_interrupt,
617	.read_status	= aqr_read_status,
618},
619{
620	PHY_ID_MATCH_MODEL(PHY_ID_AQ2104),
621	.name		= "Aquantia AQ2104",
622	.config_aneg    = aqr_config_aneg,
623	.config_intr	= aqr_config_intr,
624	.handle_interrupt = aqr_handle_interrupt,
625	.read_status	= aqr_read_status,
626},
627{
628	PHY_ID_MATCH_MODEL(PHY_ID_AQR105),
629	.name		= "Aquantia AQR105",
630	.config_aneg    = aqr_config_aneg,
631	.config_intr	= aqr_config_intr,
632	.handle_interrupt = aqr_handle_interrupt,
633	.read_status	= aqr_read_status,
634	.suspend	= aqr107_suspend,
635	.resume		= aqr107_resume,
636},
637{
638	PHY_ID_MATCH_MODEL(PHY_ID_AQR106),
639	.name		= "Aquantia AQR106",
640	.config_aneg    = aqr_config_aneg,
641	.config_intr	= aqr_config_intr,
642	.handle_interrupt = aqr_handle_interrupt,
643	.read_status	= aqr_read_status,
644},
645{
646	PHY_ID_MATCH_MODEL(PHY_ID_AQR107),
647	.name		= "Aquantia AQR107",
648	.probe		= aqr107_probe,
649	.config_init	= aqr107_config_init,
650	.config_aneg    = aqr_config_aneg,
651	.config_intr	= aqr_config_intr,
652	.handle_interrupt = aqr_handle_interrupt,
653	.read_status	= aqr107_read_status,
654	.get_tunable    = aqr107_get_tunable,
655	.set_tunable    = aqr107_set_tunable,
656	.suspend	= aqr107_suspend,
657	.resume		= aqr107_resume,
658	.get_sset_count	= aqr107_get_sset_count,
659	.get_strings	= aqr107_get_strings,
660	.get_stats	= aqr107_get_stats,
661	.link_change_notify = aqr107_link_change_notify,
662},
663{
664	PHY_ID_MATCH_MODEL(PHY_ID_AQCS109),
665	.name		= "Aquantia AQCS109",
666	.probe		= aqr107_probe,
667	.config_init	= aqcs109_config_init,
668	.config_aneg    = aqr_config_aneg,
669	.config_intr	= aqr_config_intr,
670	.handle_interrupt = aqr_handle_interrupt,
671	.read_status	= aqr107_read_status,
672	.get_tunable    = aqr107_get_tunable,
673	.set_tunable    = aqr107_set_tunable,
674	.suspend	= aqr107_suspend,
675	.resume		= aqr107_resume,
676	.get_sset_count	= aqr107_get_sset_count,
677	.get_strings	= aqr107_get_strings,
678	.get_stats	= aqr107_get_stats,
679	.link_change_notify = aqr107_link_change_notify,
680},
681{
682	PHY_ID_MATCH_MODEL(PHY_ID_AQR405),
683	.name		= "Aquantia AQR405",
684	.config_aneg    = aqr_config_aneg,
685	.config_intr	= aqr_config_intr,
686	.handle_interrupt = aqr_handle_interrupt,
687	.read_status	= aqr_read_status,
688},
689};
690
691module_phy_driver(aqr_driver);
692
693static struct mdio_device_id __maybe_unused aqr_tbl[] = {
694	{ PHY_ID_MATCH_MODEL(PHY_ID_AQ1202) },
695	{ PHY_ID_MATCH_MODEL(PHY_ID_AQ2104) },
696	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR105) },
697	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR106) },
698	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR107) },
699	{ PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) },
700	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR405) },
701	{ }
702};
703
704MODULE_DEVICE_TABLE(mdio, aqr_tbl);
705
706MODULE_DESCRIPTION("Aquantia PHY driver");
707MODULE_AUTHOR("Shaohui Xie <Shaohui.Xie@freescale.com>");
708MODULE_LICENSE("GPL v2");