Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * drivers/net/phy/at803x.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Driver for Qualcomm Atheros AR803x PHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * Author: Matus Ujhelyi <ujhelyi.m@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #include <linux/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/ethtool_netlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/of_gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/bitfield.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <linux/regulator/of_regulator.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <linux/regulator/driver.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include <dt-bindings/net/qca-ar803x.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #define AT803X_SPECIFIC_FUNCTION_CONTROL	0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #define AT803X_SFC_ASSERT_CRS			BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #define AT803X_SFC_FORCE_LINK			BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #define AT803X_SFC_MDI_CROSSOVER_MODE_M		GENMASK(6, 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #define AT803X_SFC_AUTOMATIC_CROSSOVER		0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #define AT803X_SFC_MANUAL_MDIX			0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #define AT803X_SFC_MANUAL_MDI			0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #define AT803X_SFC_SQE_TEST			BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #define AT803X_SFC_POLARITY_REVERSAL		BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #define AT803X_SFC_DISABLE_JABBER		BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #define AT803X_SPECIFIC_STATUS			0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #define AT803X_SS_SPEED_MASK			(3 << 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #define AT803X_SS_SPEED_1000			(2 << 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #define AT803X_SS_SPEED_100			(1 << 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #define AT803X_SS_SPEED_10			(0 << 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #define AT803X_SS_DUPLEX			BIT(13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #define AT803X_SS_SPEED_DUPLEX_RESOLVED		BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #define AT803X_SS_MDIX				BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #define AT803X_INTR_ENABLE			0x12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #define AT803X_INTR_ENABLE_AUTONEG_ERR		BIT(15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #define AT803X_INTR_ENABLE_SPEED_CHANGED	BIT(14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #define AT803X_INTR_ENABLE_DUPLEX_CHANGED	BIT(13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #define AT803X_INTR_ENABLE_PAGE_RECEIVED	BIT(12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #define AT803X_INTR_ENABLE_LINK_FAIL		BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #define AT803X_INTR_ENABLE_LINK_SUCCESS		BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #define AT803X_INTR_ENABLE_WIRESPEED_DOWNGRADE	BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #define AT803X_INTR_ENABLE_POLARITY_CHANGED	BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #define AT803X_INTR_ENABLE_WOL			BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #define AT803X_INTR_STATUS			0x13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #define AT803X_SMART_SPEED			0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #define AT803X_SMART_SPEED_ENABLE		BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #define AT803X_SMART_SPEED_RETRY_LIMIT_MASK	GENMASK(4, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #define AT803X_SMART_SPEED_BYPASS_TIMER		BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #define AT803X_CDT				0x16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #define AT803X_CDT_MDI_PAIR_MASK		GENMASK(9, 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) #define AT803X_CDT_ENABLE_TEST			BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #define AT803X_CDT_STATUS			0x1c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) #define AT803X_CDT_STATUS_STAT_NORMAL		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) #define AT803X_CDT_STATUS_STAT_SHORT		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #define AT803X_CDT_STATUS_STAT_OPEN		2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) #define AT803X_CDT_STATUS_STAT_FAIL		3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #define AT803X_CDT_STATUS_STAT_MASK		GENMASK(9, 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) #define AT803X_CDT_STATUS_DELTA_TIME_MASK	GENMASK(7, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) #define AT803X_LED_CONTROL			0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) #define AT803X_DEVICE_ADDR			0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) #define AT803X_LOC_MAC_ADDR_0_15_OFFSET		0x804C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) #define AT803X_LOC_MAC_ADDR_16_31_OFFSET	0x804B
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) #define AT803X_LOC_MAC_ADDR_32_47_OFFSET	0x804A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) #define AT803X_REG_CHIP_CONFIG			0x1f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) #define AT803X_BT_BX_REG_SEL			0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) #define AT803X_DEBUG_ADDR			0x1D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) #define AT803X_DEBUG_DATA			0x1E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) #define AT803X_MODE_CFG_MASK			0x0F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) #define AT803X_MODE_CFG_SGMII			0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) #define AT803X_PSSR			0x11	/*PHY-Specific Status Register*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) #define AT803X_PSSR_MR_AN_COMPLETE	0x0200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) #define AT803X_DEBUG_REG_0			0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) #define AT803X_DEBUG_RX_CLK_DLY_EN		BIT(15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) #define AT803X_DEBUG_REG_5			0x05
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) #define AT803X_DEBUG_TX_CLK_DLY_EN		BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) #define AT803X_DEBUG_REG_1F			0x1F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) #define AT803X_DEBUG_PLL_ON			BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) #define AT803X_DEBUG_RGMII_1V8			BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) /* AT803x supports either the XTAL input pad, an internal PLL or the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100)  * DSP as clock reference for the clock output pad. The XTAL reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101)  * is only used for 25 MHz output, all other frequencies need the PLL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102)  * The DSP as a clock reference is used in synchronous ethernet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103)  * applications.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105)  * By default the PLL is only enabled if there is a link. Otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106)  * the PHY will go into low power state and disabled the PLL. You can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107)  * set the PLL_ON bit (see debug register 0x1f) to keep the PLL always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108)  * enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) #define AT803X_MMD7_CLK25M			0x8016
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) #define AT803X_CLK_OUT_MASK			GENMASK(4, 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) #define AT803X_CLK_OUT_25MHZ_XTAL		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) #define AT803X_CLK_OUT_25MHZ_DSP		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) #define AT803X_CLK_OUT_50MHZ_PLL		2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) #define AT803X_CLK_OUT_50MHZ_DSP		3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) #define AT803X_CLK_OUT_62_5MHZ_PLL		4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) #define AT803X_CLK_OUT_62_5MHZ_DSP		5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) #define AT803X_CLK_OUT_125MHZ_PLL		6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) #define AT803X_CLK_OUT_125MHZ_DSP		7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) /* The AR8035 has another mask which is compatible with the AR8031/AR8033 mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122)  * but doesn't support choosing between XTAL/PLL and DSP.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) #define AT8035_CLK_OUT_MASK			GENMASK(4, 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) #define AT803X_CLK_OUT_STRENGTH_MASK		GENMASK(8, 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) #define AT803X_CLK_OUT_STRENGTH_FULL		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) #define AT803X_CLK_OUT_STRENGTH_HALF		1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) #define AT803X_CLK_OUT_STRENGTH_QUARTER		2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) #define AT803X_DEFAULT_DOWNSHIFT 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) #define AT803X_MIN_DOWNSHIFT 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) #define AT803X_MAX_DOWNSHIFT 9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) #define ATH9331_PHY_ID 0x004dd041
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) #define ATH8030_PHY_ID 0x004dd076
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) #define ATH8031_PHY_ID 0x004dd074
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) #define ATH8032_PHY_ID 0x004dd023
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) #define ATH8035_PHY_ID 0x004dd072
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) #define AT8030_PHY_ID_MASK			0xffffffef
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) MODULE_DESCRIPTION("Qualcomm Atheros AR803x PHY driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) MODULE_AUTHOR("Matus Ujhelyi");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) struct at803x_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	int flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) #define AT803X_KEEP_PLL_ENABLED	BIT(0)	/* don't turn off internal PLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	u16 clk_25m_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	u16 clk_25m_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	struct regulator_dev *vddio_rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	struct regulator_dev *vddh_rdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	struct regulator *vddio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) struct at803x_context {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	u16 bmcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	u16 advertise;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	u16 control1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	u16 int_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	u16 smart_speed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	u16 led_control;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) static int at803x_debug_reg_read(struct phy_device *phydev, u16 reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	return phy_read(phydev, AT803X_DEBUG_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) static int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 				 u16 clear, u16 set)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 	u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	ret = at803x_debug_reg_read(phydev, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	val = ret & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	val &= ~clear;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	val |= set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 	return phy_write(phydev, AT803X_DEBUG_DATA, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) static int at803x_enable_rx_delay(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 				     AT803X_DEBUG_RX_CLK_DLY_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) static int at803x_enable_tx_delay(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 				     AT803X_DEBUG_TX_CLK_DLY_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) static int at803x_disable_rx_delay(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 				     AT803X_DEBUG_RX_CLK_DLY_EN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) static int at803x_disable_tx_delay(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 				     AT803X_DEBUG_TX_CLK_DLY_EN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) /* save relevant PHY registers to private copy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) static void at803x_context_save(struct phy_device *phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 				struct at803x_context *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	context->bmcr = phy_read(phydev, MII_BMCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	context->advertise = phy_read(phydev, MII_ADVERTISE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	context->control1000 = phy_read(phydev, MII_CTRL1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	context->int_enable = phy_read(phydev, AT803X_INTR_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 	context->smart_speed = phy_read(phydev, AT803X_SMART_SPEED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 	context->led_control = phy_read(phydev, AT803X_LED_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) /* restore relevant PHY registers from private copy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) static void at803x_context_restore(struct phy_device *phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 				   const struct at803x_context *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 	phy_write(phydev, MII_BMCR, context->bmcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 	phy_write(phydev, MII_ADVERTISE, context->advertise);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	phy_write(phydev, MII_CTRL1000, context->control1000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	phy_write(phydev, AT803X_INTR_ENABLE, context->int_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	phy_write(phydev, AT803X_SMART_SPEED, context->smart_speed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 	phy_write(phydev, AT803X_LED_CONTROL, context->led_control);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) static int at803x_set_wol(struct phy_device *phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 			  struct ethtool_wolinfo *wol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	struct net_device *ndev = phydev->attached_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	const u8 *mac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	unsigned int i, offsets[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 		AT803X_LOC_MAC_ADDR_32_47_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 		AT803X_LOC_MAC_ADDR_16_31_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 		AT803X_LOC_MAC_ADDR_0_15_OFFSET,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	if (!ndev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	if (wol->wolopts & WAKE_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 		mac = (const u8 *) ndev->dev_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 		if (!is_valid_ether_addr(mac))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 		for (i = 0; i < 3; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 			phy_write_mmd(phydev, AT803X_DEVICE_ADDR, offsets[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 				      mac[(i * 2) + 1] | (mac[(i * 2)] << 8));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 		value = phy_read(phydev, AT803X_INTR_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 		value |= AT803X_INTR_ENABLE_WOL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 		ret = phy_write(phydev, AT803X_INTR_ENABLE, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 		value = phy_read(phydev, AT803X_INTR_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 		value = phy_read(phydev, AT803X_INTR_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		value &= (~AT803X_INTR_ENABLE_WOL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 		ret = phy_write(phydev, AT803X_INTR_ENABLE, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 		value = phy_read(phydev, AT803X_INTR_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) static void at803x_get_wol(struct phy_device *phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 			   struct ethtool_wolinfo *wol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	u32 value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	wol->supported = WAKE_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 	wol->wolopts = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 	value = phy_read(phydev, AT803X_INTR_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	if (value & AT803X_INTR_ENABLE_WOL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 		wol->wolopts |= WAKE_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) static int at803x_suspend(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	int wol_enabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	value = phy_read(phydev, AT803X_INTR_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	wol_enabled = value & AT803X_INTR_ENABLE_WOL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	if (wol_enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 		value = BMCR_ISOLATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 		value = BMCR_PDOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	phy_modify(phydev, MII_BMCR, 0, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) static int at803x_resume(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 	return phy_modify(phydev, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) static int at803x_rgmii_reg_set_voltage_sel(struct regulator_dev *rdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 					    unsigned int selector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	struct phy_device *phydev = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	if (selector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 		return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 					     0, AT803X_DEBUG_RGMII_1V8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 		return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 					     AT803X_DEBUG_RGMII_1V8, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) static int at803x_rgmii_reg_get_voltage_sel(struct regulator_dev *rdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	struct phy_device *phydev = rdev_get_drvdata(rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	val = at803x_debug_reg_read(phydev, AT803X_DEBUG_REG_1F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 		return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	return (val & AT803X_DEBUG_RGMII_1V8) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) static const struct regulator_ops vddio_regulator_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	.list_voltage = regulator_list_voltage_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	.set_voltage_sel = at803x_rgmii_reg_set_voltage_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 	.get_voltage_sel = at803x_rgmii_reg_get_voltage_sel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) static const unsigned int vddio_voltage_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	1500000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	1800000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) static const struct regulator_desc vddio_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 	.name = "vddio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	.of_match = of_match_ptr("vddio-regulator"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 	.n_voltages = ARRAY_SIZE(vddio_voltage_table),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	.volt_table = vddio_voltage_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	.ops = &vddio_regulator_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	.type = REGULATOR_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	.owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) static const struct regulator_ops vddh_regulator_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) static const struct regulator_desc vddh_desc = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	.name = "vddh",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 	.of_match = of_match_ptr("vddh-regulator"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	.n_voltages = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 	.fixed_uV = 2500000,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	.ops = &vddh_regulator_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	.type = REGULATOR_VOLTAGE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	.owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) static int at8031_register_regulators(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	struct at803x_priv *priv = phydev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	struct device *dev = &phydev->mdio.dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	struct regulator_config config = { };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	config.dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	config.driver_data = phydev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	priv->vddio_rdev = devm_regulator_register(dev, &vddio_desc, &config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 	if (IS_ERR(priv->vddio_rdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 		phydev_err(phydev, "failed to register VDDIO regulator\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 		return PTR_ERR(priv->vddio_rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	priv->vddh_rdev = devm_regulator_register(dev, &vddh_desc, &config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	if (IS_ERR(priv->vddh_rdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 		phydev_err(phydev, "failed to register VDDH regulator\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 		return PTR_ERR(priv->vddh_rdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) static bool at803x_match_phy_id(struct phy_device *phydev, u32 phy_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	return (phydev->phy_id & phydev->drv->phy_id_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 		== (phy_id & phydev->drv->phy_id_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) static int at803x_parse_dt(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	struct device_node *node = phydev->mdio.dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	struct at803x_priv *priv = phydev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	u32 freq, strength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	unsigned int sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	if (!IS_ENABLED(CONFIG_OF_MDIO))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	ret = of_property_read_u32(node, "qca,clk-out-frequency", &freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 		switch (freq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 		case 25000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 			sel = AT803X_CLK_OUT_25MHZ_XTAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 		case 50000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 			sel = AT803X_CLK_OUT_50MHZ_PLL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 		case 62500000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 			sel = AT803X_CLK_OUT_62_5MHZ_PLL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 		case 125000000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 			sel = AT803X_CLK_OUT_125MHZ_PLL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 			phydev_err(phydev, "invalid qca,clk-out-frequency\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 		priv->clk_25m_reg |= FIELD_PREP(AT803X_CLK_OUT_MASK, sel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 		priv->clk_25m_mask |= AT803X_CLK_OUT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 		/* Fixup for the AR8030/AR8035. This chip has another mask and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 		 * doesn't support the DSP reference. Eg. the lowest bit of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 		 * mask. The upper two bits select the same frequencies. Mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 		 * the lowest bit here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 		 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 		 * Warning:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 		 *   There was no datasheet for the AR8030 available so this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 		 *   just a guess. But the AR8035 is listed as pin compatible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 		 *   to the AR8030 so there might be a good chance it works on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 		 *   the AR8030 too.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 		if (at803x_match_phy_id(phydev, ATH8030_PHY_ID) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 		    at803x_match_phy_id(phydev, ATH8035_PHY_ID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 			priv->clk_25m_reg &= AT8035_CLK_OUT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 			priv->clk_25m_mask &= AT8035_CLK_OUT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	ret = of_property_read_u32(node, "qca,clk-out-strength", &strength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 		priv->clk_25m_mask |= AT803X_CLK_OUT_STRENGTH_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 		switch (strength) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 		case AR803X_STRENGTH_FULL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 			priv->clk_25m_reg |= AT803X_CLK_OUT_STRENGTH_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 		case AR803X_STRENGTH_HALF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 			priv->clk_25m_reg |= AT803X_CLK_OUT_STRENGTH_HALF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 		case AR803X_STRENGTH_QUARTER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 			priv->clk_25m_reg |= AT803X_CLK_OUT_STRENGTH_QUARTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 			phydev_err(phydev, "invalid qca,clk-out-strength\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	/* Only supported on AR8031/AR8033, the AR8030/AR8035 use strapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	 * options.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	if (at803x_match_phy_id(phydev, ATH8031_PHY_ID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 		if (of_property_read_bool(node, "qca,keep-pll-enabled"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 			priv->flags |= AT803X_KEEP_PLL_ENABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 		ret = at8031_register_regulators(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 		priv->vddio = devm_regulator_get_optional(&phydev->mdio.dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 							  "vddio");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 		if (IS_ERR(priv->vddio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 			phydev_err(phydev, "failed to get VDDIO regulator\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 			return PTR_ERR(priv->vddio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 		ret = regulator_enable(priv->vddio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) static int at803x_probe(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	struct device *dev = &phydev->mdio.dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	struct at803x_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 	if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	phydev->priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 	return at803x_parse_dt(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) static void at803x_remove(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	struct at803x_priv *priv = phydev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	if (priv->vddio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		regulator_disable(priv->vddio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) static int at803x_clk_out_config(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 	struct at803x_priv *priv = phydev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 	int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	if (!priv->clk_25m_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 	val = phy_read_mmd(phydev, MDIO_MMD_AN, AT803X_MMD7_CLK25M);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 		return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	val &= ~priv->clk_25m_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	val |= priv->clk_25m_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	return phy_write_mmd(phydev, MDIO_MMD_AN, AT803X_MMD7_CLK25M, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) static int at8031_pll_config(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	struct at803x_priv *priv = phydev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	/* The default after hardware reset is PLL OFF. After a soft reset, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	 * values are retained.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	if (priv->flags & AT803X_KEEP_PLL_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 		return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 					     0, AT803X_DEBUG_PLL_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 		return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 					     AT803X_DEBUG_PLL_ON, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) static int at803x_config_init(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	/* The RX and TX delay default is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	 *   after HW reset: RX delay enabled and TX delay disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	 *   after SW reset: RX delay enabled, while TX delay retains the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	 *   value before reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	    phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 		ret = at803x_enable_rx_delay(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 		ret = at803x_disable_rx_delay(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 	    phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 		ret = at803x_enable_tx_delay(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 		ret = at803x_disable_tx_delay(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	ret = at803x_clk_out_config(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 	if (at803x_match_phy_id(phydev, ATH8031_PHY_ID)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 		ret = at8031_pll_config(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) static int at803x_ack_interrupt(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	err = phy_read(phydev, AT803X_INTR_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	return (err < 0) ? err : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) static int at803x_config_intr(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	value = phy_read(phydev, AT803X_INTR_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 		value |= AT803X_INTR_ENABLE_AUTONEG_ERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 		value |= AT803X_INTR_ENABLE_SPEED_CHANGED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 		value |= AT803X_INTR_ENABLE_DUPLEX_CHANGED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 		value |= AT803X_INTR_ENABLE_LINK_FAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 		value |= AT803X_INTR_ENABLE_LINK_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 		err = phy_write(phydev, AT803X_INTR_ENABLE, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 		err = phy_write(phydev, AT803X_INTR_ENABLE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) static void at803x_link_change_notify(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	 * Conduct a hardware reset for AT8030 every time a link loss is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	 * signalled. This is necessary to circumvent a hardware bug that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	 * occurs when the cable is unplugged while TX packets are pending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	 * in the FIFO. In such cases, the FIFO enters an error mode it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	 * cannot recover from by software.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	if (phydev->state == PHY_NOLINK && phydev->mdio.reset_gpio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 		struct at803x_context context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 		at803x_context_save(phydev, &context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 		phy_device_reset(phydev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 		msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 		phy_device_reset(phydev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 		msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 		at803x_context_restore(phydev, &context);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 		phydev_dbg(phydev, "%s(): phy was reset\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) static int at803x_aneg_done(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	int ccr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 	int aneg_done = genphy_aneg_done(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	if (aneg_done != BMSR_ANEGCOMPLETE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 		return aneg_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 	 * in SGMII mode, if copper side autoneg is successful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 	 * also check SGMII side autoneg result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 	ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	if ((ccr & AT803X_MODE_CFG_MASK) != AT803X_MODE_CFG_SGMII)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 		return aneg_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	/* switch to SGMII/fiber page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr & ~AT803X_BT_BX_REG_SEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	/* check if the SGMII link is OK. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 	if (!(phy_read(phydev, AT803X_PSSR) & AT803X_PSSR_MR_AN_COMPLETE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 		phydev_warn(phydev, "803x_aneg_done: SGMII link is not ok\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 		aneg_done = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	/* switch back to copper page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	phy_write(phydev, AT803X_REG_CHIP_CONFIG, ccr | AT803X_BT_BX_REG_SEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	return aneg_done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) static int at803x_read_status(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	int ss, err, old_link = phydev->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	/* Update the link, but return if there was an error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	err = genphy_update_link(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 	/* why bother the PHY if nothing can have changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 	phydev->speed = SPEED_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	phydev->duplex = DUPLEX_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	phydev->pause = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	phydev->asym_pause = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	err = genphy_read_lpa(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	/* Read the AT8035 PHY-Specific Status register, which indicates the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	 * speed and duplex that the PHY is actually using, irrespective of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	 * whether we are in autoneg mode or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	ss = phy_read(phydev, AT803X_SPECIFIC_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	if (ss < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 		return ss;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	if (ss & AT803X_SS_SPEED_DUPLEX_RESOLVED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 		int sfc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 		sfc = phy_read(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 		if (sfc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 			return sfc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 		switch (ss & AT803X_SS_SPEED_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 		case AT803X_SS_SPEED_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 			phydev->speed = SPEED_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 		case AT803X_SS_SPEED_100:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 			phydev->speed = SPEED_100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 		case AT803X_SS_SPEED_1000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 			phydev->speed = SPEED_1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		if (ss & AT803X_SS_DUPLEX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 			phydev->duplex = DUPLEX_FULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 			phydev->duplex = DUPLEX_HALF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 		if (ss & AT803X_SS_MDIX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 			phydev->mdix = ETH_TP_MDI_X;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 			phydev->mdix = ETH_TP_MDI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 		switch (FIELD_GET(AT803X_SFC_MDI_CROSSOVER_MODE_M, sfc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 		case AT803X_SFC_MANUAL_MDI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 			phydev->mdix_ctrl = ETH_TP_MDI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 		case AT803X_SFC_MANUAL_MDIX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 			phydev->mdix_ctrl = ETH_TP_MDI_X;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		case AT803X_SFC_AUTOMATIC_CROSSOVER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 			phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 		phy_resolve_aneg_pause(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) static int at803x_config_mdix(struct phy_device *phydev, u8 ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	switch (ctrl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	case ETH_TP_MDI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		val = AT803X_SFC_MANUAL_MDI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	case ETH_TP_MDI_X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 		val = AT803X_SFC_MANUAL_MDIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 	case ETH_TP_MDI_AUTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 		val = AT803X_SFC_AUTOMATIC_CROSSOVER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	return phy_modify_changed(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 			  AT803X_SFC_MDI_CROSSOVER_MODE_M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 			  FIELD_PREP(AT803X_SFC_MDI_CROSSOVER_MODE_M, val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) static int at803x_config_aneg(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	ret = at803x_config_mdix(phydev, phydev->mdix_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	/* Changes of the midx bits are disruptive to the normal operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	 * therefore any changes to these registers must be followed by a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	 * software reset to take effect.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	if (ret == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 		ret = genphy_soft_reset(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	return genphy_config_aneg(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) static int at803x_get_downshift(struct phy_device *phydev, u8 *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	val = phy_read(phydev, AT803X_SMART_SPEED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 	if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 		return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	if (val & AT803X_SMART_SPEED_ENABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 		*d = FIELD_GET(AT803X_SMART_SPEED_RETRY_LIMIT_MASK, val) + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 		*d = DOWNSHIFT_DEV_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) static int at803x_set_downshift(struct phy_device *phydev, u8 cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	u16 mask, set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	switch (cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	case DOWNSHIFT_DEV_DEFAULT_COUNT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 		cnt = AT803X_DEFAULT_DOWNSHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	case AT803X_MIN_DOWNSHIFT ... AT803X_MAX_DOWNSHIFT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 		set = AT803X_SMART_SPEED_ENABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 		      AT803X_SMART_SPEED_BYPASS_TIMER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 		      FIELD_PREP(AT803X_SMART_SPEED_RETRY_LIMIT_MASK, cnt - 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 		mask = AT803X_SMART_SPEED_RETRY_LIMIT_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	case DOWNSHIFT_DEV_DISABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 		set = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 		mask = AT803X_SMART_SPEED_ENABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 		       AT803X_SMART_SPEED_BYPASS_TIMER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	ret = phy_modify_changed(phydev, AT803X_SMART_SPEED, mask, set);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	/* After changing the smart speed settings, we need to perform a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	 * software reset, use phy_init_hw() to make sure we set the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	 * reapply any values which might got lost during software reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	if (ret == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 		ret = phy_init_hw(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) static int at803x_get_tunable(struct phy_device *phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 			      struct ethtool_tunable *tuna, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	switch (tuna->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	case ETHTOOL_PHY_DOWNSHIFT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 		return at803x_get_downshift(phydev, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) static int at803x_set_tunable(struct phy_device *phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 			      struct ethtool_tunable *tuna, const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	switch (tuna->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	case ETHTOOL_PHY_DOWNSHIFT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 		return at803x_set_downshift(phydev, *(const u8 *)data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) static int at803x_cable_test_result_trans(u16 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	switch (FIELD_GET(AT803X_CDT_STATUS_STAT_MASK, status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 	case AT803X_CDT_STATUS_STAT_NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 		return ETHTOOL_A_CABLE_RESULT_CODE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	case AT803X_CDT_STATUS_STAT_SHORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 		return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	case AT803X_CDT_STATUS_STAT_OPEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 		return ETHTOOL_A_CABLE_RESULT_CODE_OPEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	case AT803X_CDT_STATUS_STAT_FAIL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 		return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) static bool at803x_cdt_test_failed(u16 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	return FIELD_GET(AT803X_CDT_STATUS_STAT_MASK, status) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 		AT803X_CDT_STATUS_STAT_FAIL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) static bool at803x_cdt_fault_length_valid(u16 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 	switch (FIELD_GET(AT803X_CDT_STATUS_STAT_MASK, status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	case AT803X_CDT_STATUS_STAT_OPEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	case AT803X_CDT_STATUS_STAT_SHORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) static int at803x_cdt_fault_length(u16 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 	int dt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 	/* According to the datasheet the distance to the fault is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	 * DELTA_TIME * 0.824 meters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	 * The author suspect the correct formula is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	 *   fault_distance = DELTA_TIME * (c * VF) / 125MHz / 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	 * where c is the speed of light, VF is the velocity factor of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	 * the twisted pair cable, 125MHz the counter frequency and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	 * we need to divide by 2 because the hardware will measure the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	 * round trip time to the fault and back to the PHY.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	 * With a VF of 0.69 we get the factor 0.824 mentioned in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	 * datasheet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	dt = FIELD_GET(AT803X_CDT_STATUS_DELTA_TIME_MASK, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	return (dt * 824) / 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) static int at803x_cdt_start(struct phy_device *phydev, int pair)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	u16 cdt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	cdt = FIELD_PREP(AT803X_CDT_MDI_PAIR_MASK, pair) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	      AT803X_CDT_ENABLE_TEST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	return phy_write(phydev, AT803X_CDT, cdt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) static int at803x_cdt_wait_for_completion(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	int val, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	/* One test run takes about 25ms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	ret = phy_read_poll_timeout(phydev, AT803X_CDT, val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 				    !(val & AT803X_CDT_ENABLE_TEST),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 				    30000, 100000, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	return ret < 0 ? ret : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) static int at803x_cable_test_one_pair(struct phy_device *phydev, int pair)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	static const int ethtool_pair[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 		ETHTOOL_A_CABLE_PAIR_A,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 		ETHTOOL_A_CABLE_PAIR_B,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 		ETHTOOL_A_CABLE_PAIR_C,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 		ETHTOOL_A_CABLE_PAIR_D,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	int ret, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	ret = at803x_cdt_start(phydev, pair);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	ret = at803x_cdt_wait_for_completion(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	val = phy_read(phydev, AT803X_CDT_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 		return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	if (at803x_cdt_test_failed(val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 	ethnl_cable_test_result(phydev, ethtool_pair[pair],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 				at803x_cable_test_result_trans(val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	if (at803x_cdt_fault_length_valid(val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 		ethnl_cable_test_fault_length(phydev, ethtool_pair[pair],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 					      at803x_cdt_fault_length(val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) static int at803x_cable_test_get_status(struct phy_device *phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 					bool *finished)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	unsigned long pair_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	int retries = 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	int pair, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	if (phydev->phy_id == ATH9331_PHY_ID ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	    phydev->phy_id == ATH8032_PHY_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 		pair_mask = 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 		pair_mask = 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	*finished = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	/* According to the datasheet the CDT can be performed when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 	 * there is no link partner or when the link partner is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	 * auto-negotiating. Starting the test will restart the AN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	 * automatically. It seems that doing this repeatedly we will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	 * get a slot where our link partner won't disturb our
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	 * measurement.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	while (pair_mask && retries--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 		for_each_set_bit(pair, &pair_mask, 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 			ret = at803x_cable_test_one_pair(phydev, pair);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 			if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 				return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 			if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 				clear_bit(pair, &pair_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 		if (pair_mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 			msleep(250);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	*finished = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) static int at803x_cable_test_start(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	/* Enable auto-negotiation, but advertise no capabilities, no link
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	 * will be established. A restart of the auto-negotiation is not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	 * required, because the cable test will automatically break the link.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	phy_write(phydev, MII_BMCR, BMCR_ANENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	phy_write(phydev, MII_ADVERTISE, ADVERTISE_CSMA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	if (phydev->phy_id != ATH9331_PHY_ID &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	    phydev->phy_id != ATH8032_PHY_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 		phy_write(phydev, MII_CTRL1000, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 	/* we do all the (time consuming) work later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) static struct phy_driver at803x_driver[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	/* Qualcomm Atheros AR8035 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	PHY_ID_MATCH_EXACT(ATH8035_PHY_ID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	.name			= "Qualcomm Atheros AR8035",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	.flags			= PHY_POLL_CABLE_TEST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	.probe			= at803x_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	.remove			= at803x_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	.config_aneg		= at803x_config_aneg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	.config_init		= at803x_config_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	.soft_reset		= genphy_soft_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	.set_wol		= at803x_set_wol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 	.get_wol		= at803x_get_wol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 	.suspend		= at803x_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 	.resume			= at803x_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	/* PHY_GBIT_FEATURES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 	.read_status		= at803x_read_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 	.ack_interrupt		= at803x_ack_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 	.config_intr		= at803x_config_intr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 	.get_tunable		= at803x_get_tunable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	.set_tunable		= at803x_set_tunable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	.cable_test_start	= at803x_cable_test_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	.cable_test_get_status	= at803x_cable_test_get_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	/* Qualcomm Atheros AR8030 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	.phy_id			= ATH8030_PHY_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 	.name			= "Qualcomm Atheros AR8030",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	.phy_id_mask		= AT8030_PHY_ID_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 	.probe			= at803x_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 	.remove			= at803x_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 	.config_init		= at803x_config_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 	.link_change_notify	= at803x_link_change_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	.set_wol		= at803x_set_wol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 	.get_wol		= at803x_get_wol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	.suspend		= at803x_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 	.resume			= at803x_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	/* PHY_BASIC_FEATURES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	.ack_interrupt		= at803x_ack_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 	.config_intr		= at803x_config_intr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) 	/* Qualcomm Atheros AR8031/AR8033 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	PHY_ID_MATCH_EXACT(ATH8031_PHY_ID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	.name			= "Qualcomm Atheros AR8031/AR8033",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	.flags			= PHY_POLL_CABLE_TEST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	.probe			= at803x_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	.remove			= at803x_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	.config_init		= at803x_config_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	.soft_reset		= genphy_soft_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	.set_wol		= at803x_set_wol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	.get_wol		= at803x_get_wol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	.suspend		= at803x_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	.resume			= at803x_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	/* PHY_GBIT_FEATURES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	.read_status		= at803x_read_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	.aneg_done		= at803x_aneg_done,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	.ack_interrupt		= &at803x_ack_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	.config_intr		= &at803x_config_intr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	.get_tunable		= at803x_get_tunable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	.set_tunable		= at803x_set_tunable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 	.cable_test_start	= at803x_cable_test_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	.cable_test_get_status	= at803x_cable_test_get_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	/* Qualcomm Atheros AR8032 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	PHY_ID_MATCH_EXACT(ATH8032_PHY_ID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	.name			= "Qualcomm Atheros AR8032",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	.probe			= at803x_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	.remove			= at803x_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	.flags			= PHY_POLL_CABLE_TEST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	.config_init		= at803x_config_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	.link_change_notify	= at803x_link_change_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	.set_wol		= at803x_set_wol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 	.get_wol		= at803x_get_wol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	.suspend		= at803x_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	.resume			= at803x_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	/* PHY_BASIC_FEATURES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	.ack_interrupt		= at803x_ack_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	.config_intr		= at803x_config_intr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	.cable_test_start	= at803x_cable_test_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 	.cable_test_get_status	= at803x_cable_test_get_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) }, {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	/* ATHEROS AR9331 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 	PHY_ID_MATCH_EXACT(ATH9331_PHY_ID),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	.name			= "Qualcomm Atheros AR9331 built-in PHY",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	.suspend		= at803x_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	.resume			= at803x_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	.flags			= PHY_POLL_CABLE_TEST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	/* PHY_BASIC_FEATURES */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	.ack_interrupt		= &at803x_ack_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	.config_intr		= &at803x_config_intr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	.cable_test_start	= at803x_cable_test_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 	.cable_test_get_status	= at803x_cable_test_get_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 	.read_status		= at803x_read_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	.soft_reset		= genphy_soft_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 	.config_aneg		= at803x_config_aneg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) } };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) module_phy_driver(at803x_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) static struct mdio_device_id __maybe_unused atheros_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	{ ATH8030_PHY_ID, AT8030_PHY_ID_MASK },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	{ PHY_ID_MATCH_EXACT(ATH8031_PHY_ID) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	{ PHY_ID_MATCH_EXACT(ATH8032_PHY_ID) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	{ PHY_ID_MATCH_EXACT(ATH8035_PHY_ID) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	{ PHY_ID_MATCH_EXACT(ATH9331_PHY_ID) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) MODULE_DEVICE_TABLE(mdio, atheros_tbl);