^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);