blob: a7a4481152e3be54a12d6c827c0f8b6a37fff44d [file] [log] [blame]
developerc9bd9ae2022-12-23 16:54:36 +08001--- a/drivers/net/phy/mdio-i2c.c
2+++ b/drivers/net/phy/mdio-i2c.c
developer90020932023-03-10 18:51:34 +08003@@ -12,6 +12,7 @@
developerc9bd9ae2022-12-23 16:54:36 +08004 #include <linux/i2c.h>
developer90020932023-03-10 18:51:34 +08005 #include <linux/mdio/mdio-i2c.h>
developerc9bd9ae2022-12-23 16:54:36 +08006 #include <linux/phy.h>
7+#include <linux/sfp.h>
8
developer90020932023-03-10 18:51:34 +08009 /*
10 * I2C bus addresses 0x50 and 0x51 are normally an EEPROM, which is
11@@ -28,7 +29,7 @@ static unsigned int i2c_mii_phy_addr(int
developerc9bd9ae2022-12-23 16:54:36 +080012 return phy_id + 0x40;
13 }
14
15-static int i2c_mii_read(struct mii_bus *bus, int phy_id, int reg)
16+static int i2c_mii_read_default(struct mii_bus *bus, int phy_id, int reg)
17 {
18 struct i2c_adapter *i2c = bus->priv;
19 struct i2c_msg msgs[2];
developer90020932023-03-10 18:51:34 +080020@@ -62,7 +63,8 @@ static int i2c_mii_read(struct mii_bus *
developerc9bd9ae2022-12-23 16:54:36 +080021 return data[0] << 8 | data[1];
22 }
23
24-static int i2c_mii_write(struct mii_bus *bus, int phy_id, int reg, u16 val)
25+static int i2c_mii_write_default(struct mii_bus *bus, int phy_id, int reg,
26+ u16 val)
27 {
28 struct i2c_adapter *i2c = bus->priv;
29 struct i2c_msg msg;
developer90020932023-03-10 18:51:34 +080030@@ -91,9 +93,288 @@ static int i2c_mii_write(struct mii_bus
developerc9bd9ae2022-12-23 16:54:36 +080031 return ret < 0 ? ret : 0;
32 }
33
34-struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c)
35+/* RollBall SFPs do not access internal PHY via I2C address 0x56, but
36+ * instead via address 0x51, when SFP page is set to 0x03 and password to
37+ * 0xffffffff.
38+ *
39+ * address size contents description
40+ * ------- ---- -------- -----------
41+ * 0x80 1 CMD 0x01/0x02/0x04 for write/read/done
42+ * 0x81 1 DEV Clause 45 device
43+ * 0x82 2 REG Clause 45 register
44+ * 0x84 2 VAL Register value
45+ */
46+#define ROLLBALL_PHY_I2C_ADDR 0x51
47+
48+#define ROLLBALL_PASSWORD (SFP_VSL + 3)
49+
50+#define ROLLBALL_CMD_ADDR 0x80
51+#define ROLLBALL_DATA_ADDR 0x81
52+
53+#define ROLLBALL_CMD_WRITE 0x01
54+#define ROLLBALL_CMD_READ 0x02
55+#define ROLLBALL_CMD_DONE 0x04
56+
57+#define SFP_PAGE_ROLLBALL_MDIO 3
58+
59+static int __i2c_transfer_err(struct i2c_adapter *i2c, struct i2c_msg *msgs,
60+ int num)
61+{
62+ int ret;
63+
64+ ret = __i2c_transfer(i2c, msgs, num);
65+ if (ret < 0)
66+ return ret;
67+ else if (ret != num)
68+ return -EIO;
69+ else
70+ return 0;
71+}
72+
73+static int __i2c_rollball_get_page(struct i2c_adapter *i2c, int bus_addr,
74+ u8 *page)
75+{
76+ struct i2c_msg msgs[2];
77+ u8 addr = SFP_PAGE;
78+
79+ msgs[0].addr = bus_addr;
80+ msgs[0].flags = 0;
81+ msgs[0].len = 1;
82+ msgs[0].buf = &addr;
83+
84+ msgs[1].addr = bus_addr;
85+ msgs[1].flags = I2C_M_RD;
86+ msgs[1].len = 1;
87+ msgs[1].buf = page;
88+
89+ return __i2c_transfer_err(i2c, msgs, 2);
90+}
91+
92+static int __i2c_rollball_set_page(struct i2c_adapter *i2c, int bus_addr,
93+ u8 page)
94+{
95+ struct i2c_msg msg;
96+ u8 buf[2];
97+
98+ buf[0] = SFP_PAGE;
99+ buf[1] = page;
100+
101+ msg.addr = bus_addr;
102+ msg.flags = 0;
103+ msg.len = 2;
104+ msg.buf = buf;
105+
106+ return __i2c_transfer_err(i2c, &msg, 1);
107+}
108+
109+/* In order to not interfere with other SFP code (which possibly may manipulate
110+ * SFP_PAGE), for every transfer we do this:
111+ * 1. lock the bus
112+ * 2. save content of SFP_PAGE
113+ * 3. set SFP_PAGE to 3
114+ * 4. do the transfer
115+ * 5. restore original SFP_PAGE
116+ * 6. unlock the bus
117+ * Note that one might think that steps 2 to 5 could be theoretically done all
118+ * in one call to i2c_transfer (by constructing msgs array in such a way), but
119+ * unfortunately tests show that this does not work :-( Changed SFP_PAGE does
120+ * not take into account until i2c_transfer() is done.
121+ */
122+static int i2c_transfer_rollball(struct i2c_adapter *i2c,
123+ struct i2c_msg *msgs, int num)
124+{
125+ int ret, main_err = 0;
126+ u8 saved_page;
127+
128+ i2c_lock_bus(i2c, I2C_LOCK_SEGMENT);
129+
130+ /* save original page */
131+ ret = __i2c_rollball_get_page(i2c, msgs->addr, &saved_page);
132+ if (ret)
133+ goto unlock;
134+
135+ /* change to RollBall MDIO page */
136+ ret = __i2c_rollball_set_page(i2c, msgs->addr, SFP_PAGE_ROLLBALL_MDIO);
137+ if (ret)
138+ goto unlock;
139+
140+ /* do the transfer; we try to restore original page if this fails */
141+ ret = __i2c_transfer_err(i2c, msgs, num);
142+ if (ret)
143+ main_err = ret;
144+
145+ /* restore original page */
146+ ret = __i2c_rollball_set_page(i2c, msgs->addr, saved_page);
147+
148+unlock:
149+ i2c_unlock_bus(i2c, I2C_LOCK_SEGMENT);
150+
151+ return main_err ? : ret;
152+}
153+
154+static int i2c_rollball_mii_poll(struct mii_bus *bus, int bus_addr, u8 *buf,
155+ size_t len)
156+{
157+ struct i2c_adapter *i2c = bus->priv;
158+ struct i2c_msg msgs[2];
159+ u8 cmd_addr, tmp, *res;
160+ int i, ret;
161+
162+ cmd_addr = ROLLBALL_CMD_ADDR;
163+
164+ res = buf ? buf : &tmp;
165+ len = buf ? len : 1;
166+
167+ msgs[0].addr = bus_addr;
168+ msgs[0].flags = 0;
169+ msgs[0].len = 1;
170+ msgs[0].buf = &cmd_addr;
171+
172+ msgs[1].addr = bus_addr;
173+ msgs[1].flags = I2C_M_RD;
174+ msgs[1].len = len;
175+ msgs[1].buf = res;
176+
177+ /* By experiment it takes up to 70 ms to access a register for these
178+ * SFPs. Sleep 20ms between iterations and try 10 times.
179+ */
180+ i = 10;
181+ do {
182+ msleep(20);
183+
184+ ret = i2c_transfer_rollball(i2c, msgs, ARRAY_SIZE(msgs));
185+ if (ret)
186+ return ret;
187+
188+ if (*res == ROLLBALL_CMD_DONE)
189+ return 0;
190+ } while (i-- > 0);
191+
192+ dev_info(&bus->dev, "poll timed out\n");
193+
194+ return -ETIMEDOUT;
195+}
196+
197+static int i2c_rollball_mii_cmd(struct mii_bus *bus, int bus_addr, u8 cmd,
198+ u8 *data, size_t len)
199+{
200+ struct i2c_adapter *i2c = bus->priv;
201+ struct i2c_msg msgs[2];
202+ u8 cmdbuf[2];
203+
204+ cmdbuf[0] = ROLLBALL_CMD_ADDR;
205+ cmdbuf[1] = cmd;
206+
207+ msgs[0].addr = bus_addr;
208+ msgs[0].flags = 0;
209+ msgs[0].len = len;
210+ msgs[0].buf = data;
211+
212+ msgs[1].addr = bus_addr;
213+ msgs[1].flags = 0;
214+ msgs[1].len = sizeof(cmdbuf);
215+ msgs[1].buf = cmdbuf;
216+
217+ return i2c_transfer_rollball(i2c, msgs, ARRAY_SIZE(msgs));
218+}
219+
220+static int i2c_mii_read_rollball(struct mii_bus *bus, int phy_id, int reg)
221+{
222+ u8 buf[4], res[6];
223+ int bus_addr, ret;
224+ u16 val;
225+
226+ if (!(reg & MII_ADDR_C45))
227+ return -EOPNOTSUPP;
228+
229+ bus_addr = i2c_mii_phy_addr(phy_id);
230+ if (bus_addr != ROLLBALL_PHY_I2C_ADDR)
231+ return 0xffff;
232+
233+ buf[0] = ROLLBALL_DATA_ADDR;
234+ buf[1] = (reg >> 16) & 0x1f;
235+ buf[2] = (reg >> 8) & 0xff;
236+ buf[3] = reg & 0xff;
237+
238+ ret = i2c_rollball_mii_cmd(bus, bus_addr, ROLLBALL_CMD_READ, buf,
239+ sizeof(buf));
240+ if (ret < 0)
241+ return ret;
242+
243+ ret = i2c_rollball_mii_poll(bus, bus_addr, res, sizeof(res));
244+ if (ret == -ETIMEDOUT)
245+ return 0xffff;
246+ else if (ret < 0)
247+ return ret;
248+
249+ val = res[4] << 8 | res[5];
250+
251+ return val;
252+}
253+
254+static int i2c_mii_write_rollball(struct mii_bus *bus, int phy_id, int reg,
255+ u16 val)
256+{
257+ int bus_addr, ret;
258+ u8 buf[6];
259+
260+ if (!(reg & MII_ADDR_C45))
261+ return -EOPNOTSUPP;
262+
263+ bus_addr = i2c_mii_phy_addr(phy_id);
264+ if (bus_addr != ROLLBALL_PHY_I2C_ADDR)
265+ return 0;
266+
267+ buf[0] = ROLLBALL_DATA_ADDR;
268+ buf[1] = (reg >> 16) & 0x1f;
269+ buf[2] = (reg >> 8) & 0xff;
270+ buf[3] = reg & 0xff;
271+ buf[4] = val >> 8;
272+ buf[5] = val & 0xff;
273+
274+ ret = i2c_rollball_mii_cmd(bus, bus_addr, ROLLBALL_CMD_WRITE, buf,
275+ sizeof(buf));
276+ if (ret < 0)
277+ return ret;
278+
279+ ret = i2c_rollball_mii_poll(bus, bus_addr, NULL, 0);
280+ if (ret < 0)
281+ return ret;
282+
283+ return 0;
284+}
285+
286+static int i2c_mii_init_rollball(struct i2c_adapter *i2c)
287+{
288+ struct i2c_msg msg;
289+ u8 pw[5];
290+ int ret;
291+
292+ pw[0] = ROLLBALL_PASSWORD;
293+ pw[1] = 0xff;
294+ pw[2] = 0xff;
295+ pw[3] = 0xff;
296+ pw[4] = 0xff;
297+
298+ msg.addr = ROLLBALL_PHY_I2C_ADDR;
299+ msg.flags = 0;
300+ msg.len = sizeof(pw);
301+ msg.buf = pw;
302+
303+ ret = i2c_transfer(i2c, &msg, 1);
304+ if (ret < 0)
305+ return ret;
306+ else if (ret != 1)
307+ return -EIO;
308+ else
309+ return 0;
310+}
311+
312+struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c,
313+ enum mdio_i2c_proto protocol)
314 {
315 struct mii_bus *mii;
316+ int ret;
317
318 if (!i2c_check_functionality(i2c, I2C_FUNC_I2C))
319 return ERR_PTR(-EINVAL);
developer90020932023-03-10 18:51:34 +0800320@@ -104,10 +385,28 @@ struct mii_bus *mdio_i2c_alloc(struct de
developerc9bd9ae2022-12-23 16:54:36 +0800321
322 snprintf(mii->id, MII_BUS_ID_SIZE, "i2c:%s", dev_name(parent));
323 mii->parent = parent;
324- mii->read = i2c_mii_read;
325- mii->write = i2c_mii_write;
326 mii->priv = i2c;
327
328+ switch (protocol) {
329+ case MDIO_I2C_ROLLBALL:
330+ ret = i2c_mii_init_rollball(i2c);
331+ if (ret < 0) {
332+ dev_err(parent,
333+ "Cannot initialize RollBall MDIO I2C protocol: %d\n",
334+ ret);
335+ mdiobus_free(mii);
336+ return ERR_PTR(ret);
337+ }
338+
339+ mii->read = i2c_mii_read_rollball;
340+ mii->write = i2c_mii_write_rollball;
341+ break;
342+ default:
343+ mii->read = i2c_mii_read_default;
344+ mii->write = i2c_mii_write_default;
345+ break;
346+ }
347+
348 return mii;
349 }
350 EXPORT_SYMBOL_GPL(mdio_i2c_alloc);
developer45b00642023-02-20 10:32:20 +0800351--- a/include/linux/mdio/mdio-i2c.h
352+++ b/include/linux/mdio/mdio-i2c.h
developerc9bd9ae2022-12-23 16:54:36 +0800353@@ -11,6 +11,14 @@ struct device;
354 struct i2c_adapter;
355 struct mii_bus;
356
357-struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c);
358+enum mdio_i2c_proto {
359+ MDIO_I2C_NONE,
360+ MDIO_I2C_MARVELL_C22,
361+ MDIO_I2C_C45,
362+ MDIO_I2C_ROLLBALL,
363+};
364+
365+struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c,
366+ enum mdio_i2c_proto protocol);
367
368 #endif
developer82eae452023-02-13 10:04:09 +0800369--- a/drivers/net/phy/phylink.c
370+++ b/drivers/net/phy/phylink.c
developer90020932023-03-10 18:51:34 +0800371@@ -483,62 +483,105 @@ static void phylink_resolve(struct work_
developer82eae452023-02-13 10:04:09 +0800372 struct phylink *pl = container_of(w, struct phylink, resolve);
373 struct phylink_link_state link_state;
374 struct net_device *ndev = pl->netdev;
375- int link_changed;
376+ bool mac_config = false;
377+ bool retrigger = false;
378+ bool cur_link_state;
379
380 mutex_lock(&pl->state_mutex);
381+ if (pl->netdev)
382+ cur_link_state = netif_carrier_ok(ndev);
383+ else
384+ cur_link_state = pl->old_link_state;
385+
386 if (pl->phylink_disable_state) {
387 pl->mac_link_dropped = false;
388 link_state.link = false;
389 } else if (pl->mac_link_dropped) {
390 link_state.link = false;
391+ retrigger = true;
392 } else {
393 switch (pl->cur_link_an_mode) {
394 case MLO_AN_PHY:
395 link_state = pl->phy_state;
396 phylink_resolve_flow(pl, &link_state);
397- phylink_mac_config_up(pl, &link_state);
398+ mac_config = link_state.link;
399 break;
400
401 case MLO_AN_FIXED:
402 phylink_get_fixed_state(pl, &link_state);
403- phylink_mac_config_up(pl, &link_state);
404+ mac_config = link_state.link;
405 break;
406
407 case MLO_AN_INBAND:
408 phylink_get_mac_state(pl, &link_state);
409
410+ /* The PCS may have a latching link-fail indicator.
411+ * If the link was up, bring the link down and
412+ * re-trigger the resolve. Otherwise, re-read the
413+ * PCS state to get the current status of the link.
414+ */
415+ if (!link_state.link) {
416+ if (cur_link_state)
417+ retrigger = true;
418+ else
419+ phylink_get_mac_state(pl,
420+ &link_state);
421+ }
422+
423 /* If we have a phy, the "up" state is the union of
424- * both the PHY and the MAC */
425+ * both the PHY and the MAC
426+ */
427 if (pl->phydev)
428 link_state.link &= pl->phy_state.link;
429
430 /* Only update if the PHY link is up */
431 if (pl->phydev && pl->phy_state.link) {
432+ /* If the interface has changed, force a
433+ * link down event if the link isn't already
434+ * down, and re-resolve.
435+ */
436+ if (link_state.interface !=
437+ pl->phy_state.interface) {
438+ retrigger = true;
439+ link_state.link = false;
440+ }
441 link_state.interface = pl->phy_state.interface;
442
443 /* If we have a PHY, we need to update with
444- * the pause mode bits. */
445- link_state.pause |= pl->phy_state.pause;
446- phylink_resolve_flow(pl, &link_state);
447- phylink_mac_config(pl, &link_state);
448+ * the PHY flow control bits.
449+ */
450+ link_state.pause = pl->phy_state.pause;
451+ mac_config = true;
452 }
453+ phylink_resolve_flow(pl, &link_state);
454 break;
455 }
456 }
457
458- if (pl->netdev)
459- link_changed = (link_state.link != netif_carrier_ok(ndev));
460- else
461- link_changed = (link_state.link != pl->old_link_state);
462+ if (mac_config) {
463+ if (link_state.interface != pl->link_config.interface) {
464+ /* The interface has changed, force the link down and
465+ * then reconfigure.
466+ */
467+ if (cur_link_state) {
468+ phylink_mac_link_down(pl);
469+ cur_link_state = false;
470+ }
471+ phylink_mac_config(pl, &link_state);
472+ pl->link_config.interface = link_state.interface;
473+ } else {
474+ phylink_mac_config(pl, &link_state);
475+ }
476+ }
477
478- if (link_changed) {
479+ if (link_state.link != cur_link_state) {
480 pl->old_link_state = link_state.link;
481 if (!link_state.link)
482 phylink_mac_link_down(pl);
483 else
484 phylink_mac_link_up(pl, link_state);
485 }
486- if (!link_state.link && pl->mac_link_dropped) {
487+ if (!link_state.link && retrigger) {
488 pl->mac_link_dropped = false;
489 queue_work(system_power_efficient_wq, &pl->resolve);
490 }
491@@ -1014,7 +1057,8 @@ void phylink_start(struct phylink *pl)
492 if (irq <= 0)
493 mod_timer(&pl->link_poll, jiffies + HZ);
494 }
495- if (pl->cfg_link_an_mode == MLO_AN_FIXED && pl->get_fixed_state)
496+ if ((pl->cfg_link_an_mode == MLO_AN_FIXED && pl->get_fixed_state) ||
497+ (pl->cfg_link_an_mode == MLO_AN_INBAND))
498 mod_timer(&pl->link_poll, jiffies + HZ);
499 if (pl->phydev)
500 phy_start(pl->phydev);
developerc9bd9ae2022-12-23 16:54:36 +0800501--- a/drivers/net/phy/sfp-bus.c
502+++ b/drivers/net/phy/sfp-bus.c
503@@ -10,12 +10,6 @@
504
505 #include "sfp.h"
506
507-struct sfp_quirk {
508- const char *vendor;
509- const char *part;
510- void (*modes)(const struct sfp_eeprom_id *id, unsigned long *modes);
511-};
512-
513 /**
514 * struct sfp_bus - internal representation of a sfp bus
515 */
516@@ -38,87 +32,6 @@ struct sfp_bus {
517 bool started;
518 };
519
520-static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
521- unsigned long *modes)
522-{
523- phylink_set(modes, 2500baseX_Full);
524-}
525-
526-static void sfp_quirk_ubnt_uf_instant(const struct sfp_eeprom_id *id,
527- unsigned long *modes)
528-{
529- /* Ubiquiti U-Fiber Instant module claims that support all transceiver
530- * types including 10G Ethernet which is not truth. So clear all claimed
531- * modes and set only one mode which module supports: 1000baseX_Full.
532- */
533- phylink_zero(modes);
534- phylink_set(modes, 1000baseX_Full);
535-}
536-
537-static const struct sfp_quirk sfp_quirks[] = {
538- {
539- // Alcatel Lucent G-010S-P can operate at 2500base-X, but
540- // incorrectly report 2500MBd NRZ in their EEPROM
541- .vendor = "ALCATELLUCENT",
542- .part = "G010SP",
543- .modes = sfp_quirk_2500basex,
544- }, {
545- // Alcatel Lucent G-010S-A can operate at 2500base-X, but
546- // report 3.2GBd NRZ in their EEPROM
547- .vendor = "ALCATELLUCENT",
548- .part = "3FE46541AA",
549- .modes = sfp_quirk_2500basex,
550- }, {
551- // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd
552- // NRZ in their EEPROM
553- .vendor = "HUAWEI",
554- .part = "MA5671A",
555- .modes = sfp_quirk_2500basex,
556- }, {
557- .vendor = "UBNT",
558- .part = "UF-INSTANT",
559- .modes = sfp_quirk_ubnt_uf_instant,
560- },
561-};
562-
563-static size_t sfp_strlen(const char *str, size_t maxlen)
564-{
565- size_t size, i;
566-
567- /* Trailing characters should be filled with space chars */
568- for (i = 0, size = 0; i < maxlen; i++)
569- if (str[i] != ' ')
570- size = i + 1;
571-
572- return size;
573-}
574-
575-static bool sfp_match(const char *qs, const char *str, size_t len)
576-{
577- if (!qs)
578- return true;
579- if (strlen(qs) != len)
580- return false;
581- return !strncmp(qs, str, len);
582-}
583-
584-static const struct sfp_quirk *sfp_lookup_quirk(const struct sfp_eeprom_id *id)
585-{
586- const struct sfp_quirk *q;
587- unsigned int i;
588- size_t vs, ps;
589-
590- vs = sfp_strlen(id->base.vendor_name, ARRAY_SIZE(id->base.vendor_name));
591- ps = sfp_strlen(id->base.vendor_pn, ARRAY_SIZE(id->base.vendor_pn));
592-
593- for (i = 0, q = sfp_quirks; i < ARRAY_SIZE(sfp_quirks); i++, q++)
594- if (sfp_match(q->vendor, id->base.vendor_name, vs) &&
595- sfp_match(q->part, id->base.vendor_pn, ps))
596- return q;
597-
598- return NULL;
599-}
600-
601 /**
602 * sfp_parse_port() - Parse the EEPROM base ID, setting the port type
603 * @bus: a pointer to the &struct sfp_bus structure for the sfp module
developer90020932023-03-10 18:51:34 +0800604@@ -359,7 +272,7 @@ void sfp_parse_support(struct sfp_bus *b
developerc9bd9ae2022-12-23 16:54:36 +0800605 phylink_set(modes, 1000baseX_Full);
606 }
607
608- if (bus->sfp_quirk)
609+ if (bus->sfp_quirk && bus->sfp_quirk->modes)
610 bus->sfp_quirk->modes(id, modes);
611
612 bitmap_or(support, support, modes, __ETHTOOL_LINK_MODE_MASK_NBITS);
developer90020932023-03-10 18:51:34 +0800613@@ -737,12 +650,13 @@ void sfp_link_down(struct sfp_bus *bus)
developerc9bd9ae2022-12-23 16:54:36 +0800614 }
615 EXPORT_SYMBOL_GPL(sfp_link_down);
616
617-int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id)
618+int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
619+ const struct sfp_quirk *quirk)
620 {
621 const struct sfp_upstream_ops *ops = sfp_get_upstream_ops(bus);
622 int ret = 0;
623
624- bus->sfp_quirk = sfp_lookup_quirk(id);
625+ bus->sfp_quirk = quirk;
626
627 if (ops && ops->module_insert)
628 ret = ops->module_insert(bus->upstream, id);
developerc9bd9ae2022-12-23 16:54:36 +0800629--- a/drivers/net/phy/sfp.c
630+++ b/drivers/net/phy/sfp.c
developer90020932023-03-10 18:51:34 +0800631@@ -165,6 +165,7 @@ static const enum gpiod_flags gpio_flags
developerc9bd9ae2022-12-23 16:54:36 +0800632 * on board (for a copper SFP) time to initialise.
633 */
634 #define T_WAIT msecs_to_jiffies(50)
635+#define T_WAIT_ROLLBALL msecs_to_jiffies(25000)
636 #define T_START_UP msecs_to_jiffies(300)
637 #define T_START_UP_BAD_GPON msecs_to_jiffies(60000)
638
developer90020932023-03-10 18:51:34 +0800639@@ -204,8 +205,11 @@ static const enum gpiod_flags gpio_flags
developerc9bd9ae2022-12-23 16:54:36 +0800640
641 /* SFP modules appear to always have their PHY configured for bus address
642 * 0x56 (which with mdio-i2c, translates to a PHY address of 22).
643+ * RollBall SFPs access phy via SFP Enhanced Digital Diagnostic Interface
644+ * via address 0x51 (mdio-i2c will use RollBall protocol on this address).
645 */
646-#define SFP_PHY_ADDR 22
647+#define SFP_PHY_ADDR 22
648+#define SFP_PHY_ADDR_ROLLBALL 17
649
650 struct sff_data {
651 unsigned int gpios;
652@@ -217,6 +221,7 @@ struct sfp {
653 struct i2c_adapter *i2c;
654 struct mii_bus *i2c_mii;
655 struct sfp_bus *sfp_bus;
656+ enum mdio_i2c_proto mdio_protocol;
657 struct phy_device *mod_phy;
658 const struct sff_data *type;
659 size_t i2c_block_size;
660@@ -233,6 +238,7 @@ struct sfp {
661 bool need_poll;
662
663 struct mutex st_mutex; /* Protects state */
664+ unsigned int state_hw_mask;
665 unsigned int state_soft_mask;
666 unsigned int state;
667 struct delayed_work poll;
668@@ -249,6 +255,10 @@ struct sfp {
669 struct sfp_eeprom_id id;
670 unsigned int module_power_mW;
671 unsigned int module_t_start_up;
672+ unsigned int module_t_wait;
673+ bool tx_fault_ignore;
674+
675+ const struct sfp_quirk *quirk;
676
677 #if IS_ENABLED(CONFIG_HWMON)
678 struct sfp_diag diag;
developer82185b72023-04-10 22:59:38 +0800679@@ -303,6 +313,144 @@ static const struct of_device_id sfp_of_
developerc9bd9ae2022-12-23 16:54:36 +0800680 };
681 MODULE_DEVICE_TABLE(of, sfp_of_match);
682
683+static void sfp_fixup_long_startup(struct sfp *sfp)
684+{
685+ sfp->module_t_start_up = T_START_UP_BAD_GPON;
686+}
687+
688+static void sfp_fixup_ignore_tx_fault(struct sfp *sfp)
689+{
690+ sfp->tx_fault_ignore = true;
691+}
692+
693+static void sfp_fixup_halny_gsfp(struct sfp *sfp)
694+{
695+ /* Ignore the TX_FAULT and LOS signals on this module.
696+ * these are possibly used for other purposes on this
697+ * module, e.g. a serial port.
698+ */
699+ sfp->state_hw_mask &= ~(SFP_F_TX_FAULT | SFP_F_LOS);
700+}
701+
702+static void sfp_fixup_rollball(struct sfp *sfp)
703+{
704+ sfp->mdio_protocol = MDIO_I2C_ROLLBALL;
705+ sfp->module_t_wait = T_WAIT_ROLLBALL;
706+}
707+
708+static void sfp_fixup_rollball_cc(struct sfp *sfp)
709+{
710+ sfp_fixup_rollball(sfp);
711+
712+ /* Some RollBall SFPs may have wrong (zero) extended compliance code
713+ * burned in EEPROM. For PHY probing we need the correct one.
714+ */
715+ sfp->id.base.extended_cc = SFF8024_ECC_10GBASE_T_SFI;
716+}
717+
718+static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
719+ unsigned long *modes)
720+{
721+ linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT, modes);
722+}
723+
developer82185b72023-04-10 22:59:38 +0800724+static void sfp_quirk_10000baseSR(const struct sfp_eeprom_id *id,
725+ unsigned long *modes)
726+{
727+ linkmode_set_bit(ETHTOOL_LINK_MODE_10000baseSR_Full_BIT, modes);
728+}
729+
developerc9bd9ae2022-12-23 16:54:36 +0800730+static void sfp_quirk_ubnt_uf_instant(const struct sfp_eeprom_id *id,
731+ unsigned long *modes)
732+{
733+ /* Ubiquiti U-Fiber Instant module claims that support all transceiver
734+ * types including 10G Ethernet which is not truth. So clear all claimed
735+ * modes and set only one mode which module supports: 1000baseX_Full.
736+ */
737+ linkmode_zero(modes);
738+ linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, modes);
739+}
740+
741+#define SFP_QUIRK(_v, _p, _m, _f) \
742+ { .vendor = _v, .part = _p, .modes = _m, .fixup = _f, }
743+#define SFP_QUIRK_M(_v, _p, _m) SFP_QUIRK(_v, _p, _m, NULL)
744+#define SFP_QUIRK_F(_v, _p, _f) SFP_QUIRK(_v, _p, NULL, _f)
745+
746+static const struct sfp_quirk sfp_quirks[] = {
747+ // Alcatel Lucent G-010S-P can operate at 2500base-X, but incorrectly
748+ // report 2500MBd NRZ in their EEPROM
749+ SFP_QUIRK_M("ALCATELLUCENT", "G010SP", sfp_quirk_2500basex),
750+
751+ // Alcatel Lucent G-010S-A can operate at 2500base-X, but report 3.2GBd
752+ // NRZ in their EEPROM
753+ SFP_QUIRK("ALCATELLUCENT", "3FE46541AA", sfp_quirk_2500basex,
754+ sfp_fixup_long_startup),
755+
756+ SFP_QUIRK_F("HALNy", "HL-GSFP", sfp_fixup_halny_gsfp),
757+
758+ // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd NRZ in
759+ // their EEPROM
760+ SFP_QUIRK("HUAWEI", "MA5671A", sfp_quirk_2500basex,
761+ sfp_fixup_ignore_tx_fault),
762+
763+ // Lantech 8330-262D-E can operate at 2500base-X, but incorrectly report
764+ // 2500MBd NRZ in their EEPROM
765+ SFP_QUIRK_M("Lantech", "8330-262D-E", sfp_quirk_2500basex),
766+
developer82185b72023-04-10 22:59:38 +0800767+ SFP_QUIRK_M("CISCO-JDSU", "PLRXPL-VC-S43-CG", sfp_quirk_10000baseSR),
768+
developerc9bd9ae2022-12-23 16:54:36 +0800769+ SFP_QUIRK_M("UBNT", "UF-INSTANT", sfp_quirk_ubnt_uf_instant),
770+
developer82eae452023-02-13 10:04:09 +0800771+ SFP_QUIRK_F("ETU", "ESP-T5-R", sfp_fixup_rollball_cc),
developerc9bd9ae2022-12-23 16:54:36 +0800772+ SFP_QUIRK_F("OEM", "SFP-10G-T", sfp_fixup_rollball_cc),
773+ SFP_QUIRK_F("OEM", "RTSFP-10", sfp_fixup_rollball_cc),
774+ SFP_QUIRK_F("OEM", "RTSFP-10G", sfp_fixup_rollball_cc),
775+ SFP_QUIRK_F("OEM", "TNBYV02-C0X-C3", sfp_fixup_rollball_cc),
776+ SFP_QUIRK_F("Turris", "RTSFP-10", sfp_fixup_rollball),
777+ SFP_QUIRK_F("Turris", "RTSFP-10G", sfp_fixup_rollball),
778+ SFP_QUIRK_F("JESS-LINK", "P60000BBC001-1", sfp_fixup_rollball),
779+};
780+
781+static size_t sfp_strlen(const char *str, size_t maxlen)
782+{
783+ size_t size, i;
784+
785+ /* Trailing characters should be filled with space chars, but
786+ * some manufacturers can't read SFF-8472 and use NUL.
787+ */
788+ for (i = 0, size = 0; i < maxlen; i++)
789+ if (str[i] != ' ' && str[i] != '\0')
790+ size = i + 1;
791+
792+ return size;
793+}
794+
795+static bool sfp_match(const char *qs, const char *str, size_t len)
796+{
797+ if (!qs)
798+ return true;
799+ if (strlen(qs) != len)
800+ return false;
801+ return !strncmp(qs, str, len);
802+}
803+
804+static const struct sfp_quirk *sfp_lookup_quirk(const struct sfp_eeprom_id *id)
805+{
806+ const struct sfp_quirk *q;
807+ unsigned int i;
808+ size_t vs, ps;
809+
810+ vs = sfp_strlen(id->base.vendor_name, ARRAY_SIZE(id->base.vendor_name));
811+ ps = sfp_strlen(id->base.vendor_pn, ARRAY_SIZE(id->base.vendor_pn));
812+
813+ for (i = 0, q = sfp_quirks; i < ARRAY_SIZE(sfp_quirks); i++, q++)
814+ if (sfp_match(q->vendor, id->base.vendor_name, vs) &&
815+ sfp_match(q->part, id->base.vendor_pn, ps))
816+ return q;
817+
818+ return NULL;
819+}
820+
821 static unsigned long poll_jiffies;
822
823 static unsigned int sfp_gpio_get_state(struct sfp *sfp)
developer90020932023-03-10 18:51:34 +0800824@@ -414,9 +554,6 @@ static int sfp_i2c_write(struct sfp *sfp
developerc9bd9ae2022-12-23 16:54:36 +0800825
826 static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
827 {
828- struct mii_bus *i2c_mii;
829- int ret;
830-
831 if (!i2c_check_functionality(i2c, I2C_FUNC_I2C))
832 return -EINVAL;
833
developer90020932023-03-10 18:51:34 +0800834@@ -424,7 +561,15 @@ static int sfp_i2c_configure(struct sfp
developerc9bd9ae2022-12-23 16:54:36 +0800835 sfp->read = sfp_i2c_read;
836 sfp->write = sfp_i2c_write;
837
838- i2c_mii = mdio_i2c_alloc(sfp->dev, i2c);
839+ return 0;
840+}
841+
842+static int sfp_i2c_mdiobus_create(struct sfp *sfp)
843+{
844+ struct mii_bus *i2c_mii;
845+ int ret;
846+
847+ i2c_mii = mdio_i2c_alloc(sfp->dev, sfp->i2c, sfp->mdio_protocol);
848 if (IS_ERR(i2c_mii))
849 return PTR_ERR(i2c_mii);
850
developer90020932023-03-10 18:51:34 +0800851@@ -442,6 +587,12 @@ static int sfp_i2c_configure(struct sfp
developerc9bd9ae2022-12-23 16:54:36 +0800852 return 0;
853 }
854
855+static void sfp_i2c_mdiobus_destroy(struct sfp *sfp)
856+{
857+ mdiobus_unregister(sfp->i2c_mii);
858+ sfp->i2c_mii = NULL;
859+}
860+
861 /* Interface */
862 static int sfp_read(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len)
863 {
developer90020932023-03-10 18:51:34 +0800864@@ -487,17 +638,18 @@ static void sfp_soft_set_state(struct sf
developerc9bd9ae2022-12-23 16:54:36 +0800865 static void sfp_soft_start_poll(struct sfp *sfp)
866 {
867 const struct sfp_eeprom_id *id = &sfp->id;
868+ unsigned int mask = 0;
869
870 sfp->state_soft_mask = 0;
871- if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_DISABLE &&
872- !sfp->gpio[GPIO_TX_DISABLE])
873- sfp->state_soft_mask |= SFP_F_TX_DISABLE;
874- if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_FAULT &&
875- !sfp->gpio[GPIO_TX_FAULT])
876- sfp->state_soft_mask |= SFP_F_TX_FAULT;
877- if (id->ext.enhopts & SFP_ENHOPTS_SOFT_RX_LOS &&
878- !sfp->gpio[GPIO_LOS])
879- sfp->state_soft_mask |= SFP_F_LOS;
880+ if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_DISABLE)
881+ mask |= SFP_F_TX_DISABLE;
882+ if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_FAULT)
883+ mask |= SFP_F_TX_FAULT;
884+ if (id->ext.enhopts & SFP_ENHOPTS_SOFT_RX_LOS)
885+ mask |= SFP_F_LOS;
886+
887+ // Poll the soft state for hardware pins we want to ignore
888+ sfp->state_soft_mask = ~sfp->state_hw_mask & mask;
889
890 if (sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT) &&
891 !sfp->need_poll)
developer90020932023-03-10 18:51:34 +0800892@@ -511,10 +663,11 @@ static void sfp_soft_stop_poll(struct sf
developerc9bd9ae2022-12-23 16:54:36 +0800893
894 static unsigned int sfp_get_state(struct sfp *sfp)
895 {
896- unsigned int state = sfp->get_state(sfp);
897+ unsigned int soft = sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT);
898+ unsigned int state;
899
900- if (state & SFP_F_PRESENT &&
901- sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT))
902+ state = sfp->get_state(sfp) & sfp->state_hw_mask;
903+ if (state & SFP_F_PRESENT && soft)
904 state |= sfp_soft_get_state(sfp);
905
906 return state;
developer90020932023-03-10 18:51:34 +0800907@@ -1448,12 +1601,12 @@ static void sfp_sm_phy_detach(struct sfp
developerc9bd9ae2022-12-23 16:54:36 +0800908 sfp->mod_phy = NULL;
909 }
910
911-static int sfp_sm_probe_phy(struct sfp *sfp, bool is_c45)
912+static int sfp_sm_probe_phy(struct sfp *sfp, int addr, bool is_c45)
913 {
914 struct phy_device *phy;
915 int err;
916
917- phy = get_phy_device(sfp->i2c_mii, SFP_PHY_ADDR, is_c45);
918+ phy = get_phy_device(sfp->i2c_mii, addr, is_c45);
919 if (phy == ERR_PTR(-ENODEV))
920 return PTR_ERR(phy);
921 if (IS_ERR(phy)) {
developer90020932023-03-10 18:51:34 +0800922@@ -1548,6 +1701,14 @@ static void sfp_sm_fault(struct sfp *sfp
developerc9bd9ae2022-12-23 16:54:36 +0800923 }
924 }
925
926+static int sfp_sm_add_mdio_bus(struct sfp *sfp)
927+{
928+ if (sfp->mdio_protocol != MDIO_I2C_NONE)
929+ return sfp_i2c_mdiobus_create(sfp);
930+
931+ return 0;
932+}
933+
934 /* Probe a SFP for a PHY device if the module supports copper - the PHY
935 * normally sits at I2C bus address 0x56, and may either be a clause 22
936 * or clause 45 PHY.
developer90020932023-03-10 18:51:34 +0800937@@ -1563,19 +1724,23 @@ static int sfp_sm_probe_for_phy(struct s
developerc9bd9ae2022-12-23 16:54:36 +0800938 {
939 int err = 0;
940
941- switch (sfp->id.base.extended_cc) {
942- case SFF8024_ECC_10GBASE_T_SFI:
943- case SFF8024_ECC_10GBASE_T_SR:
944- case SFF8024_ECC_5GBASE_T:
945- case SFF8024_ECC_2_5GBASE_T:
946- err = sfp_sm_probe_phy(sfp, true);
947+ switch (sfp->mdio_protocol) {
948+ case MDIO_I2C_NONE:
949 break;
950
951- default:
952- if (sfp->id.base.e1000_base_t)
953- err = sfp_sm_probe_phy(sfp, false);
954+ case MDIO_I2C_MARVELL_C22:
955+ err = sfp_sm_probe_phy(sfp, SFP_PHY_ADDR, false);
956+ break;
957+
958+ case MDIO_I2C_C45:
959+ err = sfp_sm_probe_phy(sfp, SFP_PHY_ADDR, true);
960+ break;
961+
962+ case MDIO_I2C_ROLLBALL:
963+ err = sfp_sm_probe_phy(sfp, SFP_PHY_ADDR_ROLLBALL, true);
964 break;
965 }
966+
967 return err;
968 }
969
developer90020932023-03-10 18:51:34 +0800970@@ -1819,11 +1984,33 @@ static int sfp_sm_mod_probe(struct sfp *
developerc9bd9ae2022-12-23 16:54:36 +0800971 if (ret < 0)
972 return ret;
973
974- if (!memcmp(id.base.vendor_name, "ALCATELLUCENT ", 16) &&
975- !memcmp(id.base.vendor_pn, "3FE46541AA ", 16))
976- sfp->module_t_start_up = T_START_UP_BAD_GPON;
977+ /* Initialise state bits to use from hardware */
978+ sfp->state_hw_mask = SFP_F_PRESENT;
979+ if (sfp->gpio[GPIO_TX_DISABLE])
980+ sfp->state_hw_mask |= SFP_F_TX_DISABLE;
981+ if (sfp->gpio[GPIO_TX_FAULT])
982+ sfp->state_hw_mask |= SFP_F_TX_FAULT;
983+ if (sfp->gpio[GPIO_LOS])
984+ sfp->state_hw_mask |= SFP_F_LOS;
985+
986+ sfp->module_t_start_up = T_START_UP;
987+ sfp->module_t_wait = T_WAIT;
988+
989+ sfp->tx_fault_ignore = false;
990+
991+ if (sfp->id.base.extended_cc == SFF8024_ECC_10GBASE_T_SFI ||
992+ sfp->id.base.extended_cc == SFF8024_ECC_10GBASE_T_SR ||
993+ sfp->id.base.extended_cc == SFF8024_ECC_5GBASE_T ||
994+ sfp->id.base.extended_cc == SFF8024_ECC_2_5GBASE_T)
995+ sfp->mdio_protocol = MDIO_I2C_C45;
996+ else if (sfp->id.base.e1000_base_t)
997+ sfp->mdio_protocol = MDIO_I2C_MARVELL_C22;
998 else
999- sfp->module_t_start_up = T_START_UP;
1000+ sfp->mdio_protocol = MDIO_I2C_NONE;
1001+
1002+ sfp->quirk = sfp_lookup_quirk(&id);
1003+ if (sfp->quirk && sfp->quirk->fixup)
1004+ sfp->quirk->fixup(sfp);
1005
1006 return 0;
1007 }
developer90020932023-03-10 18:51:34 +08001008@@ -1936,7 +2123,8 @@ static void sfp_sm_module(struct sfp *sf
developerc9bd9ae2022-12-23 16:54:36 +08001009 break;
1010
1011 /* Report the module insertion to the upstream device */
1012- err = sfp_module_insert(sfp->sfp_bus, &sfp->id);
1013+ err = sfp_module_insert(sfp->sfp_bus, &sfp->id,
1014+ sfp->quirk);
1015 if (err < 0) {
1016 sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0);
1017 break;
developer90020932023-03-10 18:51:34 +08001018@@ -1995,6 +2183,8 @@ static void sfp_sm_main(struct sfp *sfp,
developerc9bd9ae2022-12-23 16:54:36 +08001019 sfp_module_stop(sfp->sfp_bus);
1020 if (sfp->mod_phy)
1021 sfp_sm_phy_detach(sfp);
1022+ if (sfp->i2c_mii)
1023+ sfp_i2c_mdiobus_destroy(sfp);
1024 sfp_module_tx_disable(sfp);
1025 sfp_soft_stop_poll(sfp);
1026 sfp_sm_next(sfp, SFP_S_DOWN, 0);
developer90020932023-03-10 18:51:34 +08001027@@ -2018,9 +2208,10 @@ static void sfp_sm_main(struct sfp *sfp,
developerc9bd9ae2022-12-23 16:54:36 +08001028
1029 /* We need to check the TX_FAULT state, which is not defined
1030 * while TX_DISABLE is asserted. The earliest we want to do
1031- * anything (such as probe for a PHY) is 50ms.
1032+ * anything (such as probe for a PHY) is 50ms (or more on
1033+ * specific modules).
1034 */
1035- sfp_sm_next(sfp, SFP_S_WAIT, T_WAIT);
1036+ sfp_sm_next(sfp, SFP_S_WAIT, sfp->module_t_wait);
1037 break;
1038
1039 case SFP_S_WAIT:
developer90020932023-03-10 18:51:34 +08001040@@ -2034,8 +2225,8 @@ static void sfp_sm_main(struct sfp *sfp,
developerc9bd9ae2022-12-23 16:54:36 +08001041 * deasserting.
1042 */
1043 timeout = sfp->module_t_start_up;
1044- if (timeout > T_WAIT)
1045- timeout -= T_WAIT;
1046+ if (timeout > sfp->module_t_wait)
1047+ timeout -= sfp->module_t_wait;
1048 else
1049 timeout = 1;
1050
developer90020932023-03-10 18:51:34 +08001051@@ -2057,6 +2248,12 @@ static void sfp_sm_main(struct sfp *sfp,
developerc9bd9ae2022-12-23 16:54:36 +08001052 sfp->sm_fault_retries == N_FAULT_INIT);
1053 } else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) {
1054 init_done:
1055+ /* Create mdiobus and start trying for PHY */
1056+ ret = sfp_sm_add_mdio_bus(sfp);
1057+ if (ret < 0) {
1058+ sfp_sm_next(sfp, SFP_S_FAIL, 0);
1059+ break;
1060+ }
1061 sfp->sm_phy_retries = R_PHY_RETRY;
1062 goto phy_probe;
1063 }
developer90020932023-03-10 18:51:34 +08001064@@ -2409,6 +2606,8 @@ static int sfp_probe(struct platform_dev
developerc9bd9ae2022-12-23 16:54:36 +08001065 return PTR_ERR(sfp->gpio[i]);
1066 }
1067
1068+ sfp->state_hw_mask = SFP_F_PRESENT;
1069+
1070 sfp->get_state = sfp_gpio_get_state;
1071 sfp->set_state = sfp_gpio_set_state;
1072
developerc9bd9ae2022-12-23 16:54:36 +08001073--- a/drivers/net/phy/sfp.h
1074+++ b/drivers/net/phy/sfp.h
1075@@ -6,6 +6,13 @@
1076
1077 struct sfp;
1078
1079+struct sfp_quirk {
1080+ const char *vendor;
1081+ const char *part;
1082+ void (*modes)(const struct sfp_eeprom_id *id, unsigned long *modes);
1083+ void (*fixup)(struct sfp *sfp);
1084+};
1085+
1086 struct sfp_socket_ops {
1087 void (*attach)(struct sfp *sfp);
1088 void (*detach)(struct sfp *sfp);
developer90020932023-03-10 18:51:34 +08001089@@ -20,7 +27,8 @@ int sfp_add_phy(struct sfp_bus *bus, str
developerc9bd9ae2022-12-23 16:54:36 +08001090 void sfp_remove_phy(struct sfp_bus *bus);
1091 void sfp_link_up(struct sfp_bus *bus);
1092 void sfp_link_down(struct sfp_bus *bus);
1093-int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id);
1094+int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
1095+ const struct sfp_quirk *quirk);
1096 void sfp_module_remove(struct sfp_bus *bus);
1097 int sfp_module_start(struct sfp_bus *bus);
1098 void sfp_module_stop(struct sfp_bus *bus);
developerc9bd9ae2022-12-23 16:54:36 +08001099--- a/drivers/net/phy/marvell10g.c
1100+++ b/drivers/net/phy/marvell10g.c
developerf1e143b2023-01-09 16:25:59 +08001101@@ -32,6 +32,15 @@
1102 #define MV_PHY_ALASKA_NBT_QUIRK_REV (MARVELL_PHY_ID_88X3310 | 0xa)
1103
1104 enum {
1105+ MV_PMA_21X0_PORT_CTRL = 0xc04a,
1106+ MV_PMA_21X0_PORT_CTRL_SWRST = BIT(15),
1107+ MV_PMA_21X0_PORT_CTRL_MACTYPE_MASK = 0x7,
1108+ MV_PMA_21X0_PORT_CTRL_MACTYPE_USXGMII = 0x0,
1109+ MV_PMA_2180_PORT_CTRL_MACTYPE_DXGMII = 0x1,
1110+ MV_PMA_2180_PORT_CTRL_MACTYPE_QXGMII = 0x2,
1111+ MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER = 0x4,
1112+ MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER_NO_SGMII_AN = 0x5,
1113+ MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH = 0x6,
1114 MV_PMA_BOOT = 0xc050,
1115 MV_PMA_BOOT_FATAL = BIT(0),
1116
1117@@ -53,7 +62,18 @@ enum {
1118
1119 /* Vendor2 MMD registers */
1120 MV_V2_PORT_CTRL = 0xf001,
1121- MV_V2_PORT_CTRL_PWRDOWN = 0x0800,
1122+ MV_V2_PORT_CTRL_PWRDOWN = BIT(11),
1123+ MV_V2_33X0_PORT_CTRL_SWRST = BIT(15),
1124+ MV_V2_33X0_PORT_CTRL_MACTYPE_MASK = 0x7,
1125+ MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI = 0x0,
1126+ MV_V2_3310_PORT_CTRL_MACTYPE_XAUI_RATE_MATCH = 0x1,
1127+ MV_V2_3340_PORT_CTRL_MACTYPE_RXAUI_NO_SGMII_AN = 0x1,
1128+ MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI_RATE_MATCH = 0x2,
1129+ MV_V2_3310_PORT_CTRL_MACTYPE_XAUI = 0x3,
1130+ MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER = 0x4,
1131+ MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_NO_SGMII_AN = 0x5,
1132+ MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH = 0x6,
1133+ MV_V2_33X0_PORT_CTRL_MACTYPE_USXGMII = 0x7,
1134 MV_V2_TEMP_CTRL = 0xf08a,
1135 MV_V2_TEMP_CTRL_MASK = 0xc000,
1136 MV_V2_TEMP_CTRL_SAMPLE = 0x0000,
1137@@ -62,11 +82,24 @@ enum {
1138 MV_V2_TEMP_UNKNOWN = 0x9600, /* unknown function */
1139 };
1140
1141+struct mv3310_chip {
1142+ int (*get_mactype)(struct phy_device *phydev);
1143+ int (*init_interface)(struct phy_device *phydev, int mactype);
1144+};
1145+
1146 struct mv3310_priv {
1147+ bool rate_match;
1148+ phy_interface_t const_interface;
1149+
1150 struct device *hwmon_dev;
1151 char *hwmon_name;
1152 };
1153
1154+static const struct mv3310_chip *to_mv3310_chip(struct phy_device *phydev)
1155+{
1156+ return phydev->drv->driver_data;
1157+}
1158+
1159 #ifdef CONFIG_HWMON
1160 static umode_t mv3310_hwmon_is_visible(const void *data,
1161 enum hwmon_sensor_types type,
developer90020932023-03-10 18:51:34 +08001162@@ -155,13 +188,6 @@ static int mv3310_hwmon_config(struct ph
developerc9bd9ae2022-12-23 16:54:36 +08001163 MV_V2_TEMP_CTRL_MASK, val);
1164 }
1165
1166-static void mv3310_hwmon_disable(void *data)
1167-{
1168- struct phy_device *phydev = data;
1169-
1170- mv3310_hwmon_config(phydev, false);
1171-}
1172-
1173 static int mv3310_hwmon_probe(struct phy_device *phydev)
1174 {
1175 struct device *dev = &phydev->mdio.dev;
developer90020932023-03-10 18:51:34 +08001176@@ -185,10 +211,6 @@ static int mv3310_hwmon_probe(struct phy
developerc9bd9ae2022-12-23 16:54:36 +08001177 if (ret)
1178 return ret;
1179
1180- ret = devm_add_action_or_reset(dev, mv3310_hwmon_disable, phydev);
1181- if (ret)
1182- return ret;
1183-
1184 priv->hwmon_dev = devm_hwmon_device_register_with_info(dev,
1185 priv->hwmon_name, phydev,
1186 &mv3310_hwmon_chip_info, NULL);
developer90020932023-03-10 18:51:34 +08001187@@ -262,6 +284,11 @@ static int mv3310_probe(struct phy_devic
developerc9bd9ae2022-12-23 16:54:36 +08001188 return phy_sfp_probe(phydev, &mv3310_sfp_ops);
1189 }
1190
1191+static void mv3310_remove(struct phy_device *phydev)
1192+{
1193+ mv3310_hwmon_config(phydev, false);
1194+}
1195+
1196 static int mv3310_suspend(struct phy_device *phydev)
1197 {
1198 return phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
developer90020932023-03-10 18:51:34 +08001199@@ -297,8 +324,84 @@ static bool mv3310_has_pma_ngbaset_quirk
developerf1e143b2023-01-09 16:25:59 +08001200 MV_PHY_ALASKA_NBT_QUIRK_MASK) == MV_PHY_ALASKA_NBT_QUIRK_REV;
1201 }
1202
1203+static int mv2110_get_mactype(struct phy_device *phydev)
1204+{
1205+ int mactype;
1206+
1207+ mactype = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_21X0_PORT_CTRL);
1208+ if (mactype < 0)
1209+ return mactype;
1210+
1211+ return mactype & MV_PMA_21X0_PORT_CTRL_MACTYPE_MASK;
1212+}
1213+
1214+static int mv3310_get_mactype(struct phy_device *phydev)
1215+{
1216+ int mactype;
1217+
1218+ mactype = phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL);
1219+ if (mactype < 0)
1220+ return mactype;
1221+
1222+ return mactype & MV_V2_33X0_PORT_CTRL_MACTYPE_MASK;
1223+}
1224+
1225+static int mv2110_init_interface(struct phy_device *phydev, int mactype)
1226+{
1227+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
1228+
1229+ priv->rate_match = false;
1230+
1231+ if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH)
1232+ priv->rate_match = true;
1233+
1234+ if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_USXGMII)
1235+ priv->const_interface = PHY_INTERFACE_MODE_USXGMII;
1236+ else if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH)
1237+ priv->const_interface = PHY_INTERFACE_MODE_10GKR;
1238+ else if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER ||
1239+ mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER_NO_SGMII_AN)
1240+ priv->const_interface = PHY_INTERFACE_MODE_NA;
1241+ else
1242+ return -EINVAL;
1243+
1244+ return 0;
1245+}
1246+
1247+static int mv3310_init_interface(struct phy_device *phydev, int mactype)
1248+{
1249+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
1250+
1251+ priv->rate_match = false;
1252+
1253+ if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH ||
1254+ mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI_RATE_MATCH ||
1255+ mactype == MV_V2_3310_PORT_CTRL_MACTYPE_XAUI_RATE_MATCH)
1256+ priv->rate_match = true;
1257+
1258+ if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_USXGMII)
1259+ priv->const_interface = PHY_INTERFACE_MODE_USXGMII;
1260+ else if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH ||
1261+ mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_NO_SGMII_AN ||
1262+ mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER)
1263+ priv->const_interface = PHY_INTERFACE_MODE_10GKR;
1264+ else if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI_RATE_MATCH ||
1265+ mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI)
1266+ priv->const_interface = PHY_INTERFACE_MODE_RXAUI;
1267+ else if (mactype == MV_V2_3310_PORT_CTRL_MACTYPE_XAUI_RATE_MATCH ||
1268+ mactype == MV_V2_3310_PORT_CTRL_MACTYPE_XAUI)
1269+ priv->const_interface = PHY_INTERFACE_MODE_XAUI;
1270+ else
1271+ return -EINVAL;
1272+
1273+ return 0;
1274+}
1275+
1276 static int mv3310_config_init(struct phy_device *phydev)
1277 {
1278+ const struct mv3310_chip *chip = to_mv3310_chip(phydev);
1279+ int err, mactype;
1280+
1281 /* Check that the PHY interface type is compatible */
1282 if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
1283 phydev->interface != PHY_INTERFACE_MODE_2500BASEX &&
developer90020932023-03-10 18:51:34 +08001284@@ -307,6 +410,16 @@ static int mv3310_config_init(struct phy
developerf1e143b2023-01-09 16:25:59 +08001285 phydev->interface != PHY_INTERFACE_MODE_10GKR)
1286 return -ENODEV;
1287
1288+ mactype = chip->get_mactype(phydev);
1289+ if (mactype < 0)
1290+ return mactype;
1291+
1292+ err = chip->init_interface(phydev, mactype);
1293+ if (err) {
1294+ phydev_err(phydev, "MACTYPE configuration invalid\n");
1295+ return err;
1296+ }
1297+
1298 return 0;
1299 }
1300
developer90020932023-03-10 18:51:34 +08001301@@ -384,6 +497,23 @@ static int mv3310_aneg_done(struct phy_d
developerf1e143b2023-01-09 16:25:59 +08001302
1303 static void mv3310_update_interface(struct phy_device *phydev)
1304 {
1305+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
1306+
1307+ if (!phydev->link)
1308+ return;
1309+
1310+ /* In all of the "* with Rate Matching" modes the PHY interface is fixed
1311+ * at 10Gb. The PHY adapts the rate to actual wire speed with help of
1312+ * internal 16KB buffer.
1313+ *
1314+ * In USXGMII mode the PHY interface mode is also fixed.
1315+ */
1316+ if (priv->rate_match ||
1317+ priv->const_interface == PHY_INTERFACE_MODE_USXGMII) {
1318+ phydev->interface = priv->const_interface;
1319+ return;
1320+ }
1321+
1322 if ((phydev->interface == PHY_INTERFACE_MODE_SGMII ||
1323 phydev->interface == PHY_INTERFACE_MODE_2500BASEX ||
developer90020932023-03-10 18:51:34 +08001324 phydev->interface == PHY_INTERFACE_MODE_5GBASER ||
1325@@ -503,11 +633,22 @@ static int mv3310_read_status(struct phy
developerf1e143b2023-01-09 16:25:59 +08001326 return 0;
1327 }
1328
1329+static const struct mv3310_chip mv3310_type = {
1330+ .get_mactype = mv3310_get_mactype,
1331+ .init_interface = mv3310_init_interface,
1332+};
1333+
1334+static const struct mv3310_chip mv2111_type = {
1335+ .get_mactype = mv2110_get_mactype,
1336+ .init_interface = mv2110_init_interface,
1337+};
1338+
1339 static struct phy_driver mv3310_drivers[] = {
1340 {
1341 .phy_id = MARVELL_PHY_ID_88X3310,
1342 .phy_id_mask = MARVELL_PHY_ID_MASK,
1343 .name = "mv88x3310",
1344+ .driver_data = &mv3310_type,
1345 .get_features = mv3310_get_features,
1346 .soft_reset = genphy_no_soft_reset,
1347 .config_init = mv3310_config_init,
developer90020932023-03-10 18:51:34 +08001348@@ -517,11 +658,13 @@ static struct phy_driver mv3310_drivers[
developerc9bd9ae2022-12-23 16:54:36 +08001349 .config_aneg = mv3310_config_aneg,
1350 .aneg_done = mv3310_aneg_done,
1351 .read_status = mv3310_read_status,
1352+ .remove = mv3310_remove,
1353 },
1354 {
1355 .phy_id = MARVELL_PHY_ID_88E2110,
developerf1e143b2023-01-09 16:25:59 +08001356 .phy_id_mask = MARVELL_PHY_ID_MASK,
1357 .name = "mv88x2110",
1358+ .driver_data = &mv2111_type,
1359 .probe = mv3310_probe,
1360 .suspend = mv3310_suspend,
1361 .resume = mv3310_resume,
developer90020932023-03-10 18:51:34 +08001362@@ -530,6 +673,7 @@ static struct phy_driver mv3310_drivers[
developerc9bd9ae2022-12-23 16:54:36 +08001363 .config_aneg = mv3310_config_aneg,
1364 .aneg_done = mv3310_aneg_done,
1365 .read_status = mv3310_read_status,
1366+ .remove = mv3310_remove,
1367 },
1368 };
1369