Thread (3 messages) flat view 3 messages, 2 authors, 1d ago
HOTtoday REVIEWED: 5 (5M)

1 review trailer.

[PATCH AUTOSEL 6.18-6.1] net: phy: sfp: probe for RollBall I2C-to-MDIO bridge in mdio-i2c

From: Sasha Levin <sashal@kernel.org>
Date: 2026-08-31 13:47:38
Also in: linux-patches, lkml, stable
Subsystem: ethernet phy library, networking drivers, sff/sfp/sfp+ module support, the rest · Maintainers: Andrew Lunn, Heiner Kallweit, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Russell King, Linus Torvalds

Possibly related (same subject, not in this thread)

From: Petr Wozniak <redacted>

[ Upstream commit 8fe125892f40cbe284fba8eda49a0407984fc74c ]

The "OEM"/"SFP-10G-T" quirk entry in sfp_fixup_rollball_cc()
unconditionally forces MDIO_I2C_ROLLBALL for all modules matching that
vendor/part-number combination.  This works for modules that genuinely
implement a RollBall I2C-to-MDIO bridge, but silently breaks modules
that share the same EEPROM strings without having such a bridge.

The Realtek RTL8261BE-CG is one such module: a pure copper 10G SFP+
media converter with no I2C-to-MDIO bridge.  Its EEPROM reports
vendor="OEM", part="SFP-10G-T-I", and -- critically -- Vendor OUI
00:00:00, making OUI-based differentiation impossible.  With
MDIO_I2C_ROLLBALL forced, the module silently ACKs the unlock password
write, the MDIO bus is created, but no PHY responds; the SFP state
machine cycles through the RollBall PHY-probe retry window before
reporting no PHY.

Move the probe into i2c_mii_init_rollball() in mdio-i2c.c, where the
RollBall protocol constants are already defined.  After sending the
unlock password, issue a CMD_READ and poll for CMD_DONE up to 200 ms
(10 x 20 ms, matching the existing rollball poll tolerance).  A genuine
RollBall bridge asserts CMD_DONE within that window; modules without a
bridge never do, so i2c_mii_init_rollball() returns -ENODEV.
mdio_i2c_alloc() propagates -ENODEV to the caller to signal that no
bridge is present and PHY probing should be skipped.
sfp_sm_add_mdio_bus() catches -ENODEV and transitions
sfp->mdio_protocol to MDIO_I2C_NONE so the rest of the state machine
skips PHY probing for this module.

Any I2C-level error (NACK, timeout) during the probe is also treated as
-ENODEV: if the module does not respond at I2C address 0x51 at all,
there is certainly no RollBall bridge there, and SFP initialization
should not abort.

The probe writes are safe with respect to SFP EEPROM integrity: only
modules explicitly listed in the quirk table enter this path, and the
RollBall password unlock write to 0x51 was already issued by
i2c_mii_init_rollball() before the probe for all such modules.  Any
module without a device at 0x51 NACKs the transfer and is treated as
-ENODEV.

Add "OEM"/"SFP-10G-T-I" to the quirk table so RTL8261BE modules enter
the probe path; genuine RollBall modules continue to work as before.

Signed-off-by: Petr Wozniak <redacted>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20260527053909.2118-1-petr.wozniak@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

## Phase 1: Commit Message Forensics

**Step 1.1 — Subject line**
- Record: `[net: phy: sfp]` `[probe]` — Add runtime detection of
  RollBall I2C-to-MDIO bridge before using RollBall MDIO protocol; add
  quirk for OEM/SFP-10G-T-I (RTL8261BE).

**Step 1.2 — Tags**
- Record:
  - `Signed-off-by: Petr Wozniak [off-list ref]` (author)
  - `Reviewed-by: Maxime Chevallier [off-list ref]`
    (SFP/mdio-i2c contributor)
  - `Link: https://patch.msgid.link/20260527053909.2118-1-
    petr.wozniak@gmail.com`
  - `Signed-off-by: Jakub Kicinski [off-list ref]` (netdev
    maintainer)
  - No `Fixes:`, no `Reported-by:`, no `Cc: stable@vger.kernel.org`, no
    syzbot
  - Notable: maintainer sign-off + subsystem reviewer; v8 changelog
    documents hardware testing on BPI-R4 (MT7988A, 6.12.87)

