blob: 65698d924a80439a0d0bbf0451ea1f8d53331c6c [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;
developer90020932023-03-10 18:51:34 +0800679@@ -303,6 +313,136 @@ 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+
724+static void sfp_quirk_ubnt_uf_instant(const struct sfp_eeprom_id *id,
725+ unsigned long *modes)
726+{
727+ /* Ubiquiti U-Fiber Instant module claims that support all transceiver
728+ * types including 10G Ethernet which is not truth. So clear all claimed
729+ * modes and set only one mode which module supports: 1000baseX_Full.
730+ */
731+ linkmode_zero(modes);
732+ linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, modes);
733+}
734+
735+#define SFP_QUIRK(_v, _p, _m, _f) \
736+ { .vendor = _v, .part = _p, .modes = _m, .fixup = _f, }
737+#define SFP_QUIRK_M(_v, _p, _m) SFP_QUIRK(_v, _p, _m, NULL)
738+#define SFP_QUIRK_F(_v, _p, _f) SFP_QUIRK(_v, _p, NULL, _f)
739+
740+static const struct sfp_quirk sfp_quirks[] = {
741+ // Alcatel Lucent G-010S-P can operate at 2500base-X, but incorrectly
742+ // report 2500MBd NRZ in their EEPROM
743+ SFP_QUIRK_M("ALCATELLUCENT", "G010SP", sfp_quirk_2500basex),
744+
745+ // Alcatel Lucent G-010S-A can operate at 2500base-X, but report 3.2GBd
746+ // NRZ in their EEPROM
747+ SFP_QUIRK("ALCATELLUCENT", "3FE46541AA", sfp_quirk_2500basex,
748+ sfp_fixup_long_startup),
749+
750+ SFP_QUIRK_F("HALNy", "HL-GSFP", sfp_fixup_halny_gsfp),
751+
752+ // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd NRZ in
753+ // their EEPROM
754+ SFP_QUIRK("HUAWEI", "MA5671A", sfp_quirk_2500basex,
755+ sfp_fixup_ignore_tx_fault),
756+
757+ // Lantech 8330-262D-E can operate at 2500base-X, but incorrectly report
758+ // 2500MBd NRZ in their EEPROM
759+ SFP_QUIRK_M("Lantech", "8330-262D-E", sfp_quirk_2500basex),
760+
761+ SFP_QUIRK_M("UBNT", "UF-INSTANT", sfp_quirk_ubnt_uf_instant),
762+
developer82eae452023-02-13 10:04:09 +0800763+ SFP_QUIRK_F("ETU", "ESP-T5-R", sfp_fixup_rollball_cc),
developerc9bd9ae2022-12-23 16:54:36 +0800764+ SFP_QUIRK_F("OEM", "SFP-10G-T", sfp_fixup_rollball_cc),
765+ SFP_QUIRK_F("OEM", "RTSFP-10", sfp_fixup_rollball_cc),
766+ SFP_QUIRK_F("OEM", "RTSFP-10G", sfp_fixup_rollball_cc),
767+ SFP_QUIRK_F("OEM", "TNBYV02-C0X-C3", sfp_fixup_rollball_cc),
768+ SFP_QUIRK_F("Turris", "RTSFP-10", sfp_fixup_rollball),
769+ SFP_QUIRK_F("Turris", "RTSFP-10G", sfp_fixup_rollball),
770+ SFP_QUIRK_F("JESS-LINK", "P60000BBC001-1", sfp_fixup_rollball),
771+};
772+
773+static size_t sfp_strlen(const char *str, size_t maxlen)
774+{
775+ size_t size, i;
776+
777+ /* Trailing characters should be filled with space chars, but
778+ * some manufacturers can't read SFF-8472 and use NUL.
779+ */
780+ for (i = 0, size = 0; i < maxlen; i++)
781+ if (str[i] != ' ' && str[i] != '\0')
782+ size = i + 1;
783+
784+ return size;
785+}
786+
787+static bool sfp_match(const char *qs, const char *str, size_t len)
788+{
789+ if (!qs)
790+ return true;
791+ if (strlen(qs) != len)
792+ return false;
793+ return !strncmp(qs, str, len);
794+}
795+
796+static const struct sfp_quirk *sfp_lookup_quirk(const struct sfp_eeprom_id *id)
797+{
798+ const struct sfp_quirk *q;
799+ unsigned int i;
800+ size_t vs, ps;
801+
802+ vs = sfp_strlen(id->base.vendor_name, ARRAY_SIZE(id->base.vendor_name));
803+ ps = sfp_strlen(id->base.vendor_pn, ARRAY_SIZE(id->base.vendor_pn));
804+
805+ for (i = 0, q = sfp_quirks; i < ARRAY_SIZE(sfp_quirks); i++, q++)
806+ if (sfp_match(q->vendor, id->base.vendor_name, vs) &&
807+ sfp_match(q->part, id->base.vendor_pn, ps))
808+ return q;
809+
810+ return NULL;
811+}
812+
813 static unsigned long poll_jiffies;
814
815 static unsigned int sfp_gpio_get_state(struct sfp *sfp)
developer90020932023-03-10 18:51:34 +0800816@@ -414,9 +554,6 @@ static int sfp_i2c_write(struct sfp *sfp
developerc9bd9ae2022-12-23 16:54:36 +0800817
818 static int sfp_i2c_configure(struct sfp *sfp, struct i2c_adapter *i2c)
819 {
820- struct mii_bus *i2c_mii;
821- int ret;
822-
823 if (!i2c_check_functionality(i2c, I2C_FUNC_I2C))
824 return -EINVAL;
825
developer90020932023-03-10 18:51:34 +0800826@@ -424,7 +561,15 @@ static int sfp_i2c_configure(struct sfp
developerc9bd9ae2022-12-23 16:54:36 +0800827 sfp->read = sfp_i2c_read;
828 sfp->write = sfp_i2c_write;
829
830- i2c_mii = mdio_i2c_alloc(sfp->dev, i2c);
831+ return 0;
832+}
833+
834+static int sfp_i2c_mdiobus_create(struct sfp *sfp)
835+{
836+ struct mii_bus *i2c_mii;
837+ int ret;
838+
839+ i2c_mii = mdio_i2c_alloc(sfp->dev, sfp->i2c, sfp->mdio_protocol);
840 if (IS_ERR(i2c_mii))
841 return PTR_ERR(i2c_mii);
842
developer90020932023-03-10 18:51:34 +0800843@@ -442,6 +587,12 @@ static int sfp_i2c_configure(struct sfp
developerc9bd9ae2022-12-23 16:54:36 +0800844 return 0;
845 }
846
847+static void sfp_i2c_mdiobus_destroy(struct sfp *sfp)
848+{
849+ mdiobus_unregister(sfp->i2c_mii);
850+ sfp->i2c_mii = NULL;
851+}
852+
853 /* Interface */
854 static int sfp_read(struct sfp *sfp, bool a2, u8 addr, void *buf, size_t len)
855 {
developer90020932023-03-10 18:51:34 +0800856@@ -487,17 +638,18 @@ static void sfp_soft_set_state(struct sf
developerc9bd9ae2022-12-23 16:54:36 +0800857 static void sfp_soft_start_poll(struct sfp *sfp)
858 {
859 const struct sfp_eeprom_id *id = &sfp->id;
860+ unsigned int mask = 0;
861
862 sfp->state_soft_mask = 0;
863- if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_DISABLE &&
864- !sfp->gpio[GPIO_TX_DISABLE])
865- sfp->state_soft_mask |= SFP_F_TX_DISABLE;
866- if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_FAULT &&
867- !sfp->gpio[GPIO_TX_FAULT])
868- sfp->state_soft_mask |= SFP_F_TX_FAULT;
869- if (id->ext.enhopts & SFP_ENHOPTS_SOFT_RX_LOS &&
870- !sfp->gpio[GPIO_LOS])
871- sfp->state_soft_mask |= SFP_F_LOS;
872+ if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_DISABLE)
873+ mask |= SFP_F_TX_DISABLE;
874+ if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_FAULT)
875+ mask |= SFP_F_TX_FAULT;
876+ if (id->ext.enhopts & SFP_ENHOPTS_SOFT_RX_LOS)
877+ mask |= SFP_F_LOS;
878+
879+ // Poll the soft state for hardware pins we want to ignore
880+ sfp->state_soft_mask = ~sfp->state_hw_mask & mask;
881
882 if (sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT) &&
883 !sfp->need_poll)
developer90020932023-03-10 18:51:34 +0800884@@ -511,10 +663,11 @@ static void sfp_soft_stop_poll(struct sf
developerc9bd9ae2022-12-23 16:54:36 +0800885
886 static unsigned int sfp_get_state(struct sfp *sfp)
887 {
888- unsigned int state = sfp->get_state(sfp);
889+ unsigned int soft = sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT);
890+ unsigned int state;
891
892- if (state & SFP_F_PRESENT &&
893- sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT))
894+ state = sfp->get_state(sfp) & sfp->state_hw_mask;
895+ if (state & SFP_F_PRESENT && soft)
896 state |= sfp_soft_get_state(sfp);
897
898 return state;
developer90020932023-03-10 18:51:34 +0800899@@ -1448,12 +1601,12 @@ static void sfp_sm_phy_detach(struct sfp
developerc9bd9ae2022-12-23 16:54:36 +0800900 sfp->mod_phy = NULL;
901 }
902
903-static int sfp_sm_probe_phy(struct sfp *sfp, bool is_c45)
904+static int sfp_sm_probe_phy(struct sfp *sfp, int addr, bool is_c45)
905 {
906 struct phy_device *phy;
907 int err;
908
909- phy = get_phy_device(sfp->i2c_mii, SFP_PHY_ADDR, is_c45);
910+ phy = get_phy_device(sfp->i2c_mii, addr, is_c45);
911 if (phy == ERR_PTR(-ENODEV))
912 return PTR_ERR(phy);
913 if (IS_ERR(phy)) {
developer90020932023-03-10 18:51:34 +0800914@@ -1548,6 +1701,14 @@ static void sfp_sm_fault(struct sfp *sfp
developerc9bd9ae2022-12-23 16:54:36 +0800915 }
916 }
917
918+static int sfp_sm_add_mdio_bus(struct sfp *sfp)
919+{
920+ if (sfp->mdio_protocol != MDIO_I2C_NONE)
921+ return sfp_i2c_mdiobus_create(sfp);
922+
923+ return 0;
924+}
925+
926 /* Probe a SFP for a PHY device if the module supports copper - the PHY
927 * normally sits at I2C bus address 0x56, and may either be a clause 22
928 * or clause 45 PHY.
developer90020932023-03-10 18:51:34 +0800929@@ -1563,19 +1724,23 @@ static int sfp_sm_probe_for_phy(struct s
developerc9bd9ae2022-12-23 16:54:36 +0800930 {
931 int err = 0;
932
933- switch (sfp->id.base.extended_cc) {
934- case SFF8024_ECC_10GBASE_T_SFI:
935- case SFF8024_ECC_10GBASE_T_SR:
936- case SFF8024_ECC_5GBASE_T:
937- case SFF8024_ECC_2_5GBASE_T:
938- err = sfp_sm_probe_phy(sfp, true);
939+ switch (sfp->mdio_protocol) {
940+ case MDIO_I2C_NONE:
941 break;
942
943- default:
944- if (sfp->id.base.e1000_base_t)
945- err = sfp_sm_probe_phy(sfp, false);
946+ case MDIO_I2C_MARVELL_C22:
947+ err = sfp_sm_probe_phy(sfp, SFP_PHY_ADDR, false);
948+ break;
949+
950+ case MDIO_I2C_C45:
951+ err = sfp_sm_probe_phy(sfp, SFP_PHY_ADDR, true);
952+ break;
953+
954+ case MDIO_I2C_ROLLBALL:
955+ err = sfp_sm_probe_phy(sfp, SFP_PHY_ADDR_ROLLBALL, true);
956 break;
957 }
958+
959 return err;
960 }
961
developer90020932023-03-10 18:51:34 +0800962@@ -1819,11 +1984,33 @@ static int sfp_sm_mod_probe(struct sfp *
developerc9bd9ae2022-12-23 16:54:36 +0800963 if (ret < 0)
964 return ret;
965
966- if (!memcmp(id.base.vendor_name, "ALCATELLUCENT ", 16) &&
967- !memcmp(id.base.vendor_pn, "3FE46541AA ", 16))
968- sfp->module_t_start_up = T_START_UP_BAD_GPON;
969+ /* Initialise state bits to use from hardware */
970+ sfp->state_hw_mask = SFP_F_PRESENT;
971+ if (sfp->gpio[GPIO_TX_DISABLE])
972+ sfp->state_hw_mask |= SFP_F_TX_DISABLE;
973+ if (sfp->gpio[GPIO_TX_FAULT])
974+ sfp->state_hw_mask |= SFP_F_TX_FAULT;
975+ if (sfp->gpio[GPIO_LOS])
976+ sfp->state_hw_mask |= SFP_F_LOS;
977+
978+ sfp->module_t_start_up = T_START_UP;
979+ sfp->module_t_wait = T_WAIT;
980+
981+ sfp->tx_fault_ignore = false;
982+
983+ if (sfp->id.base.extended_cc == SFF8024_ECC_10GBASE_T_SFI ||
984+ sfp->id.base.extended_cc == SFF8024_ECC_10GBASE_T_SR ||
985+ sfp->id.base.extended_cc == SFF8024_ECC_5GBASE_T ||
986+ sfp->id.base.extended_cc == SFF8024_ECC_2_5GBASE_T)
987+ sfp->mdio_protocol = MDIO_I2C_C45;
988+ else if (sfp->id.base.e1000_base_t)
989+ sfp->mdio_protocol = MDIO_I2C_MARVELL_C22;
990 else
991- sfp->module_t_start_up = T_START_UP;
992+ sfp->mdio_protocol = MDIO_I2C_NONE;
993+
994+ sfp->quirk = sfp_lookup_quirk(&id);
995+ if (sfp->quirk && sfp->quirk->fixup)
996+ sfp->quirk->fixup(sfp);
997
998 return 0;
999 }
developer90020932023-03-10 18:51:34 +08001000@@ -1936,7 +2123,8 @@ static void sfp_sm_module(struct sfp *sf
developerc9bd9ae2022-12-23 16:54:36 +08001001 break;
1002
1003 /* Report the module insertion to the upstream device */
1004- err = sfp_module_insert(sfp->sfp_bus, &sfp->id);
1005+ err = sfp_module_insert(sfp->sfp_bus, &sfp->id,
1006+ sfp->quirk);
1007 if (err < 0) {
1008 sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0);
1009 break;
developer90020932023-03-10 18:51:34 +08001010@@ -1995,6 +2183,8 @@ static void sfp_sm_main(struct sfp *sfp,
developerc9bd9ae2022-12-23 16:54:36 +08001011 sfp_module_stop(sfp->sfp_bus);
1012 if (sfp->mod_phy)
1013 sfp_sm_phy_detach(sfp);
1014+ if (sfp->i2c_mii)
1015+ sfp_i2c_mdiobus_destroy(sfp);
1016 sfp_module_tx_disable(sfp);
1017 sfp_soft_stop_poll(sfp);
1018 sfp_sm_next(sfp, SFP_S_DOWN, 0);
developer90020932023-03-10 18:51:34 +08001019@@ -2018,9 +2208,10 @@ static void sfp_sm_main(struct sfp *sfp,
developerc9bd9ae2022-12-23 16:54:36 +08001020
1021 /* We need to check the TX_FAULT state, which is not defined
1022 * while TX_DISABLE is asserted. The earliest we want to do
1023- * anything (such as probe for a PHY) is 50ms.
1024+ * anything (such as probe for a PHY) is 50ms (or more on
1025+ * specific modules).
1026 */
1027- sfp_sm_next(sfp, SFP_S_WAIT, T_WAIT);
1028+ sfp_sm_next(sfp, SFP_S_WAIT, sfp->module_t_wait);
1029 break;
1030
1031 case SFP_S_WAIT:
developer90020932023-03-10 18:51:34 +08001032@@ -2034,8 +2225,8 @@ static void sfp_sm_main(struct sfp *sfp,
developerc9bd9ae2022-12-23 16:54:36 +08001033 * deasserting.
1034 */
1035 timeout = sfp->module_t_start_up;
1036- if (timeout > T_WAIT)
1037- timeout -= T_WAIT;
1038+ if (timeout > sfp->module_t_wait)
1039+ timeout -= sfp->module_t_wait;
1040 else
1041 timeout = 1;
1042
developer90020932023-03-10 18:51:34 +08001043@@ -2057,6 +2248,12 @@ static void sfp_sm_main(struct sfp *sfp,
developerc9bd9ae2022-12-23 16:54:36 +08001044 sfp->sm_fault_retries == N_FAULT_INIT);
1045 } else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) {
1046 init_done:
1047+ /* Create mdiobus and start trying for PHY */
1048+ ret = sfp_sm_add_mdio_bus(sfp);
1049+ if (ret < 0) {
1050+ sfp_sm_next(sfp, SFP_S_FAIL, 0);
1051+ break;
1052+ }
1053 sfp->sm_phy_retries = R_PHY_RETRY;
1054 goto phy_probe;
1055 }
developer90020932023-03-10 18:51:34 +08001056@@ -2409,6 +2606,8 @@ static int sfp_probe(struct platform_dev
developerc9bd9ae2022-12-23 16:54:36 +08001057 return PTR_ERR(sfp->gpio[i]);
1058 }
1059
1060+ sfp->state_hw_mask = SFP_F_PRESENT;
1061+
1062 sfp->get_state = sfp_gpio_get_state;
1063 sfp->set_state = sfp_gpio_set_state;
1064
developerc9bd9ae2022-12-23 16:54:36 +08001065--- a/drivers/net/phy/sfp.h
1066+++ b/drivers/net/phy/sfp.h
1067@@ -6,6 +6,13 @@
1068
1069 struct sfp;
1070
1071+struct sfp_quirk {
1072+ const char *vendor;
1073+ const char *part;
1074+ void (*modes)(const struct sfp_eeprom_id *id, unsigned long *modes);
1075+ void (*fixup)(struct sfp *sfp);
1076+};
1077+
1078 struct sfp_socket_ops {
1079 void (*attach)(struct sfp *sfp);
1080 void (*detach)(struct sfp *sfp);
developer90020932023-03-10 18:51:34 +08001081@@ -20,7 +27,8 @@ int sfp_add_phy(struct sfp_bus *bus, str
developerc9bd9ae2022-12-23 16:54:36 +08001082 void sfp_remove_phy(struct sfp_bus *bus);
1083 void sfp_link_up(struct sfp_bus *bus);
1084 void sfp_link_down(struct sfp_bus *bus);
1085-int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id);
1086+int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
1087+ const struct sfp_quirk *quirk);
1088 void sfp_module_remove(struct sfp_bus *bus);
1089 int sfp_module_start(struct sfp_bus *bus);
1090 void sfp_module_stop(struct sfp_bus *bus);
developerc9bd9ae2022-12-23 16:54:36 +08001091--- a/drivers/net/phy/marvell10g.c
1092+++ b/drivers/net/phy/marvell10g.c
developerf1e143b2023-01-09 16:25:59 +08001093@@ -32,6 +32,15 @@
1094 #define MV_PHY_ALASKA_NBT_QUIRK_REV (MARVELL_PHY_ID_88X3310 | 0xa)
1095
1096 enum {
1097+ MV_PMA_21X0_PORT_CTRL = 0xc04a,
1098+ MV_PMA_21X0_PORT_CTRL_SWRST = BIT(15),
1099+ MV_PMA_21X0_PORT_CTRL_MACTYPE_MASK = 0x7,
1100+ MV_PMA_21X0_PORT_CTRL_MACTYPE_USXGMII = 0x0,
1101+ MV_PMA_2180_PORT_CTRL_MACTYPE_DXGMII = 0x1,
1102+ MV_PMA_2180_PORT_CTRL_MACTYPE_QXGMII = 0x2,
1103+ MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER = 0x4,
1104+ MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER_NO_SGMII_AN = 0x5,
1105+ MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH = 0x6,
1106 MV_PMA_BOOT = 0xc050,
1107 MV_PMA_BOOT_FATAL = BIT(0),
1108
1109@@ -53,7 +62,18 @@ enum {
1110
1111 /* Vendor2 MMD registers */
1112 MV_V2_PORT_CTRL = 0xf001,
1113- MV_V2_PORT_CTRL_PWRDOWN = 0x0800,
1114+ MV_V2_PORT_CTRL_PWRDOWN = BIT(11),
1115+ MV_V2_33X0_PORT_CTRL_SWRST = BIT(15),
1116+ MV_V2_33X0_PORT_CTRL_MACTYPE_MASK = 0x7,
1117+ MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI = 0x0,
1118+ MV_V2_3310_PORT_CTRL_MACTYPE_XAUI_RATE_MATCH = 0x1,
1119+ MV_V2_3340_PORT_CTRL_MACTYPE_RXAUI_NO_SGMII_AN = 0x1,
1120+ MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI_RATE_MATCH = 0x2,
1121+ MV_V2_3310_PORT_CTRL_MACTYPE_XAUI = 0x3,
1122+ MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER = 0x4,
1123+ MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_NO_SGMII_AN = 0x5,
1124+ MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH = 0x6,
1125+ MV_V2_33X0_PORT_CTRL_MACTYPE_USXGMII = 0x7,
1126 MV_V2_TEMP_CTRL = 0xf08a,
1127 MV_V2_TEMP_CTRL_MASK = 0xc000,
1128 MV_V2_TEMP_CTRL_SAMPLE = 0x0000,
1129@@ -62,11 +82,24 @@ enum {
1130 MV_V2_TEMP_UNKNOWN = 0x9600, /* unknown function */
1131 };
1132
1133+struct mv3310_chip {
1134+ int (*get_mactype)(struct phy_device *phydev);
1135+ int (*init_interface)(struct phy_device *phydev, int mactype);
1136+};
1137+
1138 struct mv3310_priv {
1139+ bool rate_match;
1140+ phy_interface_t const_interface;
1141+
1142 struct device *hwmon_dev;
1143 char *hwmon_name;
1144 };
1145
1146+static const struct mv3310_chip *to_mv3310_chip(struct phy_device *phydev)
1147+{
1148+ return phydev->drv->driver_data;
1149+}
1150+
1151 #ifdef CONFIG_HWMON
1152 static umode_t mv3310_hwmon_is_visible(const void *data,
1153 enum hwmon_sensor_types type,
developer90020932023-03-10 18:51:34 +08001154@@ -155,13 +188,6 @@ static int mv3310_hwmon_config(struct ph
developerc9bd9ae2022-12-23 16:54:36 +08001155 MV_V2_TEMP_CTRL_MASK, val);
1156 }
1157
1158-static void mv3310_hwmon_disable(void *data)
1159-{
1160- struct phy_device *phydev = data;
1161-
1162- mv3310_hwmon_config(phydev, false);
1163-}
1164-
1165 static int mv3310_hwmon_probe(struct phy_device *phydev)
1166 {
1167 struct device *dev = &phydev->mdio.dev;
developer90020932023-03-10 18:51:34 +08001168@@ -185,10 +211,6 @@ static int mv3310_hwmon_probe(struct phy
developerc9bd9ae2022-12-23 16:54:36 +08001169 if (ret)
1170 return ret;
1171
1172- ret = devm_add_action_or_reset(dev, mv3310_hwmon_disable, phydev);
1173- if (ret)
1174- return ret;
1175-
1176 priv->hwmon_dev = devm_hwmon_device_register_with_info(dev,
1177 priv->hwmon_name, phydev,
1178 &mv3310_hwmon_chip_info, NULL);
developer90020932023-03-10 18:51:34 +08001179@@ -262,6 +284,11 @@ static int mv3310_probe(struct phy_devic
developerc9bd9ae2022-12-23 16:54:36 +08001180 return phy_sfp_probe(phydev, &mv3310_sfp_ops);
1181 }
1182
1183+static void mv3310_remove(struct phy_device *phydev)
1184+{
1185+ mv3310_hwmon_config(phydev, false);
1186+}
1187+
1188 static int mv3310_suspend(struct phy_device *phydev)
1189 {
1190 return phy_set_bits_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL,
developer90020932023-03-10 18:51:34 +08001191@@ -297,8 +324,84 @@ static bool mv3310_has_pma_ngbaset_quirk
developerf1e143b2023-01-09 16:25:59 +08001192 MV_PHY_ALASKA_NBT_QUIRK_MASK) == MV_PHY_ALASKA_NBT_QUIRK_REV;
1193 }
1194
1195+static int mv2110_get_mactype(struct phy_device *phydev)
1196+{
1197+ int mactype;
1198+
1199+ mactype = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_21X0_PORT_CTRL);
1200+ if (mactype < 0)
1201+ return mactype;
1202+
1203+ return mactype & MV_PMA_21X0_PORT_CTRL_MACTYPE_MASK;
1204+}
1205+
1206+static int mv3310_get_mactype(struct phy_device *phydev)
1207+{
1208+ int mactype;
1209+
1210+ mactype = phy_read_mmd(phydev, MDIO_MMD_VEND2, MV_V2_PORT_CTRL);
1211+ if (mactype < 0)
1212+ return mactype;
1213+
1214+ return mactype & MV_V2_33X0_PORT_CTRL_MACTYPE_MASK;
1215+}
1216+
1217+static int mv2110_init_interface(struct phy_device *phydev, int mactype)
1218+{
1219+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
1220+
1221+ priv->rate_match = false;
1222+
1223+ if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH)
1224+ priv->rate_match = true;
1225+
1226+ if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_USXGMII)
1227+ priv->const_interface = PHY_INTERFACE_MODE_USXGMII;
1228+ else if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH)
1229+ priv->const_interface = PHY_INTERFACE_MODE_10GKR;
1230+ else if (mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER ||
1231+ mactype == MV_PMA_21X0_PORT_CTRL_MACTYPE_5GBASER_NO_SGMII_AN)
1232+ priv->const_interface = PHY_INTERFACE_MODE_NA;
1233+ else
1234+ return -EINVAL;
1235+
1236+ return 0;
1237+}
1238+
1239+static int mv3310_init_interface(struct phy_device *phydev, int mactype)
1240+{
1241+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
1242+
1243+ priv->rate_match = false;
1244+
1245+ if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH ||
1246+ mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI_RATE_MATCH ||
1247+ mactype == MV_V2_3310_PORT_CTRL_MACTYPE_XAUI_RATE_MATCH)
1248+ priv->rate_match = true;
1249+
1250+ if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_USXGMII)
1251+ priv->const_interface = PHY_INTERFACE_MODE_USXGMII;
1252+ else if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_RATE_MATCH ||
1253+ mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER_NO_SGMII_AN ||
1254+ mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_10GBASER)
1255+ priv->const_interface = PHY_INTERFACE_MODE_10GKR;
1256+ else if (mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI_RATE_MATCH ||
1257+ mactype == MV_V2_33X0_PORT_CTRL_MACTYPE_RXAUI)
1258+ priv->const_interface = PHY_INTERFACE_MODE_RXAUI;
1259+ else if (mactype == MV_V2_3310_PORT_CTRL_MACTYPE_XAUI_RATE_MATCH ||
1260+ mactype == MV_V2_3310_PORT_CTRL_MACTYPE_XAUI)
1261+ priv->const_interface = PHY_INTERFACE_MODE_XAUI;
1262+ else
1263+ return -EINVAL;
1264+
1265+ return 0;
1266+}
1267+
1268 static int mv3310_config_init(struct phy_device *phydev)
1269 {
1270+ const struct mv3310_chip *chip = to_mv3310_chip(phydev);
1271+ int err, mactype;
1272+
1273 /* Check that the PHY interface type is compatible */
1274 if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
1275 phydev->interface != PHY_INTERFACE_MODE_2500BASEX &&
developer90020932023-03-10 18:51:34 +08001276@@ -307,6 +410,16 @@ static int mv3310_config_init(struct phy
developerf1e143b2023-01-09 16:25:59 +08001277 phydev->interface != PHY_INTERFACE_MODE_10GKR)
1278 return -ENODEV;
1279
1280+ mactype = chip->get_mactype(phydev);
1281+ if (mactype < 0)
1282+ return mactype;
1283+
1284+ err = chip->init_interface(phydev, mactype);
1285+ if (err) {
1286+ phydev_err(phydev, "MACTYPE configuration invalid\n");
1287+ return err;
1288+ }
1289+
1290 return 0;
1291 }
1292
developer90020932023-03-10 18:51:34 +08001293@@ -384,6 +497,23 @@ static int mv3310_aneg_done(struct phy_d
developerf1e143b2023-01-09 16:25:59 +08001294
1295 static void mv3310_update_interface(struct phy_device *phydev)
1296 {
1297+ struct mv3310_priv *priv = dev_get_drvdata(&phydev->mdio.dev);
1298+
1299+ if (!phydev->link)
1300+ return;
1301+
1302+ /* In all of the "* with Rate Matching" modes the PHY interface is fixed
1303+ * at 10Gb. The PHY adapts the rate to actual wire speed with help of
1304+ * internal 16KB buffer.
1305+ *
1306+ * In USXGMII mode the PHY interface mode is also fixed.
1307+ */
1308+ if (priv->rate_match ||
1309+ priv->const_interface == PHY_INTERFACE_MODE_USXGMII) {
1310+ phydev->interface = priv->const_interface;
1311+ return;
1312+ }
1313+
1314 if ((phydev->interface == PHY_INTERFACE_MODE_SGMII ||
1315 phydev->interface == PHY_INTERFACE_MODE_2500BASEX ||
developer90020932023-03-10 18:51:34 +08001316 phydev->interface == PHY_INTERFACE_MODE_5GBASER ||
1317@@ -503,11 +633,22 @@ static int mv3310_read_status(struct phy
developerf1e143b2023-01-09 16:25:59 +08001318 return 0;
1319 }
1320
1321+static const struct mv3310_chip mv3310_type = {
1322+ .get_mactype = mv3310_get_mactype,
1323+ .init_interface = mv3310_init_interface,
1324+};
1325+
1326+static const struct mv3310_chip mv2111_type = {
1327+ .get_mactype = mv2110_get_mactype,
1328+ .init_interface = mv2110_init_interface,
1329+};
1330+
1331 static struct phy_driver mv3310_drivers[] = {
1332 {
1333 .phy_id = MARVELL_PHY_ID_88X3310,
1334 .phy_id_mask = MARVELL_PHY_ID_MASK,
1335 .name = "mv88x3310",
1336+ .driver_data = &mv3310_type,
1337 .get_features = mv3310_get_features,
1338 .soft_reset = genphy_no_soft_reset,
1339 .config_init = mv3310_config_init,
developer90020932023-03-10 18:51:34 +08001340@@ -517,11 +658,13 @@ static struct phy_driver mv3310_drivers[
developerc9bd9ae2022-12-23 16:54:36 +08001341 .config_aneg = mv3310_config_aneg,
1342 .aneg_done = mv3310_aneg_done,
1343 .read_status = mv3310_read_status,
1344+ .remove = mv3310_remove,
1345 },
1346 {
1347 .phy_id = MARVELL_PHY_ID_88E2110,
developerf1e143b2023-01-09 16:25:59 +08001348 .phy_id_mask = MARVELL_PHY_ID_MASK,
1349 .name = "mv88x2110",
1350+ .driver_data = &mv2111_type,
1351 .probe = mv3310_probe,
1352 .suspend = mv3310_suspend,
1353 .resume = mv3310_resume,
developer90020932023-03-10 18:51:34 +08001354@@ -530,6 +673,7 @@ static struct phy_driver mv3310_drivers[
developerc9bd9ae2022-12-23 16:54:36 +08001355 .config_aneg = mv3310_config_aneg,
1356 .aneg_done = mv3310_aneg_done,
1357 .read_status = mv3310_read_status,
1358+ .remove = mv3310_remove,
1359 },
1360 };
1361