Commit | Line | Data |
---|---|---|
a2443fd1 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
0ca7111a MU |
2 | /* |
3 | * drivers/net/phy/at803x.c | |
4 | * | |
96c36712 | 5 | * Driver for Qualcomm Atheros AR803x PHY |
0ca7111a MU |
6 | * |
7 | * Author: Matus Ujhelyi <ujhelyi.m@gmail.com> | |
0ca7111a MU |
8 | */ |
9 | ||
10 | #include <linux/phy.h> | |
11 | #include <linux/module.h> | |
12 | #include <linux/string.h> | |
13 | #include <linux/netdevice.h> | |
14 | #include <linux/etherdevice.h> | |
6cb75767 | 15 | #include <linux/ethtool_netlink.h> |
13a56b44 | 16 | #include <linux/of_gpio.h> |
2f664823 | 17 | #include <linux/bitfield.h> |
13a56b44 | 18 | #include <linux/gpio/consumer.h> |
2f664823 MW |
19 | #include <linux/regulator/of_regulator.h> |
20 | #include <linux/regulator/driver.h> | |
21 | #include <linux/regulator/consumer.h> | |
dc4d5fcc RH |
22 | #include <linux/phylink.h> |
23 | #include <linux/sfp.h> | |
2f664823 | 24 | #include <dt-bindings/net/qca-ar803x.h> |
0ca7111a | 25 | |
7dce80c2 OR |
26 | #define AT803X_SPECIFIC_FUNCTION_CONTROL 0x10 |
27 | #define AT803X_SFC_ASSERT_CRS BIT(11) | |
28 | #define AT803X_SFC_FORCE_LINK BIT(10) | |
29 | #define AT803X_SFC_MDI_CROSSOVER_MODE_M GENMASK(6, 5) | |
30 | #define AT803X_SFC_AUTOMATIC_CROSSOVER 0x3 | |
31 | #define AT803X_SFC_MANUAL_MDIX 0x1 | |
32 | #define AT803X_SFC_MANUAL_MDI 0x0 | |
33 | #define AT803X_SFC_SQE_TEST BIT(2) | |
34 | #define AT803X_SFC_POLARITY_REVERSAL BIT(1) | |
35 | #define AT803X_SFC_DISABLE_JABBER BIT(0) | |
36 | ||
06d5f344 | 37 | #define AT803X_SPECIFIC_STATUS 0x11 |
9540cdda LJ |
38 | #define AT803X_SS_SPEED_MASK GENMASK(15, 14) |
39 | #define AT803X_SS_SPEED_1000 2 | |
40 | #define AT803X_SS_SPEED_100 1 | |
41 | #define AT803X_SS_SPEED_10 0 | |
06d5f344 RK |
42 | #define AT803X_SS_DUPLEX BIT(13) |
43 | #define AT803X_SS_SPEED_DUPLEX_RESOLVED BIT(11) | |
44 | #define AT803X_SS_MDIX BIT(6) | |
45 | ||
79c7bc05 LJ |
46 | #define QCA808X_SS_SPEED_MASK GENMASK(9, 7) |
47 | #define QCA808X_SS_SPEED_2500 4 | |
48 | ||
0ca7111a | 49 | #define AT803X_INTR_ENABLE 0x12 |
e6e4a556 MB |
50 | #define AT803X_INTR_ENABLE_AUTONEG_ERR BIT(15) |
51 | #define AT803X_INTR_ENABLE_SPEED_CHANGED BIT(14) | |
52 | #define AT803X_INTR_ENABLE_DUPLEX_CHANGED BIT(13) | |
53 | #define AT803X_INTR_ENABLE_PAGE_RECEIVED BIT(12) | |
54 | #define AT803X_INTR_ENABLE_LINK_FAIL BIT(11) | |
55 | #define AT803X_INTR_ENABLE_LINK_SUCCESS BIT(10) | |
3265f421 RH |
56 | #define AT803X_INTR_ENABLE_LINK_FAIL_BX BIT(8) |
57 | #define AT803X_INTR_ENABLE_LINK_SUCCESS_BX BIT(7) | |
e6e4a556 MB |
58 | #define AT803X_INTR_ENABLE_WIRESPEED_DOWNGRADE BIT(5) |
59 | #define AT803X_INTR_ENABLE_POLARITY_CHANGED BIT(1) | |
60 | #define AT803X_INTR_ENABLE_WOL BIT(0) | |
61 | ||
0ca7111a | 62 | #define AT803X_INTR_STATUS 0x13 |
a46bd63b | 63 | |
13a56b44 | 64 | #define AT803X_SMART_SPEED 0x14 |
cde0f4f8 MW |
65 | #define AT803X_SMART_SPEED_ENABLE BIT(5) |
66 | #define AT803X_SMART_SPEED_RETRY_LIMIT_MASK GENMASK(4, 2) | |
67 | #define AT803X_SMART_SPEED_BYPASS_TIMER BIT(1) | |
6cb75767 MW |
68 | #define AT803X_CDT 0x16 |
69 | #define AT803X_CDT_MDI_PAIR_MASK GENMASK(9, 8) | |
70 | #define AT803X_CDT_ENABLE_TEST BIT(0) | |
71 | #define AT803X_CDT_STATUS 0x1c | |
72 | #define AT803X_CDT_STATUS_STAT_NORMAL 0 | |
73 | #define AT803X_CDT_STATUS_STAT_SHORT 1 | |
74 | #define AT803X_CDT_STATUS_STAT_OPEN 2 | |
75 | #define AT803X_CDT_STATUS_STAT_FAIL 3 | |
76 | #define AT803X_CDT_STATUS_STAT_MASK GENMASK(9, 8) | |
77 | #define AT803X_CDT_STATUS_DELTA_TIME_MASK GENMASK(7, 0) | |
13a56b44 | 78 | #define AT803X_LED_CONTROL 0x18 |
a46bd63b | 79 | |
7beecaf7 LJ |
80 | #define AT803X_PHY_MMD3_WOL_CTRL 0x8012 |
81 | #define AT803X_WOL_EN BIT(5) | |
0ca7111a MU |
82 | #define AT803X_LOC_MAC_ADDR_0_15_OFFSET 0x804C |
83 | #define AT803X_LOC_MAC_ADDR_16_31_OFFSET 0x804B | |
84 | #define AT803X_LOC_MAC_ADDR_32_47_OFFSET 0x804A | |
f62265b5 ZK |
85 | #define AT803X_REG_CHIP_CONFIG 0x1f |
86 | #define AT803X_BT_BX_REG_SEL 0x8000 | |
a46bd63b | 87 | |
1ca6d1b1 M |
88 | #define AT803X_DEBUG_ADDR 0x1D |
89 | #define AT803X_DEBUG_DATA 0x1E | |
a46bd63b | 90 | |
f62265b5 | 91 | #define AT803X_MODE_CFG_MASK 0x0F |
3265f421 RH |
92 | #define AT803X_MODE_CFG_BASET_RGMII 0x00 |
93 | #define AT803X_MODE_CFG_BASET_SGMII 0x01 | |
94 | #define AT803X_MODE_CFG_BX1000_RGMII_50OHM 0x02 | |
95 | #define AT803X_MODE_CFG_BX1000_RGMII_75OHM 0x03 | |
96 | #define AT803X_MODE_CFG_BX1000_CONV_50OHM 0x04 | |
97 | #define AT803X_MODE_CFG_BX1000_CONV_75OHM 0x05 | |
98 | #define AT803X_MODE_CFG_FX100_RGMII_50OHM 0x06 | |
99 | #define AT803X_MODE_CFG_FX100_CONV_50OHM 0x07 | |
100 | #define AT803X_MODE_CFG_RGMII_AUTO_MDET 0x0B | |
101 | #define AT803X_MODE_CFG_FX100_RGMII_75OHM 0x0E | |
102 | #define AT803X_MODE_CFG_FX100_CONV_75OHM 0x0F | |
f62265b5 | 103 | |
d0e13fd5 AS |
104 | #define AT803X_PSSR 0x11 /*PHY-Specific Status Register*/ |
105 | #define AT803X_PSSR_MR_AN_COMPLETE 0x0200 | |
f62265b5 | 106 | |
67999555 | 107 | #define AT803X_DEBUG_ANALOG_TEST_CTRL 0x00 |
1ca83119 AS |
108 | #define QCA8327_DEBUG_MANU_CTRL_EN BIT(2) |
109 | #define QCA8337_DEBUG_MANU_CTRL_EN GENMASK(3, 2) | |
2e5f9f28 | 110 | #define AT803X_DEBUG_RX_CLK_DLY_EN BIT(15) |
a46bd63b | 111 | |
67999555 | 112 | #define AT803X_DEBUG_SYSTEM_CTRL_MODE 0x05 |
2e5f9f28 | 113 | #define AT803X_DEBUG_TX_CLK_DLY_EN BIT(8) |
0ca7111a | 114 | |
ba3c01ee AS |
115 | #define AT803X_DEBUG_REG_HIB_CTRL 0x0b |
116 | #define AT803X_DEBUG_HIB_CTRL_SEL_RST_80U BIT(10) | |
117 | #define AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE BIT(13) | |
9ecf0401 | 118 | #define AT803X_DEBUG_HIB_CTRL_PS_HIB_EN BIT(15) |
ba3c01ee | 119 | |
272833b9 AS |
120 | #define AT803X_DEBUG_REG_3C 0x3C |
121 | ||
67999555 | 122 | #define AT803X_DEBUG_REG_GREEN 0x3D |
ba3c01ee | 123 | #define AT803X_DEBUG_GATE_CLK_IN1000 BIT(6) |
272833b9 | 124 | |
2f664823 MW |
125 | #define AT803X_DEBUG_REG_1F 0x1F |
126 | #define AT803X_DEBUG_PLL_ON BIT(2) | |
127 | #define AT803X_DEBUG_RGMII_1V8 BIT(3) | |
128 | ||
272833b9 AS |
129 | #define MDIO_AZ_DEBUG 0x800D |
130 | ||
2f664823 MW |
131 | /* AT803x supports either the XTAL input pad, an internal PLL or the |
132 | * DSP as clock reference for the clock output pad. The XTAL reference | |
133 | * is only used for 25 MHz output, all other frequencies need the PLL. | |
134 | * The DSP as a clock reference is used in synchronous ethernet | |
135 | * applications. | |
136 | * | |
137 | * By default the PLL is only enabled if there is a link. Otherwise | |
138 | * the PHY will go into low power state and disabled the PLL. You can | |
139 | * set the PLL_ON bit (see debug register 0x1f) to keep the PLL always | |
140 | * enabled. | |
141 | */ | |
142 | #define AT803X_MMD7_CLK25M 0x8016 | |
143 | #define AT803X_CLK_OUT_MASK GENMASK(4, 2) | |
144 | #define AT803X_CLK_OUT_25MHZ_XTAL 0 | |
145 | #define AT803X_CLK_OUT_25MHZ_DSP 1 | |
146 | #define AT803X_CLK_OUT_50MHZ_PLL 2 | |
147 | #define AT803X_CLK_OUT_50MHZ_DSP 3 | |
148 | #define AT803X_CLK_OUT_62_5MHZ_PLL 4 | |
149 | #define AT803X_CLK_OUT_62_5MHZ_DSP 5 | |
150 | #define AT803X_CLK_OUT_125MHZ_PLL 6 | |
151 | #define AT803X_CLK_OUT_125MHZ_DSP 7 | |
152 | ||
428061f7 MW |
153 | /* The AR8035 has another mask which is compatible with the AR8031/AR8033 mask |
154 | * but doesn't support choosing between XTAL/PLL and DSP. | |
2f664823 MW |
155 | */ |
156 | #define AT8035_CLK_OUT_MASK GENMASK(4, 3) | |
157 | ||
158 | #define AT803X_CLK_OUT_STRENGTH_MASK GENMASK(8, 7) | |
159 | #define AT803X_CLK_OUT_STRENGTH_FULL 0 | |
160 | #define AT803X_CLK_OUT_STRENGTH_HALF 1 | |
161 | #define AT803X_CLK_OUT_STRENGTH_QUARTER 2 | |
162 | ||
d0e13fd5 AS |
163 | #define AT803X_DEFAULT_DOWNSHIFT 5 |
164 | #define AT803X_MIN_DOWNSHIFT 2 | |
165 | #define AT803X_MAX_DOWNSHIFT 9 | |
cde0f4f8 | 166 | |
390b4cad RK |
167 | #define AT803X_MMD3_SMARTEEE_CTL1 0x805b |
168 | #define AT803X_MMD3_SMARTEEE_CTL2 0x805c | |
169 | #define AT803X_MMD3_SMARTEEE_CTL3 0x805d | |
170 | #define AT803X_MMD3_SMARTEEE_CTL3_LPI_EN BIT(8) | |
171 | ||
d0e13fd5 AS |
172 | #define ATH9331_PHY_ID 0x004dd041 |
173 | #define ATH8030_PHY_ID 0x004dd076 | |
174 | #define ATH8031_PHY_ID 0x004dd074 | |
175 | #define ATH8032_PHY_ID 0x004dd023 | |
176 | #define ATH8035_PHY_ID 0x004dd072 | |
0465d8f8 | 177 | #define AT8030_PHY_ID_MASK 0xffffffef |
bd8ca17f | 178 | |
daf61732 LJ |
179 | #define QCA8081_PHY_ID 0x004dd101 |
180 | ||
b4df02b5 AS |
181 | #define QCA8327_A_PHY_ID 0x004dd033 |
182 | #define QCA8327_B_PHY_ID 0x004dd034 | |
272833b9 | 183 | #define QCA8337_PHY_ID 0x004dd036 |
fada2ce0 | 184 | #define QCA9561_PHY_ID 0x004dd042 |
272833b9 AS |
185 | #define QCA8K_PHY_ID_MASK 0xffffffff |
186 | ||
187 | #define QCA8K_DEVFLAGS_REVISION_MASK GENMASK(2, 0) | |
188 | ||
d0e13fd5 AS |
189 | #define AT803X_PAGE_FIBER 0 |
190 | #define AT803X_PAGE_COPPER 1 | |
191 | ||
192 | /* don't turn off internal PLL */ | |
193 | #define AT803X_KEEP_PLL_ENABLED BIT(0) | |
194 | #define AT803X_DISABLE_SMARTEEE BIT(1) | |
c329e5af | 195 | |
9ecf0401 WF |
196 | /* disable hibernation mode */ |
197 | #define AT803X_DISABLE_HIBERNATION_MODE BIT(2) | |
198 | ||
2acdd43f LJ |
199 | /* ADC threshold */ |
200 | #define QCA808X_PHY_DEBUG_ADC_THRESHOLD 0x2c80 | |
201 | #define QCA808X_ADC_THRESHOLD_MASK GENMASK(7, 0) | |
202 | #define QCA808X_ADC_THRESHOLD_80MV 0 | |
203 | #define QCA808X_ADC_THRESHOLD_100MV 0xf0 | |
204 | #define QCA808X_ADC_THRESHOLD_200MV 0x0f | |
205 | #define QCA808X_ADC_THRESHOLD_300MV 0xff | |
206 | ||
207 | /* CLD control */ | |
208 | #define QCA808X_PHY_MMD3_ADDR_CLD_CTRL7 0x8007 | |
209 | #define QCA808X_8023AZ_AFE_CTRL_MASK GENMASK(8, 4) | |
210 | #define QCA808X_8023AZ_AFE_EN 0x90 | |
211 | ||
212 | /* AZ control */ | |
213 | #define QCA808X_PHY_MMD3_AZ_TRAINING_CTRL 0x8008 | |
214 | #define QCA808X_MMD3_AZ_TRAINING_VAL 0x1c32 | |
215 | ||
216 | #define QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB 0x8014 | |
217 | #define QCA808X_MSE_THRESHOLD_20DB_VALUE 0x529 | |
218 | ||
219 | #define QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB 0x800E | |
220 | #define QCA808X_MSE_THRESHOLD_17DB_VALUE 0x341 | |
221 | ||
222 | #define QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB 0x801E | |
223 | #define QCA808X_MSE_THRESHOLD_27DB_VALUE 0x419 | |
224 | ||
225 | #define QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB 0x8020 | |
226 | #define QCA808X_MSE_THRESHOLD_28DB_VALUE 0x341 | |
227 | ||
228 | #define QCA808X_PHY_MMD7_TOP_OPTION1 0x901c | |
229 | #define QCA808X_TOP_OPTION1_DATA 0x0 | |
230 | ||
231 | #define QCA808X_PHY_MMD3_DEBUG_1 0xa100 | |
232 | #define QCA808X_MMD3_DEBUG_1_VALUE 0x9203 | |
233 | #define QCA808X_PHY_MMD3_DEBUG_2 0xa101 | |
234 | #define QCA808X_MMD3_DEBUG_2_VALUE 0x48ad | |
235 | #define QCA808X_PHY_MMD3_DEBUG_3 0xa103 | |
236 | #define QCA808X_MMD3_DEBUG_3_VALUE 0x1698 | |
237 | #define QCA808X_PHY_MMD3_DEBUG_4 0xa105 | |
238 | #define QCA808X_MMD3_DEBUG_4_VALUE 0x8001 | |
239 | #define QCA808X_PHY_MMD3_DEBUG_5 0xa106 | |
240 | #define QCA808X_MMD3_DEBUG_5_VALUE 0x1111 | |
241 | #define QCA808X_PHY_MMD3_DEBUG_6 0xa011 | |
242 | #define QCA808X_MMD3_DEBUG_6_VALUE 0x5f85 | |
243 | ||
9d4dae29 LJ |
244 | /* master/slave seed config */ |
245 | #define QCA808X_PHY_DEBUG_LOCAL_SEED 9 | |
246 | #define QCA808X_MASTER_SLAVE_SEED_ENABLE BIT(1) | |
247 | #define QCA808X_MASTER_SLAVE_SEED_CFG GENMASK(12, 2) | |
248 | #define QCA808X_MASTER_SLAVE_SEED_RANGE 0x32 | |
249 | ||
8c84d752 LJ |
250 | /* Hibernation yields lower power consumpiton in contrast with normal operation mode. |
251 | * when the copper cable is unplugged, the PHY enters into hibernation mode in about 10s. | |
252 | */ | |
253 | #define QCA808X_DBG_AN_TEST 0xb | |
254 | #define QCA808X_HIBERNATION_EN BIT(15) | |
255 | ||
256 | #define QCA808X_CDT_ENABLE_TEST BIT(15) | |
257 | #define QCA808X_CDT_INTER_CHECK_DIS BIT(13) | |
258 | #define QCA808X_CDT_LENGTH_UNIT BIT(10) | |
259 | ||
260 | #define QCA808X_MMD3_CDT_STATUS 0x8064 | |
261 | #define QCA808X_MMD3_CDT_DIAG_PAIR_A 0x8065 | |
262 | #define QCA808X_MMD3_CDT_DIAG_PAIR_B 0x8066 | |
263 | #define QCA808X_MMD3_CDT_DIAG_PAIR_C 0x8067 | |
264 | #define QCA808X_MMD3_CDT_DIAG_PAIR_D 0x8068 | |
265 | #define QCA808X_CDT_DIAG_LENGTH GENMASK(7, 0) | |
266 | ||
267 | #define QCA808X_CDT_CODE_PAIR_A GENMASK(15, 12) | |
268 | #define QCA808X_CDT_CODE_PAIR_B GENMASK(11, 8) | |
269 | #define QCA808X_CDT_CODE_PAIR_C GENMASK(7, 4) | |
270 | #define QCA808X_CDT_CODE_PAIR_D GENMASK(3, 0) | |
271 | #define QCA808X_CDT_STATUS_STAT_FAIL 0 | |
272 | #define QCA808X_CDT_STATUS_STAT_NORMAL 1 | |
273 | #define QCA808X_CDT_STATUS_STAT_OPEN 2 | |
274 | #define QCA808X_CDT_STATUS_STAT_SHORT 3 | |
275 | ||
daf61732 | 276 | MODULE_DESCRIPTION("Qualcomm Atheros AR803x and QCA808X PHY driver"); |
0ca7111a MU |
277 | MODULE_AUTHOR("Matus Ujhelyi"); |
278 | MODULE_LICENSE("GPL"); | |
279 | ||
272833b9 AS |
280 | enum stat_access_type { |
281 | PHY, | |
282 | MMD | |
283 | }; | |
284 | ||
285 | struct at803x_hw_stat { | |
286 | const char *string; | |
287 | u8 reg; | |
288 | u32 mask; | |
289 | enum stat_access_type access_type; | |
290 | }; | |
291 | ||
292 | static struct at803x_hw_stat at803x_hw_stats[] = { | |
293 | { "phy_idle_errors", 0xa, GENMASK(7, 0), PHY}, | |
294 | { "phy_receive_errors", 0x15, GENMASK(15, 0), PHY}, | |
295 | { "eee_wake_errors", 0x16, GENMASK(15, 0), MMD}, | |
296 | }; | |
297 | ||
2f664823 MW |
298 | struct at803x_priv { |
299 | int flags; | |
2f664823 MW |
300 | u16 clk_25m_reg; |
301 | u16 clk_25m_mask; | |
390b4cad RK |
302 | u8 smarteee_lpi_tw_1g; |
303 | u8 smarteee_lpi_tw_100m; | |
3265f421 RH |
304 | bool is_fiber; |
305 | bool is_1000basex; | |
2f664823 MW |
306 | struct regulator_dev *vddio_rdev; |
307 | struct regulator_dev *vddh_rdev; | |
308 | struct regulator *vddio; | |
272833b9 | 309 | u64 stats[ARRAY_SIZE(at803x_hw_stats)]; |
2f664823 MW |
310 | }; |
311 | ||
13a56b44 DM |
312 | struct at803x_context { |
313 | u16 bmcr; | |
314 | u16 advertise; | |
315 | u16 control1000; | |
316 | u16 int_enable; | |
317 | u16 smart_speed; | |
318 | u16 led_control; | |
319 | }; | |
320 | ||
272833b9 AS |
321 | static int at803x_debug_reg_write(struct phy_device *phydev, u16 reg, u16 data) |
322 | { | |
323 | int ret; | |
324 | ||
325 | ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg); | |
326 | if (ret < 0) | |
327 | return ret; | |
328 | ||
329 | return phy_write(phydev, AT803X_DEBUG_DATA, data); | |
330 | } | |
331 | ||
2e5f9f28 MB |
332 | static int at803x_debug_reg_read(struct phy_device *phydev, u16 reg) |
333 | { | |
334 | int ret; | |
335 | ||
336 | ret = phy_write(phydev, AT803X_DEBUG_ADDR, reg); | |
337 | if (ret < 0) | |
338 | return ret; | |
339 | ||
340 | return phy_read(phydev, AT803X_DEBUG_DATA); | |
341 | } | |
342 | ||
343 | static int at803x_debug_reg_mask(struct phy_device *phydev, u16 reg, | |
344 | u16 clear, u16 set) | |
345 | { | |
346 | u16 val; | |
347 | int ret; | |
348 | ||
349 | ret = at803x_debug_reg_read(phydev, reg); | |
350 | if (ret < 0) | |
351 | return ret; | |
352 | ||
353 | val = ret & 0xffff; | |
354 | val &= ~clear; | |
355 | val |= set; | |
356 | ||
357 | return phy_write(phydev, AT803X_DEBUG_DATA, val); | |
358 | } | |
359 | ||
c329e5af DB |
360 | static int at803x_write_page(struct phy_device *phydev, int page) |
361 | { | |
362 | int mask; | |
363 | int set; | |
364 | ||
365 | if (page == AT803X_PAGE_COPPER) { | |
366 | set = AT803X_BT_BX_REG_SEL; | |
367 | mask = 0; | |
368 | } else { | |
369 | set = 0; | |
370 | mask = AT803X_BT_BX_REG_SEL; | |
371 | } | |
372 | ||
373 | return __phy_modify(phydev, AT803X_REG_CHIP_CONFIG, mask, set); | |
374 | } | |
375 | ||
376 | static int at803x_read_page(struct phy_device *phydev) | |
377 | { | |
378 | int ccr = __phy_read(phydev, AT803X_REG_CHIP_CONFIG); | |
379 | ||
380 | if (ccr < 0) | |
381 | return ccr; | |
382 | ||
383 | if (ccr & AT803X_BT_BX_REG_SEL) | |
384 | return AT803X_PAGE_COPPER; | |
385 | ||
386 | return AT803X_PAGE_FIBER; | |
387 | } | |
388 | ||
6d4cd041 VK |
389 | static int at803x_enable_rx_delay(struct phy_device *phydev) |
390 | { | |
67999555 | 391 | return at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, 0, |
6d4cd041 VK |
392 | AT803X_DEBUG_RX_CLK_DLY_EN); |
393 | } | |
394 | ||
395 | static int at803x_enable_tx_delay(struct phy_device *phydev) | |
396 | { | |
67999555 | 397 | return at803x_debug_reg_mask(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, 0, |
6d4cd041 VK |
398 | AT803X_DEBUG_TX_CLK_DLY_EN); |
399 | } | |
400 | ||
43f2ebd5 | 401 | static int at803x_disable_rx_delay(struct phy_device *phydev) |
2e5f9f28 | 402 | { |
67999555 | 403 | return at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, |
cd28d1d6 | 404 | AT803X_DEBUG_RX_CLK_DLY_EN, 0); |
2e5f9f28 MB |
405 | } |
406 | ||
43f2ebd5 | 407 | static int at803x_disable_tx_delay(struct phy_device *phydev) |
2e5f9f28 | 408 | { |
67999555 | 409 | return at803x_debug_reg_mask(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, |
cd28d1d6 | 410 | AT803X_DEBUG_TX_CLK_DLY_EN, 0); |
2e5f9f28 MB |
411 | } |
412 | ||
13a56b44 DM |
413 | /* save relevant PHY registers to private copy */ |
414 | static void at803x_context_save(struct phy_device *phydev, | |
415 | struct at803x_context *context) | |
416 | { | |
417 | context->bmcr = phy_read(phydev, MII_BMCR); | |
418 | context->advertise = phy_read(phydev, MII_ADVERTISE); | |
419 | context->control1000 = phy_read(phydev, MII_CTRL1000); | |
420 | context->int_enable = phy_read(phydev, AT803X_INTR_ENABLE); | |
421 | context->smart_speed = phy_read(phydev, AT803X_SMART_SPEED); | |
422 | context->led_control = phy_read(phydev, AT803X_LED_CONTROL); | |
423 | } | |
424 | ||
425 | /* restore relevant PHY registers from private copy */ | |
426 | static void at803x_context_restore(struct phy_device *phydev, | |
427 | const struct at803x_context *context) | |
428 | { | |
429 | phy_write(phydev, MII_BMCR, context->bmcr); | |
430 | phy_write(phydev, MII_ADVERTISE, context->advertise); | |
431 | phy_write(phydev, MII_CTRL1000, context->control1000); | |
432 | phy_write(phydev, AT803X_INTR_ENABLE, context->int_enable); | |
433 | phy_write(phydev, AT803X_SMART_SPEED, context->smart_speed); | |
434 | phy_write(phydev, AT803X_LED_CONTROL, context->led_control); | |
435 | } | |
436 | ||
ea13c9ee M |
437 | static int at803x_set_wol(struct phy_device *phydev, |
438 | struct ethtool_wolinfo *wol) | |
0ca7111a | 439 | { |
7beecaf7 | 440 | int ret, irq_enabled; |
0ca7111a | 441 | |
ea13c9ee | 442 | if (wol->wolopts & WAKE_MAGIC) { |
d7cd5e06 VS |
443 | struct net_device *ndev = phydev->attached_dev; |
444 | const u8 *mac; | |
445 | unsigned int i; | |
446 | static const unsigned int offsets[] = { | |
447 | AT803X_LOC_MAC_ADDR_32_47_OFFSET, | |
448 | AT803X_LOC_MAC_ADDR_16_31_OFFSET, | |
449 | AT803X_LOC_MAC_ADDR_0_15_OFFSET, | |
450 | }; | |
451 | ||
452 | if (!ndev) | |
453 | return -ENODEV; | |
454 | ||
ea13c9ee | 455 | mac = (const u8 *) ndev->dev_addr; |
0ca7111a | 456 | |
ea13c9ee | 457 | if (!is_valid_ether_addr(mac)) |
fc755687 | 458 | return -EINVAL; |
0ca7111a | 459 | |
0e021396 | 460 | for (i = 0; i < 3; i++) |
c0f0b563 | 461 | phy_write_mmd(phydev, MDIO_MMD_PCS, offsets[i], |
0e021396 | 462 | mac[(i * 2) + 1] | (mac[(i * 2)] << 8)); |
ea13c9ee | 463 | |
7beecaf7 LJ |
464 | /* Enable WOL function */ |
465 | ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_PHY_MMD3_WOL_CTRL, | |
466 | 0, AT803X_WOL_EN); | |
467 | if (ret) | |
468 | return ret; | |
469 | /* Enable WOL interrupt */ | |
2d4284e8 | 470 | ret = phy_modify(phydev, AT803X_INTR_ENABLE, 0, AT803X_INTR_ENABLE_WOL); |
ea13c9ee M |
471 | if (ret) |
472 | return ret; | |
ea13c9ee | 473 | } else { |
7beecaf7 LJ |
474 | /* Disable WoL function */ |
475 | ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_PHY_MMD3_WOL_CTRL, | |
476 | AT803X_WOL_EN, 0); | |
477 | if (ret) | |
478 | return ret; | |
479 | /* Disable WOL interrupt */ | |
2d4284e8 | 480 | ret = phy_modify(phydev, AT803X_INTR_ENABLE, AT803X_INTR_ENABLE_WOL, 0); |
ea13c9ee M |
481 | if (ret) |
482 | return ret; | |
0ca7111a | 483 | } |
ea13c9ee | 484 | |
7beecaf7 LJ |
485 | /* Clear WOL status */ |
486 | ret = phy_read(phydev, AT803X_INTR_STATUS); | |
487 | if (ret < 0) | |
488 | return ret; | |
489 | ||
490 | /* Check if there are other interrupts except for WOL triggered when PHY is | |
491 | * in interrupt mode, only the interrupts enabled by AT803X_INTR_ENABLE can | |
492 | * be passed up to the interrupt PIN. | |
493 | */ | |
494 | irq_enabled = phy_read(phydev, AT803X_INTR_ENABLE); | |
495 | if (irq_enabled < 0) | |
496 | return irq_enabled; | |
497 | ||
498 | irq_enabled &= ~AT803X_INTR_ENABLE_WOL; | |
499 | if (ret & irq_enabled && !phy_polling_mode(phydev)) | |
500 | phy_trigger_machine(phydev); | |
501 | ||
502 | return 0; | |
ea13c9ee M |
503 | } |
504 | ||
505 | static void at803x_get_wol(struct phy_device *phydev, | |
506 | struct ethtool_wolinfo *wol) | |
507 | { | |
911e3a46 | 508 | int value; |
ea13c9ee M |
509 | |
510 | wol->supported = WAKE_MAGIC; | |
511 | wol->wolopts = 0; | |
512 | ||
7beecaf7 LJ |
513 | value = phy_read_mmd(phydev, MDIO_MMD_PCS, AT803X_PHY_MMD3_WOL_CTRL); |
514 | if (value < 0) | |
515 | return; | |
516 | ||
517 | if (value & AT803X_WOL_EN) | |
ea13c9ee | 518 | wol->wolopts |= WAKE_MAGIC; |
0ca7111a MU |
519 | } |
520 | ||
272833b9 AS |
521 | static int at803x_get_sset_count(struct phy_device *phydev) |
522 | { | |
523 | return ARRAY_SIZE(at803x_hw_stats); | |
524 | } | |
525 | ||
526 | static void at803x_get_strings(struct phy_device *phydev, u8 *data) | |
527 | { | |
528 | int i; | |
529 | ||
530 | for (i = 0; i < ARRAY_SIZE(at803x_hw_stats); i++) { | |
531 | strscpy(data + i * ETH_GSTRING_LEN, | |
532 | at803x_hw_stats[i].string, ETH_GSTRING_LEN); | |
533 | } | |
534 | } | |
535 | ||
536 | static u64 at803x_get_stat(struct phy_device *phydev, int i) | |
537 | { | |
538 | struct at803x_hw_stat stat = at803x_hw_stats[i]; | |
539 | struct at803x_priv *priv = phydev->priv; | |
540 | int val; | |
541 | u64 ret; | |
542 | ||
543 | if (stat.access_type == MMD) | |
544 | val = phy_read_mmd(phydev, MDIO_MMD_PCS, stat.reg); | |
545 | else | |
546 | val = phy_read(phydev, stat.reg); | |
547 | ||
548 | if (val < 0) { | |
549 | ret = U64_MAX; | |
550 | } else { | |
551 | val = val & stat.mask; | |
552 | priv->stats[i] += val; | |
553 | ret = priv->stats[i]; | |
554 | } | |
555 | ||
556 | return ret; | |
557 | } | |
558 | ||
559 | static void at803x_get_stats(struct phy_device *phydev, | |
560 | struct ethtool_stats *stats, u64 *data) | |
561 | { | |
562 | int i; | |
563 | ||
564 | for (i = 0; i < ARRAY_SIZE(at803x_hw_stats); i++) | |
565 | data[i] = at803x_get_stat(phydev, i); | |
566 | } | |
567 | ||
6229ed1f DM |
568 | static int at803x_suspend(struct phy_device *phydev) |
569 | { | |
570 | int value; | |
571 | int wol_enabled; | |
572 | ||
6229ed1f | 573 | value = phy_read(phydev, AT803X_INTR_ENABLE); |
e6e4a556 | 574 | wol_enabled = value & AT803X_INTR_ENABLE_WOL; |
6229ed1f | 575 | |
6229ed1f | 576 | if (wol_enabled) |
fea23fb5 | 577 | value = BMCR_ISOLATE; |
6229ed1f | 578 | else |
fea23fb5 | 579 | value = BMCR_PDOWN; |
6229ed1f | 580 | |
fea23fb5 | 581 | phy_modify(phydev, MII_BMCR, 0, value); |
6229ed1f DM |
582 | |
583 | return 0; | |
584 | } | |
585 | ||
586 | static int at803x_resume(struct phy_device *phydev) | |
587 | { | |
f102852f | 588 | return phy_modify(phydev, MII_BMCR, BMCR_PDOWN | BMCR_ISOLATE, 0); |
6229ed1f DM |
589 | } |
590 | ||
2f664823 MW |
591 | static int at803x_rgmii_reg_set_voltage_sel(struct regulator_dev *rdev, |
592 | unsigned int selector) | |
593 | { | |
594 | struct phy_device *phydev = rdev_get_drvdata(rdev); | |
595 | ||
596 | if (selector) | |
597 | return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F, | |
598 | 0, AT803X_DEBUG_RGMII_1V8); | |
599 | else | |
600 | return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F, | |
601 | AT803X_DEBUG_RGMII_1V8, 0); | |
602 | } | |
603 | ||
604 | static int at803x_rgmii_reg_get_voltage_sel(struct regulator_dev *rdev) | |
605 | { | |
606 | struct phy_device *phydev = rdev_get_drvdata(rdev); | |
607 | int val; | |
608 | ||
609 | val = at803x_debug_reg_read(phydev, AT803X_DEBUG_REG_1F); | |
610 | if (val < 0) | |
611 | return val; | |
612 | ||
613 | return (val & AT803X_DEBUG_RGMII_1V8) ? 1 : 0; | |
614 | } | |
615 | ||
3faaf539 | 616 | static const struct regulator_ops vddio_regulator_ops = { |
2f664823 MW |
617 | .list_voltage = regulator_list_voltage_table, |
618 | .set_voltage_sel = at803x_rgmii_reg_set_voltage_sel, | |
619 | .get_voltage_sel = at803x_rgmii_reg_get_voltage_sel, | |
620 | }; | |
621 | ||
622 | static const unsigned int vddio_voltage_table[] = { | |
623 | 1500000, | |
624 | 1800000, | |
625 | }; | |
626 | ||
627 | static const struct regulator_desc vddio_desc = { | |
628 | .name = "vddio", | |
629 | .of_match = of_match_ptr("vddio-regulator"), | |
630 | .n_voltages = ARRAY_SIZE(vddio_voltage_table), | |
631 | .volt_table = vddio_voltage_table, | |
632 | .ops = &vddio_regulator_ops, | |
633 | .type = REGULATOR_VOLTAGE, | |
634 | .owner = THIS_MODULE, | |
635 | }; | |
636 | ||
3faaf539 | 637 | static const struct regulator_ops vddh_regulator_ops = { |
2f664823 MW |
638 | }; |
639 | ||
640 | static const struct regulator_desc vddh_desc = { | |
641 | .name = "vddh", | |
642 | .of_match = of_match_ptr("vddh-regulator"), | |
643 | .n_voltages = 1, | |
644 | .fixed_uV = 2500000, | |
645 | .ops = &vddh_regulator_ops, | |
646 | .type = REGULATOR_VOLTAGE, | |
647 | .owner = THIS_MODULE, | |
648 | }; | |
649 | ||
650 | static int at8031_register_regulators(struct phy_device *phydev) | |
651 | { | |
652 | struct at803x_priv *priv = phydev->priv; | |
653 | struct device *dev = &phydev->mdio.dev; | |
654 | struct regulator_config config = { }; | |
655 | ||
656 | config.dev = dev; | |
657 | config.driver_data = phydev; | |
658 | ||
659 | priv->vddio_rdev = devm_regulator_register(dev, &vddio_desc, &config); | |
660 | if (IS_ERR(priv->vddio_rdev)) { | |
661 | phydev_err(phydev, "failed to register VDDIO regulator\n"); | |
662 | return PTR_ERR(priv->vddio_rdev); | |
663 | } | |
664 | ||
665 | priv->vddh_rdev = devm_regulator_register(dev, &vddh_desc, &config); | |
666 | if (IS_ERR(priv->vddh_rdev)) { | |
667 | phydev_err(phydev, "failed to register VDDH regulator\n"); | |
668 | return PTR_ERR(priv->vddh_rdev); | |
669 | } | |
670 | ||
671 | return 0; | |
672 | } | |
673 | ||
dc4d5fcc RH |
674 | static int at803x_sfp_insert(void *upstream, const struct sfp_eeprom_id *id) |
675 | { | |
676 | struct phy_device *phydev = upstream; | |
677 | __ETHTOOL_DECLARE_LINK_MODE_MASK(phy_support); | |
678 | __ETHTOOL_DECLARE_LINK_MODE_MASK(sfp_support); | |
fd580c98 | 679 | DECLARE_PHY_INTERFACE_MASK(interfaces); |
dc4d5fcc RH |
680 | phy_interface_t iface; |
681 | ||
682 | linkmode_zero(phy_support); | |
683 | phylink_set(phy_support, 1000baseX_Full); | |
684 | phylink_set(phy_support, 1000baseT_Full); | |
685 | phylink_set(phy_support, Autoneg); | |
686 | phylink_set(phy_support, Pause); | |
687 | phylink_set(phy_support, Asym_Pause); | |
688 | ||
689 | linkmode_zero(sfp_support); | |
fd580c98 | 690 | sfp_parse_support(phydev->sfp_bus, id, sfp_support, interfaces); |
dc4d5fcc RH |
691 | /* Some modules support 10G modes as well as others we support. |
692 | * Mask out non-supported modes so the correct interface is picked. | |
693 | */ | |
694 | linkmode_and(sfp_support, phy_support, sfp_support); | |
695 | ||
696 | if (linkmode_empty(sfp_support)) { | |
697 | dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n"); | |
698 | return -EINVAL; | |
699 | } | |
700 | ||
701 | iface = sfp_select_interface(phydev->sfp_bus, sfp_support); | |
702 | ||
703 | /* Only 1000Base-X is supported by AR8031/8033 as the downstream SerDes | |
704 | * interface for use with SFP modules. | |
705 | * However, some copper modules detected as having a preferred SGMII | |
706 | * interface do default to and function in 1000Base-X mode, so just | |
707 | * print a warning and allow such modules, as they may have some chance | |
708 | * of working. | |
709 | */ | |
710 | if (iface == PHY_INTERFACE_MODE_SGMII) | |
711 | dev_warn(&phydev->mdio.dev, "module may not function if 1000Base-X not supported\n"); | |
712 | else if (iface != PHY_INTERFACE_MODE_1000BASEX) | |
713 | return -EINVAL; | |
714 | ||
715 | return 0; | |
716 | } | |
717 | ||
718 | static const struct sfp_upstream_ops at803x_sfp_ops = { | |
719 | .attach = phy_sfp_attach, | |
720 | .detach = phy_sfp_detach, | |
721 | .module_insert = at803x_sfp_insert, | |
722 | }; | |
723 | ||
2f664823 MW |
724 | static int at803x_parse_dt(struct phy_device *phydev) |
725 | { | |
726 | struct device_node *node = phydev->mdio.dev.of_node; | |
727 | struct at803x_priv *priv = phydev->priv; | |
390b4cad | 728 | u32 freq, strength, tw; |
3f2edd30 | 729 | unsigned int sel; |
2f664823 MW |
730 | int ret; |
731 | ||
732 | if (!IS_ENABLED(CONFIG_OF_MDIO)) | |
733 | return 0; | |
734 | ||
390b4cad RK |
735 | if (of_property_read_bool(node, "qca,disable-smarteee")) |
736 | priv->flags |= AT803X_DISABLE_SMARTEEE; | |
737 | ||
9ecf0401 WF |
738 | if (of_property_read_bool(node, "qca,disable-hibernation-mode")) |
739 | priv->flags |= AT803X_DISABLE_HIBERNATION_MODE; | |
740 | ||
390b4cad RK |
741 | if (!of_property_read_u32(node, "qca,smarteee-tw-us-1g", &tw)) { |
742 | if (!tw || tw > 255) { | |
743 | phydev_err(phydev, "invalid qca,smarteee-tw-us-1g\n"); | |
744 | return -EINVAL; | |
745 | } | |
746 | priv->smarteee_lpi_tw_1g = tw; | |
747 | } | |
748 | ||
749 | if (!of_property_read_u32(node, "qca,smarteee-tw-us-100m", &tw)) { | |
750 | if (!tw || tw > 255) { | |
751 | phydev_err(phydev, "invalid qca,smarteee-tw-us-100m\n"); | |
752 | return -EINVAL; | |
753 | } | |
754 | priv->smarteee_lpi_tw_100m = tw; | |
755 | } | |
756 | ||
2f664823 MW |
757 | ret = of_property_read_u32(node, "qca,clk-out-frequency", &freq); |
758 | if (!ret) { | |
2f664823 MW |
759 | switch (freq) { |
760 | case 25000000: | |
761 | sel = AT803X_CLK_OUT_25MHZ_XTAL; | |
762 | break; | |
763 | case 50000000: | |
764 | sel = AT803X_CLK_OUT_50MHZ_PLL; | |
765 | break; | |
766 | case 62500000: | |
767 | sel = AT803X_CLK_OUT_62_5MHZ_PLL; | |
768 | break; | |
769 | case 125000000: | |
770 | sel = AT803X_CLK_OUT_125MHZ_PLL; | |
771 | break; | |
772 | default: | |
773 | phydev_err(phydev, "invalid qca,clk-out-frequency\n"); | |
774 | return -EINVAL; | |
775 | } | |
776 | ||
3f2edd30 AL |
777 | priv->clk_25m_reg |= FIELD_PREP(AT803X_CLK_OUT_MASK, sel); |
778 | priv->clk_25m_mask |= AT803X_CLK_OUT_MASK; | |
2f664823 MW |
779 | |
780 | /* Fixup for the AR8030/AR8035. This chip has another mask and | |
781 | * doesn't support the DSP reference. Eg. the lowest bit of the | |
782 | * mask. The upper two bits select the same frequencies. Mask | |
783 | * the lowest bit here. | |
784 | * | |
785 | * Warning: | |
786 | * There was no datasheet for the AR8030 available so this is | |
787 | * just a guess. But the AR8035 is listed as pin compatible | |
788 | * to the AR8030 so there might be a good chance it works on | |
789 | * the AR8030 too. | |
790 | */ | |
8887ca54 RK |
791 | if (phydev->drv->phy_id == ATH8030_PHY_ID || |
792 | phydev->drv->phy_id == ATH8035_PHY_ID) { | |
b1f4c209 OR |
793 | priv->clk_25m_reg &= AT8035_CLK_OUT_MASK; |
794 | priv->clk_25m_mask &= AT8035_CLK_OUT_MASK; | |
2f664823 MW |
795 | } |
796 | } | |
797 | ||
798 | ret = of_property_read_u32(node, "qca,clk-out-strength", &strength); | |
799 | if (!ret) { | |
800 | priv->clk_25m_mask |= AT803X_CLK_OUT_STRENGTH_MASK; | |
801 | switch (strength) { | |
802 | case AR803X_STRENGTH_FULL: | |
803 | priv->clk_25m_reg |= AT803X_CLK_OUT_STRENGTH_FULL; | |
804 | break; | |
805 | case AR803X_STRENGTH_HALF: | |
806 | priv->clk_25m_reg |= AT803X_CLK_OUT_STRENGTH_HALF; | |
807 | break; | |
808 | case AR803X_STRENGTH_QUARTER: | |
809 | priv->clk_25m_reg |= AT803X_CLK_OUT_STRENGTH_QUARTER; | |
810 | break; | |
811 | default: | |
812 | phydev_err(phydev, "invalid qca,clk-out-strength\n"); | |
813 | return -EINVAL; | |
814 | } | |
815 | } | |
816 | ||
428061f7 MW |
817 | /* Only supported on AR8031/AR8033, the AR8030/AR8035 use strapping |
818 | * options. | |
819 | */ | |
8887ca54 | 820 | if (phydev->drv->phy_id == ATH8031_PHY_ID) { |
2f664823 MW |
821 | if (of_property_read_bool(node, "qca,keep-pll-enabled")) |
822 | priv->flags |= AT803X_KEEP_PLL_ENABLED; | |
823 | ||
824 | ret = at8031_register_regulators(phydev); | |
825 | if (ret < 0) | |
826 | return ret; | |
827 | ||
828 | priv->vddio = devm_regulator_get_optional(&phydev->mdio.dev, | |
829 | "vddio"); | |
830 | if (IS_ERR(priv->vddio)) { | |
831 | phydev_err(phydev, "failed to get VDDIO regulator\n"); | |
832 | return PTR_ERR(priv->vddio); | |
833 | } | |
dc4d5fcc RH |
834 | |
835 | /* Only AR8031/8033 support 1000Base-X for SFP modules */ | |
836 | ret = phy_sfp_probe(phydev, &at803x_sfp_ops); | |
837 | if (ret < 0) | |
838 | return ret; | |
2f664823 MW |
839 | } |
840 | ||
841 | return 0; | |
842 | } | |
843 | ||
844 | static int at803x_probe(struct phy_device *phydev) | |
845 | { | |
846 | struct device *dev = &phydev->mdio.dev; | |
847 | struct at803x_priv *priv; | |
c329e5af | 848 | int ret; |
2f664823 MW |
849 | |
850 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | |
851 | if (!priv) | |
852 | return -ENOMEM; | |
853 | ||
854 | phydev->priv = priv; | |
855 | ||
c329e5af DB |
856 | ret = at803x_parse_dt(phydev); |
857 | if (ret) | |
858 | return ret; | |
859 | ||
8f7e8762 MW |
860 | if (priv->vddio) { |
861 | ret = regulator_enable(priv->vddio); | |
862 | if (ret < 0) | |
863 | return ret; | |
864 | } | |
865 | ||
3265f421 RH |
866 | if (phydev->drv->phy_id == ATH8031_PHY_ID) { |
867 | int ccr = phy_read(phydev, AT803X_REG_CHIP_CONFIG); | |
868 | int mode_cfg; | |
d7cd5e06 VS |
869 | struct ethtool_wolinfo wol = { |
870 | .wolopts = 0, | |
871 | }; | |
3265f421 | 872 | |
1f0dd412 WY |
873 | if (ccr < 0) { |
874 | ret = ccr; | |
3265f421 | 875 | goto err; |
1f0dd412 | 876 | } |
3265f421 RH |
877 | mode_cfg = ccr & AT803X_MODE_CFG_MASK; |
878 | ||
879 | switch (mode_cfg) { | |
880 | case AT803X_MODE_CFG_BX1000_RGMII_50OHM: | |
881 | case AT803X_MODE_CFG_BX1000_RGMII_75OHM: | |
882 | priv->is_1000basex = true; | |
883 | fallthrough; | |
884 | case AT803X_MODE_CFG_FX100_RGMII_50OHM: | |
885 | case AT803X_MODE_CFG_FX100_RGMII_75OHM: | |
886 | priv->is_fiber = true; | |
887 | break; | |
888 | } | |
d7cd5e06 VS |
889 | |
890 | /* Disable WOL by default */ | |
891 | ret = at803x_set_wol(phydev, &wol); | |
892 | if (ret < 0) { | |
893 | phydev_err(phydev, "failed to disable WOL on probe: %d\n", ret); | |
894 | goto err; | |
895 | } | |
3265f421 RH |
896 | } |
897 | ||
8f7e8762 | 898 | return 0; |
3265f421 RH |
899 | |
900 | err: | |
901 | if (priv->vddio) | |
902 | regulator_disable(priv->vddio); | |
903 | ||
904 | return ret; | |
2f664823 MW |
905 | } |
906 | ||
2318ca8a MW |
907 | static void at803x_remove(struct phy_device *phydev) |
908 | { | |
909 | struct at803x_priv *priv = phydev->priv; | |
910 | ||
911 | if (priv->vddio) | |
912 | regulator_disable(priv->vddio); | |
913 | } | |
914 | ||
b856150c DB |
915 | static int at803x_get_features(struct phy_device *phydev) |
916 | { | |
3265f421 | 917 | struct at803x_priv *priv = phydev->priv; |
b856150c DB |
918 | int err; |
919 | ||
920 | err = genphy_read_abilities(phydev); | |
921 | if (err) | |
922 | return err; | |
923 | ||
765c22aa LJ |
924 | if (phydev->drv->phy_id == QCA8081_PHY_ID) { |
925 | err = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_NG_EXTABLE); | |
926 | if (err < 0) | |
927 | return err; | |
928 | ||
929 | linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->supported, | |
930 | err & MDIO_PMA_NG_EXTABLE_2_5GBT); | |
931 | } | |
932 | ||
f5621a01 | 933 | if (phydev->drv->phy_id != ATH8031_PHY_ID) |
b856150c DB |
934 | return 0; |
935 | ||
936 | /* AR8031/AR8033 have different status registers | |
937 | * for copper and fiber operation. However, the | |
938 | * extended status register is the same for both | |
939 | * operation modes. | |
940 | * | |
941 | * As a result of that, ESTATUS_1000_XFULL is set | |
942 | * to 1 even when operating in copper TP mode. | |
943 | * | |
3265f421 RH |
944 | * Remove this mode from the supported link modes |
945 | * when not operating in 1000BaseX mode. | |
b856150c | 946 | */ |
3265f421 RH |
947 | if (!priv->is_1000basex) |
948 | linkmode_clear_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, | |
949 | phydev->supported); | |
950 | ||
b856150c DB |
951 | return 0; |
952 | } | |
953 | ||
390b4cad RK |
954 | static int at803x_smarteee_config(struct phy_device *phydev) |
955 | { | |
956 | struct at803x_priv *priv = phydev->priv; | |
957 | u16 mask = 0, val = 0; | |
958 | int ret; | |
959 | ||
960 | if (priv->flags & AT803X_DISABLE_SMARTEEE) | |
961 | return phy_modify_mmd(phydev, MDIO_MMD_PCS, | |
962 | AT803X_MMD3_SMARTEEE_CTL3, | |
963 | AT803X_MMD3_SMARTEEE_CTL3_LPI_EN, 0); | |
964 | ||
965 | if (priv->smarteee_lpi_tw_1g) { | |
966 | mask |= 0xff00; | |
967 | val |= priv->smarteee_lpi_tw_1g << 8; | |
968 | } | |
969 | if (priv->smarteee_lpi_tw_100m) { | |
970 | mask |= 0x00ff; | |
971 | val |= priv->smarteee_lpi_tw_100m; | |
972 | } | |
973 | if (!mask) | |
974 | return 0; | |
975 | ||
976 | ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_MMD3_SMARTEEE_CTL1, | |
977 | mask, val); | |
978 | if (ret) | |
979 | return ret; | |
980 | ||
981 | return phy_modify_mmd(phydev, MDIO_MMD_PCS, AT803X_MMD3_SMARTEEE_CTL3, | |
982 | AT803X_MMD3_SMARTEEE_CTL3_LPI_EN, | |
983 | AT803X_MMD3_SMARTEEE_CTL3_LPI_EN); | |
984 | } | |
985 | ||
2f664823 MW |
986 | static int at803x_clk_out_config(struct phy_device *phydev) |
987 | { | |
988 | struct at803x_priv *priv = phydev->priv; | |
2f664823 MW |
989 | |
990 | if (!priv->clk_25m_mask) | |
991 | return 0; | |
992 | ||
a45c1c10 RK |
993 | return phy_modify_mmd(phydev, MDIO_MMD_AN, AT803X_MMD7_CLK25M, |
994 | priv->clk_25m_mask, priv->clk_25m_reg); | |
2f664823 MW |
995 | } |
996 | ||
997 | static int at8031_pll_config(struct phy_device *phydev) | |
998 | { | |
999 | struct at803x_priv *priv = phydev->priv; | |
1000 | ||
1001 | /* The default after hardware reset is PLL OFF. After a soft reset, the | |
1002 | * values are retained. | |
1003 | */ | |
1004 | if (priv->flags & AT803X_KEEP_PLL_ENABLED) | |
1005 | return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F, | |
1006 | 0, AT803X_DEBUG_PLL_ON); | |
1007 | else | |
1008 | return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_1F, | |
1009 | AT803X_DEBUG_PLL_ON, 0); | |
1010 | } | |
1011 | ||
9ecf0401 WF |
1012 | static int at803x_hibernation_mode_config(struct phy_device *phydev) |
1013 | { | |
1014 | struct at803x_priv *priv = phydev->priv; | |
1015 | ||
1016 | /* The default after hardware reset is hibernation mode enabled. After | |
1017 | * software reset, the value is retained. | |
1018 | */ | |
1019 | if (!(priv->flags & AT803X_DISABLE_HIBERNATION_MODE)) | |
1020 | return 0; | |
1021 | ||
1022 | return at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL, | |
1023 | AT803X_DEBUG_HIB_CTRL_PS_HIB_EN, 0); | |
1024 | } | |
1025 | ||
0ca7111a MU |
1026 | static int at803x_config_init(struct phy_device *phydev) |
1027 | { | |
3265f421 | 1028 | struct at803x_priv *priv = phydev->priv; |
1ca6d1b1 | 1029 | int ret; |
0ca7111a | 1030 | |
4f3a00c7 RH |
1031 | if (phydev->drv->phy_id == ATH8031_PHY_ID) { |
1032 | /* Some bootloaders leave the fiber page selected. | |
3265f421 RH |
1033 | * Switch to the appropriate page (fiber or copper), as otherwise we |
1034 | * read the PHY capabilities from the wrong page. | |
4f3a00c7 RH |
1035 | */ |
1036 | phy_lock_mdio_bus(phydev); | |
3265f421 RH |
1037 | ret = at803x_write_page(phydev, |
1038 | priv->is_fiber ? AT803X_PAGE_FIBER : | |
1039 | AT803X_PAGE_COPPER); | |
4f3a00c7 RH |
1040 | phy_unlock_mdio_bus(phydev); |
1041 | if (ret) | |
1042 | return ret; | |
1043 | ||
1044 | ret = at8031_pll_config(phydev); | |
1045 | if (ret < 0) | |
1046 | return ret; | |
1047 | } | |
1048 | ||
6d4cd041 VK |
1049 | /* The RX and TX delay default is: |
1050 | * after HW reset: RX delay enabled and TX delay disabled | |
1051 | * after SW reset: RX delay enabled, while TX delay retains the | |
1052 | * value before reset. | |
6d4cd041 | 1053 | */ |
6d4cd041 | 1054 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || |
bb0ce4c1 | 1055 | phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) |
6d4cd041 | 1056 | ret = at803x_enable_rx_delay(phydev); |
bb0ce4c1 AD |
1057 | else |
1058 | ret = at803x_disable_rx_delay(phydev); | |
1059 | if (ret < 0) | |
1060 | return ret; | |
2e5f9f28 | 1061 | |
6d4cd041 | 1062 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || |
bb0ce4c1 | 1063 | phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) |
6d4cd041 | 1064 | ret = at803x_enable_tx_delay(phydev); |
bb0ce4c1 AD |
1065 | else |
1066 | ret = at803x_disable_tx_delay(phydev); | |
2f664823 MW |
1067 | if (ret < 0) |
1068 | return ret; | |
1ca6d1b1 | 1069 | |
390b4cad RK |
1070 | ret = at803x_smarteee_config(phydev); |
1071 | if (ret < 0) | |
1072 | return ret; | |
1073 | ||
2f664823 MW |
1074 | ret = at803x_clk_out_config(phydev); |
1075 | if (ret < 0) | |
1076 | return ret; | |
1077 | ||
9ecf0401 WF |
1078 | ret = at803x_hibernation_mode_config(phydev); |
1079 | if (ret < 0) | |
1080 | return ret; | |
1081 | ||
3c51fa5d RK |
1082 | /* Ar803x extended next page bit is enabled by default. Cisco |
1083 | * multigig switches read this bit and attempt to negotiate 10Gbps | |
1084 | * rates even if the next page bit is disabled. This is incorrect | |
1085 | * behaviour but we still need to accommodate it. XNP is only needed | |
1086 | * for 10Gbps support, so disable XNP. | |
1087 | */ | |
1088 | return phy_modify(phydev, MII_ADVERTISE, MDIO_AN_CTRL1_XNP, 0); | |
0ca7111a MU |
1089 | } |
1090 | ||
77a99394 ZQ |
1091 | static int at803x_ack_interrupt(struct phy_device *phydev) |
1092 | { | |
1093 | int err; | |
1094 | ||
a46bd63b | 1095 | err = phy_read(phydev, AT803X_INTR_STATUS); |
77a99394 ZQ |
1096 | |
1097 | return (err < 0) ? err : 0; | |
1098 | } | |
1099 | ||
1100 | static int at803x_config_intr(struct phy_device *phydev) | |
1101 | { | |
3265f421 | 1102 | struct at803x_priv *priv = phydev->priv; |
77a99394 ZQ |
1103 | int err; |
1104 | int value; | |
1105 | ||
a46bd63b | 1106 | value = phy_read(phydev, AT803X_INTR_ENABLE); |
77a99394 | 1107 | |
e6e4a556 | 1108 | if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { |
a3417885 IC |
1109 | /* Clear any pending interrupts */ |
1110 | err = at803x_ack_interrupt(phydev); | |
1111 | if (err) | |
1112 | return err; | |
1113 | ||
e6e4a556 MB |
1114 | value |= AT803X_INTR_ENABLE_AUTONEG_ERR; |
1115 | value |= AT803X_INTR_ENABLE_SPEED_CHANGED; | |
1116 | value |= AT803X_INTR_ENABLE_DUPLEX_CHANGED; | |
1117 | value |= AT803X_INTR_ENABLE_LINK_FAIL; | |
1118 | value |= AT803X_INTR_ENABLE_LINK_SUCCESS; | |
3265f421 RH |
1119 | if (priv->is_fiber) { |
1120 | value |= AT803X_INTR_ENABLE_LINK_FAIL_BX; | |
1121 | value |= AT803X_INTR_ENABLE_LINK_SUCCESS_BX; | |
1122 | } | |
e6e4a556 MB |
1123 | |
1124 | err = phy_write(phydev, AT803X_INTR_ENABLE, value); | |
a3417885 | 1125 | } else { |
a46bd63b | 1126 | err = phy_write(phydev, AT803X_INTR_ENABLE, 0); |
a3417885 IC |
1127 | if (err) |
1128 | return err; | |
1129 | ||
1130 | /* Clear any pending interrupts */ | |
1131 | err = at803x_ack_interrupt(phydev); | |
1132 | } | |
77a99394 ZQ |
1133 | |
1134 | return err; | |
1135 | } | |
1136 | ||
29773097 IC |
1137 | static irqreturn_t at803x_handle_interrupt(struct phy_device *phydev) |
1138 | { | |
1139 | int irq_status, int_enabled; | |
1140 | ||
1141 | irq_status = phy_read(phydev, AT803X_INTR_STATUS); | |
1142 | if (irq_status < 0) { | |
1143 | phy_error(phydev); | |
1144 | return IRQ_NONE; | |
1145 | } | |
1146 | ||
1147 | /* Read the current enabled interrupts */ | |
1148 | int_enabled = phy_read(phydev, AT803X_INTR_ENABLE); | |
1149 | if (int_enabled < 0) { | |
1150 | phy_error(phydev); | |
1151 | return IRQ_NONE; | |
1152 | } | |
1153 | ||
1154 | /* See if this was one of our enabled interrupts */ | |
1155 | if (!(irq_status & int_enabled)) | |
1156 | return IRQ_NONE; | |
1157 | ||
1158 | phy_trigger_machine(phydev); | |
1159 | ||
1160 | return IRQ_HANDLED; | |
1161 | } | |
1162 | ||
13a56b44 DM |
1163 | static void at803x_link_change_notify(struct phy_device *phydev) |
1164 | { | |
13a56b44 DM |
1165 | /* |
1166 | * Conduct a hardware reset for AT8030 every time a link loss is | |
1167 | * signalled. This is necessary to circumvent a hardware bug that | |
1168 | * occurs when the cable is unplugged while TX packets are pending | |
1169 | * in the FIFO. In such cases, the FIFO enters an error mode it | |
1170 | * cannot recover from by software. | |
1171 | */ | |
6110ed2d | 1172 | if (phydev->state == PHY_NOLINK && phydev->mdio.reset_gpio) { |
5c5f626b | 1173 | struct at803x_context context; |
a05d7dfc | 1174 | |
5c5f626b | 1175 | at803x_context_save(phydev, &context); |
a05d7dfc | 1176 | |
5c5f626b HK |
1177 | phy_device_reset(phydev, 1); |
1178 | msleep(1); | |
1179 | phy_device_reset(phydev, 0); | |
1180 | msleep(1); | |
a05d7dfc | 1181 | |
5c5f626b | 1182 | at803x_context_restore(phydev, &context); |
a05d7dfc | 1183 | |
5c5f626b | 1184 | phydev_dbg(phydev, "%s(): phy was reset\n", __func__); |
13a56b44 DM |
1185 | } |
1186 | } | |
1187 | ||
79c7bc05 | 1188 | static int at803x_read_specific_status(struct phy_device *phydev) |
06d5f344 | 1189 | { |
79c7bc05 | 1190 | int ss; |
06d5f344 RK |
1191 | |
1192 | /* Read the AT8035 PHY-Specific Status register, which indicates the | |
1193 | * speed and duplex that the PHY is actually using, irrespective of | |
1194 | * whether we are in autoneg mode or not. | |
1195 | */ | |
1196 | ss = phy_read(phydev, AT803X_SPECIFIC_STATUS); | |
1197 | if (ss < 0) | |
1198 | return ss; | |
1199 | ||
1200 | if (ss & AT803X_SS_SPEED_DUPLEX_RESOLVED) { | |
79c7bc05 | 1201 | int sfc, speed; |
7dce80c2 OR |
1202 | |
1203 | sfc = phy_read(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL); | |
1204 | if (sfc < 0) | |
1205 | return sfc; | |
1206 | ||
79c7bc05 LJ |
1207 | /* qca8081 takes the different bits for speed value from at803x */ |
1208 | if (phydev->drv->phy_id == QCA8081_PHY_ID) | |
1209 | speed = FIELD_GET(QCA808X_SS_SPEED_MASK, ss); | |
1210 | else | |
1211 | speed = FIELD_GET(AT803X_SS_SPEED_MASK, ss); | |
1212 | ||
1213 | switch (speed) { | |
06d5f344 RK |
1214 | case AT803X_SS_SPEED_10: |
1215 | phydev->speed = SPEED_10; | |
1216 | break; | |
1217 | case AT803X_SS_SPEED_100: | |
1218 | phydev->speed = SPEED_100; | |
1219 | break; | |
1220 | case AT803X_SS_SPEED_1000: | |
1221 | phydev->speed = SPEED_1000; | |
1222 | break; | |
79c7bc05 LJ |
1223 | case QCA808X_SS_SPEED_2500: |
1224 | phydev->speed = SPEED_2500; | |
1225 | break; | |
06d5f344 RK |
1226 | } |
1227 | if (ss & AT803X_SS_DUPLEX) | |
1228 | phydev->duplex = DUPLEX_FULL; | |
1229 | else | |
1230 | phydev->duplex = DUPLEX_HALF; | |
7dce80c2 | 1231 | |
06d5f344 RK |
1232 | if (ss & AT803X_SS_MDIX) |
1233 | phydev->mdix = ETH_TP_MDI_X; | |
1234 | else | |
1235 | phydev->mdix = ETH_TP_MDI; | |
7dce80c2 OR |
1236 | |
1237 | switch (FIELD_GET(AT803X_SFC_MDI_CROSSOVER_MODE_M, sfc)) { | |
1238 | case AT803X_SFC_MANUAL_MDI: | |
1239 | phydev->mdix_ctrl = ETH_TP_MDI; | |
1240 | break; | |
1241 | case AT803X_SFC_MANUAL_MDIX: | |
1242 | phydev->mdix_ctrl = ETH_TP_MDI_X; | |
1243 | break; | |
1244 | case AT803X_SFC_AUTOMATIC_CROSSOVER: | |
1245 | phydev->mdix_ctrl = ETH_TP_MDI_AUTO; | |
1246 | break; | |
1247 | } | |
06d5f344 RK |
1248 | } |
1249 | ||
79c7bc05 LJ |
1250 | return 0; |
1251 | } | |
1252 | ||
1253 | static int at803x_read_status(struct phy_device *phydev) | |
1254 | { | |
3265f421 | 1255 | struct at803x_priv *priv = phydev->priv; |
79c7bc05 LJ |
1256 | int err, old_link = phydev->link; |
1257 | ||
3265f421 RH |
1258 | if (priv->is_1000basex) |
1259 | return genphy_c37_read_status(phydev); | |
1260 | ||
79c7bc05 LJ |
1261 | /* Update the link, but return if there was an error */ |
1262 | err = genphy_update_link(phydev); | |
1263 | if (err) | |
1264 | return err; | |
1265 | ||
1266 | /* why bother the PHY if nothing can have changed */ | |
1267 | if (phydev->autoneg == AUTONEG_ENABLE && old_link && phydev->link) | |
1268 | return 0; | |
1269 | ||
1270 | phydev->speed = SPEED_UNKNOWN; | |
1271 | phydev->duplex = DUPLEX_UNKNOWN; | |
1272 | phydev->pause = 0; | |
1273 | phydev->asym_pause = 0; | |
1274 | ||
1275 | err = genphy_read_lpa(phydev); | |
1276 | if (err < 0) | |
1277 | return err; | |
1278 | ||
1279 | err = at803x_read_specific_status(phydev); | |
1280 | if (err < 0) | |
1281 | return err; | |
1282 | ||
06d5f344 RK |
1283 | if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete) |
1284 | phy_resolve_aneg_pause(phydev); | |
1285 | ||
1286 | return 0; | |
1287 | } | |
1288 | ||
7dce80c2 OR |
1289 | static int at803x_config_mdix(struct phy_device *phydev, u8 ctrl) |
1290 | { | |
1291 | u16 val; | |
1292 | ||
1293 | switch (ctrl) { | |
1294 | case ETH_TP_MDI: | |
1295 | val = AT803X_SFC_MANUAL_MDI; | |
1296 | break; | |
1297 | case ETH_TP_MDI_X: | |
1298 | val = AT803X_SFC_MANUAL_MDIX; | |
1299 | break; | |
1300 | case ETH_TP_MDI_AUTO: | |
1301 | val = AT803X_SFC_AUTOMATIC_CROSSOVER; | |
1302 | break; | |
1303 | default: | |
1304 | return 0; | |
1305 | } | |
1306 | ||
1307 | return phy_modify_changed(phydev, AT803X_SPECIFIC_FUNCTION_CONTROL, | |
1308 | AT803X_SFC_MDI_CROSSOVER_MODE_M, | |
1309 | FIELD_PREP(AT803X_SFC_MDI_CROSSOVER_MODE_M, val)); | |
1310 | } | |
1311 | ||
1312 | static int at803x_config_aneg(struct phy_device *phydev) | |
1313 | { | |
3265f421 | 1314 | struct at803x_priv *priv = phydev->priv; |
7dce80c2 OR |
1315 | int ret; |
1316 | ||
1317 | ret = at803x_config_mdix(phydev, phydev->mdix_ctrl); | |
1318 | if (ret < 0) | |
1319 | return ret; | |
1320 | ||
1321 | /* Changes of the midx bits are disruptive to the normal operation; | |
1322 | * therefore any changes to these registers must be followed by a | |
1323 | * software reset to take effect. | |
1324 | */ | |
1325 | if (ret == 1) { | |
1326 | ret = genphy_soft_reset(phydev); | |
1327 | if (ret < 0) | |
1328 | return ret; | |
1329 | } | |
1330 | ||
3265f421 RH |
1331 | if (priv->is_1000basex) |
1332 | return genphy_c37_config_aneg(phydev); | |
1333 | ||
f884d449 LJ |
1334 | /* Do not restart auto-negotiation by setting ret to 0 defautly, |
1335 | * when calling __genphy_config_aneg later. | |
1336 | */ | |
1337 | ret = 0; | |
1338 | ||
1339 | if (phydev->drv->phy_id == QCA8081_PHY_ID) { | |
1340 | int phy_ctrl = 0; | |
1341 | ||
1342 | /* The reg MII_BMCR also needs to be configured for force mode, the | |
1343 | * genphy_config_aneg is also needed. | |
1344 | */ | |
1345 | if (phydev->autoneg == AUTONEG_DISABLE) | |
1346 | genphy_c45_pma_setup_forced(phydev); | |
1347 | ||
1348 | if (linkmode_test_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->advertising)) | |
1349 | phy_ctrl = MDIO_AN_10GBT_CTRL_ADV2_5G; | |
1350 | ||
1351 | ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL, | |
1352 | MDIO_AN_10GBT_CTRL_ADV2_5G, phy_ctrl); | |
1353 | if (ret < 0) | |
1354 | return ret; | |
1355 | } | |
1356 | ||
1357 | return __genphy_config_aneg(phydev, ret); | |
7dce80c2 OR |
1358 | } |
1359 | ||
cde0f4f8 MW |
1360 | static int at803x_get_downshift(struct phy_device *phydev, u8 *d) |
1361 | { | |
1362 | int val; | |
1363 | ||
1364 | val = phy_read(phydev, AT803X_SMART_SPEED); | |
1365 | if (val < 0) | |
1366 | return val; | |
1367 | ||
1368 | if (val & AT803X_SMART_SPEED_ENABLE) | |
1369 | *d = FIELD_GET(AT803X_SMART_SPEED_RETRY_LIMIT_MASK, val) + 2; | |
1370 | else | |
1371 | *d = DOWNSHIFT_DEV_DISABLE; | |
1372 | ||
1373 | return 0; | |
1374 | } | |
1375 | ||
1376 | static int at803x_set_downshift(struct phy_device *phydev, u8 cnt) | |
1377 | { | |
1378 | u16 mask, set; | |
1379 | int ret; | |
1380 | ||
1381 | switch (cnt) { | |
1382 | case DOWNSHIFT_DEV_DEFAULT_COUNT: | |
1383 | cnt = AT803X_DEFAULT_DOWNSHIFT; | |
1384 | fallthrough; | |
1385 | case AT803X_MIN_DOWNSHIFT ... AT803X_MAX_DOWNSHIFT: | |
1386 | set = AT803X_SMART_SPEED_ENABLE | | |
1387 | AT803X_SMART_SPEED_BYPASS_TIMER | | |
1388 | FIELD_PREP(AT803X_SMART_SPEED_RETRY_LIMIT_MASK, cnt - 2); | |
1389 | mask = AT803X_SMART_SPEED_RETRY_LIMIT_MASK; | |
1390 | break; | |
1391 | case DOWNSHIFT_DEV_DISABLE: | |
1392 | set = 0; | |
1393 | mask = AT803X_SMART_SPEED_ENABLE | | |
1394 | AT803X_SMART_SPEED_BYPASS_TIMER; | |
1395 | break; | |
1396 | default: | |
1397 | return -EINVAL; | |
1398 | } | |
1399 | ||
1400 | ret = phy_modify_changed(phydev, AT803X_SMART_SPEED, mask, set); | |
1401 | ||
1402 | /* After changing the smart speed settings, we need to perform a | |
1403 | * software reset, use phy_init_hw() to make sure we set the | |
1404 | * reapply any values which might got lost during software reset. | |
1405 | */ | |
1406 | if (ret == 1) | |
1407 | ret = phy_init_hw(phydev); | |
1408 | ||
1409 | return ret; | |
1410 | } | |
1411 | ||
1412 | static int at803x_get_tunable(struct phy_device *phydev, | |
1413 | struct ethtool_tunable *tuna, void *data) | |
1414 | { | |
1415 | switch (tuna->id) { | |
1416 | case ETHTOOL_PHY_DOWNSHIFT: | |
1417 | return at803x_get_downshift(phydev, data); | |
1418 | default: | |
1419 | return -EOPNOTSUPP; | |
1420 | } | |
1421 | } | |
1422 | ||
1423 | static int at803x_set_tunable(struct phy_device *phydev, | |
1424 | struct ethtool_tunable *tuna, const void *data) | |
1425 | { | |
1426 | switch (tuna->id) { | |
1427 | case ETHTOOL_PHY_DOWNSHIFT: | |
1428 | return at803x_set_downshift(phydev, *(const u8 *)data); | |
1429 | default: | |
1430 | return -EOPNOTSUPP; | |
1431 | } | |
1432 | } | |
1433 | ||
6cb75767 MW |
1434 | static int at803x_cable_test_result_trans(u16 status) |
1435 | { | |
1436 | switch (FIELD_GET(AT803X_CDT_STATUS_STAT_MASK, status)) { | |
1437 | case AT803X_CDT_STATUS_STAT_NORMAL: | |
1438 | return ETHTOOL_A_CABLE_RESULT_CODE_OK; | |
1439 | case AT803X_CDT_STATUS_STAT_SHORT: | |
1440 | return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT; | |
1441 | case AT803X_CDT_STATUS_STAT_OPEN: | |
1442 | return ETHTOOL_A_CABLE_RESULT_CODE_OPEN; | |
1443 | case AT803X_CDT_STATUS_STAT_FAIL: | |
1444 | default: | |
1445 | return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC; | |
1446 | } | |
1447 | } | |
1448 | ||
1449 | static bool at803x_cdt_test_failed(u16 status) | |
1450 | { | |
1451 | return FIELD_GET(AT803X_CDT_STATUS_STAT_MASK, status) == | |
1452 | AT803X_CDT_STATUS_STAT_FAIL; | |
1453 | } | |
1454 | ||
1455 | static bool at803x_cdt_fault_length_valid(u16 status) | |
1456 | { | |
1457 | switch (FIELD_GET(AT803X_CDT_STATUS_STAT_MASK, status)) { | |
1458 | case AT803X_CDT_STATUS_STAT_OPEN: | |
1459 | case AT803X_CDT_STATUS_STAT_SHORT: | |
1460 | return true; | |
1461 | } | |
1462 | return false; | |
1463 | } | |
1464 | ||
1465 | static int at803x_cdt_fault_length(u16 status) | |
1466 | { | |
1467 | int dt; | |
1468 | ||
1469 | /* According to the datasheet the distance to the fault is | |
1470 | * DELTA_TIME * 0.824 meters. | |
1471 | * | |
1472 | * The author suspect the correct formula is: | |
1473 | * | |
1474 | * fault_distance = DELTA_TIME * (c * VF) / 125MHz / 2 | |
1475 | * | |
1476 | * where c is the speed of light, VF is the velocity factor of | |
1477 | * the twisted pair cable, 125MHz the counter frequency and | |
1478 | * we need to divide by 2 because the hardware will measure the | |
1479 | * round trip time to the fault and back to the PHY. | |
1480 | * | |
1481 | * With a VF of 0.69 we get the factor 0.824 mentioned in the | |
1482 | * datasheet. | |
1483 | */ | |
1484 | dt = FIELD_GET(AT803X_CDT_STATUS_DELTA_TIME_MASK, status); | |
1485 | ||
1486 | return (dt * 824) / 10; | |
1487 | } | |
1488 | ||
1489 | static int at803x_cdt_start(struct phy_device *phydev, int pair) | |
1490 | { | |
1491 | u16 cdt; | |
1492 | ||
8c84d752 LJ |
1493 | /* qca8081 takes the different bit 15 to enable CDT test */ |
1494 | if (phydev->drv->phy_id == QCA8081_PHY_ID) | |
1495 | cdt = QCA808X_CDT_ENABLE_TEST | | |
1496 | QCA808X_CDT_LENGTH_UNIT | | |
1497 | QCA808X_CDT_INTER_CHECK_DIS; | |
1498 | else | |
1499 | cdt = FIELD_PREP(AT803X_CDT_MDI_PAIR_MASK, pair) | | |
1500 | AT803X_CDT_ENABLE_TEST; | |
6cb75767 MW |
1501 | |
1502 | return phy_write(phydev, AT803X_CDT, cdt); | |
1503 | } | |
1504 | ||
1505 | static int at803x_cdt_wait_for_completion(struct phy_device *phydev) | |
1506 | { | |
1507 | int val, ret; | |
8c84d752 LJ |
1508 | u16 cdt_en; |
1509 | ||
1510 | if (phydev->drv->phy_id == QCA8081_PHY_ID) | |
1511 | cdt_en = QCA808X_CDT_ENABLE_TEST; | |
1512 | else | |
1513 | cdt_en = AT803X_CDT_ENABLE_TEST; | |
6cb75767 MW |
1514 | |
1515 | /* One test run takes about 25ms */ | |
1516 | ret = phy_read_poll_timeout(phydev, AT803X_CDT, val, | |
8c84d752 | 1517 | !(val & cdt_en), |
6cb75767 MW |
1518 | 30000, 100000, true); |
1519 | ||
1520 | return ret < 0 ? ret : 0; | |
1521 | } | |
1522 | ||
1523 | static int at803x_cable_test_one_pair(struct phy_device *phydev, int pair) | |
1524 | { | |
1525 | static const int ethtool_pair[] = { | |
1526 | ETHTOOL_A_CABLE_PAIR_A, | |
1527 | ETHTOOL_A_CABLE_PAIR_B, | |
1528 | ETHTOOL_A_CABLE_PAIR_C, | |
1529 | ETHTOOL_A_CABLE_PAIR_D, | |
1530 | }; | |
1531 | int ret, val; | |
1532 | ||
1533 | ret = at803x_cdt_start(phydev, pair); | |
1534 | if (ret) | |
1535 | return ret; | |
1536 | ||
1537 | ret = at803x_cdt_wait_for_completion(phydev); | |
1538 | if (ret) | |
1539 | return ret; | |
1540 | ||
1541 | val = phy_read(phydev, AT803X_CDT_STATUS); | |
1542 | if (val < 0) | |
1543 | return val; | |
1544 | ||
1545 | if (at803x_cdt_test_failed(val)) | |
1546 | return 0; | |
1547 | ||
1548 | ethnl_cable_test_result(phydev, ethtool_pair[pair], | |
1549 | at803x_cable_test_result_trans(val)); | |
1550 | ||
1551 | if (at803x_cdt_fault_length_valid(val)) | |
1552 | ethnl_cable_test_fault_length(phydev, ethtool_pair[pair], | |
1553 | at803x_cdt_fault_length(val)); | |
1554 | ||
1555 | return 1; | |
1556 | } | |
1557 | ||
1558 | static int at803x_cable_test_get_status(struct phy_device *phydev, | |
1559 | bool *finished) | |
1560 | { | |
dc0f3ed1 | 1561 | unsigned long pair_mask; |
6cb75767 MW |
1562 | int retries = 20; |
1563 | int pair, ret; | |
1564 | ||
dc0f3ed1 | 1565 | if (phydev->phy_id == ATH9331_PHY_ID || |
fada2ce0 DB |
1566 | phydev->phy_id == ATH8032_PHY_ID || |
1567 | phydev->phy_id == QCA9561_PHY_ID) | |
dc0f3ed1 OR |
1568 | pair_mask = 0x3; |
1569 | else | |
1570 | pair_mask = 0xf; | |
1571 | ||
6cb75767 MW |
1572 | *finished = false; |
1573 | ||
1574 | /* According to the datasheet the CDT can be performed when | |
1575 | * there is no link partner or when the link partner is | |
1576 | * auto-negotiating. Starting the test will restart the AN | |
1577 | * automatically. It seems that doing this repeatedly we will | |
1578 | * get a slot where our link partner won't disturb our | |
1579 | * measurement. | |
1580 | */ | |
1581 | while (pair_mask && retries--) { | |
1582 | for_each_set_bit(pair, &pair_mask, 4) { | |
1583 | ret = at803x_cable_test_one_pair(phydev, pair); | |
1584 | if (ret < 0) | |
1585 | return ret; | |
1586 | if (ret) | |
1587 | clear_bit(pair, &pair_mask); | |
1588 | } | |
1589 | if (pair_mask) | |
1590 | msleep(250); | |
1591 | } | |
1592 | ||
1593 | *finished = true; | |
1594 | ||
1595 | return 0; | |
1596 | } | |
1597 | ||
1598 | static int at803x_cable_test_start(struct phy_device *phydev) | |
1599 | { | |
1600 | /* Enable auto-negotiation, but advertise no capabilities, no link | |
1601 | * will be established. A restart of the auto-negotiation is not | |
1602 | * required, because the cable test will automatically break the link. | |
1603 | */ | |
1604 | phy_write(phydev, MII_BMCR, BMCR_ANENABLE); | |
1605 | phy_write(phydev, MII_ADVERTISE, ADVERTISE_CSMA); | |
dc0f3ed1 | 1606 | if (phydev->phy_id != ATH9331_PHY_ID && |
fada2ce0 DB |
1607 | phydev->phy_id != ATH8032_PHY_ID && |
1608 | phydev->phy_id != QCA9561_PHY_ID) | |
dc0f3ed1 | 1609 | phy_write(phydev, MII_CTRL1000, 0); |
6cb75767 MW |
1610 | |
1611 | /* we do all the (time consuming) work later */ | |
1612 | return 0; | |
1613 | } | |
1614 | ||
272833b9 AS |
1615 | static int qca83xx_config_init(struct phy_device *phydev) |
1616 | { | |
1617 | u8 switch_revision; | |
1618 | ||
1619 | switch_revision = phydev->dev_flags & QCA8K_DEVFLAGS_REVISION_MASK; | |
1620 | ||
1621 | switch (switch_revision) { | |
1622 | case 1: | |
1623 | /* For 100M waveform */ | |
67999555 | 1624 | at803x_debug_reg_write(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, 0x02ea); |
272833b9 | 1625 | /* Turn on Gigabit clock */ |
67999555 | 1626 | at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x68a0); |
272833b9 AS |
1627 | break; |
1628 | ||
1629 | case 2: | |
1630 | phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0x0); | |
1631 | fallthrough; | |
1632 | case 4: | |
1633 | phy_write_mmd(phydev, MDIO_MMD_PCS, MDIO_AZ_DEBUG, 0x803f); | |
67999555 AS |
1634 | at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_GREEN, 0x6860); |
1635 | at803x_debug_reg_write(phydev, AT803X_DEBUG_SYSTEM_CTRL_MODE, 0x2c46); | |
272833b9 AS |
1636 | at803x_debug_reg_write(phydev, AT803X_DEBUG_REG_3C, 0x6000); |
1637 | break; | |
1638 | } | |
1639 | ||
1ca83119 AS |
1640 | /* QCA8327 require DAC amplitude adjustment for 100m set to +6%. |
1641 | * Disable on init and enable only with 100m speed following | |
1642 | * qca original source code. | |
1643 | */ | |
1644 | if (phydev->drv->phy_id == QCA8327_A_PHY_ID || | |
1645 | phydev->drv->phy_id == QCA8327_B_PHY_ID) | |
67999555 | 1646 | at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, |
1ca83119 AS |
1647 | QCA8327_DEBUG_MANU_CTRL_EN, 0); |
1648 | ||
9d1c29b4 AS |
1649 | /* Following original QCA sourcecode set port to prefer master */ |
1650 | phy_set_bits(phydev, MII_CTRL1000, CTL1000_PREFER_MASTER); | |
1651 | ||
272833b9 AS |
1652 | return 0; |
1653 | } | |
1654 | ||
1ca83119 AS |
1655 | static void qca83xx_link_change_notify(struct phy_device *phydev) |
1656 | { | |
1657 | /* QCA8337 doesn't require DAC Amplitude adjustement */ | |
1658 | if (phydev->drv->phy_id == QCA8337_PHY_ID) | |
1659 | return; | |
1660 | ||
1661 | /* Set DAC Amplitude adjustment to +6% for 100m on link running */ | |
1662 | if (phydev->state == PHY_RUNNING) { | |
1663 | if (phydev->speed == SPEED_100) | |
67999555 | 1664 | at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, |
1ca83119 AS |
1665 | QCA8327_DEBUG_MANU_CTRL_EN, |
1666 | QCA8327_DEBUG_MANU_CTRL_EN); | |
1667 | } else { | |
1668 | /* Reset DAC Amplitude adjustment */ | |
67999555 | 1669 | at803x_debug_reg_mask(phydev, AT803X_DEBUG_ANALOG_TEST_CTRL, |
1ca83119 AS |
1670 | QCA8327_DEBUG_MANU_CTRL_EN, 0); |
1671 | } | |
1672 | } | |
1673 | ||
ba3c01ee AS |
1674 | static int qca83xx_resume(struct phy_device *phydev) |
1675 | { | |
1676 | int ret, val; | |
1677 | ||
1678 | /* Skip reset if not suspended */ | |
1679 | if (!phydev->suspended) | |
1680 | return 0; | |
1681 | ||
1682 | /* Reinit the port, reset values set by suspend */ | |
1683 | qca83xx_config_init(phydev); | |
1684 | ||
1685 | /* Reset the port on port resume */ | |
1686 | phy_set_bits(phydev, MII_BMCR, BMCR_RESET | BMCR_ANENABLE); | |
1687 | ||
1688 | /* On resume from suspend the switch execute a reset and | |
1689 | * restart auto-negotiation. Wait for reset to complete. | |
1690 | */ | |
1691 | ret = phy_read_poll_timeout(phydev, MII_BMCR, val, !(val & BMCR_RESET), | |
1692 | 50000, 600000, true); | |
1693 | if (ret) | |
1694 | return ret; | |
1695 | ||
1696 | msleep(1); | |
1697 | ||
1698 | return 0; | |
1699 | } | |
1700 | ||
1701 | static int qca83xx_suspend(struct phy_device *phydev) | |
1702 | { | |
1703 | u16 mask = 0; | |
1704 | ||
1705 | /* Only QCA8337 support actual suspend. | |
1706 | * QCA8327 cause port unreliability when phy suspend | |
1707 | * is set. | |
1708 | */ | |
1709 | if (phydev->drv->phy_id == QCA8337_PHY_ID) { | |
1710 | genphy_suspend(phydev); | |
1711 | } else { | |
1712 | mask |= ~(BMCR_SPEED1000 | BMCR_FULLDPLX); | |
1713 | phy_modify(phydev, MII_BMCR, mask, 0); | |
1714 | } | |
1715 | ||
67999555 | 1716 | at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_GREEN, |
ba3c01ee AS |
1717 | AT803X_DEBUG_GATE_CLK_IN1000, 0); |
1718 | ||
1719 | at803x_debug_reg_mask(phydev, AT803X_DEBUG_REG_HIB_CTRL, | |
1720 | AT803X_DEBUG_HIB_CTRL_EN_ANY_CHANGE | | |
1721 | AT803X_DEBUG_HIB_CTRL_SEL_RST_80U, 0); | |
1722 | ||
1723 | return 0; | |
1724 | } | |
1725 | ||
2acdd43f LJ |
1726 | static int qca808x_phy_fast_retrain_config(struct phy_device *phydev) |
1727 | { | |
1728 | int ret; | |
1729 | ||
1730 | /* Enable fast retrain */ | |
1731 | ret = genphy_c45_fast_retrain(phydev, true); | |
1732 | if (ret) | |
1733 | return ret; | |
1734 | ||
1735 | phy_write_mmd(phydev, MDIO_MMD_AN, QCA808X_PHY_MMD7_TOP_OPTION1, | |
1736 | QCA808X_TOP_OPTION1_DATA); | |
1737 | phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_20DB, | |
1738 | QCA808X_MSE_THRESHOLD_20DB_VALUE); | |
1739 | phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_17DB, | |
1740 | QCA808X_MSE_THRESHOLD_17DB_VALUE); | |
1741 | phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_27DB, | |
1742 | QCA808X_MSE_THRESHOLD_27DB_VALUE); | |
1743 | phy_write_mmd(phydev, MDIO_MMD_PMAPMD, QCA808X_PHY_MMD1_MSE_THRESHOLD_28DB, | |
1744 | QCA808X_MSE_THRESHOLD_28DB_VALUE); | |
1745 | phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_1, | |
1746 | QCA808X_MMD3_DEBUG_1_VALUE); | |
1747 | phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_4, | |
1748 | QCA808X_MMD3_DEBUG_4_VALUE); | |
1749 | phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_5, | |
1750 | QCA808X_MMD3_DEBUG_5_VALUE); | |
1751 | phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_3, | |
1752 | QCA808X_MMD3_DEBUG_3_VALUE); | |
1753 | phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_6, | |
1754 | QCA808X_MMD3_DEBUG_6_VALUE); | |
1755 | phy_write_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_DEBUG_2, | |
1756 | QCA808X_MMD3_DEBUG_2_VALUE); | |
1757 | ||
1758 | return 0; | |
1759 | } | |
1760 | ||
9d4dae29 LJ |
1761 | static int qca808x_phy_ms_random_seed_set(struct phy_device *phydev) |
1762 | { | |
8032bf12 | 1763 | u16 seed_value = get_random_u32_below(QCA808X_MASTER_SLAVE_SEED_RANGE); |
9d4dae29 LJ |
1764 | |
1765 | return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED, | |
1766 | QCA808X_MASTER_SLAVE_SEED_CFG, | |
1767 | FIELD_PREP(QCA808X_MASTER_SLAVE_SEED_CFG, seed_value)); | |
1768 | } | |
1769 | ||
1770 | static int qca808x_phy_ms_seed_enable(struct phy_device *phydev, bool enable) | |
1771 | { | |
1772 | u16 seed_enable = 0; | |
1773 | ||
1774 | if (enable) | |
1775 | seed_enable = QCA808X_MASTER_SLAVE_SEED_ENABLE; | |
1776 | ||
1777 | return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_LOCAL_SEED, | |
1778 | QCA808X_MASTER_SLAVE_SEED_ENABLE, seed_enable); | |
1779 | } | |
1780 | ||
2acdd43f LJ |
1781 | static int qca808x_config_init(struct phy_device *phydev) |
1782 | { | |
1783 | int ret; | |
1784 | ||
1785 | /* Active adc&vga on 802.3az for the link 1000M and 100M */ | |
1786 | ret = phy_modify_mmd(phydev, MDIO_MMD_PCS, QCA808X_PHY_MMD3_ADDR_CLD_CTRL7, | |
1787 | QCA808X_8023AZ_AFE_CTRL_MASK, QCA808X_8023AZ_AFE_EN); | |
1788 | if (ret) | |
1789 | return ret; | |
1790 | ||
1791 | /* Adjust the threshold on 802.3az for the link 1000M */ | |
1792 | ret = phy_write_mmd(phydev, MDIO_MMD_PCS, | |
1793 | QCA808X_PHY_MMD3_AZ_TRAINING_CTRL, QCA808X_MMD3_AZ_TRAINING_VAL); | |
1794 | if (ret) | |
1795 | return ret; | |
1796 | ||
1797 | /* Config the fast retrain for the link 2500M */ | |
1798 | ret = qca808x_phy_fast_retrain_config(phydev); | |
1799 | if (ret) | |
1800 | return ret; | |
1801 | ||
9d4dae29 LJ |
1802 | /* Configure lower ramdom seed to make phy linked as slave mode */ |
1803 | ret = qca808x_phy_ms_random_seed_set(phydev); | |
1804 | if (ret) | |
1805 | return ret; | |
1806 | ||
1807 | /* Enable seed */ | |
1808 | ret = qca808x_phy_ms_seed_enable(phydev, true); | |
1809 | if (ret) | |
1810 | return ret; | |
1811 | ||
2acdd43f LJ |
1812 | /* Configure adc threshold as 100mv for the link 10M */ |
1813 | return at803x_debug_reg_mask(phydev, QCA808X_PHY_DEBUG_ADC_THRESHOLD, | |
1814 | QCA808X_ADC_THRESHOLD_MASK, QCA808X_ADC_THRESHOLD_100MV); | |
1815 | } | |
1816 | ||
79c7bc05 LJ |
1817 | static int qca808x_read_status(struct phy_device *phydev) |
1818 | { | |
1819 | int ret; | |
1820 | ||
1821 | ret = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_STAT); | |
1822 | if (ret < 0) | |
1823 | return ret; | |
1824 | ||
1825 | linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, phydev->lp_advertising, | |
1826 | ret & MDIO_AN_10GBT_STAT_LP2_5G); | |
1827 | ||
1828 | ret = genphy_read_status(phydev); | |
1829 | if (ret) | |
1830 | return ret; | |
1831 | ||
1832 | ret = at803x_read_specific_status(phydev); | |
1833 | if (ret < 0) | |
1834 | return ret; | |
1835 | ||
881cc731 JM |
1836 | if (phydev->link) { |
1837 | if (phydev->speed == SPEED_2500) | |
1838 | phydev->interface = PHY_INTERFACE_MODE_2500BASEX; | |
1839 | else | |
1840 | phydev->interface = PHY_INTERFACE_MODE_SGMII; | |
1841 | } else { | |
1842 | /* generate seed as a lower random value to make PHY linked as SLAVE easily, | |
1843 | * except for master/slave configuration fault detected. | |
1844 | * the reason for not putting this code into the function link_change_notify is | |
1845 | * the corner case where the link partner is also the qca8081 PHY and the seed | |
1846 | * value is configured as the same value, the link can't be up and no link change | |
1847 | * occurs. | |
1848 | */ | |
8bc1c543 LJ |
1849 | if (phydev->master_slave_state == MASTER_SLAVE_STATE_ERR) { |
1850 | qca808x_phy_ms_seed_enable(phydev, false); | |
1851 | } else { | |
1852 | qca808x_phy_ms_random_seed_set(phydev); | |
1853 | qca808x_phy_ms_seed_enable(phydev, true); | |
1854 | } | |
1855 | } | |
1856 | ||
79c7bc05 LJ |
1857 | return 0; |
1858 | } | |
1859 | ||
9d4dae29 LJ |
1860 | static int qca808x_soft_reset(struct phy_device *phydev) |
1861 | { | |
1862 | int ret; | |
1863 | ||
1864 | ret = genphy_soft_reset(phydev); | |
1865 | if (ret < 0) | |
1866 | return ret; | |
1867 | ||
1868 | return qca808x_phy_ms_seed_enable(phydev, true); | |
1869 | } | |
1870 | ||
8c84d752 LJ |
1871 | static bool qca808x_cdt_fault_length_valid(int cdt_code) |
1872 | { | |
1873 | switch (cdt_code) { | |
1874 | case QCA808X_CDT_STATUS_STAT_SHORT: | |
1875 | case QCA808X_CDT_STATUS_STAT_OPEN: | |
1876 | return true; | |
1877 | default: | |
1878 | return false; | |
1879 | } | |
1880 | } | |
1881 | ||
1882 | static int qca808x_cable_test_result_trans(int cdt_code) | |
1883 | { | |
1884 | switch (cdt_code) { | |
1885 | case QCA808X_CDT_STATUS_STAT_NORMAL: | |
1886 | return ETHTOOL_A_CABLE_RESULT_CODE_OK; | |
1887 | case QCA808X_CDT_STATUS_STAT_SHORT: | |
1888 | return ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT; | |
1889 | case QCA808X_CDT_STATUS_STAT_OPEN: | |
1890 | return ETHTOOL_A_CABLE_RESULT_CODE_OPEN; | |
1891 | case QCA808X_CDT_STATUS_STAT_FAIL: | |
1892 | default: | |
1893 | return ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC; | |
1894 | } | |
1895 | } | |
1896 | ||
1897 | static int qca808x_cdt_fault_length(struct phy_device *phydev, int pair) | |
1898 | { | |
1899 | int val; | |
1900 | u32 cdt_length_reg = 0; | |
1901 | ||
1902 | switch (pair) { | |
1903 | case ETHTOOL_A_CABLE_PAIR_A: | |
1904 | cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_A; | |
1905 | break; | |
1906 | case ETHTOOL_A_CABLE_PAIR_B: | |
1907 | cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_B; | |
1908 | break; | |
1909 | case ETHTOOL_A_CABLE_PAIR_C: | |
1910 | cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_C; | |
1911 | break; | |
1912 | case ETHTOOL_A_CABLE_PAIR_D: | |
1913 | cdt_length_reg = QCA808X_MMD3_CDT_DIAG_PAIR_D; | |
1914 | break; | |
1915 | default: | |
1916 | return -EINVAL; | |
1917 | } | |
1918 | ||
1919 | val = phy_read_mmd(phydev, MDIO_MMD_PCS, cdt_length_reg); | |
1920 | if (val < 0) | |
1921 | return val; | |
1922 | ||
1923 | return (FIELD_GET(QCA808X_CDT_DIAG_LENGTH, val) * 824) / 10; | |
1924 | } | |
1925 | ||
1926 | static int qca808x_cable_test_start(struct phy_device *phydev) | |
1927 | { | |
1928 | int ret; | |
1929 | ||
1930 | /* perform CDT with the following configs: | |
1931 | * 1. disable hibernation. | |
1932 | * 2. force PHY working in MDI mode. | |
1933 | * 3. for PHY working in 1000BaseT. | |
1934 | * 4. configure the threshold. | |
1935 | */ | |
1936 | ||
1937 | ret = at803x_debug_reg_mask(phydev, QCA808X_DBG_AN_TEST, QCA808X_HIBERNATION_EN, 0); | |
1938 | if (ret < 0) | |
1939 | return ret; | |
1940 | ||
1941 | ret = at803x_config_mdix(phydev, ETH_TP_MDI); | |
1942 | if (ret < 0) | |
1943 | return ret; | |
1944 | ||
1945 | /* Force 1000base-T needs to configure PMA/PMD and MII_BMCR */ | |
1946 | phydev->duplex = DUPLEX_FULL; | |
1947 | phydev->speed = SPEED_1000; | |
1948 | ret = genphy_c45_pma_setup_forced(phydev); | |
1949 | if (ret < 0) | |
1950 | return ret; | |
1951 | ||
1952 | ret = genphy_setup_forced(phydev); | |
1953 | if (ret < 0) | |
1954 | return ret; | |
1955 | ||
1956 | /* configure the thresholds for open, short, pair ok test */ | |
1957 | phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8074, 0xc040); | |
1958 | phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8076, 0xc040); | |
1959 | phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8077, 0xa060); | |
1960 | phy_write_mmd(phydev, MDIO_MMD_PCS, 0x8078, 0xc050); | |
1961 | phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807a, 0xc060); | |
1962 | phy_write_mmd(phydev, MDIO_MMD_PCS, 0x807e, 0xb060); | |
1963 | ||
1964 | return 0; | |
1965 | } | |
1966 | ||
1967 | static int qca808x_cable_test_get_status(struct phy_device *phydev, bool *finished) | |
1968 | { | |
1969 | int ret, val; | |
1970 | int pair_a, pair_b, pair_c, pair_d; | |
1971 | ||
1972 | *finished = false; | |
1973 | ||
1974 | ret = at803x_cdt_start(phydev, 0); | |
1975 | if (ret) | |
1976 | return ret; | |
1977 | ||
1978 | ret = at803x_cdt_wait_for_completion(phydev); | |
1979 | if (ret) | |
1980 | return ret; | |
1981 | ||
1982 | val = phy_read_mmd(phydev, MDIO_MMD_PCS, QCA808X_MMD3_CDT_STATUS); | |
1983 | if (val < 0) | |
1984 | return val; | |
1985 | ||
1986 | pair_a = FIELD_GET(QCA808X_CDT_CODE_PAIR_A, val); | |
1987 | pair_b = FIELD_GET(QCA808X_CDT_CODE_PAIR_B, val); | |
1988 | pair_c = FIELD_GET(QCA808X_CDT_CODE_PAIR_C, val); | |
1989 | pair_d = FIELD_GET(QCA808X_CDT_CODE_PAIR_D, val); | |
1990 | ||
1991 | ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_A, | |
1992 | qca808x_cable_test_result_trans(pair_a)); | |
1993 | ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_B, | |
1994 | qca808x_cable_test_result_trans(pair_b)); | |
1995 | ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_C, | |
1996 | qca808x_cable_test_result_trans(pair_c)); | |
1997 | ethnl_cable_test_result(phydev, ETHTOOL_A_CABLE_PAIR_D, | |
1998 | qca808x_cable_test_result_trans(pair_d)); | |
1999 | ||
2000 | if (qca808x_cdt_fault_length_valid(pair_a)) | |
2001 | ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_A, | |
2002 | qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_A)); | |
2003 | if (qca808x_cdt_fault_length_valid(pair_b)) | |
2004 | ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_B, | |
2005 | qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_B)); | |
2006 | if (qca808x_cdt_fault_length_valid(pair_c)) | |
2007 | ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_C, | |
2008 | qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_C)); | |
2009 | if (qca808x_cdt_fault_length_valid(pair_d)) | |
2010 | ethnl_cable_test_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_D, | |
2011 | qca808x_cdt_fault_length(phydev, ETHTOOL_A_CABLE_PAIR_D)); | |
2012 | ||
2013 | *finished = true; | |
2014 | ||
2015 | return 0; | |
2016 | } | |
2017 | ||
317420ab M |
2018 | static struct phy_driver at803x_driver[] = { |
2019 | { | |
96c36712 | 2020 | /* Qualcomm Atheros AR8035 */ |
0465d8f8 | 2021 | PHY_ID_MATCH_EXACT(ATH8035_PHY_ID), |
96c36712 | 2022 | .name = "Qualcomm Atheros AR8035", |
6cb75767 | 2023 | .flags = PHY_POLL_CABLE_TEST, |
2f664823 | 2024 | .probe = at803x_probe, |
2318ca8a | 2025 | .remove = at803x_remove, |
7dce80c2 | 2026 | .config_aneg = at803x_config_aneg, |
13a56b44 | 2027 | .config_init = at803x_config_init, |
cde0f4f8 | 2028 | .soft_reset = genphy_soft_reset, |
13a56b44 DM |
2029 | .set_wol = at803x_set_wol, |
2030 | .get_wol = at803x_get_wol, | |
2031 | .suspend = at803x_suspend, | |
2032 | .resume = at803x_resume, | |
dcdecdcf | 2033 | /* PHY_GBIT_FEATURES */ |
06d5f344 | 2034 | .read_status = at803x_read_status, |
0eae5982 | 2035 | .config_intr = at803x_config_intr, |
29773097 | 2036 | .handle_interrupt = at803x_handle_interrupt, |
cde0f4f8 MW |
2037 | .get_tunable = at803x_get_tunable, |
2038 | .set_tunable = at803x_set_tunable, | |
6cb75767 MW |
2039 | .cable_test_start = at803x_cable_test_start, |
2040 | .cable_test_get_status = at803x_cable_test_get_status, | |
317420ab | 2041 | }, { |
96c36712 | 2042 | /* Qualcomm Atheros AR8030 */ |
13a56b44 | 2043 | .phy_id = ATH8030_PHY_ID, |
96c36712 | 2044 | .name = "Qualcomm Atheros AR8030", |
0465d8f8 | 2045 | .phy_id_mask = AT8030_PHY_ID_MASK, |
2f664823 | 2046 | .probe = at803x_probe, |
2318ca8a | 2047 | .remove = at803x_remove, |
13a56b44 DM |
2048 | .config_init = at803x_config_init, |
2049 | .link_change_notify = at803x_link_change_notify, | |
2050 | .set_wol = at803x_set_wol, | |
2051 | .get_wol = at803x_get_wol, | |
2052 | .suspend = at803x_suspend, | |
2053 | .resume = at803x_resume, | |
dcdecdcf | 2054 | /* PHY_BASIC_FEATURES */ |
0eae5982 | 2055 | .config_intr = at803x_config_intr, |
29773097 | 2056 | .handle_interrupt = at803x_handle_interrupt, |
05d7cce8 | 2057 | }, { |
96c36712 | 2058 | /* Qualcomm Atheros AR8031/AR8033 */ |
0465d8f8 | 2059 | PHY_ID_MATCH_EXACT(ATH8031_PHY_ID), |
96c36712 | 2060 | .name = "Qualcomm Atheros AR8031/AR8033", |
6cb75767 | 2061 | .flags = PHY_POLL_CABLE_TEST, |
2f664823 | 2062 | .probe = at803x_probe, |
2318ca8a | 2063 | .remove = at803x_remove, |
13a56b44 | 2064 | .config_init = at803x_config_init, |
63477a5d | 2065 | .config_aneg = at803x_config_aneg, |
cde0f4f8 | 2066 | .soft_reset = genphy_soft_reset, |
13a56b44 DM |
2067 | .set_wol = at803x_set_wol, |
2068 | .get_wol = at803x_get_wol, | |
2069 | .suspend = at803x_suspend, | |
2070 | .resume = at803x_resume, | |
c329e5af DB |
2071 | .read_page = at803x_read_page, |
2072 | .write_page = at803x_write_page, | |
b856150c | 2073 | .get_features = at803x_get_features, |
06d5f344 | 2074 | .read_status = at803x_read_status, |
13a56b44 | 2075 | .config_intr = &at803x_config_intr, |
29773097 | 2076 | .handle_interrupt = at803x_handle_interrupt, |
cde0f4f8 MW |
2077 | .get_tunable = at803x_get_tunable, |
2078 | .set_tunable = at803x_set_tunable, | |
6cb75767 MW |
2079 | .cable_test_start = at803x_cable_test_start, |
2080 | .cable_test_get_status = at803x_cable_test_get_status, | |
5800091a DB |
2081 | }, { |
2082 | /* Qualcomm Atheros AR8032 */ | |
2083 | PHY_ID_MATCH_EXACT(ATH8032_PHY_ID), | |
2084 | .name = "Qualcomm Atheros AR8032", | |
2085 | .probe = at803x_probe, | |
2086 | .remove = at803x_remove, | |
dc0f3ed1 | 2087 | .flags = PHY_POLL_CABLE_TEST, |
5800091a DB |
2088 | .config_init = at803x_config_init, |
2089 | .link_change_notify = at803x_link_change_notify, | |
2090 | .set_wol = at803x_set_wol, | |
2091 | .get_wol = at803x_get_wol, | |
2092 | .suspend = at803x_suspend, | |
2093 | .resume = at803x_resume, | |
2094 | /* PHY_BASIC_FEATURES */ | |
5800091a | 2095 | .config_intr = at803x_config_intr, |
29773097 | 2096 | .handle_interrupt = at803x_handle_interrupt, |
dc0f3ed1 OR |
2097 | .cable_test_start = at803x_cable_test_start, |
2098 | .cable_test_get_status = at803x_cable_test_get_status, | |
7908d2ce OR |
2099 | }, { |
2100 | /* ATHEROS AR9331 */ | |
2101 | PHY_ID_MATCH_EXACT(ATH9331_PHY_ID), | |
96c36712 | 2102 | .name = "Qualcomm Atheros AR9331 built-in PHY", |
9926de73 OR |
2103 | .probe = at803x_probe, |
2104 | .remove = at803x_remove, | |
7908d2ce OR |
2105 | .suspend = at803x_suspend, |
2106 | .resume = at803x_resume, | |
dc0f3ed1 | 2107 | .flags = PHY_POLL_CABLE_TEST, |
7908d2ce | 2108 | /* PHY_BASIC_FEATURES */ |
7908d2ce | 2109 | .config_intr = &at803x_config_intr, |
29773097 | 2110 | .handle_interrupt = at803x_handle_interrupt, |
dc0f3ed1 OR |
2111 | .cable_test_start = at803x_cable_test_start, |
2112 | .cable_test_get_status = at803x_cable_test_get_status, | |
7dce80c2 OR |
2113 | .read_status = at803x_read_status, |
2114 | .soft_reset = genphy_soft_reset, | |
2115 | .config_aneg = at803x_config_aneg, | |
fada2ce0 DB |
2116 | }, { |
2117 | /* Qualcomm Atheros QCA9561 */ | |
2118 | PHY_ID_MATCH_EXACT(QCA9561_PHY_ID), | |
2119 | .name = "Qualcomm Atheros QCA9561 built-in PHY", | |
9926de73 OR |
2120 | .probe = at803x_probe, |
2121 | .remove = at803x_remove, | |
fada2ce0 DB |
2122 | .suspend = at803x_suspend, |
2123 | .resume = at803x_resume, | |
2124 | .flags = PHY_POLL_CABLE_TEST, | |
2125 | /* PHY_BASIC_FEATURES */ | |
2126 | .config_intr = &at803x_config_intr, | |
2127 | .handle_interrupt = at803x_handle_interrupt, | |
2128 | .cable_test_start = at803x_cable_test_start, | |
2129 | .cable_test_get_status = at803x_cable_test_get_status, | |
2130 | .read_status = at803x_read_status, | |
2131 | .soft_reset = genphy_soft_reset, | |
2132 | .config_aneg = at803x_config_aneg, | |
272833b9 AS |
2133 | }, { |
2134 | /* QCA8337 */ | |
d44fd860 AS |
2135 | .phy_id = QCA8337_PHY_ID, |
2136 | .phy_id_mask = QCA8K_PHY_ID_MASK, | |
2137 | .name = "Qualcomm Atheros 8337 internal PHY", | |
272833b9 | 2138 | /* PHY_GBIT_FEATURES */ |
1ca83119 | 2139 | .link_change_notify = qca83xx_link_change_notify, |
d44fd860 AS |
2140 | .probe = at803x_probe, |
2141 | .flags = PHY_IS_INTERNAL, | |
2142 | .config_init = qca83xx_config_init, | |
2143 | .soft_reset = genphy_soft_reset, | |
2144 | .get_sset_count = at803x_get_sset_count, | |
2145 | .get_strings = at803x_get_strings, | |
2146 | .get_stats = at803x_get_stats, | |
ba3c01ee AS |
2147 | .suspend = qca83xx_suspend, |
2148 | .resume = qca83xx_resume, | |
0ccf8511 | 2149 | }, { |
b4df02b5 | 2150 | /* QCA8327-A from switch QCA8327-AL1A */ |
d44fd860 AS |
2151 | .phy_id = QCA8327_A_PHY_ID, |
2152 | .phy_id_mask = QCA8K_PHY_ID_MASK, | |
2153 | .name = "Qualcomm Atheros 8327-A internal PHY", | |
b4df02b5 | 2154 | /* PHY_GBIT_FEATURES */ |
1ca83119 | 2155 | .link_change_notify = qca83xx_link_change_notify, |
d44fd860 AS |
2156 | .probe = at803x_probe, |
2157 | .flags = PHY_IS_INTERNAL, | |
2158 | .config_init = qca83xx_config_init, | |
2159 | .soft_reset = genphy_soft_reset, | |
2160 | .get_sset_count = at803x_get_sset_count, | |
2161 | .get_strings = at803x_get_strings, | |
2162 | .get_stats = at803x_get_stats, | |
ba3c01ee AS |
2163 | .suspend = qca83xx_suspend, |
2164 | .resume = qca83xx_resume, | |
b4df02b5 AS |
2165 | }, { |
2166 | /* QCA8327-B from switch QCA8327-BL1A */ | |
d44fd860 AS |
2167 | .phy_id = QCA8327_B_PHY_ID, |
2168 | .phy_id_mask = QCA8K_PHY_ID_MASK, | |
2169 | .name = "Qualcomm Atheros 8327-B internal PHY", | |
0ccf8511 | 2170 | /* PHY_GBIT_FEATURES */ |
1ca83119 | 2171 | .link_change_notify = qca83xx_link_change_notify, |
d44fd860 AS |
2172 | .probe = at803x_probe, |
2173 | .flags = PHY_IS_INTERNAL, | |
2174 | .config_init = qca83xx_config_init, | |
2175 | .soft_reset = genphy_soft_reset, | |
2176 | .get_sset_count = at803x_get_sset_count, | |
2177 | .get_strings = at803x_get_strings, | |
2178 | .get_stats = at803x_get_stats, | |
ba3c01ee AS |
2179 | .suspend = qca83xx_suspend, |
2180 | .resume = qca83xx_resume, | |
daf61732 LJ |
2181 | }, { |
2182 | /* Qualcomm QCA8081 */ | |
2183 | PHY_ID_MATCH_EXACT(QCA8081_PHY_ID), | |
2184 | .name = "Qualcomm QCA8081", | |
8c84d752 | 2185 | .flags = PHY_POLL_CABLE_TEST, |
9926de73 OR |
2186 | .probe = at803x_probe, |
2187 | .remove = at803x_remove, | |
daf61732 LJ |
2188 | .config_intr = at803x_config_intr, |
2189 | .handle_interrupt = at803x_handle_interrupt, | |
2190 | .get_tunable = at803x_get_tunable, | |
2191 | .set_tunable = at803x_set_tunable, | |
2192 | .set_wol = at803x_set_wol, | |
2193 | .get_wol = at803x_get_wol, | |
765c22aa | 2194 | .get_features = at803x_get_features, |
f884d449 | 2195 | .config_aneg = at803x_config_aneg, |
daf61732 LJ |
2196 | .suspend = genphy_suspend, |
2197 | .resume = genphy_resume, | |
79c7bc05 | 2198 | .read_status = qca808x_read_status, |
2acdd43f | 2199 | .config_init = qca808x_config_init, |
9d4dae29 | 2200 | .soft_reset = qca808x_soft_reset, |
8c84d752 LJ |
2201 | .cable_test_start = qca808x_cable_test_start, |
2202 | .cable_test_get_status = qca808x_cable_test_get_status, | |
272833b9 | 2203 | }, }; |
0ca7111a | 2204 | |
50fd7150 | 2205 | module_phy_driver(at803x_driver); |
0ca7111a MU |
2206 | |
2207 | static struct mdio_device_id __maybe_unused atheros_tbl[] = { | |
0465d8f8 MW |
2208 | { ATH8030_PHY_ID, AT8030_PHY_ID_MASK }, |
2209 | { PHY_ID_MATCH_EXACT(ATH8031_PHY_ID) }, | |
5800091a | 2210 | { PHY_ID_MATCH_EXACT(ATH8032_PHY_ID) }, |
0465d8f8 | 2211 | { PHY_ID_MATCH_EXACT(ATH8035_PHY_ID) }, |
7908d2ce | 2212 | { PHY_ID_MATCH_EXACT(ATH9331_PHY_ID) }, |
0ccf8511 | 2213 | { PHY_ID_MATCH_EXACT(QCA8337_PHY_ID) }, |
b4df02b5 AS |
2214 | { PHY_ID_MATCH_EXACT(QCA8327_A_PHY_ID) }, |
2215 | { PHY_ID_MATCH_EXACT(QCA8327_B_PHY_ID) }, | |
fada2ce0 | 2216 | { PHY_ID_MATCH_EXACT(QCA9561_PHY_ID) }, |
daf61732 | 2217 | { PHY_ID_MATCH_EXACT(QCA8081_PHY_ID) }, |
0ca7111a MU |
2218 | { } |
2219 | }; | |
2220 | ||
2221 | MODULE_DEVICE_TABLE(mdio, atheros_tbl); |