blob: 3b33f63fd0250ae03eb03b042552c5815b718763 [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001From c9de73988a35c6c85810a992954ac568cca503e5 Mon Sep 17 00:00:00 2001
2From: Russell King <rmk+kernel@armlinux.org.uk>
3Date: Wed, 2 Oct 2019 10:31:10 +0100
4Subject: [PATCH 648/660] net: mdio-i2c: add support for Clause 45 accesses
5
6Some SFP+ modules have PHYs on them just like SFP modules do, except
7they are Clause 45 PHYs. The I2C protocol used to access them is
8modified slightly in order to send the device address and 16-bit
9register index.
10
11Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
12---
13 drivers/net/phy/mdio-i2c.c | 28 ++++++++++++++++++++--------
14 1 file changed, 20 insertions(+), 8 deletions(-)
15
16--- a/drivers/net/phy/mdio-i2c.c
17+++ b/drivers/net/phy/mdio-i2c.c
18@@ -32,17 +32,24 @@ static int i2c_mii_read(struct mii_bus *
19 {
20 struct i2c_adapter *i2c = bus->priv;
21 struct i2c_msg msgs[2];
22- u8 data[2], dev_addr = reg;
23+ u8 addr[3], data[2], *p;
24 int bus_addr, ret;
25
26 if (!i2c_mii_valid_phy_id(phy_id))
27 return 0xffff;
28
29+ p = addr;
30+ if (reg & MII_ADDR_C45) {
31+ *p++ = 0x20 | ((reg >> 16) & 31);
32+ *p++ = reg >> 8;
33+ }
34+ *p++ = reg;
35+
36 bus_addr = i2c_mii_phy_addr(phy_id);
37 msgs[0].addr = bus_addr;
38 msgs[0].flags = 0;
39- msgs[0].len = 1;
40- msgs[0].buf = &dev_addr;
41+ msgs[0].len = p - addr;
42+ msgs[0].buf = addr;
43 msgs[1].addr = bus_addr;
44 msgs[1].flags = I2C_M_RD;
45 msgs[1].len = sizeof(data);
46@@ -60,18 +67,23 @@ static int i2c_mii_write(struct mii_bus
47 struct i2c_adapter *i2c = bus->priv;
48 struct i2c_msg msg;
49 int ret;
50- u8 data[3];
51+ u8 data[5], *p;
52
53 if (!i2c_mii_valid_phy_id(phy_id))
54 return 0;
55
56- data[0] = reg;
57- data[1] = val >> 8;
58- data[2] = val;
59+ p = data;
60+ if (reg & MII_ADDR_C45) {
61+ *p++ = (reg >> 16) & 31;
62+ *p++ = reg >> 8;
63+ }
64+ *p++ = reg;
65+ *p++ = val >> 8;
66+ *p++ = val;
67
68 msg.addr = i2c_mii_phy_addr(phy_id);
69 msg.flags = 0;
70- msg.len = 3;
71+ msg.len = p - data;
72 msg.buf = data;
73
74 ret = i2c_transfer(i2c, &msg, 1);