**Step 1.3 — Body analysis**
- Record:
  - **Bug:** `sfp_fixup_rollball_cc()` for `"OEM"/"SFP-10G-T"`
    unconditionally sets `MDIO_I2C_ROLLBALL`. Modules with matching
    EEPROM strings but no RollBall bridge get the wrong protocol.
  - **Affected hardware:** Realtek RTL8261BE-CG (`vendor="OEM"`,
    `part="SFP-10G-T-I"`, OUI `00:00:00`).
  - **Symptom:** Password unlock ACKs, MDIO bus is created, no PHY
    responds; state machine burns through RollBall PHY-probe retries
    (`phy_t_retry` = 1s × `R_PHY_RETRY` = 25 → up to ~25s) before
    logging “no PHY detected”.
  - **Fix:** Probe RollBall bridge in `i2c_mii_init_rollball()` after
    unlock; return `-ENODEV` if no `CMD_DONE`; `sfp_sm_add_mdio_bus()`
    downgrades to `MDIO_I2C_NONE` and skips PHY probing. Add
    `"OEM"/"SFP-10G-T-I"` quirk to enter probe path.
  - **Root cause:** EEPROM-based quirk matching cannot distinguish
    RollBall vs non-RollBall modules sharing OEM strings.

**Step 1.4 — Hidden bug fix?**
- Record: Yes. Described as probing/enhancement, but it fixes incorrect
  MDIO protocol selection — a functional hardware-support bug, not
  cosmetic cleanup.

---

## Phase 2: Diff Analysis

**Step 2.1 — Inventory**
- Record:
  - `drivers/net/mdio/mdio-i2c.c`: +~48 lines (new
    `i2c_mii_probe_rollball()`, extend `i2c_mii_init_rollball()`, adjust
    error logging in `mdio_i2c_alloc()`)
  - `drivers/net/phy/sfp.c`: +~9 lines (new quirk entry, `-ENODEV`
    handling in `sfp_sm_add_mdio_bus()`)
  - Functions: `i2c_mii_probe_rollball()`, `i2c_mii_init_rollball()`,
    `mdio_i2c_alloc()`, `sfp_sm_add_mdio_bus()`
  - Scope: two-file, surgical hardware-quirk fix

**Step 2.2 — Code flow per hunk**

| Hunk | Before | After |
|------|--------|-------|
| `i2c_mii_init_rollball()` | Password write only; success → return 0 |
Password write + RollBall CMD_READ/CMD_DONE probe (10×20ms); I2C NACK →
`-ENODEV` |
| `mdio_i2c_alloc()` ROLLBALL case | Any init failure logged as error |
`-ENODEV` (no bridge) logged silently |
| `sfp_sm_add_mdio_bus()` | Always create bus if protocol ≠ NONE | On
`-ENODEV`, set `mdio_protocol = MDIO_I2C_NONE`, continue |
| `sfp_quirks[]` | No `SFP-10G-T-I` entry | Add `SFP_QUIRK_F("OEM",
"SFP-10G-T-I", sfp_fixup_rollball)` |

**Step 2.3 — Bug mechanism**
- Record: **Logic / hardware-quirk correctness fix.** Wrong MDIO
  protocol forced by EEPROM quirk matching. Non-RollBall copper SFP+
  modules get RollBall init + lengthy failed PHY probes. Fix adds
  runtime bridge detection and graceful fallback.

**Step 2.4 — Fix quality**
- Record: Obviously correct; reuses existing RollBall constants and
  10×20ms polling pattern from `i2c_rollball_mii_poll()`. Minimal
  regression risk for genuine RollBall modules (probe must pass
  CMD_DONE, which real bridges do). Low risk: only modules already in
  quirk table enter this path.

---

## Phase 3: Git History Investigation

**Step 3.1 — Blame**
- Record:
  - `i2c_mii_init_rollball()`: introduced `09bbedac72d5a` (2022-09-30,
    v6.1 era) — password-only init, no bridge probe
  - `sfp_fixup_rollball_cc()` / `OEM/SFP-10G-T` quirk: introduced
    `324e88cbe3b7b` (2022-09-30)
  - `OEM/SFP-10G-T` also touched in `5859a99b52254` (Fiberstore/Walsun
    support, 2024)
  - All present in this tree (v6.18.44)

