brintos

brintos / linux-shallow public Read only

0
0
Text · 23.3 KiB · 5f056d7 Raw
927 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Driver for the Texas Instruments DP83869 PHY3 * Copyright (C) 2019 Texas Instruments Inc.4 */5 6#include <linux/ethtool.h>7#include <linux/etherdevice.h>8#include <linux/kernel.h>9#include <linux/mii.h>10#include <linux/module.h>11#include <linux/of.h>12#include <linux/phy.h>13#include <linux/delay.h>14#include <linux/bitfield.h>15 16#include <dt-bindings/net/ti-dp83869.h>17 18#define DP83869_PHY_ID		0x2000a0f119#define DP83561_PHY_ID		0x2000a1a420#define DP83869_DEVADDR		0x1f21 22#define MII_DP83869_PHYCTRL	0x1023#define MII_DP83869_MICR	0x1224#define MII_DP83869_ISR		0x1325#define DP83869_CFG2		0x1426#define DP83869_CTRL		0x1f27#define DP83869_CFG4		0x1e28 29/* Extended Registers */30#define DP83869_GEN_CFG3        0x003131#define DP83869_RGMIICTL	0x003232#define DP83869_STRAP_STS1	0x006e33#define DP83869_RGMIIDCTL	0x008634#define DP83869_RXFCFG		0x013435#define DP83869_RXFPMD1		0x013636#define DP83869_RXFPMD2		0x013737#define DP83869_RXFPMD3		0x013838#define DP83869_RXFSOP1		0x013939#define DP83869_RXFSOP2		0x013A40#define DP83869_RXFSOP3		0x013B41#define DP83869_IO_MUX_CFG	0x017042#define DP83869_OP_MODE		0x01df43#define DP83869_FX_CTRL		0x0c0044 45#define DP83869_SW_RESET	BIT(15)46#define DP83869_SW_RESTART	BIT(14)47 48/* MICR Interrupt bits */49#define MII_DP83869_MICR_AN_ERR_INT_EN		BIT(15)50#define MII_DP83869_MICR_SPEED_CHNG_INT_EN	BIT(14)51#define MII_DP83869_MICR_DUP_MODE_CHNG_INT_EN	BIT(13)52#define MII_DP83869_MICR_PAGE_RXD_INT_EN	BIT(12)53#define MII_DP83869_MICR_AUTONEG_COMP_INT_EN	BIT(11)54#define MII_DP83869_MICR_LINK_STS_CHNG_INT_EN	BIT(10)55#define MII_DP83869_MICR_FALSE_CARRIER_INT_EN	BIT(8)56#define MII_DP83869_MICR_SLEEP_MODE_CHNG_INT_EN	BIT(4)57#define MII_DP83869_MICR_WOL_INT_EN		BIT(3)58#define MII_DP83869_MICR_XGMII_ERR_INT_EN	BIT(2)59#define MII_DP83869_MICR_POL_CHNG_INT_EN	BIT(1)60#define MII_DP83869_MICR_JABBER_INT_EN		BIT(0)61 62#define MII_DP83869_BMCR_DEFAULT	(BMCR_ANENABLE | \63					 BMCR_FULLDPLX | \64					 BMCR_SPEED1000)65 66#define MII_DP83869_FIBER_ADVERTISE    (ADVERTISED_FIBRE | \67					ADVERTISED_Pause | \68					ADVERTISED_Asym_Pause)69 70/* This is the same bit mask as the BMCR so re-use the BMCR default */71#define DP83869_FX_CTRL_DEFAULT	MII_DP83869_BMCR_DEFAULT72 73/* CFG1 bits */74#define DP83869_CFG1_DEFAULT	(ADVERTISE_1000HALF | \75				 ADVERTISE_1000FULL | \76				 CTL1000_AS_MASTER)77 78/* RGMIICTL bits */79#define DP83869_RGMII_TX_CLK_DELAY_EN		BIT(1)80#define DP83869_RGMII_RX_CLK_DELAY_EN		BIT(0)81 82/* RGMIIDCTL */83#define DP83869_RGMII_CLK_DELAY_SHIFT		484#define DP83869_CLK_DELAY_DEF			785 86/* STRAP_STS1 bits */87#define DP83869_STRAP_OP_MODE_MASK		GENMASK(2, 0)88#define DP83869_STRAP_STS1_RESERVED		BIT(11)89#define DP83869_STRAP_MIRROR_ENABLED           BIT(12)90 91/* PHYCTRL bits */92#define DP83869_RX_FIFO_SHIFT	1293#define DP83869_TX_FIFO_SHIFT	1494 95/* PHY_CTRL lower bytes 0x48 are declared as reserved */96#define DP83869_PHY_CTRL_DEFAULT	0x4897#define DP83869_PHYCR_FIFO_DEPTH_MASK	GENMASK(15, 12)98#define DP83869_PHYCR_RESERVED_MASK	BIT(11)99 100/* IO_MUX_CFG bits */101#define DP83869_IO_MUX_CFG_IO_IMPEDANCE_CTRL	0x1f102 103#define DP83869_IO_MUX_CFG_IO_IMPEDANCE_MAX	0x0104#define DP83869_IO_MUX_CFG_IO_IMPEDANCE_MIN	0x1f105#define DP83869_IO_MUX_CFG_CLK_O_SEL_MASK	(0x1f << 8)106#define DP83869_IO_MUX_CFG_CLK_O_SEL_SHIFT	8107 108/* CFG3 bits */109#define DP83869_CFG3_PORT_MIRROR_EN              BIT(0)110 111/* CFG4 bits */112#define DP83869_INT_OE	BIT(7)113 114/* OP MODE */115#define DP83869_OP_MODE_MII			BIT(5)116#define DP83869_SGMII_RGMII_BRIDGE		BIT(6)117 118/* RXFCFG bits*/119#define DP83869_WOL_MAGIC_EN		BIT(0)120#define DP83869_WOL_PATTERN_EN		BIT(1)121#define DP83869_WOL_BCAST_EN		BIT(2)122#define DP83869_WOL_UCAST_EN		BIT(4)123#define DP83869_WOL_SEC_EN		BIT(5)124#define DP83869_WOL_ENH_MAC		BIT(7)125 126/* CFG2 bits */127#define DP83869_DOWNSHIFT_EN		(BIT(8) | BIT(9))128#define DP83869_DOWNSHIFT_ATTEMPT_MASK	(BIT(10) | BIT(11))129#define DP83869_DOWNSHIFT_1_COUNT_VAL	0130#define DP83869_DOWNSHIFT_2_COUNT_VAL	1131#define DP83869_DOWNSHIFT_4_COUNT_VAL	2132#define DP83869_DOWNSHIFT_8_COUNT_VAL	3133#define DP83869_DOWNSHIFT_1_COUNT	1134#define DP83869_DOWNSHIFT_2_COUNT	2135#define DP83869_DOWNSHIFT_4_COUNT	4136#define DP83869_DOWNSHIFT_8_COUNT	8137 138enum {139	DP83869_PORT_MIRRORING_KEEP,140	DP83869_PORT_MIRRORING_EN,141	DP83869_PORT_MIRRORING_DIS,142};143 144struct dp83869_private {145	int tx_fifo_depth;146	int rx_fifo_depth;147	s32 rx_int_delay;148	s32 tx_int_delay;149	int io_impedance;150	int port_mirroring;151	bool rxctrl_strap_quirk;152	int clk_output_sel;153	int mode;154};155 156static int dp83869_read_status(struct phy_device *phydev)157{158	struct dp83869_private *dp83869 = phydev->priv;159	int ret;160 161	ret = genphy_read_status(phydev);162	if (ret)163		return ret;164 165	if (linkmode_test_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported)) {166		if (phydev->link) {167			if (dp83869->mode == DP83869_RGMII_100_BASE)168				phydev->speed = SPEED_100;169		} else {170			phydev->speed = SPEED_UNKNOWN;171			phydev->duplex = DUPLEX_UNKNOWN;172		}173	}174 175	return 0;176}177 178static int dp83869_ack_interrupt(struct phy_device *phydev)179{180	int err = phy_read(phydev, MII_DP83869_ISR);181 182	if (err < 0)183		return err;184 185	return 0;186}187 188static int dp83869_config_intr(struct phy_device *phydev)189{190	int micr_status = 0, err;191 192	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {193		err = dp83869_ack_interrupt(phydev);194		if (err)195			return err;196 197		micr_status = phy_read(phydev, MII_DP83869_MICR);198		if (micr_status < 0)199			return micr_status;200 201		micr_status |=202			(MII_DP83869_MICR_AN_ERR_INT_EN |203			MII_DP83869_MICR_SPEED_CHNG_INT_EN |204			MII_DP83869_MICR_AUTONEG_COMP_INT_EN |205			MII_DP83869_MICR_LINK_STS_CHNG_INT_EN |206			MII_DP83869_MICR_DUP_MODE_CHNG_INT_EN |207			MII_DP83869_MICR_SLEEP_MODE_CHNG_INT_EN);208 209		err = phy_write(phydev, MII_DP83869_MICR, micr_status);210	} else {211		err = phy_write(phydev, MII_DP83869_MICR, micr_status);212		if (err)213			return err;214 215		err = dp83869_ack_interrupt(phydev);216	}217 218	return err;219}220 221static irqreturn_t dp83869_handle_interrupt(struct phy_device *phydev)222{223	int irq_status, irq_enabled;224 225	irq_status = phy_read(phydev, MII_DP83869_ISR);226	if (irq_status < 0) {227		phy_error(phydev);228		return IRQ_NONE;229	}230 231	irq_enabled = phy_read(phydev, MII_DP83869_MICR);232	if (irq_enabled < 0) {233		phy_error(phydev);234		return IRQ_NONE;235	}236 237	if (!(irq_status & irq_enabled))238		return IRQ_NONE;239 240	phy_trigger_machine(phydev);241 242	return IRQ_HANDLED;243}244 245static int dp83869_set_wol(struct phy_device *phydev,246			   struct ethtool_wolinfo *wol)247{248	struct net_device *ndev = phydev->attached_dev;249	int val_rxcfg, val_micr;250	const u8 *mac;251	int ret;252 253	val_rxcfg = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_RXFCFG);254	if (val_rxcfg < 0)255		return val_rxcfg;256 257	val_micr = phy_read(phydev, MII_DP83869_MICR);258	if (val_micr < 0)259		return val_micr;260 261	if (wol->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_UCAST |262			    WAKE_BCAST)) {263		val_rxcfg |= DP83869_WOL_ENH_MAC;264		val_micr |= MII_DP83869_MICR_WOL_INT_EN;265 266		if (wol->wolopts & WAKE_MAGIC ||267		    wol->wolopts & WAKE_MAGICSECURE) {268			mac = (const u8 *)ndev->dev_addr;269 270			if (!is_valid_ether_addr(mac))271				return -EINVAL;272 273			ret = phy_write_mmd(phydev, DP83869_DEVADDR,274					    DP83869_RXFPMD1,275					    mac[1] << 8 | mac[0]);276			if (ret)277				return ret;278 279			ret = phy_write_mmd(phydev, DP83869_DEVADDR,280					    DP83869_RXFPMD2,281					    mac[3] << 8 | mac[2]);282			if (ret)283				return ret;284 285			ret = phy_write_mmd(phydev, DP83869_DEVADDR,286					    DP83869_RXFPMD3,287					    mac[5] << 8 | mac[4]);288			if (ret)289				return ret;290 291			val_rxcfg |= DP83869_WOL_MAGIC_EN;292		} else {293			val_rxcfg &= ~DP83869_WOL_MAGIC_EN;294		}295 296		if (wol->wolopts & WAKE_MAGICSECURE) {297			ret = phy_write_mmd(phydev, DP83869_DEVADDR,298					    DP83869_RXFSOP1,299					    (wol->sopass[1] << 8) | wol->sopass[0]);300			if (ret)301				return ret;302 303			ret = phy_write_mmd(phydev, DP83869_DEVADDR,304					    DP83869_RXFSOP2,305					    (wol->sopass[3] << 8) | wol->sopass[2]);306			if (ret)307				return ret;308			ret = phy_write_mmd(phydev, DP83869_DEVADDR,309					    DP83869_RXFSOP3,310					    (wol->sopass[5] << 8) | wol->sopass[4]);311			if (ret)312				return ret;313 314			val_rxcfg |= DP83869_WOL_SEC_EN;315		} else {316			val_rxcfg &= ~DP83869_WOL_SEC_EN;317		}318 319		if (wol->wolopts & WAKE_UCAST)320			val_rxcfg |= DP83869_WOL_UCAST_EN;321		else322			val_rxcfg &= ~DP83869_WOL_UCAST_EN;323 324		if (wol->wolopts & WAKE_BCAST)325			val_rxcfg |= DP83869_WOL_BCAST_EN;326		else327			val_rxcfg &= ~DP83869_WOL_BCAST_EN;328	} else {329		val_rxcfg &= ~DP83869_WOL_ENH_MAC;330		val_micr &= ~MII_DP83869_MICR_WOL_INT_EN;331	}332 333	ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_RXFCFG, val_rxcfg);334	if (ret)335		return ret;336 337	return phy_write(phydev, MII_DP83869_MICR, val_micr);338}339 340static void dp83869_get_wol(struct phy_device *phydev,341			    struct ethtool_wolinfo *wol)342{343	int value, sopass_val;344 345	wol->supported = (WAKE_UCAST | WAKE_BCAST | WAKE_MAGIC |346			WAKE_MAGICSECURE);347	wol->wolopts = 0;348 349	value = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_RXFCFG);350	if (value < 0) {351		phydev_err(phydev, "Failed to read RX CFG\n");352		return;353	}354 355	if (value & DP83869_WOL_UCAST_EN)356		wol->wolopts |= WAKE_UCAST;357 358	if (value & DP83869_WOL_BCAST_EN)359		wol->wolopts |= WAKE_BCAST;360 361	if (value & DP83869_WOL_MAGIC_EN)362		wol->wolopts |= WAKE_MAGIC;363 364	if (value & DP83869_WOL_SEC_EN) {365		sopass_val = phy_read_mmd(phydev, DP83869_DEVADDR,366					  DP83869_RXFSOP1);367		if (sopass_val < 0) {368			phydev_err(phydev, "Failed to read RX SOP 1\n");369			return;370		}371 372		wol->sopass[0] = (sopass_val & 0xff);373		wol->sopass[1] = (sopass_val >> 8);374 375		sopass_val = phy_read_mmd(phydev, DP83869_DEVADDR,376					  DP83869_RXFSOP2);377		if (sopass_val < 0) {378			phydev_err(phydev, "Failed to read RX SOP 2\n");379			return;380		}381 382		wol->sopass[2] = (sopass_val & 0xff);383		wol->sopass[3] = (sopass_val >> 8);384 385		sopass_val = phy_read_mmd(phydev, DP83869_DEVADDR,386					  DP83869_RXFSOP3);387		if (sopass_val < 0) {388			phydev_err(phydev, "Failed to read RX SOP 3\n");389			return;390		}391 392		wol->sopass[4] = (sopass_val & 0xff);393		wol->sopass[5] = (sopass_val >> 8);394 395		wol->wolopts |= WAKE_MAGICSECURE;396	}397 398	if (!(value & DP83869_WOL_ENH_MAC))399		wol->wolopts = 0;400}401 402static int dp83869_get_downshift(struct phy_device *phydev, u8 *data)403{404	int val, cnt, enable, count;405 406	val = phy_read(phydev, DP83869_CFG2);407	if (val < 0)408		return val;409 410	enable = FIELD_GET(DP83869_DOWNSHIFT_EN, val);411	cnt = FIELD_GET(DP83869_DOWNSHIFT_ATTEMPT_MASK, val);412 413	switch (cnt) {414	case DP83869_DOWNSHIFT_1_COUNT_VAL:415		count = DP83869_DOWNSHIFT_1_COUNT;416		break;417	case DP83869_DOWNSHIFT_2_COUNT_VAL:418		count = DP83869_DOWNSHIFT_2_COUNT;419		break;420	case DP83869_DOWNSHIFT_4_COUNT_VAL:421		count = DP83869_DOWNSHIFT_4_COUNT;422		break;423	case DP83869_DOWNSHIFT_8_COUNT_VAL:424		count = DP83869_DOWNSHIFT_8_COUNT;425		break;426	default:427		return -EINVAL;428	}429 430	*data = enable ? count : DOWNSHIFT_DEV_DISABLE;431 432	return 0;433}434 435static int dp83869_set_downshift(struct phy_device *phydev, u8 cnt)436{437	int val, count;438 439	if (cnt > DP83869_DOWNSHIFT_8_COUNT)440		return -EINVAL;441 442	if (!cnt)443		return phy_clear_bits(phydev, DP83869_CFG2,444				      DP83869_DOWNSHIFT_EN);445 446	switch (cnt) {447	case DP83869_DOWNSHIFT_1_COUNT:448		count = DP83869_DOWNSHIFT_1_COUNT_VAL;449		break;450	case DP83869_DOWNSHIFT_2_COUNT:451		count = DP83869_DOWNSHIFT_2_COUNT_VAL;452		break;453	case DP83869_DOWNSHIFT_4_COUNT:454		count = DP83869_DOWNSHIFT_4_COUNT_VAL;455		break;456	case DP83869_DOWNSHIFT_8_COUNT:457		count = DP83869_DOWNSHIFT_8_COUNT_VAL;458		break;459	default:460		phydev_err(phydev,461			   "Downshift count must be 1, 2, 4 or 8\n");462		return -EINVAL;463	}464 465	val = DP83869_DOWNSHIFT_EN;466	val |= FIELD_PREP(DP83869_DOWNSHIFT_ATTEMPT_MASK, count);467 468	return phy_modify(phydev, DP83869_CFG2,469			  DP83869_DOWNSHIFT_EN | DP83869_DOWNSHIFT_ATTEMPT_MASK,470			  val);471}472 473static int dp83869_get_tunable(struct phy_device *phydev,474			       struct ethtool_tunable *tuna, void *data)475{476	switch (tuna->id) {477	case ETHTOOL_PHY_DOWNSHIFT:478		return dp83869_get_downshift(phydev, data);479	default:480		return -EOPNOTSUPP;481	}482}483 484static int dp83869_set_tunable(struct phy_device *phydev,485			       struct ethtool_tunable *tuna, const void *data)486{487	switch (tuna->id) {488	case ETHTOOL_PHY_DOWNSHIFT:489		return dp83869_set_downshift(phydev, *(const u8 *)data);490	default:491		return -EOPNOTSUPP;492	}493}494 495static int dp83869_config_port_mirroring(struct phy_device *phydev)496{497	struct dp83869_private *dp83869 = phydev->priv;498 499	if (dp83869->port_mirroring == DP83869_PORT_MIRRORING_EN)500		return phy_set_bits_mmd(phydev, DP83869_DEVADDR,501					DP83869_GEN_CFG3,502					DP83869_CFG3_PORT_MIRROR_EN);503	else504		return phy_clear_bits_mmd(phydev, DP83869_DEVADDR,505					  DP83869_GEN_CFG3,506					  DP83869_CFG3_PORT_MIRROR_EN);507}508 509static int dp83869_set_strapped_mode(struct phy_device *phydev)510{511	struct dp83869_private *dp83869 = phydev->priv;512	int val;513 514	val = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_STRAP_STS1);515	if (val < 0)516		return val;517 518	dp83869->mode = val & DP83869_STRAP_OP_MODE_MASK;519 520	return 0;521}522 523#if IS_ENABLED(CONFIG_OF_MDIO)524static const int dp83869_internal_delay[] = {250, 500, 750, 1000, 1250, 1500,525					     1750, 2000, 2250, 2500, 2750, 3000,526					     3250, 3500, 3750, 4000};527 528static int dp83869_of_init(struct phy_device *phydev)529{530	struct dp83869_private *dp83869 = phydev->priv;531	struct device *dev = &phydev->mdio.dev;532	struct device_node *of_node = dev->of_node;533	int delay_size = ARRAY_SIZE(dp83869_internal_delay);534	int ret;535 536	if (!of_node)537		return -ENODEV;538 539	dp83869->io_impedance = -EINVAL;540 541	/* Optional configuration */542	ret = of_property_read_u32(of_node, "ti,clk-output-sel",543				   &dp83869->clk_output_sel);544	if (ret || dp83869->clk_output_sel > DP83869_CLK_O_SEL_REF_CLK)545		dp83869->clk_output_sel = DP83869_CLK_O_SEL_REF_CLK;546 547	ret = of_property_read_u32(of_node, "ti,op-mode", &dp83869->mode);548	if (ret == 0) {549		if (dp83869->mode < DP83869_RGMII_COPPER_ETHERNET ||550		    dp83869->mode > DP83869_SGMII_COPPER_ETHERNET)551			return -EINVAL;552	} else {553		ret = dp83869_set_strapped_mode(phydev);554		if (ret)555			return ret;556	}557 558	if (of_property_read_bool(of_node, "ti,max-output-impedance"))559		dp83869->io_impedance = DP83869_IO_MUX_CFG_IO_IMPEDANCE_MAX;560	else if (of_property_read_bool(of_node, "ti,min-output-impedance"))561		dp83869->io_impedance = DP83869_IO_MUX_CFG_IO_IMPEDANCE_MIN;562 563	if (of_property_read_bool(of_node, "enet-phy-lane-swap")) {564		dp83869->port_mirroring = DP83869_PORT_MIRRORING_EN;565	} else {566		/* If the lane swap is not in the DT then check the straps */567		ret = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_STRAP_STS1);568		if (ret < 0)569			return ret;570 571		if (ret & DP83869_STRAP_MIRROR_ENABLED)572			dp83869->port_mirroring = DP83869_PORT_MIRRORING_EN;573		else574			dp83869->port_mirroring = DP83869_PORT_MIRRORING_DIS;575 576		ret = 0;577	}578 579	if (of_property_read_u32(of_node, "rx-fifo-depth",580				 &dp83869->rx_fifo_depth))581		dp83869->rx_fifo_depth = DP83869_PHYCR_FIFO_DEPTH_4_B_NIB;582 583	if (of_property_read_u32(of_node, "tx-fifo-depth",584				 &dp83869->tx_fifo_depth))585		dp83869->tx_fifo_depth = DP83869_PHYCR_FIFO_DEPTH_4_B_NIB;586 587	dp83869->rx_int_delay = phy_get_internal_delay(phydev, dev,588						       &dp83869_internal_delay[0],589						       delay_size, true);590	if (dp83869->rx_int_delay < 0)591		dp83869->rx_int_delay = DP83869_CLK_DELAY_DEF;592 593	dp83869->tx_int_delay = phy_get_internal_delay(phydev, dev,594						       &dp83869_internal_delay[0],595						       delay_size, false);596	if (dp83869->tx_int_delay < 0)597		dp83869->tx_int_delay = DP83869_CLK_DELAY_DEF;598 599	return ret;600}601#else602static int dp83869_of_init(struct phy_device *phydev)603{604	return dp83869_set_strapped_mode(phydev);605}606#endif /* CONFIG_OF_MDIO */607 608static int dp83869_configure_rgmii(struct phy_device *phydev,609				   struct dp83869_private *dp83869)610{611	int ret = 0, val;612 613	if (phy_interface_is_rgmii(phydev)) {614		val = phy_read(phydev, MII_DP83869_PHYCTRL);615		if (val < 0)616			return val;617 618		val &= ~DP83869_PHYCR_FIFO_DEPTH_MASK;619		val |= (dp83869->tx_fifo_depth << DP83869_TX_FIFO_SHIFT);620		val |= (dp83869->rx_fifo_depth << DP83869_RX_FIFO_SHIFT);621 622		ret = phy_write(phydev, MII_DP83869_PHYCTRL, val);623		if (ret)624			return ret;625	}626 627	if (dp83869->io_impedance >= 0)628		ret = phy_modify_mmd(phydev, DP83869_DEVADDR,629				     DP83869_IO_MUX_CFG,630				     DP83869_IO_MUX_CFG_IO_IMPEDANCE_CTRL,631				     dp83869->io_impedance &632				     DP83869_IO_MUX_CFG_IO_IMPEDANCE_CTRL);633 634	return ret;635}636 637static int dp83869_configure_fiber(struct phy_device *phydev,638				   struct dp83869_private *dp83869)639{640	int bmcr;641	int ret;642 643	/* Only allow advertising what this PHY supports */644	linkmode_and(phydev->advertising, phydev->advertising,645		     phydev->supported);646 647	linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported);648 649	if (dp83869->mode == DP83869_RGMII_1000_BASE) {650		linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT,651				 phydev->supported);652	} else {653		linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT,654				 phydev->supported);655		linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Half_BIT,656				 phydev->supported);657 658		/* Auto neg is not supported in 100base FX mode */659		bmcr = phy_read(phydev, MII_BMCR);660		if (bmcr < 0)661			return bmcr;662 663		phydev->autoneg = AUTONEG_DISABLE;664		linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->supported);665		linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, phydev->advertising);666 667		if (bmcr & BMCR_ANENABLE) {668			ret =  phy_modify(phydev, MII_BMCR, BMCR_ANENABLE, 0);669			if (ret < 0)670				return ret;671		}672	}673 674	/* Update advertising from supported */675	linkmode_or(phydev->advertising, phydev->advertising,676		    phydev->supported);677 678	return 0;679}680 681static int dp83869_configure_mode(struct phy_device *phydev,682				  struct dp83869_private *dp83869)683{684	int phy_ctrl_val;685	int ret;686 687	if (dp83869->mode < DP83869_RGMII_COPPER_ETHERNET ||688	    dp83869->mode > DP83869_SGMII_COPPER_ETHERNET)689		return -EINVAL;690 691	/* Below init sequence for each operational mode is defined in692	 * section 9.4.8 of the datasheet.693	 */694	phy_ctrl_val = dp83869->mode;695	if (phydev->interface == PHY_INTERFACE_MODE_MII) {696		if (dp83869->mode == DP83869_100M_MEDIA_CONVERT ||697		    dp83869->mode == DP83869_RGMII_100_BASE ||698		    dp83869->mode == DP83869_RGMII_COPPER_ETHERNET) {699			phy_ctrl_val |= DP83869_OP_MODE_MII;700		} else {701			phydev_err(phydev, "selected op-mode is not valid with MII mode\n");702			return -EINVAL;703		}704	}705 706	ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_OP_MODE,707			    phy_ctrl_val);708	if (ret)709		return ret;710 711	ret = phy_write(phydev, MII_BMCR, MII_DP83869_BMCR_DEFAULT);712	if (ret)713		return ret;714 715	phy_ctrl_val = (dp83869->rx_fifo_depth << DP83869_RX_FIFO_SHIFT |716			dp83869->tx_fifo_depth << DP83869_TX_FIFO_SHIFT |717			DP83869_PHY_CTRL_DEFAULT);718 719	switch (dp83869->mode) {720	case DP83869_RGMII_COPPER_ETHERNET:721		ret = phy_write(phydev, MII_DP83869_PHYCTRL,722				phy_ctrl_val);723		if (ret)724			return ret;725 726		ret = phy_write(phydev, MII_CTRL1000, DP83869_CFG1_DEFAULT);727		if (ret)728			return ret;729 730		ret = dp83869_configure_rgmii(phydev, dp83869);731		if (ret)732			return ret;733		break;734	case DP83869_RGMII_SGMII_BRIDGE:735		ret = phy_modify_mmd(phydev, DP83869_DEVADDR, DP83869_OP_MODE,736				     DP83869_SGMII_RGMII_BRIDGE,737				     DP83869_SGMII_RGMII_BRIDGE);738		if (ret)739			return ret;740 741		ret = phy_write_mmd(phydev, DP83869_DEVADDR,742				    DP83869_FX_CTRL, DP83869_FX_CTRL_DEFAULT);743		if (ret)744			return ret;745 746		break;747	case DP83869_1000M_MEDIA_CONVERT:748		ret = phy_write(phydev, MII_DP83869_PHYCTRL,749				phy_ctrl_val);750		if (ret)751			return ret;752 753		ret = phy_write_mmd(phydev, DP83869_DEVADDR,754				    DP83869_FX_CTRL, DP83869_FX_CTRL_DEFAULT);755		if (ret)756			return ret;757		break;758	case DP83869_100M_MEDIA_CONVERT:759		ret = phy_write(phydev, MII_DP83869_PHYCTRL,760				phy_ctrl_val);761		if (ret)762			return ret;763		break;764	case DP83869_SGMII_COPPER_ETHERNET:765		ret = phy_write(phydev, MII_DP83869_PHYCTRL,766				phy_ctrl_val);767		if (ret)768			return ret;769 770		ret = phy_write(phydev, MII_CTRL1000, DP83869_CFG1_DEFAULT);771		if (ret)772			return ret;773 774		ret = phy_write_mmd(phydev, DP83869_DEVADDR,775				    DP83869_FX_CTRL, DP83869_FX_CTRL_DEFAULT);776		if (ret)777			return ret;778 779		break;780	case DP83869_RGMII_1000_BASE:781	case DP83869_RGMII_100_BASE:782		ret = dp83869_configure_fiber(phydev, dp83869);783		break;784	default:785		return -EINVAL;786	}787 788	return ret;789}790 791static int dp83869_config_init(struct phy_device *phydev)792{793	struct dp83869_private *dp83869 = phydev->priv;794	int ret, val;795 796	/* Force speed optimization for the PHY even if it strapped */797	ret = phy_modify(phydev, DP83869_CFG2, DP83869_DOWNSHIFT_EN,798			 DP83869_DOWNSHIFT_EN);799	if (ret)800		return ret;801 802	ret = dp83869_configure_mode(phydev, dp83869);803	if (ret)804		return ret;805 806	/* Enable Interrupt output INT_OE in CFG4 register */807	if (phy_interrupt_is_valid(phydev)) {808		val = phy_read(phydev, DP83869_CFG4);809		val |= DP83869_INT_OE;810		phy_write(phydev, DP83869_CFG4, val);811	}812 813	if (dp83869->port_mirroring != DP83869_PORT_MIRRORING_KEEP)814		dp83869_config_port_mirroring(phydev);815 816	/* Clock output selection if muxing property is set */817	if (dp83869->clk_output_sel != DP83869_CLK_O_SEL_REF_CLK)818		ret = phy_modify_mmd(phydev,819				     DP83869_DEVADDR, DP83869_IO_MUX_CFG,820				     DP83869_IO_MUX_CFG_CLK_O_SEL_MASK,821				     dp83869->clk_output_sel <<822				     DP83869_IO_MUX_CFG_CLK_O_SEL_SHIFT);823 824	if (phy_interface_is_rgmii(phydev)) {825		ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_RGMIIDCTL,826				    dp83869->rx_int_delay |827			dp83869->tx_int_delay << DP83869_RGMII_CLK_DELAY_SHIFT);828		if (ret)829			return ret;830 831		val = phy_read_mmd(phydev, DP83869_DEVADDR, DP83869_RGMIICTL);832		val |= (DP83869_RGMII_TX_CLK_DELAY_EN |833			DP83869_RGMII_RX_CLK_DELAY_EN);834 835		if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)836			val &= ~(DP83869_RGMII_TX_CLK_DELAY_EN |837				 DP83869_RGMII_RX_CLK_DELAY_EN);838 839		if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)840			val &= ~DP83869_RGMII_TX_CLK_DELAY_EN;841 842		if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)843			val &= ~DP83869_RGMII_RX_CLK_DELAY_EN;844 845		ret = phy_write_mmd(phydev, DP83869_DEVADDR, DP83869_RGMIICTL,846				    val);847	}848 849	return ret;850}851 852static int dp83869_probe(struct phy_device *phydev)853{854	struct dp83869_private *dp83869;855	int ret;856 857	dp83869 = devm_kzalloc(&phydev->mdio.dev, sizeof(*dp83869),858			       GFP_KERNEL);859	if (!dp83869)860		return -ENOMEM;861 862	phydev->priv = dp83869;863 864	ret = dp83869_of_init(phydev);865	if (ret)866		return ret;867 868	if (dp83869->mode == DP83869_RGMII_100_BASE ||869	    dp83869->mode == DP83869_RGMII_1000_BASE)870		phydev->port = PORT_FIBRE;871 872	return dp83869_config_init(phydev);873}874 875static int dp83869_phy_reset(struct phy_device *phydev)876{877	int ret;878 879	ret = phy_write(phydev, DP83869_CTRL, DP83869_SW_RESET);880	if (ret < 0)881		return ret;882 883	usleep_range(10, 20);884 885	/* Global sw reset sets all registers to default.886	 * Need to set the registers in the PHY to the right config.887	 */888	return dp83869_config_init(phydev);889}890 891 892#define DP83869_PHY_DRIVER(_id, _name)				\893{								\894	PHY_ID_MATCH_MODEL(_id),				\895	.name		= (_name),				\896	.probe          = dp83869_probe,			\897	.config_init	= dp83869_config_init,			\898	.soft_reset	= dp83869_phy_reset,			\899	.config_intr	= dp83869_config_intr,			\900	.handle_interrupt = dp83869_handle_interrupt,		\901	.read_status	= dp83869_read_status,			\902	.get_tunable	= dp83869_get_tunable,			\903	.set_tunable	= dp83869_set_tunable,			\904	.get_wol	= dp83869_get_wol,			\905	.set_wol	= dp83869_set_wol,			\906	.suspend	= genphy_suspend,			\907	.resume		= genphy_resume,			\908}909 910static struct phy_driver dp83869_driver[] = {911	DP83869_PHY_DRIVER(DP83869_PHY_ID, "TI DP83869"),912	DP83869_PHY_DRIVER(DP83561_PHY_ID, "TI DP83561-SP"),913 914};915module_phy_driver(dp83869_driver);916 917static struct mdio_device_id __maybe_unused dp83869_tbl[] = {918	{ PHY_ID_MATCH_MODEL(DP83869_PHY_ID) },919	{ PHY_ID_MATCH_MODEL(DP83561_PHY_ID) },920	{ }921};922MODULE_DEVICE_TABLE(mdio, dp83869_tbl);923 924MODULE_DESCRIPTION("Texas Instruments DP83869 PHY driver");925MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com");926MODULE_LICENSE("GPL v2");927