kernel: copy kernel 4.19 code to 5.4
[oweals/openwrt.git] / target / linux / generic / pending-5.4 / 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);