**Step 3.2 — Fixes: tag**
- Record: N/A — no `Fixes:` tag. Underlying issue introduced with
  RollBall support (2022); unconditional quirk matching is the design
  gap.

**Step 3.3 — Related file history**
- Record: Recent stable churn in these files includes `86d379fcf1b79`
  (mii_bus free in destroy), SMBus support, other SFP quirks. No
  conflicting fix for this issue. Standalone patch (v8, no series
  dependency).

**Step 3.4 — Author context**
- Record: Petr Wozniak has one prior commit in this tree
  (`86d379fcf1b79`, SFP mii_bus free). Maxime Chevallier contributed
  SMBus mdio-i2c and SFP SMBus support. Jakub Kicinski is netdev
  maintainer.

**Step 3.5 — Dependencies**
- Record: Self-contained. All symbols (`i2c_transfer_rollball`,
  `ROLLBALL_*` constants, `sfp_fixup_rollball`, `sfp_sm_add_mdio_bus`)
  exist in v6.18.44. No prerequisite commits required.

---

## Phase 4: Mailing List and External Research

**Step 4.1 — Original discussion**
- Record: Local mbox `v8_20260527_petr_wozniak_net_phy_sfp_probe_for_rol
  lball_i2c_to_mdio_bridge_in_mdio_i2c.mbx` contains v8 submission. `b4
  dig` on commit hash failed (commit not in local tree); `b4 am` found
  2-message thread. Lore web fetch blocked (403/Anubis). Review
  evolution v1→v8 documented in cover letter.

**Step 4.2 — Reviewers**
- Record: `Reviewed-by: Maxime Chevallier` (mdio-i2c/SFP contributor).
  Jakub Kicinski merged. Multiple review rounds with Maxime and Jakub
  feedback incorporated.

**Step 4.3 — Bug report**
- Record: No formal bugzilla/syzbot. Hardware validation documented in
  v8 changelog: RTL8261BE → `MDIO_I2C_NONE`, link Up 10Gbps; genuine
  RollBall `OEM/SFP-10G-T` → bridge detected, link Up 10Gbps. Tested on
  BPI-R4, kernel 6.12.87.

**Step 4.4 — Series context**
- Record: Standalone 1-patch series (v8). No other patches required.

**Step 4.5 — Stable list**
- Record: No stable-list discussion found (lore fetch blocked). Not a
  negative signal per instructions.

---

## Phase 5: Code Semantic Analysis

**Step 5.1 — Key functions**
- Record: `i2c_mii_probe_rollball()`, `i2c_mii_init_rollball()`,
  `mdio_i2c_alloc()`, `sfp_i2c_mdiobus_create()`,
  `sfp_sm_add_mdio_bus()`, `sfp_sm_probe_for_phy()`

**Step 5.2 — Callers**
- Record:
  - `mdio_i2c_alloc()` ← `sfp_i2c_mdiobus_create()` ←
    `sfp_sm_add_mdio_bus()` ← SFP state machine `SFP_S_INIT` (module
    hotplug/insertion)
  - Triggered on every SFP module insert for quirk-matched RollBall
    candidates

**Step 5.3 — Callees**
- Record: `i2c_transfer()`, `i2c_transfer_rollball()`, `msleep(20)`,
  `mdiobus_alloc/free/register`

**Step 5.4 — Reachability**
- Record: Userspace cannot directly trigger; triggered by SFP hotplug on
  hardware with `CONFIG_SFP` + SFP cage. Common embedded/router use case
  (e.g. BPI-R4). Bug affects real device bring-up.

**Step 5.5 — Similar patterns**
- Record: `i2c_rollball_mii_poll()` already uses identical 10×20ms
  CMD_DONE polling (lines 318–331 of `mdio-i2c.c`). New probe mirrors
  established pattern.

---

## Phase 6: Cross-Reference Against Local Tree (v6.18.44)

**Step 6.1 — Buggy code present?**
- Record: **Yes.** `i2c_mii_init_rollball()` at line 422 does password-
  only init. `OEM/SFP-10G-T` quirk at line 582 uses
  `sfp_fixup_rollball_cc`. No `SFP-10G-T-I` quirk. No
  `i2c_mii_probe_rollball()`. Fix not yet applied.

**Step 6.2 — Backport complications**
- Record: Clean apply expected. File structure matches diff context. No
  significant refactor since RollBall support landed.

