hc
2024-05-10 61598093bbdd283a7edc367d900f223070ead8d2
kernel/drivers/net/phy/marvell10g.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0+
12 /*
23 * Marvell 10G 88x3310 PHY driver
34 *
....@@ -22,11 +23,18 @@
2223 * link takes priority and the other port is completely locked out.
2324 */
2425 #include <linux/ctype.h>
26
+#include <linux/delay.h>
2527 #include <linux/hwmon.h>
2628 #include <linux/marvell_phy.h>
2729 #include <linux/phy.h>
30
+#include <linux/sfp.h>
31
+
32
+#define MV_PHY_ALASKA_NBT_QUIRK_MASK 0xfffffffe
33
+#define MV_PHY_ALASKA_NBT_QUIRK_REV (MARVELL_PHY_ID_88X3310 | 0xa)
2834
2935 enum {
36
+ MV_PMA_FW_VER0 = 0xc011,
37
+ MV_PMA_FW_VER1 = 0xc012,
3038 MV_PMA_BOOT = 0xc050,
3139 MV_PMA_BOOT_FATAL = BIT(0),
3240
....@@ -34,10 +42,32 @@
3442 MV_PCS_BASE_R = 0x1000,
3543 MV_PCS_1000BASEX = 0x2000,
3644
37
- MV_PCS_PAIRSWAP = 0x8182,
38
- MV_PCS_PAIRSWAP_MASK = 0x0003,
39
- MV_PCS_PAIRSWAP_AB = 0x0002,
40
- MV_PCS_PAIRSWAP_NONE = 0x0003,
45
+ MV_PCS_CSCR1 = 0x8000,
46
+ MV_PCS_CSCR1_ED_MASK = 0x0300,
47
+ MV_PCS_CSCR1_ED_OFF = 0x0000,
48
+ MV_PCS_CSCR1_ED_RX = 0x0200,
49
+ MV_PCS_CSCR1_ED_NLP = 0x0300,
50
+ MV_PCS_CSCR1_MDIX_MASK = 0x0060,
51
+ MV_PCS_CSCR1_MDIX_MDI = 0x0000,
52
+ MV_PCS_CSCR1_MDIX_MDIX = 0x0020,
53
+ MV_PCS_CSCR1_MDIX_AUTO = 0x0060,
54
+
55
+ MV_PCS_CSSR1 = 0x8008,
56
+ MV_PCS_CSSR1_SPD1_MASK = 0xc000,
57
+ MV_PCS_CSSR1_SPD1_SPD2 = 0xc000,
58
+ MV_PCS_CSSR1_SPD1_1000 = 0x8000,
59
+ MV_PCS_CSSR1_SPD1_100 = 0x4000,
60
+ MV_PCS_CSSR1_SPD1_10 = 0x0000,
61
+ MV_PCS_CSSR1_DUPLEX_FULL= BIT(13),
62
+ MV_PCS_CSSR1_RESOLVED = BIT(11),
63
+ MV_PCS_CSSR1_MDIX = BIT(6),
64
+ MV_PCS_CSSR1_SPD2_MASK = 0x000c,
65
+ MV_PCS_CSSR1_SPD2_5000 = 0x0008,
66
+ MV_PCS_CSSR1_SPD2_2500 = 0x0004,
67
+ MV_PCS_CSSR1_SPD2_10000 = 0x0000,
68
+
69
+ /* Temperature read register (88E2110 only) */
70
+ MV_PCS_TEMP = 0x8042,
4171
4272 /* These registers appear at 0x800X and 0xa00X - the 0xa00X control
4373 * registers appear to set themselves to the 0x800X when AN is
....@@ -47,6 +77,12 @@
4777 MV_AN_STAT1000 = 0x8001, /* 1000base-T status register */
4878
4979 /* Vendor2 MMD registers */
80
+ MV_V2_PORT_CTRL = 0xf001,
81
+ MV_V2_PORT_CTRL_SWRST = BIT(15),
82
+ MV_V2_PORT_CTRL_PWRDOWN = BIT(11),
83
+ MV_V2_PORT_MAC_TYPE_MASK = 0x7,
84
+ MV_V2_PORT_MAC_TYPE_RATE_MATCH = 0x6,
85
+ /* Temperature control/read registers (88X3310 only) */
5086 MV_V2_TEMP_CTRL = 0xf08a,
5187 MV_V2_TEMP_CTRL_MASK = 0xc000,
5288 MV_V2_TEMP_CTRL_SAMPLE = 0x0000,
....@@ -56,27 +92,12 @@
5692 };
5793
5894 struct mv3310_priv {
95
+ u32 firmware_ver;
96
+ bool rate_match;
97
+
5998 struct device *hwmon_dev;
6099 char *hwmon_name;
61100 };
62
-
63
-static int mv3310_modify(struct phy_device *phydev, int devad, u16 reg,
64
- u16 mask, u16 bits)
65
-{
66
- int old, val, ret;
67
-
68
- old = phy_read_mmd(phydev, devad, reg);
69
- if (old < 0)
70
- return old;
71
-
72
- val = (old & ~mask) | (bits & mask);
73
- if (val == old)
74
- return 0;
75
-
76
- ret = phy_write_mmd(phydev, devad, reg, val);
77
-
78
- return ret < 0 ? ret : 1;
79
-}
80101
81102 #ifdef CONFIG_HWMON
82103 static umode_t mv3310_hwmon_is_visible(const void *data,
....@@ -88,6 +109,24 @@
88109 if (type == hwmon_temp && attr == hwmon_temp_input)
89110 return 0444;
90111 return 0;
112
+}
113
+
114
+static int mv3310_hwmon_read_temp_reg(struct phy_device *phydev)
115
+{
116
+ return phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP);
117
+}
118
+
119
+static int mv2110_hwmon_read_temp_reg(struct phy_device *phydev)
120
+{
121
+ return phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_TEMP);
122
+}
123
+
124
+static int mv10g_hwmon_read_temp_reg(struct phy_device *phydev)
125
+{
126
+ if (phydev->drv->phy_id == MARVELL_PHY_ID_88X3310)
127
+ return mv3310_hwmon_read_temp_reg(phydev);
128
+ else /* MARVELL_PHY_ID_88E2110 */
129
+ return mv2110_hwmon_read_temp_reg(phydev);
91130 }
92131
93132 static int mv3310_hwmon_read(struct device *dev, enum hwmon_sensor_types type,
....@@ -102,7 +141,7 @@
102141 }
103142
104143 if (type == hwmon_temp && attr == hwmon_temp_input) {
105
- temp = phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP);
144
+ temp = mv10g_hwmon_read_temp_reg(phydev);
106145 if (temp < 0)
107146 return temp;
108147
....@@ -155,23 +194,18 @@
155194 u16 val;
156195 int ret;
157196
197
+ if (phydev->drv->phy_id != MARVELL_PHY_ID_88X3310)
198
+ return 0;
199
+
158200 ret = phy_write_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP,
159201 MV_V2_TEMP_UNKNOWN);
160202 if (ret < 0)
161203 return ret;
162204
163205 val = enable ? MV_V2_TEMP_CTRL_SAMPLE : MV_V2_TEMP_CTRL_DISABLE;
164
- ret = mv3310_modify(phydev, MDIO_MMD_VEND2, MV_V2_TEMP_CTRL,
165
- MV_V2_TEMP_CTRL_MASK, val);
166206
167
- return ret < 0 ? ret : 0;
168
-}
169
-
170
-static void mv3310_hwmon_disable(void *data)
171
-{
172
- struct phy_device *phydev = data;
173
-
174
- mv3310_hwmon_config(phydev, false);
207
+ return phy_modify_mmd(phydev, MDIO_MMD_VEND2, MV_V2_TEMP_CTRL,
208
+ MV_V2_TEMP_CTRL_MASK, val);
175209 }
176210
177211 static int mv3310_hwmon_probe(struct phy_device *phydev)
....@@ -197,10 +231,6 @@
197231 if (ret)
198232 return ret;
199233
200
- ret = devm_add_action_or_reset(dev, mv3310_hwmon_disable, phydev);
201
- if (ret)
202
- return ret;
203
-
204234 priv->hwmon_dev = devm_hwmon_device_register_with_info(dev,
205235 priv->hwmon_name, phydev,
206236 &mv3310_hwmon_chip_info, NULL);
....@@ -218,6 +248,125 @@
218248 return 0;
219249 }
220250 #endif
251
+
252
+static int mv3310_power_down(struct phy_device *phydev)
253
+{
254
+ return phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
255
+ MV_V2_PORT_CTRL_PWRDOWN);
256
+}
257
+
258
+static int mv3310_power_up(struct phy_device *phydev)
259
+{
260
+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
261
+ int ret;
262
+
263
+ ret = phy_clear_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
264
+ MV_V2_PORT_CTRL_PWRDOWN);
265
+
266
+ /* Sometimes, the power down bit doesn't clear immediately, and
267
+ * a read of this register causes the bit not to clear. Delay
268
+ * 100us to allow the PHY to come out of power down mode before
269
+ * the next access.
270
+ */
271
+ udelay(100);
272
+
273
+ if (phydev->drv->phy_id != MARVELL_PHY_ID_88X3310 ||
274
+ priv->firmware_ver < 0x00030000)
275
+ return ret;
276
+
277
+ return phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
278
+ MV_V2_PORT_CTRL_SWRST);
279
+}
280
+
281
+static int mv3310_reset(struct phy_device *phydev, u32 unit)
282
+{
283
+ int val, err;
284
+
285
+ err = phy_modify_mmd(phydev, MDIO_MMD_PCS, unit + MDIO_CTRL1,
286
+ MDIO_CTRL1_RESET, MDIO_CTRL1_RESET);
287
+ if (err < 0)
288
+ return err;
289
+
290
+ return phy_read_mmd_poll_timeout(phydev, MDIO_MMD_PCS,
291
+ unit + MDIO_CTRL1, val,
292
+ !(val & MDIO_CTRL1_RESET),
293
+ 5000, 100000, true);
294
+}
295
+
296
+static int mv3310_get_edpd(struct phy_device *phydev, u16 *edpd)
297
+{
298
+ int val;
299
+
300
+ val = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_CSCR1);
301
+ if (val < 0)
302
+ return val;
303
+
304
+ switch (val & MV_PCS_CSCR1_ED_MASK) {
305
+ case MV_PCS_CSCR1_ED_NLP:
306
+ *edpd = 1000;
307
+ break;
308
+ case MV_PCS_CSCR1_ED_RX:
309
+ *edpd = ETHTOOL_PHY_EDPD_NO_TX;
310
+ break;
311
+ default:
312
+ *edpd = ETHTOOL_PHY_EDPD_DISABLE;
313
+ break;
314
+ }
315
+ return 0;
316
+}
317
+
318
+static int mv3310_set_edpd(struct phy_device *phydev, u16 edpd)
319
+{
320
+ u16 val;
321
+ int err;
322
+
323
+ switch (edpd) {
324
+ case 1000:
325
+ case ETHTOOL_PHY_EDPD_DFLT_TX_MSECS:
326
+ val = MV_PCS_CSCR1_ED_NLP;
327
+ break;
328
+
329
+ case ETHTOOL_PHY_EDPD_NO_TX:
330
+ val = MV_PCS_CSCR1_ED_RX;
331
+ break;
332
+
333
+ case ETHTOOL_PHY_EDPD_DISABLE:
334
+ val = MV_PCS_CSCR1_ED_OFF;
335
+ break;
336
+
337
+ default:
338
+ return -EINVAL;
339
+ }
340
+
341
+ err = phy_modify_mmd_changed(phydev, MDIO_MMD_PCS, MV_PCS_CSCR1,
342
+ MV_PCS_CSCR1_ED_MASK, val);
343
+ if (err > 0)
344
+ err = mv3310_reset(phydev, MV_PCS_BASE_T);
345
+
346
+ return err;
347
+}
348
+
349
+static int mv3310_sfp_insert(void *upstream, const struct sfp_eeprom_id *id)
350
+{
351
+ struct phy_device *phydev = upstream;
352
+ __ETHTOOL_DECLARE_LINK_MODE_MASK(support) = { 0, };
353
+ phy_interface_t iface;
354
+
355
+ sfp_parse_support(phydev->sfp_bus, id, support);
356
+ iface = sfp_select_interface(phydev->sfp_bus, support);
357
+
358
+ if (iface != PHY_INTERFACE_MODE_10GBASER) {
359
+ dev_err(&phydev->mdio.dev, "incompatible SFP module inserted\n");
360
+ return -EINVAL;
361
+ }
362
+ return 0;
363
+}
364
+
365
+static const struct sfp_upstream_ops mv3310_sfp_ops = {
366
+ .attach = phy_sfp_attach,
367
+ .detach = phy_sfp_detach,
368
+ .module_insert = mv3310_sfp_insert,
369
+};
221370
222371 static int mv3310_probe(struct phy_device *phydev)
223372 {
....@@ -245,172 +394,187 @@
245394
246395 dev_set_drvdata(&phydev->mdio.dev, priv);
247396
397
+ ret = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_FW_VER0);
398
+ if (ret < 0)
399
+ return ret;
400
+
401
+ priv->firmware_ver = ret << 16;
402
+
403
+ ret = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_FW_VER1);
404
+ if (ret < 0)
405
+ return ret;
406
+
407
+ priv->firmware_ver |= ret;
408
+
409
+ phydev_info(phydev, "Firmware version %u.%u.%u.%u\n",
410
+ priv->firmware_ver >> 24, (priv->firmware_ver >> 16) & 255,
411
+ (priv->firmware_ver >> 8) & 255, priv->firmware_ver & 255);
412
+
413
+ /* Powering down the port when not in use saves about 600mW */
414
+ ret = mv3310_power_down(phydev);
415
+ if (ret)
416
+ return ret;
417
+
248418 ret = mv3310_hwmon_probe(phydev);
249419 if (ret)
250420 return ret;
251421
252
- return 0;
422
+ return phy_sfp_probe(phydev, &mv3310_sfp_ops);
423
+}
424
+
425
+static void mv3310_remove(struct phy_device *phydev)
426
+{
427
+ mv3310_hwmon_config(phydev, false);
253428 }
254429
255430 static int mv3310_suspend(struct phy_device *phydev)
256431 {
257
- return 0;
432
+ return mv3310_power_down(phydev);
258433 }
259434
260435 static int mv3310_resume(struct phy_device *phydev)
261436 {
437
+ int ret;
438
+
439
+ ret = mv3310_power_up(phydev);
440
+ if (ret)
441
+ return ret;
442
+
262443 return mv3310_hwmon_config(phydev, true);
444
+}
445
+
446
+/* Some PHYs in the Alaska family such as the 88X3310 and the 88E2010
447
+ * don't set bit 14 in PMA Extended Abilities (1.11), although they do
448
+ * support 2.5GBASET and 5GBASET. For these models, we can still read their
449
+ * 2.5G/5G extended abilities register (1.21). We detect these models based on
450
+ * the PMA device identifier, with a mask matching models known to have this
451
+ * issue
452
+ */
453
+static bool mv3310_has_pma_ngbaset_quirk(struct phy_device *phydev)
454
+{
455
+ if (!(phydev->c45_ids.devices_in_package & MDIO_DEVS_PMAPMD))
456
+ return false;
457
+
458
+ /* Only some revisions of the 88X3310 family PMA seem to be impacted */
459
+ return (phydev->c45_ids.device_ids[MDIO_MMD_PMAPMD] &
460
+ MV_PHY_ALASKA_NBT_QUIRK_MASK) == MV_PHY_ALASKA_NBT_QUIRK_REV;
263461 }
264462
265463 static int mv3310_config_init(struct phy_device *phydev)
266464 {
267
- __ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, };
268
- u32 mask;
465
+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
466
+ int err;
269467 int val;
270468
271469 /* Check that the PHY interface type is compatible */
272470 if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
471
+ phydev->interface != PHY_INTERFACE_MODE_2500BASEX &&
273472 phydev->interface != PHY_INTERFACE_MODE_XAUI &&
274473 phydev->interface != PHY_INTERFACE_MODE_RXAUI &&
275
- phydev->interface != PHY_INTERFACE_MODE_10GKR)
474
+ phydev->interface != PHY_INTERFACE_MODE_10GBASER)
276475 return -ENODEV;
277476
278
- __set_bit(ETHTOOL_LINK_MODE_Pause_BIT, supported);
279
- __set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, supported);
477
+ phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
280478
281
- if (phydev->c45_ids.devices_in_package & MDIO_DEVS_AN) {
282
- val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
283
- if (val < 0)
284
- return val;
479
+ /* Power up so reset works */
480
+ err = mv3310_power_up(phydev);
481
+ if (err)
482
+ return err;
285483
286
- if (val & MDIO_AN_STAT1_ABLE)
287
- __set_bit(ETHTOOL_LINK_MODE_Autoneg_BIT, supported);
288
- }
289
-
290
- val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_STAT2);
484
+ val = phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL);
291485 if (val < 0)
292486 return val;
487
+ priv->rate_match = ((val & MV_V2_PORT_MAC_TYPE_MASK) ==
488
+ MV_V2_PORT_MAC_TYPE_RATE_MATCH);
293489
294
- /* Ethtool does not support the WAN mode bits */
295
- if (val & (MDIO_PMA_STAT2_10GBSR | MDIO_PMA_STAT2_10GBLR |
296
- MDIO_PMA_STAT2_10GBER | MDIO_PMA_STAT2_10GBLX4 |
297
- MDIO_PMA_STAT2_10GBSW | MDIO_PMA_STAT2_10GBLW |
298
- MDIO_PMA_STAT2_10GBEW))
299
- __set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, supported);
300
- if (val & MDIO_PMA_STAT2_10GBSR)
301
- __set_bit(ETHTOOL_LINK_MODE_10000baseSR_Full_BIT, supported);
302
- if (val & MDIO_PMA_STAT2_10GBLR)
303
- __set_bit(ETHTOOL_LINK_MODE_10000baseLR_Full_BIT, supported);
304
- if (val & MDIO_PMA_STAT2_10GBER)
305
- __set_bit(ETHTOOL_LINK_MODE_10000baseER_Full_BIT, supported);
490
+ /* Enable EDPD mode - saving 600mW */
491
+ return mv3310_set_edpd(phydev, ETHTOOL_PHY_EDPD_DFLT_TX_MSECS);
492
+}
306493
307
- if (val & MDIO_PMA_STAT2_EXTABLE) {
308
- val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_PMA_EXTABLE);
494
+static int mv3310_get_features(struct phy_device *phydev)
495
+{
496
+ int ret, val;
497
+
498
+ ret = genphy_c45_pma_read_abilities(phydev);
499
+ if (ret)
500
+ return ret;
501
+
502
+ if (mv3310_has_pma_ngbaset_quirk(phydev)) {
503
+ val = phy_read_mmd(phydev, MDIO_MMD_PMAPMD,
504
+ MDIO_PMA_NG_EXTABLE);
309505 if (val < 0)
310506 return val;
311507
312
- if (val & (MDIO_PMA_EXTABLE_10GBT | MDIO_PMA_EXTABLE_1000BT |
313
- MDIO_PMA_EXTABLE_100BTX | MDIO_PMA_EXTABLE_10BT))
314
- __set_bit(ETHTOOL_LINK_MODE_TP_BIT, supported);
315
- if (val & MDIO_PMA_EXTABLE_10GBLRM)
316
- __set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, supported);
317
- if (val & (MDIO_PMA_EXTABLE_10GBKX4 | MDIO_PMA_EXTABLE_10GBKR |
318
- MDIO_PMA_EXTABLE_1000BKX))
319
- __set_bit(ETHTOOL_LINK_MODE_Backplane_BIT, supported);
320
- if (val & MDIO_PMA_EXTABLE_10GBLRM)
321
- __set_bit(ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT,
322
- supported);
323
- if (val & MDIO_PMA_EXTABLE_10GBT)
324
- __set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT,
325
- supported);
326
- if (val & MDIO_PMA_EXTABLE_10GBKX4)
327
- __set_bit(ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT,
328
- supported);
329
- if (val & MDIO_PMA_EXTABLE_10GBKR)
330
- __set_bit(ETHTOOL_LINK_MODE_10000baseKR_Full_BIT,
331
- supported);
332
- if (val & MDIO_PMA_EXTABLE_1000BT)
333
- __set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
334
- supported);
335
- if (val & MDIO_PMA_EXTABLE_1000BKX)
336
- __set_bit(ETHTOOL_LINK_MODE_1000baseKX_Full_BIT,
337
- supported);
338
- if (val & MDIO_PMA_EXTABLE_100BTX) {
339
- __set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT,
340
- supported);
341
- __set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT,
342
- supported);
343
- }
344
- if (val & MDIO_PMA_EXTABLE_10BT) {
345
- __set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT,
346
- supported);
347
- __set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT,
348
- supported);
349
- }
508
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT,
509
+ phydev->supported,
510
+ val & MDIO_PMA_NG_EXTABLE_2_5GBT);
511
+
512
+ linkmode_mod_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT,
513
+ phydev->supported,
514
+ val & MDIO_PMA_NG_EXTABLE_5GBT);
350515 }
351516
352
- if (!ethtool_convert_link_mode_to_legacy_u32(&mask, supported))
353
- dev_warn(&phydev->mdio.dev,
354
- "PHY supports (%*pb) more modes than phylib supports, some modes not supported.\n",
355
- __ETHTOOL_LINK_MODE_MASK_NBITS, supported);
356
-
357
- phydev->supported &= mask;
358
- phydev->advertising &= phydev->supported;
359
-
360517 return 0;
518
+}
519
+
520
+static int mv3310_config_mdix(struct phy_device *phydev)
521
+{
522
+ u16 val;
523
+ int err;
524
+
525
+ switch (phydev->mdix_ctrl) {
526
+ case ETH_TP_MDI_AUTO:
527
+ val = MV_PCS_CSCR1_MDIX_AUTO;
528
+ break;
529
+ case ETH_TP_MDI_X:
530
+ val = MV_PCS_CSCR1_MDIX_MDIX;
531
+ break;
532
+ case ETH_TP_MDI:
533
+ val = MV_PCS_CSCR1_MDIX_MDI;
534
+ break;
535
+ default:
536
+ return -EINVAL;
537
+ }
538
+
539
+ err = phy_modify_mmd_changed(phydev, MDIO_MMD_PCS, MV_PCS_CSCR1,
540
+ MV_PCS_CSCR1_MDIX_MASK, val);
541
+ if (err > 0)
542
+ err = mv3310_reset(phydev, MV_PCS_BASE_T);
543
+
544
+ return err;
361545 }
362546
363547 static int mv3310_config_aneg(struct phy_device *phydev)
364548 {
365549 bool changed = false;
366
- u32 advertising;
550
+ u16 reg;
367551 int ret;
368552
369
- /* We don't support manual MDI control */
370
- phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
553
+ ret = mv3310_config_mdix(phydev);
554
+ if (ret < 0)
555
+ return ret;
371556
372
- if (phydev->autoneg == AUTONEG_DISABLE) {
373
- ret = genphy_c45_pma_setup_forced(phydev);
374
- if (ret < 0)
375
- return ret;
557
+ if (phydev->autoneg == AUTONEG_DISABLE)
558
+ return genphy_c45_pma_setup_forced(phydev);
376559
377
- return genphy_c45_an_disable_aneg(phydev);
378
- }
379
-
380
- phydev->advertising &= phydev->supported;
381
- advertising = phydev->advertising;
382
-
383
- ret = mv3310_modify(phydev, MDIO_MMD_AN, MDIO_AN_ADVERTISE,
384
- ADVERTISE_ALL | ADVERTISE_100BASE4 |
385
- ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM,
386
- ethtool_adv_to_mii_adv_t(advertising));
560
+ ret = genphy_c45_an_config_aneg(phydev);
387561 if (ret < 0)
388562 return ret;
389563 if (ret > 0)
390564 changed = true;
391565
392
- ret = mv3310_modify(phydev, MDIO_MMD_AN, MV_AN_CTRL1000,
393
- ADVERTISE_1000FULL | ADVERTISE_1000HALF,
394
- ethtool_adv_to_mii_ctrl1000_t(advertising));
566
+ /* Clause 45 has no standardized support for 1000BaseT, therefore
567
+ * use vendor registers for this mode.
568
+ */
569
+ reg = linkmode_adv_to_mii_ctrl1000_t(phydev->advertising);
570
+ ret = phy_modify_mmd_changed(phydev, MDIO_MMD_AN, MV_AN_CTRL1000,
571
+ ADVERTISE_1000FULL | ADVERTISE_1000HALF, reg);
395572 if (ret < 0)
396573 return ret;
397574 if (ret > 0)
398575 changed = true;
399576
400
- /* 10G control register */
401
- ret = mv3310_modify(phydev, MDIO_MMD_AN, MDIO_AN_10GBT_CTRL,
402
- MDIO_AN_10GBT_CTRL_ADV10G,
403
- advertising & ADVERTISED_10000baseT_Full ?
404
- MDIO_AN_10GBT_CTRL_ADV10G : 0);
405
- if (ret < 0)
406
- return ret;
407
- if (ret > 0)
408
- changed = true;
409
-
410
- if (changed)
411
- ret = genphy_c45_restart_aneg(phydev);
412
-
413
- return ret;
577
+ return genphy_c45_check_and_restart_aneg(phydev, changed);
414578 }
415579
416580 static int mv3310_aneg_done(struct phy_device *phydev)
....@@ -429,70 +593,114 @@
429593
430594 static void mv3310_update_interface(struct phy_device *phydev)
431595 {
596
+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
597
+
598
+ /* In "XFI with Rate Matching" mode the PHY interface is fixed at
599
+ * 10Gb. The PHY adapts the rate to actual wire speed with help of
600
+ * internal 16KB buffer.
601
+ */
602
+ if (priv->rate_match) {
603
+ phydev->interface = PHY_INTERFACE_MODE_10GBASER;
604
+ return;
605
+ }
606
+
432607 if ((phydev->interface == PHY_INTERFACE_MODE_SGMII ||
433
- phydev->interface == PHY_INTERFACE_MODE_10GKR) && phydev->link) {
608
+ phydev->interface == PHY_INTERFACE_MODE_2500BASEX ||
609
+ phydev->interface == PHY_INTERFACE_MODE_10GBASER) &&
610
+ phydev->link) {
434611 /* The PHY automatically switches its serdes interface (and
435
- * active PHYXS instance) between Cisco SGMII and 10GBase-KR
436
- * modes according to the speed. Florian suggests setting
437
- * phydev->interface to communicate this to the MAC. Only do
438
- * this if we are already in either SGMII or 10GBase-KR mode.
612
+ * active PHYXS instance) between Cisco SGMII, 10GBase-R and
613
+ * 2500BaseX modes according to the speed. Florian suggests
614
+ * setting phydev->interface to communicate this to the MAC.
615
+ * Only do this if we are already in one of the above modes.
439616 */
440
- if (phydev->speed == SPEED_10000)
441
- phydev->interface = PHY_INTERFACE_MODE_10GKR;
442
- else if (phydev->speed >= SPEED_10 &&
443
- phydev->speed < SPEED_10000)
617
+ switch (phydev->speed) {
618
+ case SPEED_10000:
619
+ phydev->interface = PHY_INTERFACE_MODE_10GBASER;
620
+ break;
621
+ case SPEED_2500:
622
+ phydev->interface = PHY_INTERFACE_MODE_2500BASEX;
623
+ break;
624
+ case SPEED_1000:
625
+ case SPEED_100:
626
+ case SPEED_10:
444627 phydev->interface = PHY_INTERFACE_MODE_SGMII;
628
+ break;
629
+ default:
630
+ break;
631
+ }
445632 }
446633 }
447634
448635 /* 10GBASE-ER,LR,LRM,SR do not support autonegotiation. */
449
-static int mv3310_read_10gbr_status(struct phy_device *phydev)
636
+static int mv3310_read_status_10gbaser(struct phy_device *phydev)
450637 {
451638 phydev->link = 1;
452639 phydev->speed = SPEED_10000;
453640 phydev->duplex = DUPLEX_FULL;
454
-
455
- mv3310_update_interface(phydev);
641
+ phydev->port = PORT_FIBRE;
456642
457643 return 0;
458644 }
459645
460
-static int mv3310_read_status(struct phy_device *phydev)
646
+static int mv3310_read_status_copper(struct phy_device *phydev)
461647 {
462
- u32 mmd_mask = phydev->c45_ids.devices_in_package;
463
- int val;
648
+ int cssr1, speed, val;
464649
465
- /* The vendor devads do not report link status. Avoid the PHYXS
466
- * instance as there are three, and its status depends on the MAC
467
- * being appropriately configured for the negotiated speed.
468
- */
469
- mmd_mask &= ~(BIT(MDIO_MMD_VEND1) | BIT(MDIO_MMD_VEND2) |
470
- BIT(MDIO_MMD_PHYXS));
471
-
472
- phydev->speed = SPEED_UNKNOWN;
473
- phydev->duplex = DUPLEX_UNKNOWN;
474
- phydev->lp_advertising = 0;
475
- phydev->link = 0;
476
- phydev->pause = 0;
477
- phydev->asym_pause = 0;
478
- phydev->mdix = 0;
479
-
480
- val = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_BASE_R + MDIO_STAT1);
650
+ val = genphy_c45_read_link(phydev);
481651 if (val < 0)
482652 return val;
483
-
484
- if (val & MDIO_STAT1_LSTATUS)
485
- return mv3310_read_10gbr_status(phydev);
486
-
487
- val = genphy_c45_read_link(phydev, mmd_mask);
488
- if (val < 0)
489
- return val;
490
-
491
- phydev->link = val > 0 ? 1 : 0;
492653
493654 val = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_STAT1);
494655 if (val < 0)
495656 return val;
657
+
658
+ cssr1 = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_CSSR1);
659
+ if (cssr1 < 0)
660
+ return cssr1;
661
+
662
+ /* If the link settings are not resolved, mark the link down */
663
+ if (!(cssr1 & MV_PCS_CSSR1_RESOLVED)) {
664
+ phydev->link = 0;
665
+ return 0;
666
+ }
667
+
668
+ /* Read the copper link settings */
669
+ speed = cssr1 & MV_PCS_CSSR1_SPD1_MASK;
670
+ if (speed == MV_PCS_CSSR1_SPD1_SPD2)
671
+ speed |= cssr1 & MV_PCS_CSSR1_SPD2_MASK;
672
+
673
+ switch (speed) {
674
+ case MV_PCS_CSSR1_SPD1_SPD2 | MV_PCS_CSSR1_SPD2_10000:
675
+ phydev->speed = SPEED_10000;
676
+ break;
677
+
678
+ case MV_PCS_CSSR1_SPD1_SPD2 | MV_PCS_CSSR1_SPD2_5000:
679
+ phydev->speed = SPEED_5000;
680
+ break;
681
+
682
+ case MV_PCS_CSSR1_SPD1_SPD2 | MV_PCS_CSSR1_SPD2_2500:
683
+ phydev->speed = SPEED_2500;
684
+ break;
685
+
686
+ case MV_PCS_CSSR1_SPD1_1000:
687
+ phydev->speed = SPEED_1000;
688
+ break;
689
+
690
+ case MV_PCS_CSSR1_SPD1_100:
691
+ phydev->speed = SPEED_100;
692
+ break;
693
+
694
+ case MV_PCS_CSSR1_SPD1_10:
695
+ phydev->speed = SPEED_10;
696
+ break;
697
+ }
698
+
699
+ phydev->duplex = cssr1 & MV_PCS_CSSR1_DUPLEX_FULL ?
700
+ DUPLEX_FULL : DUPLEX_HALF;
701
+ phydev->port = PORT_TP;
702
+ phydev->mdix = cssr1 & MV_PCS_CSSR1_MDIX ?
703
+ ETH_TP_MDI_X : ETH_TP_MDI;
496704
497705 if (val & MDIO_AN_STAT1_COMPLETE) {
498706 val = genphy_c45_read_lpa(phydev);
....@@ -504,61 +712,72 @@
504712 if (val < 0)
505713 return val;
506714
507
- phydev->lp_advertising |= mii_stat1000_to_ethtool_lpa_t(val);
715
+ mii_stat1000_mod_linkmode_lpa_t(phydev->lp_advertising, val);
508716
509
- if (phydev->autoneg == AUTONEG_ENABLE)
510
- phy_resolve_aneg_linkmode(phydev);
717
+ /* Update the pause status */
718
+ phy_resolve_aneg_pause(phydev);
511719 }
512
-
513
- if (phydev->autoneg != AUTONEG_ENABLE) {
514
- val = genphy_c45_read_pma(phydev);
515
- if (val < 0)
516
- return val;
517
- }
518
-
519
- if (phydev->speed == SPEED_10000) {
520
- val = genphy_c45_read_mdix(phydev);
521
- if (val < 0)
522
- return val;
523
- } else {
524
- val = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_PAIRSWAP);
525
- if (val < 0)
526
- return val;
527
-
528
- switch (val & MV_PCS_PAIRSWAP_MASK) {
529
- case MV_PCS_PAIRSWAP_AB:
530
- phydev->mdix = ETH_TP_MDI_X;
531
- break;
532
- case MV_PCS_PAIRSWAP_NONE:
533
- phydev->mdix = ETH_TP_MDI;
534
- break;
535
- default:
536
- phydev->mdix = ETH_TP_MDI_INVALID;
537
- break;
538
- }
539
- }
540
-
541
- mv3310_update_interface(phydev);
542720
543721 return 0;
544722 }
545723
724
+static int mv3310_read_status(struct phy_device *phydev)
725
+{
726
+ int err, val;
727
+
728
+ phydev->speed = SPEED_UNKNOWN;
729
+ phydev->duplex = DUPLEX_UNKNOWN;
730
+ linkmode_zero(phydev->lp_advertising);
731
+ phydev->link = 0;
732
+ phydev->pause = 0;
733
+ phydev->asym_pause = 0;
734
+ phydev->mdix = ETH_TP_MDI_INVALID;
735
+
736
+ val = phy_read_mmd(phydev, MDIO_MMD_PCS, MV_PCS_BASE_R + MDIO_STAT1);
737
+ if (val < 0)
738
+ return val;
739
+
740
+ if (val & MDIO_STAT1_LSTATUS)
741
+ err = mv3310_read_status_10gbaser(phydev);
742
+ else
743
+ err = mv3310_read_status_copper(phydev);
744
+ if (err < 0)
745
+ return err;
746
+
747
+ if (phydev->link)
748
+ mv3310_update_interface(phydev);
749
+
750
+ return 0;
751
+}
752
+
753
+static int mv3310_get_tunable(struct phy_device *phydev,
754
+ struct ethtool_tunable *tuna, void *data)
755
+{
756
+ switch (tuna->id) {
757
+ case ETHTOOL_PHY_EDPD:
758
+ return mv3310_get_edpd(phydev, data);
759
+ default:
760
+ return -EOPNOTSUPP;
761
+ }
762
+}
763
+
764
+static int mv3310_set_tunable(struct phy_device *phydev,
765
+ struct ethtool_tunable *tuna, const void *data)
766
+{
767
+ switch (tuna->id) {
768
+ case ETHTOOL_PHY_EDPD:
769
+ return mv3310_set_edpd(phydev, *(u16 *)data);
770
+ default:
771
+ return -EOPNOTSUPP;
772
+ }
773
+}
774
+
546775 static struct phy_driver mv3310_drivers[] = {
547776 {
548
- .phy_id = 0x002b09aa,
777
+ .phy_id = MARVELL_PHY_ID_88X3310,
549778 .phy_id_mask = MARVELL_PHY_ID_MASK,
550779 .name = "mv88x3310",
551
- .features = SUPPORTED_10baseT_Full |
552
- SUPPORTED_10baseT_Half |
553
- SUPPORTED_100baseT_Full |
554
- SUPPORTED_100baseT_Half |
555
- SUPPORTED_1000baseT_Full |
556
- SUPPORTED_Autoneg |
557
- SUPPORTED_TP |
558
- SUPPORTED_FIBRE |
559
- SUPPORTED_10000baseT_Full |
560
- SUPPORTED_Backplane,
561
- .soft_reset = gen10g_no_soft_reset,
780
+ .get_features = mv3310_get_features,
562781 .config_init = mv3310_config_init,
563782 .probe = mv3310_probe,
564783 .suspend = mv3310_suspend,
....@@ -566,13 +785,32 @@
566785 .config_aneg = mv3310_config_aneg,
567786 .aneg_done = mv3310_aneg_done,
568787 .read_status = mv3310_read_status,
788
+ .get_tunable = mv3310_get_tunable,
789
+ .set_tunable = mv3310_set_tunable,
790
+ .remove = mv3310_remove,
791
+ },
792
+ {
793
+ .phy_id = MARVELL_PHY_ID_88E2110,
794
+ .phy_id_mask = MARVELL_PHY_ID_MASK,
795
+ .name = "mv88x2110",
796
+ .probe = mv3310_probe,
797
+ .suspend = mv3310_suspend,
798
+ .resume = mv3310_resume,
799
+ .config_init = mv3310_config_init,
800
+ .config_aneg = mv3310_config_aneg,
801
+ .aneg_done = mv3310_aneg_done,
802
+ .read_status = mv3310_read_status,
803
+ .get_tunable = mv3310_get_tunable,
804
+ .set_tunable = mv3310_set_tunable,
805
+ .remove = mv3310_remove,
569806 },
570807 };
571808
572809 module_phy_driver(mv3310_drivers);
573810
574811 static struct mdio_device_id __maybe_unused mv3310_tbl[] = {
575
- { 0x002b09aa, MARVELL_PHY_ID_MASK },
812
+ { MARVELL_PHY_ID_88X3310, MARVELL_PHY_ID_MASK },
813
+ { MARVELL_PHY_ID_88E2110, MARVELL_PHY_ID_MASK },
576814 { },
577815 };
578816 MODULE_DEVICE_TABLE(mdio, mv3310_tbl);