brintos

brintos / linux-shallow public Read only

0
0
Text · 32.2 KiB · c33a5ef Raw
1124 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Driver for Aquantia PHY4 *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	0x03a1b44519#define PHY_ID_AQ2104	0x03a1b46020#define PHY_ID_AQR105	0x03a1b4a221#define PHY_ID_AQR106	0x03a1b4d022#define PHY_ID_AQR107	0x03a1b4e023#define PHY_ID_AQCS109	0x03a1b5c224#define PHY_ID_AQR405	0x03a1b4b025#define PHY_ID_AQR111	0x03a1b61026#define PHY_ID_AQR111B0	0x03a1b61227#define PHY_ID_AQR112	0x03a1b66228#define PHY_ID_AQR412	0x03a1b71229#define PHY_ID_AQR113	0x31c31c4030#define PHY_ID_AQR113C	0x31c31c1231#define PHY_ID_AQR114C	0x31c31c2232#define PHY_ID_AQR115C	0x31c31c3333#define PHY_ID_AQR813	0x31c31cb234 35#define MDIO_PHYXS_VEND_IF_STATUS		0xe81236#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK	GENMASK(7, 3)37#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR	038#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX	139#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI	240#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII	341#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI	442#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII	643#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI	744#define MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII	1045 46#define MDIO_AN_VEND_PROV			0xc40047#define MDIO_AN_VEND_PROV_1000BASET_FULL	BIT(15)48#define MDIO_AN_VEND_PROV_1000BASET_HALF	BIT(14)49#define MDIO_AN_VEND_PROV_5000BASET_FULL	BIT(11)50#define MDIO_AN_VEND_PROV_2500BASET_FULL	BIT(10)51#define MDIO_AN_VEND_PROV_DOWNSHIFT_EN		BIT(4)52#define MDIO_AN_VEND_PROV_DOWNSHIFT_MASK	GENMASK(3, 0)53#define MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT	454 55#define MDIO_AN_TX_VEND_STATUS1			0xc80056#define MDIO_AN_TX_VEND_STATUS1_RATE_MASK	GENMASK(3, 1)57#define MDIO_AN_TX_VEND_STATUS1_10BASET		058#define MDIO_AN_TX_VEND_STATUS1_100BASETX	159#define MDIO_AN_TX_VEND_STATUS1_1000BASET	260#define MDIO_AN_TX_VEND_STATUS1_10GBASET	361#define MDIO_AN_TX_VEND_STATUS1_2500BASET	462#define MDIO_AN_TX_VEND_STATUS1_5000BASET	563#define MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX	BIT(0)64 65#define MDIO_AN_TX_VEND_INT_STATUS1		0xcc0066#define MDIO_AN_TX_VEND_INT_STATUS1_DOWNSHIFT	BIT(1)67 68#define MDIO_AN_TX_VEND_INT_STATUS2		0xcc0169#define MDIO_AN_TX_VEND_INT_STATUS2_MASK	BIT(0)70 71#define MDIO_AN_TX_VEND_INT_MASK2		0xd40172#define MDIO_AN_TX_VEND_INT_MASK2_LINK		BIT(0)73 74#define MDIO_AN_RX_LP_STAT1			0xe82075#define MDIO_AN_RX_LP_STAT1_1000BASET_FULL	BIT(15)76#define MDIO_AN_RX_LP_STAT1_1000BASET_HALF	BIT(14)77#define MDIO_AN_RX_LP_STAT1_SHORT_REACH		BIT(13)78#define MDIO_AN_RX_LP_STAT1_AQRATE_DOWNSHIFT	BIT(12)79#define MDIO_AN_RX_LP_STAT1_AQ_PHY		BIT(2)80 81#define MDIO_AN_RX_LP_STAT4			0xe82382#define MDIO_AN_RX_LP_STAT4_FW_MAJOR		GENMASK(15, 8)83#define MDIO_AN_RX_LP_STAT4_FW_MINOR		GENMASK(7, 0)84 85#define MDIO_AN_RX_VEND_STAT3			0xe83286#define MDIO_AN_RX_VEND_STAT3_AFR		BIT(0)87 88/* Sleep and timeout for checking if the Processor-Intensive89 * MDIO operation is finished90 */91#define AQR107_OP_IN_PROG_SLEEP		100092#define AQR107_OP_IN_PROG_TIMEOUT	10000093 94static int aqr107_get_sset_count(struct phy_device *phydev)95{96	return AQR107_SGMII_STAT_SZ;97}98 99static void aqr107_get_strings(struct phy_device *phydev, u8 *data)100{101	int i;102 103	for (i = 0; i < AQR107_SGMII_STAT_SZ; i++)104		strscpy(data + i * ETH_GSTRING_LEN, aqr107_hw_stats[i].name,105			ETH_GSTRING_LEN);106}107 108static u64 aqr107_get_stat(struct phy_device *phydev, int index)109{110	const struct aqr107_hw_stat *stat = aqr107_hw_stats + index;111	int len_l = min(stat->size, 16);112	int len_h = stat->size - len_l;113	u64 ret;114	int val;115 116	val = phy_read_mmd(phydev, MDIO_MMD_C22EXT, stat->reg);117	if (val < 0)118		return U64_MAX;119 120	ret = val & GENMASK(len_l - 1, 0);121	if (len_h) {122		val = phy_read_mmd(phydev, MDIO_MMD_C22EXT, stat->reg + 1);123		if (val < 0)124			return U64_MAX;125 126		ret += (val & GENMASK(len_h - 1, 0)) << 16;127	}128 129	return ret;130}131 132static void aqr107_get_stats(struct phy_device *phydev,133			     struct ethtool_stats *stats, u64 *data)134{135	struct aqr107_priv *priv = phydev->priv;136	u64 val;137	int i;138 139	for (i = 0; i < AQR107_SGMII_STAT_SZ; i++) {140		val = aqr107_get_stat(phydev, i);141		if (val == U64_MAX)142			phydev_err(phydev, "Reading HW Statistics failed for %s\n",143				   aqr107_hw_stats[i].name);144		else145			priv->sgmii_stats[i] += val;146 147		data[i] = priv->sgmii_stats[i];148	}149}150 151static int aqr_config_aneg(struct phy_device *phydev)152{153	bool changed = false;154	u16 reg;155	int ret;156 157	if (phydev->autoneg == AUTONEG_DISABLE)158		return genphy_c45_pma_setup_forced(phydev);159 160	ret = genphy_c45_an_config_aneg(phydev);161	if (ret < 0)162		return ret;163	if (ret > 0)164		changed = true;165 166	/* Clause 45 has no standardized support for 1000BaseT, therefore167	 * use vendor registers for this mode.168	 */169	reg = 0;170	if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,171			      phydev->advertising))172		reg |= MDIO_AN_VEND_PROV_1000BASET_FULL;173 174	if (linkmode_test_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,175			      phydev->advertising))176		reg |= MDIO_AN_VEND_PROV_1000BASET_HALF;177 178	/* Handle the case when the 2.5G and 5G speeds are not advertised */179	if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,180			      phydev->advertising))181		reg |= MDIO_AN_VEND_PROV_2500BASET_FULL;182 183	if (linkmode_test_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,184			      phydev->advertising))185		reg |= MDIO_AN_VEND_PROV_5000BASET_FULL;186 187	ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV,188				     MDIO_AN_VEND_PROV_1000BASET_HALF |189				     MDIO_AN_VEND_PROV_1000BASET_FULL |190				     MDIO_AN_VEND_PROV_2500BASET_FULL |191				     MDIO_AN_VEND_PROV_5000BASET_FULL, reg);192	if (ret < 0)193		return ret;194	if (ret > 0)195		changed = true;196 197	return genphy_c45_check_and_restart_aneg(phydev, changed);198}199 200static int aqr_config_intr(struct phy_device *phydev)201{202	bool en = phydev->interrupts == PHY_INTERRUPT_ENABLED;203	int err;204 205	if (en) {206		/* Clear any pending interrupts before enabling them */207		err = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS2);208		if (err < 0)209			return err;210	}211 212	err = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_MASK2,213			    en ? MDIO_AN_TX_VEND_INT_MASK2_LINK : 0);214	if (err < 0)215		return err;216 217	err = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_STD_MASK,218			    en ? VEND1_GLOBAL_INT_STD_MASK_ALL : 0);219	if (err < 0)220		return err;221 222	err = phy_write_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_INT_VEND_MASK,223			    en ? VEND1_GLOBAL_INT_VEND_MASK_GLOBAL3 |224			    VEND1_GLOBAL_INT_VEND_MASK_AN : 0);225	if (err < 0)226		return err;227 228	if (!en) {229		/* Clear any pending interrupts after we have disabled them */230		err = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_INT_STATUS2);231		if (err < 0)232			return err;233	}234 235	return 0;236}237 238static irqreturn_t aqr_handle_interrupt(struct phy_device *phydev)239{240	int irq_status;241 242	irq_status = phy_read_mmd(phydev, MDIO_MMD_AN,243				  MDIO_AN_TX_VEND_INT_STATUS2);244	if (irq_status < 0) {245		phy_error(phydev);246		return IRQ_NONE;247	}248 249	if (!(irq_status & MDIO_AN_TX_VEND_INT_STATUS2_MASK))250		return IRQ_NONE;251 252	phy_trigger_machine(phydev);253 254	return IRQ_HANDLED;255}256 257static int aqr_read_status(struct phy_device *phydev)258{259	int val;260 261	if (phydev->autoneg == AUTONEG_ENABLE) {262		val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_RX_LP_STAT1);263		if (val < 0)264			return val;265 266		linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,267				 phydev->lp_advertising,268				 val & MDIO_AN_RX_LP_STAT1_1000BASET_FULL);269		linkmode_mod_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT,270				 phydev->lp_advertising,271				 val & MDIO_AN_RX_LP_STAT1_1000BASET_HALF);272	}273 274	return genphy_c45_read_status(phydev);275}276 277static int aqr107_read_rate(struct phy_device *phydev)278{279	u32 config_reg;280	int val;281 282	val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_TX_VEND_STATUS1);283	if (val < 0)284		return val;285 286	if (val & MDIO_AN_TX_VEND_STATUS1_FULL_DUPLEX)287		phydev->duplex = DUPLEX_FULL;288	else289		phydev->duplex = DUPLEX_HALF;290 291	switch (FIELD_GET(MDIO_AN_TX_VEND_STATUS1_RATE_MASK, val)) {292	case MDIO_AN_TX_VEND_STATUS1_10BASET:293		phydev->speed = SPEED_10;294		config_reg = VEND1_GLOBAL_CFG_10M;295		break;296	case MDIO_AN_TX_VEND_STATUS1_100BASETX:297		phydev->speed = SPEED_100;298		config_reg = VEND1_GLOBAL_CFG_100M;299		break;300	case MDIO_AN_TX_VEND_STATUS1_1000BASET:301		phydev->speed = SPEED_1000;302		config_reg = VEND1_GLOBAL_CFG_1G;303		break;304	case MDIO_AN_TX_VEND_STATUS1_2500BASET:305		phydev->speed = SPEED_2500;306		config_reg = VEND1_GLOBAL_CFG_2_5G;307		break;308	case MDIO_AN_TX_VEND_STATUS1_5000BASET:309		phydev->speed = SPEED_5000;310		config_reg = VEND1_GLOBAL_CFG_5G;311		break;312	case MDIO_AN_TX_VEND_STATUS1_10GBASET:313		phydev->speed = SPEED_10000;314		config_reg = VEND1_GLOBAL_CFG_10G;315		break;316	default:317		phydev->speed = SPEED_UNKNOWN;318		return 0;319	}320 321	val = phy_read_mmd(phydev, MDIO_MMD_VEND1, config_reg);322	if (val < 0)323		return val;324 325	if (FIELD_GET(VEND1_GLOBAL_CFG_RATE_ADAPT, val) ==326	    VEND1_GLOBAL_CFG_RATE_ADAPT_PAUSE)327		phydev->rate_matching = RATE_MATCH_PAUSE;328	else329		phydev->rate_matching = RATE_MATCH_NONE;330 331	return 0;332}333 334static int aqr107_read_status(struct phy_device *phydev)335{336	int val, ret;337 338	ret = aqr_read_status(phydev);339	if (ret)340		return ret;341 342	if (!phydev->link || phydev->autoneg == AUTONEG_DISABLE)343		return 0;344 345	val = phy_read_mmd(phydev, MDIO_MMD_PHYXS, MDIO_PHYXS_VEND_IF_STATUS);346	if (val < 0)347		return val;348 349	switch (FIELD_GET(MDIO_PHYXS_VEND_IF_STATUS_TYPE_MASK, val)) {350	case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KR:351		phydev->interface = PHY_INTERFACE_MODE_10GKR;352		break;353	case MDIO_PHYXS_VEND_IF_STATUS_TYPE_KX:354		phydev->interface = PHY_INTERFACE_MODE_1000BASEKX;355		break;356	case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XFI:357		phydev->interface = PHY_INTERFACE_MODE_10GBASER;358		break;359	case MDIO_PHYXS_VEND_IF_STATUS_TYPE_USXGMII:360		phydev->interface = PHY_INTERFACE_MODE_USXGMII;361		break;362	case MDIO_PHYXS_VEND_IF_STATUS_TYPE_XAUI:363		phydev->interface = PHY_INTERFACE_MODE_XAUI;364		break;365	case MDIO_PHYXS_VEND_IF_STATUS_TYPE_SGMII:366		phydev->interface = PHY_INTERFACE_MODE_SGMII;367		break;368	case MDIO_PHYXS_VEND_IF_STATUS_TYPE_RXAUI:369		phydev->interface = PHY_INTERFACE_MODE_RXAUI;370		break;371	case MDIO_PHYXS_VEND_IF_STATUS_TYPE_OCSGMII:372		phydev->interface = PHY_INTERFACE_MODE_2500BASEX;373		break;374	default:375		phydev->interface = PHY_INTERFACE_MODE_NA;376		break;377	}378 379	/* Read possibly downshifted rate from vendor register */380	return aqr107_read_rate(phydev);381}382 383static int aqr107_get_downshift(struct phy_device *phydev, u8 *data)384{385	int val, cnt, enable;386 387	val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV);388	if (val < 0)389		return val;390 391	enable = FIELD_GET(MDIO_AN_VEND_PROV_DOWNSHIFT_EN, val);392	cnt = FIELD_GET(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, val);393 394	*data = enable && cnt ? cnt : DOWNSHIFT_DEV_DISABLE;395 396	return 0;397}398 399static int aqr107_set_downshift(struct phy_device *phydev, u8 cnt)400{401	int val = 0;402 403	if (!FIELD_FIT(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, cnt))404		return -E2BIG;405 406	if (cnt != DOWNSHIFT_DEV_DISABLE) {407		val = MDIO_AN_VEND_PROV_DOWNSHIFT_EN;408		val |= FIELD_PREP(MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, cnt);409	}410 411	return phy_modify_mmd(phydev, MDIO_MMD_AN, MDIO_AN_VEND_PROV,412			      MDIO_AN_VEND_PROV_DOWNSHIFT_EN |413			      MDIO_AN_VEND_PROV_DOWNSHIFT_MASK, val);414}415 416static int aqr107_get_tunable(struct phy_device *phydev,417			      struct ethtool_tunable *tuna, void *data)418{419	switch (tuna->id) {420	case ETHTOOL_PHY_DOWNSHIFT:421		return aqr107_get_downshift(phydev, data);422	default:423		return -EOPNOTSUPP;424	}425}426 427static int aqr107_set_tunable(struct phy_device *phydev,428			      struct ethtool_tunable *tuna, const void *data)429{430	switch (tuna->id) {431	case ETHTOOL_PHY_DOWNSHIFT:432		return aqr107_set_downshift(phydev, *(const u8 *)data);433	default:434		return -EOPNOTSUPP;435	}436}437 438#define AQR_FW_WAIT_SLEEP_US	20000439#define AQR_FW_WAIT_TIMEOUT_US	2000000440 441/* If we configure settings whilst firmware is still initializing the chip,442 * then these settings may be overwritten. Therefore make sure chip443 * initialization has completed. Use presence of the firmware ID as444 * indicator for initialization having completed.445 * The chip also provides a "reset completed" bit, but it's cleared after446 * read. Therefore function would time out if called again.447 */448int aqr_wait_reset_complete(struct phy_device *phydev)449{450	int ret, val;451 452	ret = read_poll_timeout(phy_read_mmd, val, val != 0,453				AQR_FW_WAIT_SLEEP_US, AQR_FW_WAIT_TIMEOUT_US,454				false, phydev, MDIO_MMD_VEND1,455				VEND1_GLOBAL_FW_ID);456	if (val < 0) {457		phydev_err(phydev, "Failed to read VEND1_GLOBAL_FW_ID: %pe\n",458			   ERR_PTR(val));459		return val;460	}461 462	return ret;463}464 465static void aqr107_chip_info(struct phy_device *phydev)466{467	u8 fw_major, fw_minor, build_id, prov_id;468	int val;469 470	val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_FW_ID);471	if (val < 0)472		return;473 474	fw_major = FIELD_GET(VEND1_GLOBAL_FW_ID_MAJOR, val);475	fw_minor = FIELD_GET(VEND1_GLOBAL_FW_ID_MINOR, val);476 477	val = phy_read_mmd(phydev, MDIO_MMD_VEND1, VEND1_GLOBAL_RSVD_STAT1);478	if (val < 0)479		return;480 481	build_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_FW_BUILD_ID, val);482	prov_id = FIELD_GET(VEND1_GLOBAL_RSVD_STAT1_PROV_ID, val);483 484	phydev_dbg(phydev, "FW %u.%u, Build %u, Provisioning %u\n",485		   fw_major, fw_minor, build_id, prov_id);486}487 488static int aqr107_config_init(struct phy_device *phydev)489{490	struct aqr107_priv *priv = phydev->priv;491	u32 led_active_low;492	int ret;493 494	/* Check that the PHY interface type is compatible */495	if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&496	    phydev->interface != PHY_INTERFACE_MODE_1000BASEKX &&497	    phydev->interface != PHY_INTERFACE_MODE_2500BASEX &&498	    phydev->interface != PHY_INTERFACE_MODE_XGMII &&499	    phydev->interface != PHY_INTERFACE_MODE_USXGMII &&500	    phydev->interface != PHY_INTERFACE_MODE_10GKR &&501	    phydev->interface != PHY_INTERFACE_MODE_10GBASER &&502	    phydev->interface != PHY_INTERFACE_MODE_XAUI &&503	    phydev->interface != PHY_INTERFACE_MODE_RXAUI)504		return -ENODEV;505 506	WARN(phydev->interface == PHY_INTERFACE_MODE_XGMII,507	     "Your devicetree is out of date, please update it. The AQR107 family doesn't support XGMII, maybe you mean USXGMII.\n");508 509	ret = aqr_wait_reset_complete(phydev);510	if (!ret)511		aqr107_chip_info(phydev);512 513	ret = aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT);514	if (ret)515		return ret;516 517	/* Restore LED polarity state after reset */518	for_each_set_bit(led_active_low, &priv->leds_active_low, AQR_MAX_LEDS) {519		ret = aqr_phy_led_active_low_set(phydev, led_active_low, true);520		if (ret)521			return ret;522	}523 524	return 0;525}526 527static int aqcs109_config_init(struct phy_device *phydev)528{529	int ret;530 531	/* Check that the PHY interface type is compatible */532	if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&533	    phydev->interface != PHY_INTERFACE_MODE_2500BASEX)534		return -ENODEV;535 536	ret = aqr_wait_reset_complete(phydev);537	if (!ret)538		aqr107_chip_info(phydev);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_wait_processor_intensive_op(struct phy_device *phydev)589{590	int val, err;591 592	/* The datasheet notes to wait at least 1ms after issuing a593	 * processor intensive operation before checking.594	 * We cannot use the 'sleep_before_read' parameter of read_poll_timeout595	 * because that just determines the maximum time slept, not the minimum.596	 */597	usleep_range(1000, 5000);598 599	err = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,600					VEND1_GLOBAL_GEN_STAT2, val,601					!(val & VEND1_GLOBAL_GEN_STAT2_OP_IN_PROG),602					AQR107_OP_IN_PROG_SLEEP,603					AQR107_OP_IN_PROG_TIMEOUT, false);604	if (err) {605		phydev_err(phydev, "timeout: processor-intensive MDIO operation\n");606		return err;607	}608 609	return 0;610}611 612static int aqr107_get_rate_matching(struct phy_device *phydev,613				    phy_interface_t iface)614{615	if (iface == PHY_INTERFACE_MODE_10GBASER ||616	    iface == PHY_INTERFACE_MODE_2500BASEX ||617	    iface == PHY_INTERFACE_MODE_NA)618		return RATE_MATCH_PAUSE;619	return RATE_MATCH_NONE;620}621 622static int aqr107_suspend(struct phy_device *phydev)623{624	int err;625 626	err = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,627			       MDIO_CTRL1_LPOWER);628	if (err)629		return err;630 631	return aqr107_wait_processor_intensive_op(phydev);632}633 634static int aqr107_resume(struct phy_device *phydev)635{636	int err;637 638	err = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1, MDIO_CTRL1,639				 MDIO_CTRL1_LPOWER);640	if (err)641		return err;642 643	return aqr107_wait_processor_intensive_op(phydev);644}645 646static const u16 aqr_global_cfg_regs[] = {647	VEND1_GLOBAL_CFG_10M,648	VEND1_GLOBAL_CFG_100M,649	VEND1_GLOBAL_CFG_1G,650	VEND1_GLOBAL_CFG_2_5G,651	VEND1_GLOBAL_CFG_5G,652	VEND1_GLOBAL_CFG_10G653};654 655static int aqr107_fill_interface_modes(struct phy_device *phydev)656{657	unsigned long *possible = phydev->possible_interfaces;658	unsigned int serdes_mode, rate_adapt;659	phy_interface_t interface;660	int i, val;661 662	/* Walk the media-speed configuration registers to determine which663	 * host-side serdes modes may be used by the PHY depending on the664	 * negotiated media speed.665	 */666	for (i = 0; i < ARRAY_SIZE(aqr_global_cfg_regs); i++) {667		val = phy_read_mmd(phydev, MDIO_MMD_VEND1,668				   aqr_global_cfg_regs[i]);669		if (val < 0)670			return val;671 672		serdes_mode = FIELD_GET(VEND1_GLOBAL_CFG_SERDES_MODE, val);673		rate_adapt = FIELD_GET(VEND1_GLOBAL_CFG_RATE_ADAPT, val);674 675		switch (serdes_mode) {676		case VEND1_GLOBAL_CFG_SERDES_MODE_XFI:677			if (rate_adapt == VEND1_GLOBAL_CFG_RATE_ADAPT_USX)678				interface = PHY_INTERFACE_MODE_USXGMII;679			else680				interface = PHY_INTERFACE_MODE_10GBASER;681			break;682 683		case VEND1_GLOBAL_CFG_SERDES_MODE_XFI5G:684			interface = PHY_INTERFACE_MODE_5GBASER;685			break;686 687		case VEND1_GLOBAL_CFG_SERDES_MODE_OCSGMII:688			interface = PHY_INTERFACE_MODE_2500BASEX;689			break;690 691		case VEND1_GLOBAL_CFG_SERDES_MODE_SGMII:692			interface = PHY_INTERFACE_MODE_SGMII;693			break;694 695		default:696			phydev_warn(phydev, "unrecognised serdes mode %u\n",697				    serdes_mode);698			interface = PHY_INTERFACE_MODE_NA;699			break;700		}701 702		if (interface != PHY_INTERFACE_MODE_NA)703			__set_bit(interface, possible);704	}705 706	return 0;707}708 709static int aqr113c_fill_interface_modes(struct phy_device *phydev)710{711	int val, ret;712 713	/* It's been observed on some models that - when coming out of suspend714	 * - the FW signals that the PHY is ready but the GLOBAL_CFG registers715	 * continue on returning zeroes for some time. Let's poll the 100M716	 * register until it returns a real value as both 113c and 115c support717	 * this mode.718	 */719	ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,720					VEND1_GLOBAL_CFG_100M, val, val != 0,721					1000, 100000, false);722	if (ret)723		return ret;724 725	return aqr107_fill_interface_modes(phydev);726}727 728static int aqr115c_get_features(struct phy_device *phydev)729{730	unsigned long *supported = phydev->supported;731 732	/* PHY supports speeds up to 2.5G with autoneg. PMA capabilities733	 * are not useful.734	 */735	linkmode_or(supported, supported, phy_gbit_features);736	linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, supported);737 738	return 0;739}740 741static int aqr111_get_features(struct phy_device *phydev)742{743	/* PHY supports speeds up to 5G with autoneg. PMA capabilities744	 * are not useful.745	 */746	aqr115c_get_features(phydev);747	linkmode_set_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,748			 phydev->supported);749 750	return 0;751}752 753static int aqr113c_config_init(struct phy_device *phydev)754{755	int ret;756 757	ret = aqr107_config_init(phydev);758	if (ret < 0)759		return ret;760 761	ret = phy_clear_bits_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_TXDIS,762				 MDIO_PMD_TXDIS_GLOBAL);763	if (ret)764		return ret;765 766	ret = aqr107_wait_processor_intensive_op(phydev);767	if (ret)768		return ret;769 770	return aqr113c_fill_interface_modes(phydev);771}772 773static int aqr107_probe(struct phy_device *phydev)774{775	int ret;776 777	phydev->priv = devm_kzalloc(&phydev->mdio.dev,778				    sizeof(struct aqr107_priv), GFP_KERNEL);779	if (!phydev->priv)780		return -ENOMEM;781 782	ret = aqr_firmware_load(phydev);783	if (ret)784		return ret;785 786	return aqr_hwmon_probe(phydev);787}788 789 790static struct phy_driver aqr_driver[] = {791{792	PHY_ID_MATCH_MODEL(PHY_ID_AQ1202),793	.name		= "Aquantia AQ1202",794	.config_aneg    = aqr_config_aneg,795	.config_intr	= aqr_config_intr,796	.handle_interrupt = aqr_handle_interrupt,797	.read_status	= aqr_read_status,798},799{800	PHY_ID_MATCH_MODEL(PHY_ID_AQ2104),801	.name		= "Aquantia AQ2104",802	.config_aneg    = aqr_config_aneg,803	.config_intr	= aqr_config_intr,804	.handle_interrupt = aqr_handle_interrupt,805	.read_status	= aqr_read_status,806},807{808	PHY_ID_MATCH_MODEL(PHY_ID_AQR105),809	.name		= "Aquantia AQR105",810	.config_aneg    = aqr_config_aneg,811	.config_intr	= aqr_config_intr,812	.handle_interrupt = aqr_handle_interrupt,813	.read_status	= aqr_read_status,814	.suspend	= aqr107_suspend,815	.resume		= aqr107_resume,816},817{818	PHY_ID_MATCH_MODEL(PHY_ID_AQR106),819	.name		= "Aquantia AQR106",820	.config_aneg    = aqr_config_aneg,821	.config_intr	= aqr_config_intr,822	.handle_interrupt = aqr_handle_interrupt,823	.read_status	= aqr_read_status,824},825{826	PHY_ID_MATCH_MODEL(PHY_ID_AQR107),827	.name		= "Aquantia AQR107",828	.probe		= aqr107_probe,829	.get_rate_matching = aqr107_get_rate_matching,830	.config_init	= aqr107_config_init,831	.config_aneg    = aqr_config_aneg,832	.config_intr	= aqr_config_intr,833	.handle_interrupt = aqr_handle_interrupt,834	.read_status	= aqr107_read_status,835	.get_tunable    = aqr107_get_tunable,836	.set_tunable    = aqr107_set_tunable,837	.suspend	= aqr107_suspend,838	.resume		= aqr107_resume,839	.get_sset_count	= aqr107_get_sset_count,840	.get_strings	= aqr107_get_strings,841	.get_stats	= aqr107_get_stats,842	.link_change_notify = aqr107_link_change_notify,843	.led_brightness_set = aqr_phy_led_brightness_set,844	.led_hw_is_supported = aqr_phy_led_hw_is_supported,845	.led_hw_control_set = aqr_phy_led_hw_control_set,846	.led_hw_control_get = aqr_phy_led_hw_control_get,847	.led_polarity_set = aqr_phy_led_polarity_set,848},849{850	PHY_ID_MATCH_MODEL(PHY_ID_AQCS109),851	.name		= "Aquantia AQCS109",852	.probe		= aqr107_probe,853	.get_rate_matching = aqr107_get_rate_matching,854	.config_init	= aqcs109_config_init,855	.config_aneg    = aqr_config_aneg,856	.config_intr	= aqr_config_intr,857	.handle_interrupt = aqr_handle_interrupt,858	.read_status	= aqr107_read_status,859	.get_tunable    = aqr107_get_tunable,860	.set_tunable    = aqr107_set_tunable,861	.suspend	= aqr107_suspend,862	.resume		= aqr107_resume,863	.get_sset_count	= aqr107_get_sset_count,864	.get_strings	= aqr107_get_strings,865	.get_stats	= aqr107_get_stats,866	.get_features   = aqr115c_get_features,867	.link_change_notify = aqr107_link_change_notify,868	.led_brightness_set = aqr_phy_led_brightness_set,869	.led_hw_is_supported = aqr_phy_led_hw_is_supported,870	.led_hw_control_set = aqr_phy_led_hw_control_set,871	.led_hw_control_get = aqr_phy_led_hw_control_get,872	.led_polarity_set = aqr_phy_led_polarity_set,873},874{875	PHY_ID_MATCH_MODEL(PHY_ID_AQR111),876	.name		= "Aquantia AQR111",877	.probe		= aqr107_probe,878	.get_rate_matching = aqr107_get_rate_matching,879	.config_init	= aqr107_config_init,880	.config_aneg    = aqr_config_aneg,881	.config_intr	= aqr_config_intr,882	.handle_interrupt = aqr_handle_interrupt,883	.read_status	= aqr107_read_status,884	.get_tunable    = aqr107_get_tunable,885	.set_tunable    = aqr107_set_tunable,886	.suspend	= aqr107_suspend,887	.resume		= aqr107_resume,888	.get_sset_count	= aqr107_get_sset_count,889	.get_strings	= aqr107_get_strings,890	.get_stats	= aqr107_get_stats,891	.get_features   = aqr111_get_features,892	.link_change_notify = aqr107_link_change_notify,893	.led_brightness_set = aqr_phy_led_brightness_set,894	.led_hw_is_supported = aqr_phy_led_hw_is_supported,895	.led_hw_control_set = aqr_phy_led_hw_control_set,896	.led_hw_control_get = aqr_phy_led_hw_control_get,897	.led_polarity_set = aqr_phy_led_polarity_set,898},899{900	PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0),901	.name		= "Aquantia AQR111B0",902	.probe		= aqr107_probe,903	.get_rate_matching = aqr107_get_rate_matching,904	.config_init	= aqr107_config_init,905	.config_aneg    = aqr_config_aneg,906	.config_intr	= aqr_config_intr,907	.handle_interrupt = aqr_handle_interrupt,908	.read_status	= aqr107_read_status,909	.get_tunable    = aqr107_get_tunable,910	.set_tunable    = aqr107_set_tunable,911	.suspend	= aqr107_suspend,912	.resume		= aqr107_resume,913	.get_sset_count	= aqr107_get_sset_count,914	.get_strings	= aqr107_get_strings,915	.get_stats	= aqr107_get_stats,916	.get_features   = aqr111_get_features,917	.link_change_notify = aqr107_link_change_notify,918	.led_brightness_set = aqr_phy_led_brightness_set,919	.led_hw_is_supported = aqr_phy_led_hw_is_supported,920	.led_hw_control_set = aqr_phy_led_hw_control_set,921	.led_hw_control_get = aqr_phy_led_hw_control_get,922	.led_polarity_set = aqr_phy_led_polarity_set,923},924{925	PHY_ID_MATCH_MODEL(PHY_ID_AQR405),926	.name		= "Aquantia AQR405",927	.config_aneg    = aqr_config_aneg,928	.config_intr	= aqr_config_intr,929	.handle_interrupt = aqr_handle_interrupt,930	.read_status	= aqr_read_status,931},932{933	PHY_ID_MATCH_MODEL(PHY_ID_AQR112),934	.name		= "Aquantia AQR112",935	.probe		= aqr107_probe,936	.config_aneg    = aqr_config_aneg,937	.config_intr	= aqr_config_intr,938	.handle_interrupt = aqr_handle_interrupt,939	.get_tunable    = aqr107_get_tunable,940	.set_tunable    = aqr107_set_tunable,941	.suspend	= aqr107_suspend,942	.resume		= aqr107_resume,943	.read_status	= aqr107_read_status,944	.get_rate_matching = aqr107_get_rate_matching,945	.get_sset_count = aqr107_get_sset_count,946	.get_strings	= aqr107_get_strings,947	.get_stats	= aqr107_get_stats,948	.link_change_notify = aqr107_link_change_notify,949	.led_brightness_set = aqr_phy_led_brightness_set,950	.led_hw_is_supported = aqr_phy_led_hw_is_supported,951	.led_hw_control_set = aqr_phy_led_hw_control_set,952	.led_hw_control_get = aqr_phy_led_hw_control_get,953	.led_polarity_set = aqr_phy_led_polarity_set,954},955{956	PHY_ID_MATCH_MODEL(PHY_ID_AQR412),957	.name		= "Aquantia AQR412",958	.probe		= aqr107_probe,959	.config_aneg    = aqr_config_aneg,960	.config_intr	= aqr_config_intr,961	.handle_interrupt = aqr_handle_interrupt,962	.get_tunable    = aqr107_get_tunable,963	.set_tunable    = aqr107_set_tunable,964	.suspend	= aqr107_suspend,965	.resume		= aqr107_resume,966	.read_status	= aqr107_read_status,967	.get_rate_matching = aqr107_get_rate_matching,968	.get_sset_count = aqr107_get_sset_count,969	.get_strings	= aqr107_get_strings,970	.get_stats	= aqr107_get_stats,971	.link_change_notify = aqr107_link_change_notify,972},973{974	PHY_ID_MATCH_MODEL(PHY_ID_AQR113),975	.name		= "Aquantia AQR113",976	.probe          = aqr107_probe,977	.get_rate_matching = aqr107_get_rate_matching,978	.config_init    = aqr113c_config_init,979	.config_aneg    = aqr_config_aneg,980	.config_intr    = aqr_config_intr,981	.handle_interrupt       = aqr_handle_interrupt,982	.read_status    = aqr107_read_status,983	.get_tunable    = aqr107_get_tunable,984	.set_tunable    = aqr107_set_tunable,985	.suspend        = aqr107_suspend,986	.resume         = aqr107_resume,987	.get_sset_count = aqr107_get_sset_count,988	.get_strings    = aqr107_get_strings,989	.get_stats      = aqr107_get_stats,990	.link_change_notify = aqr107_link_change_notify,991	.led_brightness_set = aqr_phy_led_brightness_set,992	.led_hw_is_supported = aqr_phy_led_hw_is_supported,993	.led_hw_control_set = aqr_phy_led_hw_control_set,994	.led_hw_control_get = aqr_phy_led_hw_control_get,995	.led_polarity_set = aqr_phy_led_polarity_set,996},997{998	PHY_ID_MATCH_MODEL(PHY_ID_AQR113C),999	.name           = "Aquantia AQR113C",1000	.probe          = aqr107_probe,1001	.get_rate_matching = aqr107_get_rate_matching,1002	.config_init    = aqr113c_config_init,1003	.config_aneg    = aqr_config_aneg,1004	.config_intr    = aqr_config_intr,1005	.handle_interrupt       = aqr_handle_interrupt,1006	.read_status    = aqr107_read_status,1007	.get_tunable    = aqr107_get_tunable,1008	.set_tunable    = aqr107_set_tunable,1009	.suspend        = aqr107_suspend,1010	.resume         = aqr107_resume,1011	.get_sset_count = aqr107_get_sset_count,1012	.get_strings    = aqr107_get_strings,1013	.get_stats      = aqr107_get_stats,1014	.link_change_notify = aqr107_link_change_notify,1015	.led_brightness_set = aqr_phy_led_brightness_set,1016	.led_hw_is_supported = aqr_phy_led_hw_is_supported,1017	.led_hw_control_set = aqr_phy_led_hw_control_set,1018	.led_hw_control_get = aqr_phy_led_hw_control_get,1019	.led_polarity_set = aqr_phy_led_polarity_set,1020},1021{1022	PHY_ID_MATCH_MODEL(PHY_ID_AQR114C),1023	.name           = "Aquantia AQR114C",1024	.probe          = aqr107_probe,1025	.get_rate_matching = aqr107_get_rate_matching,1026	.config_init    = aqr107_config_init,1027	.config_aneg    = aqr_config_aneg,1028	.config_intr    = aqr_config_intr,1029	.handle_interrupt = aqr_handle_interrupt,1030	.read_status    = aqr107_read_status,1031	.get_tunable    = aqr107_get_tunable,1032	.set_tunable    = aqr107_set_tunable,1033	.suspend        = aqr107_suspend,1034	.resume         = aqr107_resume,1035	.get_sset_count = aqr107_get_sset_count,1036	.get_strings    = aqr107_get_strings,1037	.get_stats      = aqr107_get_stats,1038	.get_features   = aqr111_get_features,1039	.link_change_notify = aqr107_link_change_notify,1040	.led_brightness_set = aqr_phy_led_brightness_set,1041	.led_hw_is_supported = aqr_phy_led_hw_is_supported,1042	.led_hw_control_set = aqr_phy_led_hw_control_set,1043	.led_hw_control_get = aqr_phy_led_hw_control_get,1044	.led_polarity_set = aqr_phy_led_polarity_set,1045},1046{1047	PHY_ID_MATCH_MODEL(PHY_ID_AQR115C),1048	.name           = "Aquantia AQR115C",1049	.probe          = aqr107_probe,1050	.get_rate_matching = aqr107_get_rate_matching,1051	.config_init    = aqr113c_config_init,1052	.config_aneg    = aqr_config_aneg,1053	.config_intr    = aqr_config_intr,1054	.handle_interrupt = aqr_handle_interrupt,1055	.read_status    = aqr107_read_status,1056	.get_tunable    = aqr107_get_tunable,1057	.set_tunable    = aqr107_set_tunable,1058	.suspend        = aqr107_suspend,1059	.resume         = aqr107_resume,1060	.get_sset_count = aqr107_get_sset_count,1061	.get_strings    = aqr107_get_strings,1062	.get_stats      = aqr107_get_stats,1063	.get_features   = aqr115c_get_features,1064	.link_change_notify = aqr107_link_change_notify,1065	.led_brightness_set = aqr_phy_led_brightness_set,1066	.led_hw_is_supported = aqr_phy_led_hw_is_supported,1067	.led_hw_control_set = aqr_phy_led_hw_control_set,1068	.led_hw_control_get = aqr_phy_led_hw_control_get,1069	.led_polarity_set = aqr_phy_led_polarity_set,1070},1071{1072	PHY_ID_MATCH_MODEL(PHY_ID_AQR813),1073	.name		= "Aquantia AQR813",1074	.probe		= aqr107_probe,1075	.get_rate_matching = aqr107_get_rate_matching,1076	.config_init	= aqr107_config_init,1077	.config_aneg    = aqr_config_aneg,1078	.config_intr	= aqr_config_intr,1079	.handle_interrupt = aqr_handle_interrupt,1080	.read_status	= aqr107_read_status,1081	.get_tunable    = aqr107_get_tunable,1082	.set_tunable    = aqr107_set_tunable,1083	.suspend	= aqr107_suspend,1084	.resume		= aqr107_resume,1085	.get_sset_count	= aqr107_get_sset_count,1086	.get_strings	= aqr107_get_strings,1087	.get_stats	= aqr107_get_stats,1088	.link_change_notify = aqr107_link_change_notify,1089	.led_brightness_set = aqr_phy_led_brightness_set,1090	.led_hw_is_supported = aqr_phy_led_hw_is_supported,1091	.led_hw_control_set = aqr_phy_led_hw_control_set,1092	.led_hw_control_get = aqr_phy_led_hw_control_get,1093	.led_polarity_set = aqr_phy_led_polarity_set,1094},1095};1096 1097module_phy_driver(aqr_driver);1098 1099static struct mdio_device_id __maybe_unused aqr_tbl[] = {1100	{ PHY_ID_MATCH_MODEL(PHY_ID_AQ1202) },1101	{ PHY_ID_MATCH_MODEL(PHY_ID_AQ2104) },1102	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR105) },1103	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR106) },1104	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR107) },1105	{ PHY_ID_MATCH_MODEL(PHY_ID_AQCS109) },1106	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR405) },1107	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR111) },1108	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR111B0) },1109	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR112) },1110	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR412) },1111	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR113) },1112	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR113C) },1113	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR114C) },1114	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR115C) },1115	{ PHY_ID_MATCH_MODEL(PHY_ID_AQR813) },1116	{ }1117};1118 1119MODULE_DEVICE_TABLE(mdio, aqr_tbl);1120 1121MODULE_DESCRIPTION("Aquantia PHY driver");1122MODULE_AUTHOR("Shaohui Xie <Shaohui.Xie@freescale.com>");1123MODULE_LICENSE("GPL v2");1124