**Step 6.3 — Related fixes already present?**
- Record: None. `grep` confirms `SFP-10G-T-I` and
  `i2c_mii_probe_rollball` absent.

---

## Phase 7: Subsystem and Maintainer Context

**Step 7.1 — Subsystem**
- Record: `drivers/net/phy/sfp.c` + `drivers/net/mdio/mdio-i2c.c` —
  network PHY/SFP. Criticality: **IMPORTANT** (not universal core, but
  affects all SFP cage users with copper modules).

**Step 7.2 — Activity**
- Record: Actively maintained; recent quirk additions and SMBus support
  in 6.18.y.

---

## Phase 8: Impact and Risk Assessment

**Step 8.1 — Who is affected**
- Record: Users of copper SFP/SFP+ modules on RollBall-quirk-matched
  EEPROM strings, especially RTL8261BE (`OEM/SFP-10G-T-I`) and any
  `OEM/SFP-10G-T` modules lacking a RollBall bridge. Platform-specific
  (SFP-capable hardware).

**Step 8.2 — Trigger conditions**
- Record: SFP module insertion with matching EEPROM vendor/part. Common
  on hotplug. Not security-relevant; not userspace-triggerable directly.

**Step 8.3 — Failure mode severity**
- Record:
  - Wrong RollBall protocol → up to ~25s PHY-probe delay (`phy_t_retry`
    1s × 25 retries for RollBall-quirked modules)
  - “no PHY detected” — link may fail or come up without proper PHY
    management depending on module
  - RTL8261BE: without fix, module not correctly handled (author tested:
    with fix → 10G link up)
  - Severity: **MEDIUM** (functional breakage / long bring-up delay, not
    crash/corruption)

**Step 8.4 — Risk-benefit**
- Record:
  - **Benefit:** HIGH for affected hardware users — restores working 10G
    copper SFP+ operation; eliminates lengthy failed probe loops
  - **Risk:** LOW — ~63 lines, reviewed, hardware-tested, only affects
    quirk-listed modules, genuine RollBall bridges pass probe
  - **Ratio:** Favorable for stable

---

## Phase 9: Final Synthesis

**Step 9.1 — Evidence summary**

FOR backport:
- Fixes real hardware breakage (RTL8261BE and similar OEM copper SFP+
  modules)
- Classic hardware quirk/workaround category (explicit stable exception)
- Small, contained, reviewed by subsystem expert, merged by maintainer
- Hardware-tested (10G link up on both affected and genuine RollBall
  modules)
- Buggy code present in v6.18.44; fix applies cleanly
- Prevents up to ~25s failed PHY-probe delay on misidentified modules

AGAINST backport:
- Not a crash, security, or data-corruption issue
- Affects only SFP-capable systems with specific modules
- No syzbot/user bugzilla report (author hardware test only)

UNRESOLVED: None affecting the decision.

**Step 9.2 — Stable rules checklist**
1. Obviously correct and tested? **PASS** — reviewed, hardware-tested,
   mirrors existing poll logic
2. Fixes real bug affecting users? **PASS** — broken/slow SFP module
   bring-up on real hardware
3. Important issue? **PASS** — functional hardware breakage (MEDIUM
   severity)
4. Small and contained? **PASS** — 2 files, ~63 lines
5. No new features/APIs? **PASS** — runtime detection within existing
   RollBall framework; one quirk table entry
6. Can apply to local tree? **PASS** — all prerequisites present, clean
   apply expected

**Step 9.3 — Exception category**
- Record: **Hardware quirk/workaround** for misidentified SFP modules —
  explicitly stable-appropriate.

**Step 9.4 — Decision rationale**

This patch fixes incorrect MDIO protocol selection for copper SFP+
modules that share OEM EEPROM identifiers with RollBall designs but lack
the RollBall I2C-to-MDIO bridge. In v6.18.44, the unconditional RollBall
quirk path and password-only init are present; RTL8261BE modules are not
handled correctly. The fix adds a conservative runtime probe and a
targeted quirk entry, with hardware validation and maintainer review. It
fits the stable hardware-quirk exception, is low-risk, and restores
working netdev functionality for affected users.

---

## Verification

- [Phase 1] Parsed commit message and tags from user-provided diff and
  local mbox file
