kernel: sfp: add two fixes submitted to upstream
[openwrt/openwrt.git] / target / linux / generic / pending-4.19 / 745-net-mdio-i2c-add-support-for-Clause-45-accesses.patch
1 From c9de73988a35c6c85810a992954ac568cca503e5 Mon Sep 17 00:00:00 2001
2 From: Russell King <rmk+kernel@armlinux.org.uk>
3 Date: Wed, 2 Oct 2019 10:31:10 +0100
4 Subject: [PATCH 648/660] net: mdio-i2c: add support for Clause 45 accesses
5
6 Some SFP+ modules have PHYs on them just like SFP modules do, except
7 they are Clause 45 PHYs. The I2C protocol used to access them is
8 modified slightly in order to send the device address and 16-bit
9 register index.
10
11 Signed-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 @@ -36,17 +36,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 @@ -64,18 +71,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);