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)  *  Driver for Analog Devices Industrial Ethernet PHYs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Copyright 2019 Analog Devices Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/bitfield.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/mii.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/property.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #define PHY_ID_ADIN1200				0x0283bc20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #define PHY_ID_ADIN1300				0x0283bc30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define ADIN1300_MII_EXT_REG_PTR		0x0010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define ADIN1300_MII_EXT_REG_DATA		0x0011
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #define ADIN1300_PHY_CTRL1			0x0012
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define   ADIN1300_AUTO_MDI_EN			BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define   ADIN1300_MAN_MDIX_EN			BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define ADIN1300_RX_ERR_CNT			0x0014
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define ADIN1300_PHY_CTRL_STATUS2		0x0015
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define   ADIN1300_NRG_PD_EN			BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define   ADIN1300_NRG_PD_TX_EN			BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #define   ADIN1300_NRG_PD_STATUS		BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #define ADIN1300_PHY_CTRL2			0x0016
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #define   ADIN1300_DOWNSPEED_AN_100_EN		BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #define   ADIN1300_DOWNSPEED_AN_10_EN		BIT(10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define   ADIN1300_GROUP_MDIO_EN		BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define   ADIN1300_DOWNSPEEDS_EN	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	(ADIN1300_DOWNSPEED_AN_100_EN | ADIN1300_DOWNSPEED_AN_10_EN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) #define ADIN1300_PHY_CTRL3			0x0017
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #define   ADIN1300_LINKING_EN			BIT(13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #define   ADIN1300_DOWNSPEED_RETRIES_MSK	GENMASK(12, 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #define ADIN1300_INT_MASK_REG			0x0018
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #define   ADIN1300_INT_MDIO_SYNC_EN		BIT(9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #define   ADIN1300_INT_ANEG_STAT_CHNG_EN	BIT(8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #define   ADIN1300_INT_ANEG_PAGE_RX_EN		BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) #define   ADIN1300_INT_IDLE_ERR_CNT_EN		BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #define   ADIN1300_INT_MAC_FIFO_OU_EN		BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #define   ADIN1300_INT_RX_STAT_CHNG_EN		BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #define   ADIN1300_INT_LINK_STAT_CHNG_EN	BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #define   ADIN1300_INT_SPEED_CHNG_EN		BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #define   ADIN1300_INT_HW_IRQ_EN		BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) #define ADIN1300_INT_MASK_EN	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	(ADIN1300_INT_LINK_STAT_CHNG_EN | ADIN1300_INT_HW_IRQ_EN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) #define ADIN1300_INT_STATUS_REG			0x0019
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define ADIN1300_PHY_STATUS1			0x001a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) #define   ADIN1300_PAIR_01_SWAP			BIT(11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) /* EEE register addresses, accessible via Clause 22 access using
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  * ADIN1300_MII_EXT_REG_PTR & ADIN1300_MII_EXT_REG_DATA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  * The bit-fields are the same as specified by IEEE for EEE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) #define ADIN1300_EEE_CAP_REG			0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) #define ADIN1300_EEE_ADV_REG			0x8001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #define ADIN1300_EEE_LPABLE_REG			0x8002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) #define ADIN1300_CLOCK_STOP_REG			0x9400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) #define ADIN1300_LPI_WAKE_ERR_CNT_REG		0xa000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) #define ADIN1300_GE_SOFT_RESET_REG		0xff0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) #define   ADIN1300_GE_SOFT_RESET		BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) #define ADIN1300_GE_RGMII_CFG_REG		0xff23
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) #define   ADIN1300_GE_RGMII_RX_MSK		GENMASK(8, 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) #define   ADIN1300_GE_RGMII_RX_SEL(x)		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		FIELD_PREP(ADIN1300_GE_RGMII_RX_MSK, x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) #define   ADIN1300_GE_RGMII_GTX_MSK		GENMASK(5, 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) #define   ADIN1300_GE_RGMII_GTX_SEL(x)		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		FIELD_PREP(ADIN1300_GE_RGMII_GTX_MSK, x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) #define   ADIN1300_GE_RGMII_RXID_EN		BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) #define   ADIN1300_GE_RGMII_TXID_EN		BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) #define   ADIN1300_GE_RGMII_EN			BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) /* RGMII internal delay settings for rx and tx for ADIN1300 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) #define ADIN1300_RGMII_1_60_NS			0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) #define ADIN1300_RGMII_1_80_NS			0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) #define	ADIN1300_RGMII_2_00_NS			0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) #define	ADIN1300_RGMII_2_20_NS			0x0006
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) #define	ADIN1300_RGMII_2_40_NS			0x0007
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) #define ADIN1300_GE_RMII_CFG_REG		0xff24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) #define   ADIN1300_GE_RMII_FIFO_DEPTH_MSK	GENMASK(6, 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) #define   ADIN1300_GE_RMII_FIFO_DEPTH_SEL(x)	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		FIELD_PREP(ADIN1300_GE_RMII_FIFO_DEPTH_MSK, x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) #define   ADIN1300_GE_RMII_EN			BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) /* RMII fifo depth values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define ADIN1300_RMII_4_BITS			0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define ADIN1300_RMII_8_BITS			0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define ADIN1300_RMII_12_BITS			0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define ADIN1300_RMII_16_BITS			0x0003
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define ADIN1300_RMII_20_BITS			0x0004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define ADIN1300_RMII_24_BITS			0x0005
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)  * struct adin_cfg_reg_map - map a config value to aregister value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)  * @cfg:	value in device configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)  * @reg:	value in the register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct adin_cfg_reg_map {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	int cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static const struct adin_cfg_reg_map adin_rgmii_delays[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	{ 1600, ADIN1300_RGMII_1_60_NS },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	{ 1800, ADIN1300_RGMII_1_80_NS },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	{ 2000, ADIN1300_RGMII_2_00_NS },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	{ 2200, ADIN1300_RGMII_2_20_NS },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	{ 2400, ADIN1300_RGMII_2_40_NS },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) static const struct adin_cfg_reg_map adin_rmii_fifo_depths[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	{ 4,  ADIN1300_RMII_4_BITS },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	{ 8,  ADIN1300_RMII_8_BITS },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	{ 12, ADIN1300_RMII_12_BITS },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	{ 16, ADIN1300_RMII_16_BITS },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	{ 20, ADIN1300_RMII_20_BITS },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	{ 24, ADIN1300_RMII_24_BITS },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)  * struct adin_clause45_mmd_map - map to convert Clause 45 regs to Clause 22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)  * @devad:		device address used in Clause 45 access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)  * @cl45_regnum:	register address defined by Clause 45
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)  * @adin_regnum:	equivalent register address accessible via Clause 22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) struct adin_clause45_mmd_map {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	int devad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	u16 cl45_regnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	u16 adin_regnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static const struct adin_clause45_mmd_map adin_clause45_mmd_map[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	{ MDIO_MMD_PCS,	MDIO_PCS_EEE_ABLE,	ADIN1300_EEE_CAP_REG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	{ MDIO_MMD_AN,	MDIO_AN_EEE_LPABLE,	ADIN1300_EEE_LPABLE_REG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	{ MDIO_MMD_AN,	MDIO_AN_EEE_ADV,	ADIN1300_EEE_ADV_REG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	{ MDIO_MMD_PCS,	MDIO_CTRL1,		ADIN1300_CLOCK_STOP_REG },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	{ MDIO_MMD_PCS, MDIO_PCS_EEE_WK_ERR,	ADIN1300_LPI_WAKE_ERR_CNT_REG },
^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 adin_hw_stat {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	const char *string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	u16 reg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	u16 reg2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static const struct adin_hw_stat adin_hw_stats[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	{ "total_frames_checked_count",		0x940A, 0x940B }, /* hi + lo */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	{ "length_error_frames_count",		0x940C },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	{ "alignment_error_frames_count",	0x940D },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	{ "symbol_error_count",			0x940E },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	{ "oversized_frames_count",		0x940F },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	{ "undersized_frames_count",		0x9410 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	{ "odd_nibble_frames_count",		0x9411 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	{ "odd_preamble_packet_count",		0x9412 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	{ "dribble_bits_frames_count",		0x9413 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	{ "false_carrier_events_count",		0x9414 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) };
^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)  * struct adin_priv - ADIN PHY driver private data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)  * @stats:		statistic counters for the PHY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct adin_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	u64			stats[ARRAY_SIZE(adin_hw_stats)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static int adin_lookup_reg_value(const struct adin_cfg_reg_map *tbl, int cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	size_t i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	for (i = 0; tbl[i].cfg; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		if (tbl[i].cfg == cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 			return tbl[i].reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static u32 adin_get_reg_value(struct phy_device *phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 			      const char *prop_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 			      const struct adin_cfg_reg_map *tbl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 			      u32 dflt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	struct device *dev = &phydev->mdio.dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	if (device_property_read_u32(dev, prop_name, &val))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 		return dflt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	rc = adin_lookup_reg_value(tbl, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		phydev_warn(phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 			    "Unsupported value %u for %s using default (%u)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 			    val, prop_name, dflt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		return dflt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static int adin_config_rgmii_mode(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	if (!phy_interface_is_rgmii(phydev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 					  ADIN1300_GE_RGMII_CFG_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 					  ADIN1300_GE_RGMII_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	reg = phy_read_mmd(phydev, MDIO_MMD_VEND1, ADIN1300_GE_RGMII_CFG_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	if (reg < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		return reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	reg |= ADIN1300_GE_RGMII_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	    phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 		reg |= ADIN1300_GE_RGMII_RXID_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 		val = adin_get_reg_value(phydev, "adi,rx-internal-delay-ps",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 					 adin_rgmii_delays,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 					 ADIN1300_RGMII_2_00_NS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		reg &= ~ADIN1300_GE_RGMII_RX_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		reg |= ADIN1300_GE_RGMII_RX_SEL(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		reg &= ~ADIN1300_GE_RGMII_RXID_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	    phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		reg |= ADIN1300_GE_RGMII_TXID_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 		val = adin_get_reg_value(phydev, "adi,tx-internal-delay-ps",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 					 adin_rgmii_delays,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 					 ADIN1300_RGMII_2_00_NS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 		reg &= ~ADIN1300_GE_RGMII_GTX_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		reg |= ADIN1300_GE_RGMII_GTX_SEL(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		reg &= ~ADIN1300_GE_RGMII_TXID_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	return phy_write_mmd(phydev, MDIO_MMD_VEND1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 			     ADIN1300_GE_RGMII_CFG_REG, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static int adin_config_rmii_mode(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	if (phydev->interface != PHY_INTERFACE_MODE_RMII)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 					  ADIN1300_GE_RMII_CFG_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 					  ADIN1300_GE_RMII_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	reg = phy_read_mmd(phydev, MDIO_MMD_VEND1, ADIN1300_GE_RMII_CFG_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	if (reg < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		return reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	reg |= ADIN1300_GE_RMII_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	val = adin_get_reg_value(phydev, "adi,fifo-depth-bits",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 				 adin_rmii_fifo_depths,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 				 ADIN1300_RMII_8_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	reg &= ~ADIN1300_GE_RMII_FIFO_DEPTH_MSK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	reg |= ADIN1300_GE_RMII_FIFO_DEPTH_SEL(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	return phy_write_mmd(phydev, MDIO_MMD_VEND1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 			     ADIN1300_GE_RMII_CFG_REG, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static int adin_get_downshift(struct phy_device *phydev, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	int val, cnt, enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	val = phy_read(phydev, ADIN1300_PHY_CTRL2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	cnt = phy_read(phydev, ADIN1300_PHY_CTRL3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	if (cnt < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		return cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	enable = FIELD_GET(ADIN1300_DOWNSPEEDS_EN, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	cnt = FIELD_GET(ADIN1300_DOWNSPEED_RETRIES_MSK, cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	*data = (enable && cnt) ? cnt : DOWNSHIFT_DEV_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) static int adin_set_downshift(struct phy_device *phydev, u8 cnt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	if (cnt == DOWNSHIFT_DEV_DISABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		return phy_clear_bits(phydev, ADIN1300_PHY_CTRL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 				      ADIN1300_DOWNSPEEDS_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	if (cnt > 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		return -E2BIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	val = FIELD_PREP(ADIN1300_DOWNSPEED_RETRIES_MSK, cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	val |= ADIN1300_LINKING_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	rc = phy_modify(phydev, ADIN1300_PHY_CTRL3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 			ADIN1300_LINKING_EN | ADIN1300_DOWNSPEED_RETRIES_MSK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 			val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	return phy_set_bits(phydev, ADIN1300_PHY_CTRL2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 			    ADIN1300_DOWNSPEEDS_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) static int adin_get_edpd(struct phy_device *phydev, u16 *tx_interval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	val = phy_read(phydev, ADIN1300_PHY_CTRL_STATUS2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	if (val < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	if (ADIN1300_NRG_PD_EN & val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		if (val & ADIN1300_NRG_PD_TX_EN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 			/* default is 1 second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 			*tx_interval = ETHTOOL_PHY_EDPD_DFLT_TX_MSECS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 			*tx_interval = ETHTOOL_PHY_EDPD_NO_TX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		*tx_interval = ETHTOOL_PHY_EDPD_DISABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	return 0;
^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 int adin_set_edpd(struct phy_device *phydev, u16 tx_interval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	u16 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 	if (tx_interval == ETHTOOL_PHY_EDPD_DISABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		return phy_clear_bits(phydev, ADIN1300_PHY_CTRL_STATUS2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 				(ADIN1300_NRG_PD_EN | ADIN1300_NRG_PD_TX_EN));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	val = ADIN1300_NRG_PD_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	switch (tx_interval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	case 1000: /* 1 second */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	case ETHTOOL_PHY_EDPD_DFLT_TX_MSECS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		val |= ADIN1300_NRG_PD_TX_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	case ETHTOOL_PHY_EDPD_NO_TX:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	return phy_modify(phydev, ADIN1300_PHY_CTRL_STATUS2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 			  (ADIN1300_NRG_PD_EN | ADIN1300_NRG_PD_TX_EN),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 			  val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static int adin_get_tunable(struct phy_device *phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 			    struct ethtool_tunable *tuna, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	switch (tuna->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	case ETHTOOL_PHY_DOWNSHIFT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		return adin_get_downshift(phydev, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 	case ETHTOOL_PHY_EDPD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		return adin_get_edpd(phydev, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) static int adin_set_tunable(struct phy_device *phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 			    struct ethtool_tunable *tuna, const void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	switch (tuna->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	case ETHTOOL_PHY_DOWNSHIFT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		return adin_set_downshift(phydev, *(const u8 *)data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	case ETHTOOL_PHY_EDPD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		return adin_set_edpd(phydev, *(const u16 *)data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	}
^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 adin_config_init(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	rc = adin_config_rgmii_mode(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	rc = adin_config_rmii_mode(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	rc = adin_set_downshift(phydev, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	rc = adin_set_edpd(phydev, ETHTOOL_PHY_EDPD_DFLT_TX_MSECS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	phydev_dbg(phydev, "PHY is using mode '%s'\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		   phy_modes(phydev->interface));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) static int adin_phy_ack_intr(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 	/* Clear pending interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	int rc = phy_read(phydev, ADIN1300_INT_STATUS_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	return rc < 0 ? rc : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) static int adin_phy_config_intr(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		return phy_set_bits(phydev, ADIN1300_INT_MASK_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 				    ADIN1300_INT_MASK_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	return phy_clear_bits(phydev, ADIN1300_INT_MASK_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 			      ADIN1300_INT_MASK_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) static int adin_cl45_to_adin_reg(struct phy_device *phydev, int devad,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 				 u16 cl45_regnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	const struct adin_clause45_mmd_map *m;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	if (devad == MDIO_MMD_VEND1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		return cl45_regnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	for (i = 0; i < ARRAY_SIZE(adin_clause45_mmd_map); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 		m = &adin_clause45_mmd_map[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		if (m->devad == devad && m->cl45_regnum == cl45_regnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 			return m->adin_regnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	phydev_err(phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 		   "No translation available for devad: %d reg: %04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		   devad, cl45_regnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) static int adin_read_mmd(struct phy_device *phydev, int devad, u16 regnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	struct mii_bus *bus = phydev->mdio.bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	int phy_addr = phydev->mdio.addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	int adin_regnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	adin_regnum = adin_cl45_to_adin_reg(phydev, devad, regnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	if (adin_regnum < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 		return adin_regnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	err = __mdiobus_write(bus, phy_addr, ADIN1300_MII_EXT_REG_PTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 			      adin_regnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	return __mdiobus_read(bus, phy_addr, ADIN1300_MII_EXT_REG_DATA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) static int adin_write_mmd(struct phy_device *phydev, int devad, u16 regnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 			  u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	struct mii_bus *bus = phydev->mdio.bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	int phy_addr = phydev->mdio.addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	int adin_regnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	adin_regnum = adin_cl45_to_adin_reg(phydev, devad, regnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	if (adin_regnum < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 		return adin_regnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	err = __mdiobus_write(bus, phy_addr, ADIN1300_MII_EXT_REG_PTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 			      adin_regnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	return __mdiobus_write(bus, phy_addr, ADIN1300_MII_EXT_REG_DATA, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) static int adin_config_mdix(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	bool auto_en, mdix_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	mdix_en = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	auto_en = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	switch (phydev->mdix_ctrl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	case ETH_TP_MDI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	case ETH_TP_MDI_X:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		mdix_en = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 	case ETH_TP_MDI_AUTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 		auto_en = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 	reg = phy_read(phydev, ADIN1300_PHY_CTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 	if (reg < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		return reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 	if (mdix_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		reg |= ADIN1300_MAN_MDIX_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		reg &= ~ADIN1300_MAN_MDIX_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 	if (auto_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 		reg |= ADIN1300_AUTO_MDI_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 		reg &= ~ADIN1300_AUTO_MDI_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	return phy_write(phydev, ADIN1300_PHY_CTRL1, reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) static int adin_config_aneg(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 	ret = adin_config_mdix(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 	return genphy_config_aneg(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) static int adin_mdix_update(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	bool auto_en, mdix_en;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	bool swapped;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	reg = phy_read(phydev, ADIN1300_PHY_CTRL1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	if (reg < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 		return reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	auto_en = !!(reg & ADIN1300_AUTO_MDI_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	mdix_en = !!(reg & ADIN1300_MAN_MDIX_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	/* If MDI/MDIX is forced, just read it from the control reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 	if (!auto_en) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 		if (mdix_en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 			phydev->mdix = ETH_TP_MDI_X;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 			phydev->mdix = ETH_TP_MDI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	/**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	 * Otherwise, we need to deduce it from the PHY status2 reg.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	 * When Auto-MDI is enabled, the ADIN1300_MAN_MDIX_EN bit implies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	 * a preference for MDIX when it is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 	reg = phy_read(phydev, ADIN1300_PHY_STATUS1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	if (reg < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 		return reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 	swapped = !!(reg & ADIN1300_PAIR_01_SWAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 	if (mdix_en != swapped)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 		phydev->mdix = ETH_TP_MDI_X;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 		phydev->mdix = ETH_TP_MDI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) static int adin_read_status(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	ret = adin_mdix_update(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	return genphy_read_status(phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) static int adin_soft_reset(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	/* The reset bit is self-clearing, set it and wait */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	rc = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 			      ADIN1300_GE_SOFT_RESET_REG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 			      ADIN1300_GE_SOFT_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	msleep(20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	/* If we get a read error something may be wrong */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 	rc = phy_read_mmd(phydev, MDIO_MMD_VEND1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 			  ADIN1300_GE_SOFT_RESET_REG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	return rc < 0 ? rc : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) static int adin_get_sset_count(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 	return ARRAY_SIZE(adin_hw_stats);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) static void adin_get_strings(struct phy_device *phydev, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 	for (i = 0; i < ARRAY_SIZE(adin_hw_stats); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 		strlcpy(&data[i * ETH_GSTRING_LEN],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 			adin_hw_stats[i].string, ETH_GSTRING_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) static int adin_read_mmd_stat_regs(struct phy_device *phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) 				   const struct adin_hw_stat *stat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 				   u32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, stat->reg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	*val = (ret & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	if (stat->reg2 == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, stat->reg2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	*val <<= 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	*val |= (ret & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) static u64 adin_get_stat(struct phy_device *phydev, int i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 	const struct adin_hw_stat *stat = &adin_hw_stats[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 	struct adin_priv *priv = phydev->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) 	if (stat->reg1 > 0x1f) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) 		ret = adin_read_mmd_stat_regs(phydev, stat, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) 			return (u64)(~0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) 		ret = phy_read(phydev, stat->reg1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 		if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 			return (u64)(~0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 		val = (ret & 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 	priv->stats[i] += val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 	return priv->stats[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) static void adin_get_stats(struct phy_device *phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 			   struct ethtool_stats *stats, u64 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 	int i, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 	/* latch copies of all the frame-checker counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 	rc = phy_read(phydev, ADIN1300_RX_ERR_CNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 	if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 	for (i = 0; i < ARRAY_SIZE(adin_hw_stats); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 		data[i] = adin_get_stat(phydev, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) static int adin_probe(struct phy_device *phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 	struct device *dev = &phydev->mdio.dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 	struct adin_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 	if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 	phydev->priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) static struct phy_driver adin_driver[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 		PHY_ID_MATCH_MODEL(PHY_ID_ADIN1200),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 		.name		= "ADIN1200",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 		.probe		= adin_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 		.config_init	= adin_config_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 		.soft_reset	= adin_soft_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 		.config_aneg	= adin_config_aneg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 		.read_status	= adin_read_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 		.get_tunable	= adin_get_tunable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 		.set_tunable	= adin_set_tunable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 		.ack_interrupt	= adin_phy_ack_intr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 		.config_intr	= adin_phy_config_intr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 		.get_sset_count	= adin_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 		.get_strings	= adin_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 		.get_stats	= adin_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 		.resume		= genphy_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 		.suspend	= genphy_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 		.read_mmd	= adin_read_mmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 		.write_mmd	= adin_write_mmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 		PHY_ID_MATCH_MODEL(PHY_ID_ADIN1300),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 		.name		= "ADIN1300",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 		.probe		= adin_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 		.config_init	= adin_config_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) 		.soft_reset	= adin_soft_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) 		.config_aneg	= adin_config_aneg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) 		.read_status	= adin_read_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 		.get_tunable	= adin_get_tunable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 		.set_tunable	= adin_set_tunable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 		.ack_interrupt	= adin_phy_ack_intr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 		.config_intr	= adin_phy_config_intr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 		.get_sset_count	= adin_get_sset_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 		.get_strings	= adin_get_strings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 		.get_stats	= adin_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 		.resume		= genphy_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 		.suspend	= genphy_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 		.read_mmd	= adin_read_mmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 		.write_mmd	= adin_write_mmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) module_phy_driver(adin_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) static struct mdio_device_id __maybe_unused adin_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 	{ PHY_ID_MATCH_MODEL(PHY_ID_ADIN1200) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 	{ PHY_ID_MATCH_MODEL(PHY_ID_ADIN1300) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) MODULE_DEVICE_TABLE(mdio, adin_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) MODULE_DESCRIPTION("Analog Devices Industrial Ethernet PHY driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) MODULE_LICENSE("GPL");