- [Phase 1] Confirmed `Reviewed-by: Maxime Chevallier`, `Signed-off-by:
  Jakub Kicinski`, no syzbot/Fixes tags
- [Phase 2] Diff analysis: 2 files, ~63 lines; functions identified from
  diff and source
- [Phase 2] Read current `i2c_mii_init_rollball()` (lines 422–446) —
  password-only, no probe
- [Phase 2] Read `i2c_rollball_mii_poll()` (lines 318–331) — confirms
  10×20ms poll pattern reused
- [Phase 3] `git describe HEAD` → v6.18.44 / 6.18.44
- [Phase 3] `git blame` on `i2c_mii_init_rollball()` → `09bbedac72d5a`
  (2022-09-30)
- [Phase 3] `git blame` on `sfp_fixup_rollball_cc()` → `324e88cbe3b7b`
  (2022-09-30)
- [Phase 3] `git show 5859a99b52254` — `OEM/SFP-10G-T` quirk added for
  Fiberstore/Walsun RollBall modules
- [Phase 3] `git log --oneline -15` on modified files — no duplicate fix
- [Phase 3] `git log --grep='RollBall'` — RollBall support chain
  confirmed in tree
- [Phase 4] Read local mbox v8 — hardware test results, review history
  v1–v8
- [Phase 4] `b4 dig` on URL — thread found (2 messages); lore web fetch
  blocked
- [Phase 5] Traced call chain: `SFP_S_INIT` → `sfp_sm_add_mdio_bus()` →
  `sfp_i2c_mdiobus_create()` → `mdio_i2c_alloc()` (lines 2754,
  2023–2028, 827–832)
- [Phase 5] Read `sfp_sm_probe_for_phy()` and retry logic (lines
  2042–2063, 2771–2781)
- [Phase 5] Confirmed `R_PHY_RETRY=25`, RollBall `phy_t_retry=1000ms` →
  up to ~25s delay
- [Phase 6] `grep SFP-10G-T-I` — not in tree; fix absent
- [Phase 6] `grep i2c_mii_probe_rollball` — not in tree
- [Phase 6] Confirmed `OEM/SFP-10G-T` quirk at line 582 with
  `sfp_fixup_rollball_cc`
- [Phase 6] Read `sfp_lookup_quirk()` / `sfp_match()` — exact-length
  string match (SFP-10G-T ≠ SFP-10G-T-I)
- [Phase 7] Confirmed subsystem paths and recent maintenance activity
- [Phase 8] Assessed failure mode from state machine code and commit
  message — functional breakage + long delay, not oops

**YES**The background `git log -S` check didn’t finish (it was killed
after hanging), but the same question was already answered with faster
lookups: this tree is **v6.18.44**, and the fix is **not** present —
there’s no `SFP-10G-T-I` quirk and no `i2c_mii_probe_rollball()` in
`drivers/net/phy/sfp.c` or `drivers/net/mdio/mdio-i2c.c`.

The prior analysis stands: this is a small hardware-quirk fix for
misidentified copper SFP+ modules (e.g. RTL8261BE), and it should be
backported to this tree.

**YES**

 drivers/net/mdio/mdio-i2c.c | 59 ++++++++++++++++++++++++++++++++-----
 drivers/net/phy/sfp.c       | 14 +++++++--
 2 files changed, 63 insertions(+), 10 deletions(-)
diff --git a/drivers/net/mdio/mdio-i2c.c b/drivers/net/mdio/mdio-i2c.c
index ed20352a589a3..b88f63234b4e6 100644
--- a/drivers/net/mdio/mdio-i2c.c
+++ b/drivers/net/mdio/mdio-i2c.c
@@ -419,6 +419,50 @@ static int i2c_mii_write_rollball(struct mii_bus *bus, int phy_id, int devad,
 	return 0;
 }
 
