hc
2024-05-10 748e4f3d702def1a4bff191e0cf93b6a05340f01
kernel/drivers/net/phy/dp83867.c
....@@ -1,16 +1,7 @@
1
-/*
2
- * Driver for the Texas Instruments DP83867 PHY
1
+// SPDX-License-Identifier: GPL-2.0
2
+/* Driver for the Texas Instruments DP83867 PHY
33 *
44 * Copyright (C) 2015 Texas Instruments Inc.
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
145 */
156
167 #include <linux/ethtool.h>
....@@ -19,6 +10,10 @@
1910 #include <linux/module.h>
2011 #include <linux/of.h>
2112 #include <linux/phy.h>
13
+#include <linux/delay.h>
14
+#include <linux/netdevice.h>
15
+#include <linux/etherdevice.h>
16
+#include <linux/bitfield.h>
2217
2318 #include <dt-bindings/net/ti-dp83867.h>
2419
....@@ -26,13 +21,16 @@
2621 #define DP83867_DEVADDR 0x1f
2722
2823 #define MII_DP83867_PHYCTRL 0x10
24
+#define MII_DP83867_PHYSTS 0x11
2925 #define MII_DP83867_MICR 0x12
3026 #define MII_DP83867_ISR 0x13
31
-#define DP83867_CTRL 0x1f
27
+#define DP83867_CFG2 0x14
3228 #define DP83867_CFG3 0x1e
29
+#define DP83867_CTRL 0x1f
3330
3431 /* Extended Registers */
35
-#define DP83867_CFG4 0x0031
32
+#define DP83867_FLD_THR_CFG 0x002e
33
+#define DP83867_CFG4 0x0031
3634 #define DP83867_CFG4_SGMII_ANEG_MASK (BIT(5) | BIT(6))
3735 #define DP83867_CFG4_SGMII_ANEG_TIMER_11MS (3 << 5)
3836 #define DP83867_CFG4_SGMII_ANEG_TIMER_800US (2 << 5)
....@@ -41,16 +39,23 @@
4139
4240 #define DP83867_RGMIICTL 0x0032
4341 #define DP83867_STRAP_STS1 0x006E
42
+#define DP83867_STRAP_STS2 0x006f
4443 #define DP83867_RGMIIDCTL 0x0086
44
+#define DP83867_DSP_FFE_CFG 0x012c
45
+#define DP83867_RXFCFG 0x0134
46
+#define DP83867_RXFPMD1 0x0136
47
+#define DP83867_RXFPMD2 0x0137
48
+#define DP83867_RXFPMD3 0x0138
49
+#define DP83867_RXFSOP1 0x0139
50
+#define DP83867_RXFSOP2 0x013A
51
+#define DP83867_RXFSOP3 0x013B
4552 #define DP83867_IO_MUX_CFG 0x0170
53
+#define DP83867_SGMIICTL 0x00D3
4654 #define DP83867_10M_SGMII_CFG 0x016F
4755 #define DP83867_10M_SGMII_RATE_ADAPT_MASK BIT(7)
4856
4957 #define DP83867_SW_RESET BIT(15)
5058 #define DP83867_SW_RESTART BIT(14)
51
-
52
-/* PHYCTRL bits */
53
-#define MII_DP83867_PHYCTRL_FORCE_LINK_GOOD BIT(10)
5459
5560 /* MICR Interrupt bits */
5661 #define MII_DP83867_MICR_AN_ERR_INT_EN BIT(15)
....@@ -70,24 +75,70 @@
7075 #define DP83867_RGMII_TX_CLK_DELAY_EN BIT(1)
7176 #define DP83867_RGMII_RX_CLK_DELAY_EN BIT(0)
7277
78
+/* SGMIICTL bits */
79
+#define DP83867_SGMII_TYPE BIT(14)
80
+
81
+/* RXFCFG bits*/
82
+#define DP83867_WOL_MAGIC_EN BIT(0)
83
+#define DP83867_WOL_BCAST_EN BIT(2)
84
+#define DP83867_WOL_UCAST_EN BIT(4)
85
+#define DP83867_WOL_SEC_EN BIT(5)
86
+#define DP83867_WOL_ENH_MAC BIT(7)
87
+
7388 /* STRAP_STS1 bits */
7489 #define DP83867_STRAP_STS1_RESERVED BIT(11)
7590
91
+/* STRAP_STS2 bits */
92
+#define DP83867_STRAP_STS2_CLK_SKEW_TX_MASK GENMASK(6, 4)
93
+#define DP83867_STRAP_STS2_CLK_SKEW_TX_SHIFT 4
94
+#define DP83867_STRAP_STS2_CLK_SKEW_RX_MASK GENMASK(2, 0)
95
+#define DP83867_STRAP_STS2_CLK_SKEW_RX_SHIFT 0
96
+#define DP83867_STRAP_STS2_CLK_SKEW_NONE BIT(2)
97
+#define DP83867_STRAP_STS2_STRAP_FLD BIT(10)
98
+
7699 /* PHY CTRL bits */
77
-#define DP83867_PHYCR_FIFO_DEPTH_SHIFT 14
78
-#define DP83867_PHYCR_FIFO_DEPTH_MASK (3 << 14)
100
+#define DP83867_PHYCR_TX_FIFO_DEPTH_SHIFT 14
101
+#define DP83867_PHYCR_RX_FIFO_DEPTH_SHIFT 12
102
+#define DP83867_PHYCR_FIFO_DEPTH_MAX 0x03
103
+#define DP83867_PHYCR_TX_FIFO_DEPTH_MASK GENMASK(15, 14)
104
+#define DP83867_PHYCR_RX_FIFO_DEPTH_MASK GENMASK(13, 12)
79105 #define DP83867_PHYCR_RESERVED_MASK BIT(11)
106
+#define DP83867_PHYCR_FORCE_LINK_GOOD BIT(10)
80107
81108 /* RGMIIDCTL bits */
109
+#define DP83867_RGMII_TX_CLK_DELAY_MAX 0xf
82110 #define DP83867_RGMII_TX_CLK_DELAY_SHIFT 4
111
+#define DP83867_RGMII_TX_CLK_DELAY_INV (DP83867_RGMII_TX_CLK_DELAY_MAX + 1)
112
+#define DP83867_RGMII_RX_CLK_DELAY_MAX 0xf
113
+#define DP83867_RGMII_RX_CLK_DELAY_SHIFT 0
114
+#define DP83867_RGMII_RX_CLK_DELAY_INV (DP83867_RGMII_RX_CLK_DELAY_MAX + 1)
83115
84116 /* IO_MUX_CFG bits */
85
-#define DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL 0x1f
86
-
117
+#define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MASK 0x1f
87118 #define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX 0x0
88119 #define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN 0x1f
120
+#define DP83867_IO_MUX_CFG_CLK_O_DISABLE BIT(6)
89121 #define DP83867_IO_MUX_CFG_CLK_O_SEL_MASK (0x1f << 8)
90122 #define DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT 8
123
+
124
+/* PHY STS bits */
125
+#define DP83867_PHYSTS_1000 BIT(15)
126
+#define DP83867_PHYSTS_100 BIT(14)
127
+#define DP83867_PHYSTS_DUPLEX BIT(13)
128
+#define DP83867_PHYSTS_LINK BIT(10)
129
+
130
+/* CFG2 bits */
131
+#define DP83867_DOWNSHIFT_EN (BIT(8) | BIT(9))
132
+#define DP83867_DOWNSHIFT_ATTEMPT_MASK (BIT(10) | BIT(11))
133
+#define DP83867_DOWNSHIFT_1_COUNT_VAL 0
134
+#define DP83867_DOWNSHIFT_2_COUNT_VAL 1
135
+#define DP83867_DOWNSHIFT_4_COUNT_VAL 2
136
+#define DP83867_DOWNSHIFT_8_COUNT_VAL 3
137
+#define DP83867_DOWNSHIFT_1_COUNT 1
138
+#define DP83867_DOWNSHIFT_2_COUNT 2
139
+#define DP83867_DOWNSHIFT_4_COUNT 4
140
+#define DP83867_DOWNSHIFT_8_COUNT 8
141
+#define DP83867_SGMII_AUTONEG_EN BIT(7)
91142
92143 /* CFG3 bits */
93144 #define DP83867_CFG3_INT_OE BIT(7)
....@@ -96,6 +147,9 @@
96147 /* CFG4 bits */
97148 #define DP83867_CFG4_PORT_MIRROR_EN BIT(0)
98149
150
+/* FLD_THR_CFG */
151
+#define DP83867_FLD_THR_CFG_ENERGY_LOST_THR_MASK 0x7
152
+
99153 enum {
100154 DP83867_PORT_MIRROING_KEEP,
101155 DP83867_PORT_MIRROING_EN,
....@@ -103,13 +157,16 @@
103157 };
104158
105159 struct dp83867_private {
106
- int rx_id_delay;
107
- int tx_id_delay;
108
- int fifo_depth;
160
+ u32 rx_id_delay;
161
+ u32 tx_id_delay;
162
+ u32 tx_fifo_depth;
163
+ u32 rx_fifo_depth;
109164 int io_impedance;
110165 int port_mirroring;
111166 bool rxctrl_strap_quirk;
112
- int clk_output_sel;
167
+ bool set_clk_output;
168
+ u32 clk_output_sel;
169
+ bool sgmii_ref_clk_en;
113170 };
114171
115172 static int dp83867_ack_interrupt(struct phy_device *phydev)
....@@ -120,6 +177,115 @@
120177 return err;
121178
122179 return 0;
180
+}
181
+
182
+static int dp83867_set_wol(struct phy_device *phydev,
183
+ struct ethtool_wolinfo *wol)
184
+{
185
+ struct net_device *ndev = phydev->attached_dev;
186
+ u16 val_rxcfg, val_micr;
187
+ u8 *mac;
188
+
189
+ val_rxcfg = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_RXFCFG);
190
+ val_micr = phy_read(phydev, MII_DP83867_MICR);
191
+
192
+ if (wol->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE | WAKE_UCAST |
193
+ WAKE_BCAST)) {
194
+ val_rxcfg |= DP83867_WOL_ENH_MAC;
195
+ val_micr |= MII_DP83867_MICR_WOL_INT_EN;
196
+
197
+ if (wol->wolopts & WAKE_MAGIC) {
198
+ mac = (u8 *)ndev->dev_addr;
199
+
200
+ if (!is_valid_ether_addr(mac))
201
+ return -EINVAL;
202
+
203
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFPMD1,
204
+ (mac[1] << 8 | mac[0]));
205
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFPMD2,
206
+ (mac[3] << 8 | mac[2]));
207
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFPMD3,
208
+ (mac[5] << 8 | mac[4]));
209
+
210
+ val_rxcfg |= DP83867_WOL_MAGIC_EN;
211
+ } else {
212
+ val_rxcfg &= ~DP83867_WOL_MAGIC_EN;
213
+ }
214
+
215
+ if (wol->wolopts & WAKE_MAGICSECURE) {
216
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFSOP1,
217
+ (wol->sopass[1] << 8) | wol->sopass[0]);
218
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFSOP2,
219
+ (wol->sopass[3] << 8) | wol->sopass[2]);
220
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFSOP3,
221
+ (wol->sopass[5] << 8) | wol->sopass[4]);
222
+
223
+ val_rxcfg |= DP83867_WOL_SEC_EN;
224
+ } else {
225
+ val_rxcfg &= ~DP83867_WOL_SEC_EN;
226
+ }
227
+
228
+ if (wol->wolopts & WAKE_UCAST)
229
+ val_rxcfg |= DP83867_WOL_UCAST_EN;
230
+ else
231
+ val_rxcfg &= ~DP83867_WOL_UCAST_EN;
232
+
233
+ if (wol->wolopts & WAKE_BCAST)
234
+ val_rxcfg |= DP83867_WOL_BCAST_EN;
235
+ else
236
+ val_rxcfg &= ~DP83867_WOL_BCAST_EN;
237
+ } else {
238
+ val_rxcfg &= ~DP83867_WOL_ENH_MAC;
239
+ val_micr &= ~MII_DP83867_MICR_WOL_INT_EN;
240
+ }
241
+
242
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RXFCFG, val_rxcfg);
243
+ phy_write(phydev, MII_DP83867_MICR, val_micr);
244
+
245
+ return 0;
246
+}
247
+
248
+static void dp83867_get_wol(struct phy_device *phydev,
249
+ struct ethtool_wolinfo *wol)
250
+{
251
+ u16 value, sopass_val;
252
+
253
+ wol->supported = (WAKE_UCAST | WAKE_BCAST | WAKE_MAGIC |
254
+ WAKE_MAGICSECURE);
255
+ wol->wolopts = 0;
256
+
257
+ value = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_RXFCFG);
258
+
259
+ if (value & DP83867_WOL_UCAST_EN)
260
+ wol->wolopts |= WAKE_UCAST;
261
+
262
+ if (value & DP83867_WOL_BCAST_EN)
263
+ wol->wolopts |= WAKE_BCAST;
264
+
265
+ if (value & DP83867_WOL_MAGIC_EN)
266
+ wol->wolopts |= WAKE_MAGIC;
267
+
268
+ if (value & DP83867_WOL_SEC_EN) {
269
+ sopass_val = phy_read_mmd(phydev, DP83867_DEVADDR,
270
+ DP83867_RXFSOP1);
271
+ wol->sopass[0] = (sopass_val & 0xff);
272
+ wol->sopass[1] = (sopass_val >> 8);
273
+
274
+ sopass_val = phy_read_mmd(phydev, DP83867_DEVADDR,
275
+ DP83867_RXFSOP2);
276
+ wol->sopass[2] = (sopass_val & 0xff);
277
+ wol->sopass[3] = (sopass_val >> 8);
278
+
279
+ sopass_val = phy_read_mmd(phydev, DP83867_DEVADDR,
280
+ DP83867_RXFSOP3);
281
+ wol->sopass[4] = (sopass_val & 0xff);
282
+ wol->sopass[5] = (sopass_val >> 8);
283
+
284
+ wol->wolopts |= WAKE_MAGICSECURE;
285
+ }
286
+
287
+ if (!(value & DP83867_WOL_ENH_MAC))
288
+ wol->wolopts = 0;
123289 }
124290
125291 static int dp83867_config_intr(struct phy_device *phydev)
....@@ -146,25 +312,183 @@
146312 return phy_write(phydev, MII_DP83867_MICR, micr_status);
147313 }
148314
149
-static int dp83867_config_port_mirroring(struct phy_device *phydev)
315
+static int dp83867_read_status(struct phy_device *phydev)
150316 {
151
- struct dp83867_private *dp83867 =
152
- (struct dp83867_private *)phydev->priv;
153
- u16 val;
317
+ int status = phy_read(phydev, MII_DP83867_PHYSTS);
318
+ int ret;
154319
155
- val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4);
320
+ ret = genphy_read_status(phydev);
321
+ if (ret)
322
+ return ret;
156323
157
- if (dp83867->port_mirroring == DP83867_PORT_MIRROING_EN)
158
- val |= DP83867_CFG4_PORT_MIRROR_EN;
324
+ if (status < 0)
325
+ return status;
326
+
327
+ if (status & DP83867_PHYSTS_DUPLEX)
328
+ phydev->duplex = DUPLEX_FULL;
159329 else
160
- val &= ~DP83867_CFG4_PORT_MIRROR_EN;
330
+ phydev->duplex = DUPLEX_HALF;
161331
162
- phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4, val);
332
+ if (status & DP83867_PHYSTS_1000)
333
+ phydev->speed = SPEED_1000;
334
+ else if (status & DP83867_PHYSTS_100)
335
+ phydev->speed = SPEED_100;
336
+ else
337
+ phydev->speed = SPEED_10;
163338
164339 return 0;
165340 }
166341
167
-#ifdef CONFIG_OF_MDIO
342
+static int dp83867_get_downshift(struct phy_device *phydev, u8 *data)
343
+{
344
+ int val, cnt, enable, count;
345
+
346
+ val = phy_read(phydev, DP83867_CFG2);
347
+ if (val < 0)
348
+ return val;
349
+
350
+ enable = FIELD_GET(DP83867_DOWNSHIFT_EN, val);
351
+ cnt = FIELD_GET(DP83867_DOWNSHIFT_ATTEMPT_MASK, val);
352
+
353
+ switch (cnt) {
354
+ case DP83867_DOWNSHIFT_1_COUNT_VAL:
355
+ count = DP83867_DOWNSHIFT_1_COUNT;
356
+ break;
357
+ case DP83867_DOWNSHIFT_2_COUNT_VAL:
358
+ count = DP83867_DOWNSHIFT_2_COUNT;
359
+ break;
360
+ case DP83867_DOWNSHIFT_4_COUNT_VAL:
361
+ count = DP83867_DOWNSHIFT_4_COUNT;
362
+ break;
363
+ case DP83867_DOWNSHIFT_8_COUNT_VAL:
364
+ count = DP83867_DOWNSHIFT_8_COUNT;
365
+ break;
366
+ default:
367
+ return -EINVAL;
368
+ }
369
+
370
+ *data = enable ? count : DOWNSHIFT_DEV_DISABLE;
371
+
372
+ return 0;
373
+}
374
+
375
+static int dp83867_set_downshift(struct phy_device *phydev, u8 cnt)
376
+{
377
+ int val, count;
378
+
379
+ if (cnt > DP83867_DOWNSHIFT_8_COUNT)
380
+ return -E2BIG;
381
+
382
+ if (!cnt)
383
+ return phy_clear_bits(phydev, DP83867_CFG2,
384
+ DP83867_DOWNSHIFT_EN);
385
+
386
+ switch (cnt) {
387
+ case DP83867_DOWNSHIFT_1_COUNT:
388
+ count = DP83867_DOWNSHIFT_1_COUNT_VAL;
389
+ break;
390
+ case DP83867_DOWNSHIFT_2_COUNT:
391
+ count = DP83867_DOWNSHIFT_2_COUNT_VAL;
392
+ break;
393
+ case DP83867_DOWNSHIFT_4_COUNT:
394
+ count = DP83867_DOWNSHIFT_4_COUNT_VAL;
395
+ break;
396
+ case DP83867_DOWNSHIFT_8_COUNT:
397
+ count = DP83867_DOWNSHIFT_8_COUNT_VAL;
398
+ break;
399
+ default:
400
+ phydev_err(phydev,
401
+ "Downshift count must be 1, 2, 4 or 8\n");
402
+ return -EINVAL;
403
+ }
404
+
405
+ val = DP83867_DOWNSHIFT_EN;
406
+ val |= FIELD_PREP(DP83867_DOWNSHIFT_ATTEMPT_MASK, count);
407
+
408
+ return phy_modify(phydev, DP83867_CFG2,
409
+ DP83867_DOWNSHIFT_EN | DP83867_DOWNSHIFT_ATTEMPT_MASK,
410
+ val);
411
+}
412
+
413
+static int dp83867_get_tunable(struct phy_device *phydev,
414
+ struct ethtool_tunable *tuna, void *data)
415
+{
416
+ switch (tuna->id) {
417
+ case ETHTOOL_PHY_DOWNSHIFT:
418
+ return dp83867_get_downshift(phydev, data);
419
+ default:
420
+ return -EOPNOTSUPP;
421
+ }
422
+}
423
+
424
+static int dp83867_set_tunable(struct phy_device *phydev,
425
+ struct ethtool_tunable *tuna, const void *data)
426
+{
427
+ switch (tuna->id) {
428
+ case ETHTOOL_PHY_DOWNSHIFT:
429
+ return dp83867_set_downshift(phydev, *(const u8 *)data);
430
+ default:
431
+ return -EOPNOTSUPP;
432
+ }
433
+}
434
+
435
+static int dp83867_config_port_mirroring(struct phy_device *phydev)
436
+{
437
+ struct dp83867_private *dp83867 =
438
+ (struct dp83867_private *)phydev->priv;
439
+
440
+ if (dp83867->port_mirroring == DP83867_PORT_MIRROING_EN)
441
+ phy_set_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4,
442
+ DP83867_CFG4_PORT_MIRROR_EN);
443
+ else
444
+ phy_clear_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4,
445
+ DP83867_CFG4_PORT_MIRROR_EN);
446
+ return 0;
447
+}
448
+
449
+static int dp83867_verify_rgmii_cfg(struct phy_device *phydev)
450
+{
451
+ struct dp83867_private *dp83867 = phydev->priv;
452
+
453
+ /* Existing behavior was to use default pin strapping delay in rgmii
454
+ * mode, but rgmii should have meant no delay. Warn existing users.
455
+ */
456
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
457
+ const u16 val = phy_read_mmd(phydev, DP83867_DEVADDR,
458
+ DP83867_STRAP_STS2);
459
+ const u16 txskew = (val & DP83867_STRAP_STS2_CLK_SKEW_TX_MASK) >>
460
+ DP83867_STRAP_STS2_CLK_SKEW_TX_SHIFT;
461
+ const u16 rxskew = (val & DP83867_STRAP_STS2_CLK_SKEW_RX_MASK) >>
462
+ DP83867_STRAP_STS2_CLK_SKEW_RX_SHIFT;
463
+
464
+ if (txskew != DP83867_STRAP_STS2_CLK_SKEW_NONE ||
465
+ rxskew != DP83867_STRAP_STS2_CLK_SKEW_NONE)
466
+ phydev_warn(phydev,
467
+ "PHY has delays via pin strapping, but phy-mode = 'rgmii'\n"
468
+ "Should be 'rgmii-id' to use internal delays txskew:%x rxskew:%x\n",
469
+ txskew, rxskew);
470
+ }
471
+
472
+ /* RX delay *must* be specified if internal delay of RX is used. */
473
+ if ((phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
474
+ phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) &&
475
+ dp83867->rx_id_delay == DP83867_RGMII_RX_CLK_DELAY_INV) {
476
+ phydev_err(phydev, "ti,rx-internal-delay must be specified\n");
477
+ return -EINVAL;
478
+ }
479
+
480
+ /* TX delay *must* be specified if internal delay of TX is used. */
481
+ if ((phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
482
+ phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) &&
483
+ dp83867->tx_id_delay == DP83867_RGMII_TX_CLK_DELAY_INV) {
484
+ phydev_err(phydev, "ti,tx-internal-delay must be specified\n");
485
+ return -EINVAL;
486
+ }
487
+
488
+ return 0;
489
+}
490
+
491
+#if IS_ENABLED(CONFIG_OF_MDIO)
168492 static int dp83867_of_init(struct phy_device *phydev)
169493 {
170494 struct dp83867_private *dp83867 = phydev->priv;
....@@ -175,38 +499,55 @@
175499 if (!of_node)
176500 return -ENODEV;
177501
178
- dp83867->io_impedance = -EINVAL;
179
-
180502 /* Optional configuration */
181503 ret = of_property_read_u32(of_node, "ti,clk-output-sel",
182504 &dp83867->clk_output_sel);
183
- if (ret || dp83867->clk_output_sel > DP83867_CLK_O_SEL_REF_CLK)
184
- /* Keep the default value if ti,clk-output-sel is not set
185
- * or too high
505
+ /* If not set, keep default */
506
+ if (!ret) {
507
+ dp83867->set_clk_output = true;
508
+ /* Valid values are 0 to DP83867_CLK_O_SEL_REF_CLK or
509
+ * DP83867_CLK_O_SEL_OFF.
186510 */
187
- dp83867->clk_output_sel = DP83867_CLK_O_SEL_REF_CLK;
511
+ if (dp83867->clk_output_sel > DP83867_CLK_O_SEL_REF_CLK &&
512
+ dp83867->clk_output_sel != DP83867_CLK_O_SEL_OFF) {
513
+ phydev_err(phydev, "ti,clk-output-sel value %u out of range\n",
514
+ dp83867->clk_output_sel);
515
+ return -EINVAL;
516
+ }
517
+ }
188518
189519 if (of_property_read_bool(of_node, "ti,max-output-impedance"))
190520 dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX;
191521 else if (of_property_read_bool(of_node, "ti,min-output-impedance"))
192522 dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN;
523
+ else
524
+ dp83867->io_impedance = -1; /* leave at default */
193525
194526 dp83867->rxctrl_strap_quirk = of_property_read_bool(of_node,
195
- "ti,dp83867-rxctrl-strap-quirk");
527
+ "ti,dp83867-rxctrl-strap-quirk");
196528
529
+ dp83867->sgmii_ref_clk_en = of_property_read_bool(of_node,
530
+ "ti,sgmii-ref-clock-output-enable");
531
+
532
+ dp83867->rx_id_delay = DP83867_RGMII_RX_CLK_DELAY_INV;
197533 ret = of_property_read_u32(of_node, "ti,rx-internal-delay",
198534 &dp83867->rx_id_delay);
199
- if (ret &&
200
- (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
201
- phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID))
202
- return ret;
535
+ if (!ret && dp83867->rx_id_delay > DP83867_RGMII_RX_CLK_DELAY_MAX) {
536
+ phydev_err(phydev,
537
+ "ti,rx-internal-delay value of %u out of range\n",
538
+ dp83867->rx_id_delay);
539
+ return -EINVAL;
540
+ }
203541
542
+ dp83867->tx_id_delay = DP83867_RGMII_TX_CLK_DELAY_INV;
204543 ret = of_property_read_u32(of_node, "ti,tx-internal-delay",
205544 &dp83867->tx_id_delay);
206
- if (ret &&
207
- (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
208
- phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID))
209
- return ret;
545
+ if (!ret && dp83867->tx_id_delay > DP83867_RGMII_TX_CLK_DELAY_MAX) {
546
+ phydev_err(phydev,
547
+ "ti,tx-internal-delay value of %u out of range\n",
548
+ dp83867->tx_id_delay);
549
+ return -EINVAL;
550
+ }
210551
211552 if (of_property_read_bool(of_node, "enet-phy-lane-swap"))
212553 dp83867->port_mirroring = DP83867_PORT_MIRROING_EN;
....@@ -214,8 +555,34 @@
214555 if (of_property_read_bool(of_node, "enet-phy-lane-no-swap"))
215556 dp83867->port_mirroring = DP83867_PORT_MIRROING_DIS;
216557
217
- return of_property_read_u32(of_node, "ti,fifo-depth",
218
- &dp83867->fifo_depth);
558
+ ret = of_property_read_u32(of_node, "ti,fifo-depth",
559
+ &dp83867->tx_fifo_depth);
560
+ if (ret) {
561
+ ret = of_property_read_u32(of_node, "tx-fifo-depth",
562
+ &dp83867->tx_fifo_depth);
563
+ if (ret)
564
+ dp83867->tx_fifo_depth =
565
+ DP83867_PHYCR_FIFO_DEPTH_4_B_NIB;
566
+ }
567
+
568
+ if (dp83867->tx_fifo_depth > DP83867_PHYCR_FIFO_DEPTH_MAX) {
569
+ phydev_err(phydev, "tx-fifo-depth value %u out of range\n",
570
+ dp83867->tx_fifo_depth);
571
+ return -EINVAL;
572
+ }
573
+
574
+ ret = of_property_read_u32(of_node, "rx-fifo-depth",
575
+ &dp83867->rx_fifo_depth);
576
+ if (ret)
577
+ dp83867->rx_fifo_depth = DP83867_PHYCR_FIFO_DEPTH_4_B_NIB;
578
+
579
+ if (dp83867->rx_fifo_depth > DP83867_PHYCR_FIFO_DEPTH_MAX) {
580
+ phydev_err(phydev, "rx-fifo-depth value %u out of range\n",
581
+ dp83867->rx_fifo_depth);
582
+ return -EINVAL;
583
+ }
584
+
585
+ return 0;
219586 }
220587 #else
221588 static int dp83867_of_init(struct phy_device *phydev)
....@@ -224,39 +591,80 @@
224591 }
225592 #endif /* CONFIG_OF_MDIO */
226593
227
-static int dp83867_config_init(struct phy_device *phydev)
594
+static int dp83867_probe(struct phy_device *phydev)
228595 {
229596 struct dp83867_private *dp83867;
597
+
598
+ dp83867 = devm_kzalloc(&phydev->mdio.dev, sizeof(*dp83867),
599
+ GFP_KERNEL);
600
+ if (!dp83867)
601
+ return -ENOMEM;
602
+
603
+ phydev->priv = dp83867;
604
+
605
+ return dp83867_of_init(phydev);
606
+}
607
+
608
+static int dp83867_config_init(struct phy_device *phydev)
609
+{
610
+ struct dp83867_private *dp83867 = phydev->priv;
230611 int ret, val, bs;
231612 u16 delay;
232613
233
- if (!phydev->priv) {
234
- dp83867 = devm_kzalloc(&phydev->mdio.dev, sizeof(*dp83867),
235
- GFP_KERNEL);
236
- if (!dp83867)
237
- return -ENOMEM;
614
+ /* Force speed optimization for the PHY even if it strapped */
615
+ ret = phy_modify(phydev, DP83867_CFG2, DP83867_DOWNSHIFT_EN,
616
+ DP83867_DOWNSHIFT_EN);
617
+ if (ret)
618
+ return ret;
238619
239
- phydev->priv = dp83867;
240
- ret = dp83867_of_init(phydev);
241
- if (ret)
242
- return ret;
243
- } else {
244
- dp83867 = (struct dp83867_private *)phydev->priv;
245
- }
620
+ ret = dp83867_verify_rgmii_cfg(phydev);
621
+ if (ret)
622
+ return ret;
246623
247624 /* RX_DV/RX_CTRL strapped in mode 1 or mode 2 workaround */
248
- if (dp83867->rxctrl_strap_quirk) {
249
- val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4);
250
- val &= ~BIT(7);
251
- phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4, val);
625
+ if (dp83867->rxctrl_strap_quirk)
626
+ phy_clear_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4,
627
+ BIT(7));
628
+
629
+ bs = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_STRAP_STS2);
630
+ if (bs & DP83867_STRAP_STS2_STRAP_FLD) {
631
+ /* When using strap to enable FLD, the ENERGY_LOST_FLD_THR will
632
+ * be set to 0x2. This may causes the PHY link to be unstable -
633
+ * the default value 0x1 need to be restored.
634
+ */
635
+ ret = phy_modify_mmd(phydev, DP83867_DEVADDR,
636
+ DP83867_FLD_THR_CFG,
637
+ DP83867_FLD_THR_CFG_ENERGY_LOST_THR_MASK,
638
+ 0x1);
639
+ if (ret)
640
+ return ret;
641
+ }
642
+
643
+ if (phy_interface_is_rgmii(phydev) ||
644
+ phydev->interface == PHY_INTERFACE_MODE_SGMII) {
645
+ val = phy_read(phydev, MII_DP83867_PHYCTRL);
646
+ if (val < 0)
647
+ return val;
648
+
649
+ val &= ~DP83867_PHYCR_TX_FIFO_DEPTH_MASK;
650
+ val |= (dp83867->tx_fifo_depth <<
651
+ DP83867_PHYCR_TX_FIFO_DEPTH_SHIFT);
652
+
653
+ if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
654
+ val &= ~DP83867_PHYCR_RX_FIFO_DEPTH_MASK;
655
+ val |= (dp83867->rx_fifo_depth <<
656
+ DP83867_PHYCR_RX_FIFO_DEPTH_SHIFT);
657
+ }
658
+
659
+ ret = phy_write(phydev, MII_DP83867_PHYCTRL, val);
660
+ if (ret)
661
+ return ret;
252662 }
253663
254664 if (phy_interface_is_rgmii(phydev)) {
255665 val = phy_read(phydev, MII_DP83867_PHYCTRL);
256666 if (val < 0)
257667 return val;
258
- val &= ~DP83867_PHYCR_FIFO_DEPTH_MASK;
259
- val |= (dp83867->fifo_depth << DP83867_PHYCR_FIFO_DEPTH_SHIFT);
260668
261669 /* The code below checks if "port mirroring" N/A MODE4 has been
262670 * enabled during power on bootstrap.
....@@ -276,9 +684,16 @@
276684 if (ret)
277685 return ret;
278686
279
- /* Set up RGMII delays */
687
+ /* If rgmii mode with no internal delay is selected, we do NOT use
688
+ * aligned mode as one might expect. Instead we use the PHY's default
689
+ * based on pin strapping. And the "mode 0" default is to *use*
690
+ * internal delay with a value of 7 (2.00 ns).
691
+ *
692
+ * Set up RGMII delays
693
+ */
280694 val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_RGMIICTL);
281695
696
+ val &= ~(DP83867_RGMII_TX_CLK_DELAY_EN | DP83867_RGMII_RX_CLK_DELAY_EN);
282697 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
283698 val |= (DP83867_RGMII_TX_CLK_DELAY_EN | DP83867_RGMII_RX_CLK_DELAY_EN);
284699
....@@ -290,24 +705,22 @@
290705
291706 phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RGMIICTL, val);
292707
293
- delay = (dp83867->rx_id_delay |
294
- (dp83867->tx_id_delay << DP83867_RGMII_TX_CLK_DELAY_SHIFT));
708
+ delay = 0;
709
+ if (dp83867->rx_id_delay != DP83867_RGMII_RX_CLK_DELAY_INV)
710
+ delay |= dp83867->rx_id_delay;
711
+ if (dp83867->tx_id_delay != DP83867_RGMII_TX_CLK_DELAY_INV)
712
+ delay |= dp83867->tx_id_delay <<
713
+ DP83867_RGMII_TX_CLK_DELAY_SHIFT;
295714
296715 phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_RGMIIDCTL,
297716 delay);
298
-
299
- if (dp83867->io_impedance >= 0) {
300
- val = phy_read_mmd(phydev, DP83867_DEVADDR,
301
- DP83867_IO_MUX_CFG);
302
-
303
- val &= ~DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL;
304
- val |= dp83867->io_impedance &
305
- DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL;
306
-
307
- phy_write_mmd(phydev, DP83867_DEVADDR,
308
- DP83867_IO_MUX_CFG, val);
309
- }
310717 }
718
+
719
+ /* If specified, set io impedance */
720
+ if (dp83867->io_impedance >= 0)
721
+ phy_modify_mmd(phydev, DP83867_DEVADDR, DP83867_IO_MUX_CFG,
722
+ DP83867_IO_MUX_CFG_IO_IMPEDANCE_MASK,
723
+ dp83867->io_impedance);
311724
312725 if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
313726 /* For support SPEED_10 in SGMII mode
....@@ -316,12 +729,10 @@
316729 * does not affect SPEED_100 and
317730 * SPEED_1000.
318731 */
319
- val = phy_read_mmd(phydev, DP83867_DEVADDR,
320
- DP83867_10M_SGMII_CFG);
321
- val &= ~DP83867_10M_SGMII_RATE_ADAPT_MASK;
322
- ret = phy_write_mmd(phydev, DP83867_DEVADDR,
323
- DP83867_10M_SGMII_CFG, val);
324
-
732
+ ret = phy_modify_mmd(phydev, DP83867_DEVADDR,
733
+ DP83867_10M_SGMII_CFG,
734
+ DP83867_10M_SGMII_RATE_ADAPT_MASK,
735
+ 0);
325736 if (ret)
326737 return ret;
327738
....@@ -329,13 +740,32 @@
329740 * are 01). That is not enough to finalize autoneg on some
330741 * devices. Increase this timer duration to maximum 16ms.
331742 */
332
- val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4);
333
- val &= ~DP83867_CFG4_SGMII_ANEG_MASK;
334
- val |= DP83867_CFG4_SGMII_ANEG_TIMER_16MS;
335
- ret = phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4, val);
743
+ ret = phy_modify_mmd(phydev, DP83867_DEVADDR,
744
+ DP83867_CFG4,
745
+ DP83867_CFG4_SGMII_ANEG_MASK,
746
+ DP83867_CFG4_SGMII_ANEG_TIMER_16MS);
336747
337748 if (ret)
338749 return ret;
750
+
751
+ val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_SGMIICTL);
752
+ /* SGMII type is set to 4-wire mode by default.
753
+ * If we place appropriate property in dts (see above)
754
+ * switch on 6-wire mode.
755
+ */
756
+ if (dp83867->sgmii_ref_clk_en)
757
+ val |= DP83867_SGMII_TYPE;
758
+ else
759
+ val &= ~DP83867_SGMII_TYPE;
760
+ phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_SGMIICTL, val);
761
+
762
+ /* This is a SW workaround for link instability if RX_CTRL is
763
+ * not strapped to mode 3 or 4 in HW. This is required for SGMII
764
+ * in addition to clearing bit 7, handled above.
765
+ */
766
+ if (dp83867->rxctrl_strap_quirk)
767
+ phy_set_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4,
768
+ BIT(8));
339769 }
340770
341771 val = phy_read(phydev, DP83867_CFG3);
....@@ -350,28 +780,19 @@
350780 dp83867_config_port_mirroring(phydev);
351781
352782 /* Clock output selection if muxing property is set */
353
- if (dp83867->clk_output_sel != DP83867_CLK_O_SEL_REF_CLK) {
354
- val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_IO_MUX_CFG);
355
- val &= ~DP83867_IO_MUX_CFG_CLK_O_SEL_MASK;
356
- val |= (dp83867->clk_output_sel << DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT);
357
- phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_IO_MUX_CFG, val);
358
- }
783
+ if (dp83867->set_clk_output) {
784
+ u16 mask = DP83867_IO_MUX_CFG_CLK_O_DISABLE;
359785
360
- /* Check if the PHY is an internal testing mode.
361
- * This mode can cause connection problems.
362
- */
363
- val = phy_read_mmd_indirect(phydev, DP83867_CFG4, DP83867_DEVADDR);
364
- if (val & BIT(7)) {
365
- val &= ~BIT(7);
366
- phy_write_mmd_indirect(phydev, DP83867_CFG4, DP83867_DEVADDR,
367
- val);
368
- }
786
+ if (dp83867->clk_output_sel == DP83867_CLK_O_SEL_OFF) {
787
+ val = DP83867_IO_MUX_CFG_CLK_O_DISABLE;
788
+ } else {
789
+ mask |= DP83867_IO_MUX_CFG_CLK_O_SEL_MASK;
790
+ val = dp83867->clk_output_sel <<
791
+ DP83867_IO_MUX_CFG_CLK_O_SEL_SHIFT;
792
+ }
369793
370
- /* Disable FORCE_LINK_GOOD */
371
- val = phy_read(phydev, MII_DP83867_PHYCTRL);
372
- if (val & MII_DP83867_PHYCTRL_FORCE_LINK_GOOD) {
373
- val &= ~(MII_DP83867_PHYCTRL_FORCE_LINK_GOOD);
374
- phy_write(phydev, MII_DP83867_PHYCTRL, val);
794
+ phy_modify_mmd(phydev, DP83867_DEVADDR, DP83867_IO_MUX_CFG,
795
+ mask, val);
375796 }
376797
377798 return 0;
....@@ -385,7 +806,55 @@
385806 if (err < 0)
386807 return err;
387808
388
- return dp83867_config_init(phydev);
809
+ usleep_range(10, 20);
810
+
811
+ err = phy_modify(phydev, MII_DP83867_PHYCTRL,
812
+ DP83867_PHYCR_FORCE_LINK_GOOD, 0);
813
+ if (err < 0)
814
+ return err;
815
+
816
+ /* Configure the DSP Feedforward Equalizer Configuration register to
817
+ * improve short cable (< 1 meter) performance. This will not affect
818
+ * long cable performance.
819
+ */
820
+ err = phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_DSP_FFE_CFG,
821
+ 0x0e81);
822
+ if (err < 0)
823
+ return err;
824
+
825
+ err = phy_write(phydev, DP83867_CTRL, DP83867_SW_RESTART);
826
+ if (err < 0)
827
+ return err;
828
+
829
+ usleep_range(10, 20);
830
+
831
+ return 0;
832
+}
833
+
834
+static void dp83867_link_change_notify(struct phy_device *phydev)
835
+{
836
+ /* There is a limitation in DP83867 PHY device where SGMII AN is
837
+ * only triggered once after the device is booted up. Even after the
838
+ * PHY TPI is down and up again, SGMII AN is not triggered and
839
+ * hence no new in-band message from PHY to MAC side SGMII.
840
+ * This could cause an issue during power up, when PHY is up prior
841
+ * to MAC. At this condition, once MAC side SGMII is up, MAC side
842
+ * SGMII wouldn`t receive new in-band message from TI PHY with
843
+ * correct link status, speed and duplex info.
844
+ * Thus, implemented a SW solution here to retrigger SGMII Auto-Neg
845
+ * whenever there is a link change.
846
+ */
847
+ if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
848
+ int val = 0;
849
+
850
+ val = phy_clear_bits(phydev, DP83867_CFG2,
851
+ DP83867_SGMII_AUTONEG_EN);
852
+ if (val < 0)
853
+ return;
854
+
855
+ phy_set_bits(phydev, DP83867_CFG2,
856
+ DP83867_SGMII_AUTONEG_EN);
857
+ }
389858 }
390859
391860 static struct phy_driver dp83867_driver[] = {
....@@ -393,11 +862,18 @@
393862 .phy_id = DP83867_PHY_ID,
394863 .phy_id_mask = 0xfffffff0,
395864 .name = "TI DP83867",
396
- .features = PHY_GBIT_FEATURES,
397
- .flags = PHY_HAS_INTERRUPT,
865
+ /* PHY_GBIT_FEATURES */
398866
867
+ .probe = dp83867_probe,
399868 .config_init = dp83867_config_init,
400869 .soft_reset = dp83867_phy_reset,
870
+
871
+ .read_status = dp83867_read_status,
872
+ .get_tunable = dp83867_get_tunable,
873
+ .set_tunable = dp83867_set_tunable,
874
+
875
+ .get_wol = dp83867_get_wol,
876
+ .set_wol = dp83867_set_wol,
401877
402878 /* IRQ related */
403879 .ack_interrupt = dp83867_ack_interrupt,
....@@ -405,6 +881,8 @@
405881
406882 .suspend = genphy_suspend,
407883 .resume = genphy_resume,
884
+
885
+ .link_change_notify = dp83867_link_change_notify,
408886 },
409887 };
410888 module_phy_driver(dp83867_driver);
....@@ -418,4 +896,4 @@
418896
419897 MODULE_DESCRIPTION("Texas Instruments DP83867 PHY driver");
420898 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com");
421
-MODULE_LICENSE("GPL");
899
+MODULE_LICENSE("GPL v2");