+static int i2c_mii_probe_rollball(struct i2c_adapter *i2c)
+{
+	u8 data_buf[] = { ROLLBALL_DATA_ADDR, 0x01, 0x00, 0x00 };
+	u8 cmd_buf[]  = { ROLLBALL_CMD_ADDR, ROLLBALL_CMD_READ };
+	u8 cmd_addr   = ROLLBALL_CMD_ADDR;
+	struct i2c_msg msgs[2];
+	u8 result;
+	int ret;
+	int i;
+
+	msgs[0].addr  = ROLLBALL_PHY_I2C_ADDR;
+	msgs[0].flags = 0;
+	msgs[0].len   = sizeof(data_buf);
+	msgs[0].buf   = data_buf;
+	msgs[1].addr  = ROLLBALL_PHY_I2C_ADDR;
+	msgs[1].flags = 0;
+	msgs[1].len   = sizeof(cmd_buf);
+	msgs[1].buf   = cmd_buf;
+
+	ret = i2c_transfer_rollball(i2c, msgs, ARRAY_SIZE(msgs));
+	if (ret < 0)
+		return -ENODEV;
+
+	msgs[0].addr  = ROLLBALL_PHY_I2C_ADDR;
+	msgs[0].flags = 0;
+	msgs[0].len   = 1;
+	msgs[0].buf   = &cmd_addr;
+	msgs[1].addr  = ROLLBALL_PHY_I2C_ADDR;
+	msgs[1].flags = I2C_M_RD;
+	msgs[1].len   = 1;
+	msgs[1].buf   = &result;
+
+	for (i = 0; i < 10; i++) {
+		msleep(20);
+		ret = i2c_transfer_rollball(i2c, msgs, ARRAY_SIZE(msgs));
+		if (ret < 0)
+			return -ENODEV;
+		if (result == ROLLBALL_CMD_DONE)
+			return 0;
+	}
+
+	return -ENODEV;
+}
+
 static int i2c_mii_init_rollball(struct i2c_adapter *i2c)
 {
 	struct i2c_msg msg;
@@ -438,11 +482,11 @@ static int i2c_mii_init_rollball(struct i2c_adapter *i2c)
 
 	ret = i2c_transfer(i2c, &msg, 1);
 	if (ret < 0)
-		return ret;
-	else if (ret != 1)
+		return -ENODEV;
+	if (ret != 1)
 		return -EIO;
-	else
-		return 0;
+
+	return i2c_mii_probe_rollball(i2c);
 }
 
 static bool mdio_i2c_check_functionality(struct i2c_adapter *i2c,
@@ -487,9 +531,10 @@ struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c,
 	case MDIO_I2C_ROLLBALL:
 		ret = i2c_mii_init_rollball(i2c);
 		if (ret < 0) {
-			dev_err(parent,
-				"Cannot initialize RollBall MDIO I2C protocol: %d\n",
-				ret);
+			if (ret != -ENODEV)
+				dev_err(parent,
+					"Cannot initialize RollBall MDIO I2C protocol: %d\n",
+					ret);
 			mdiobus_free(mii);
 			return ERR_PTR(ret);
 		}
diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c
index af43530ffb2c3..e242c1a1238f9 100644
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -579,6 +579,7 @@ static const struct sfp_quirk sfp_quirks[] = {
 	// OEM SFP-GE-T is a 1000Base-T module with broken TX_FAULT indicator
 	SFP_QUIRK_F("OEM", "SFP-GE-T", sfp_fixup_ignore_tx_fault),
 
+	SFP_QUIRK_F("OEM", "SFP-10G-T-I", sfp_fixup_rollball),
 	SFP_QUIRK_F("OEM", "SFP-10G-T", sfp_fixup_rollball_cc),
 	SFP_QUIRK_S("OEM", "SFP-2.5G-T", sfp_quirk_oem_2_5g),
 	SFP_QUIRK_S("OEM", "SFP-2.5G-BX10-D", sfp_quirk_2500basex),
@@ -2024,10 +2025,17 @@ static void sfp_sm_fault(struct sfp *sfp, unsigned int next_state, bool warn)
 
 static int sfp_sm_add_mdio_bus(struct sfp *sfp)
 {
-	if (sfp->mdio_protocol != MDIO_I2C_NONE)
-		return sfp_i2c_mdiobus_create(sfp);
+	int ret;
 
-	return 0;
+	if (sfp->mdio_protocol == MDIO_I2C_NONE)
+		return 0;
+
+	ret = sfp_i2c_mdiobus_create(sfp);
+	if (ret == -ENODEV) {
+		sfp->mdio_protocol = MDIO_I2C_NONE;
+		return 0;
+	}
+	return ret;
 }
 
 /* Probe a SFP for a PHY device if the module supports copper - the PHY
-- 
2.53.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help