realtek: copy dts/files/patches/configs for 5.15
[openwrt/staging/stintel.git] / target / linux / realtek / patches-5.15 / 711-net-phy-add-an-MDIO-SMBus-library.patch
1 From d585c55b9f70cf9e8c66820d7efe7130c683f19e Mon Sep 17 00:00:00 2001
2 From: Antoine Tenart <antoine.tenart@bootlin.com>
3 Date: Fri, 21 Feb 2020 11:51:27 +0100
4 Subject: [PATCH 2/3] net: phy: add an MDIO SMBus library
5
6 Signed-off-by: Antoine Tenart <antoine.tenart@bootlin.com>
7 ---
8 drivers/net/mdio/Kconfig | 11 +++++++
9 drivers/net/mdio/Makefile | 1 +
10 drivers/net/mdio/mdio-smbus.c | 62 +++++++++++++++++++++++++++++++++++
11 drivers/net/phy/Kconfig | 1 +
12 include/linux/mdio/mdio-i2c.h | 16 +++++++++
13 5 files changed, 91 insertions(+)
14 create mode 100644 drivers/net/mdio/mdio-smbus.c
15
16 --- a/drivers/net/mdio/Kconfig
17 +++ b/drivers/net/mdio/Kconfig
18 @@ -40,6 +40,17 @@ config MDIO_SUN4I
19 interface units of the Allwinner SoC that have an EMAC (A10,
20 A12, A10s, etc.)
21
22 +config MDIO_SMBUS
23 + tristate
24 + depends on I2C_SMBUS
25 + help
26 + Support SMBus based PHYs. This provides a MDIO bus bridged
27 + to SMBus to allow PHYs connected in SMBus mode to be accessed
28 + using the existing infrastructure.
29 +
30 + This is library mode.
31 +
32 +
33 config MDIO_XGENE
34 tristate "APM X-Gene SoC MDIO bus controller"
35 depends on ARCH_XGENE || COMPILE_TEST
36 --- a/drivers/net/mdio/Makefile
37 +++ b/drivers/net/mdio/Makefile
38 @@ -17,6 +17,7 @@ obj-$(CONFIG_MDIO_MOXART) += mdio-moxar
39 obj-$(CONFIG_MDIO_MSCC_MIIM) += mdio-mscc-miim.o
40 obj-$(CONFIG_MDIO_MVUSB) += mdio-mvusb.o
41 obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon.o
42 +obj-$(CONFIG_MDIO_SMBUS) += mdio-smbus.o
43 obj-$(CONFIG_MDIO_SUN4I) += mdio-sun4i.o
44 obj-$(CONFIG_MDIO_THUNDER) += mdio-thunder.o
45 obj-$(CONFIG_MDIO_XGENE) += mdio-xgene.o
46 --- /dev/null
47 +++ b/drivers/net/mdio/mdio-smbus.c
48 @@ -0,0 +1,62 @@
49 +// SPDX-License-Identifier: GPL-2.0-or-later
50 +/*
51 + * MDIO SMBus bridge
52 + *
53 + * Copyright (C) 2020 Antoine Tenart
54 + *
55 + * Network PHYs can appear on SMBus when they are part of SFP modules.
56 + */
57 +#include <linux/i2c.h>
58 +#include <linux/phy.h>
59 +#include <linux/mdio/mdio-i2c.h>
60 +
61 +static int smbus_mii_read(struct mii_bus *mii, int phy_id, int reg)
62 +{
63 + struct i2c_adapter *i2c = mii->priv;
64 + union i2c_smbus_data data;
65 + int ret;
66 +
67 + ret = i2c_smbus_xfer(i2c, i2c_mii_phy_addr(phy_id), 0, I2C_SMBUS_READ,
68 + reg, I2C_SMBUS_BYTE_DATA, &data);
69 + if (ret < 0)
70 + return 0xff;
71 +
72 + return data.byte;
73 +}
74 +
75 +static int smbus_mii_write(struct mii_bus *mii, int phy_id, int reg, u16 val)
76 +{
77 + struct i2c_adapter *i2c = mii->priv;
78 + union i2c_smbus_data data;
79 + int ret;
80 +
81 + data.byte = val;
82 +
83 + ret = i2c_smbus_xfer(i2c, i2c_mii_phy_addr(phy_id), 0, I2C_SMBUS_WRITE,
84 + reg, I2C_SMBUS_BYTE_DATA, &data);
85 + return ret < 0 ? ret : 0;
86 +}
87 +
88 +struct mii_bus *mdio_smbus_alloc(struct device *parent, struct i2c_adapter *i2c)
89 +{
90 + struct mii_bus *mii;
91 +
92 + if (!i2c_check_functionality(i2c, I2C_FUNC_SMBUS_BYTE_DATA))
93 + return ERR_PTR(-EINVAL);
94 +
95 + mii = mdiobus_alloc();
96 + if (!mii)
97 + return ERR_PTR(-ENOMEM);
98 +
99 + snprintf(mii->id, MII_BUS_ID_SIZE, "smbus:%s", dev_name(parent));
100 + mii->parent = parent;
101 + mii->read = smbus_mii_read;
102 + mii->write = smbus_mii_write;
103 + mii->priv = i2c;
104 +
105 + return mii;
106 +}
107 +
108 +MODULE_AUTHOR("Antoine Tenart");
109 +MODULE_DESCRIPTION("MDIO SMBus bridge library");
110 +MODULE_LICENSE("GPL");
111 --- a/drivers/net/phy/Kconfig
112 +++ b/drivers/net/phy/Kconfig
113 @@ -60,6 +60,7 @@ config SFP
114 depends on I2C && PHYLINK
115 depends on HWMON || HWMON=n
116 select MDIO_I2C
117 + select MDIO_SMBUS
118
119 comment "Switch configuration API + drivers"
120
121 --- a/include/linux/mdio/mdio-i2c.h
122 +++ b/include/linux/mdio/mdio-i2c.h
123 @@ -12,5 +12,21 @@ struct i2c_adapter;
124 struct mii_bus;
125
126 struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c);
127 +struct mii_bus *mdio_smbus_alloc(struct device *parent, struct i2c_adapter *i2c);
128 +
129 +/*
130 + * I2C bus addresses 0x50 and 0x51 are normally an EEPROM, which is
131 + * specified to be present in SFP modules. These correspond with PHY
132 + * addresses 16 and 17. Disallow access to these "phy" addresses.
133 + */
134 +static bool i2c_mii_valid_phy_id(int phy_id)
135 +{
136 + return phy_id != 0x10 && phy_id != 0x11;
137 +}
138 +
139 +static unsigned int i2c_mii_phy_addr(int phy_id)
140 +{
141 + return phy_id + 0x40;
142 +}
143
144 #endif
145 --- a/drivers/net/mdio/mdio-i2c.c
146 +++ b/drivers/net/mdio/mdio-i2c.c
147 @@ -13,21 +13,6 @@
148 #include <linux/mdio/mdio-i2c.h>
149 #include <linux/phy.h>
150
151 -/*
152 - * I2C bus addresses 0x50 and 0x51 are normally an EEPROM, which is
153 - * specified to be present in SFP modules. These correspond with PHY
154 - * addresses 16 and 17. Disallow access to these "phy" addresses.
155 - */
156 -static bool i2c_mii_valid_phy_id(int phy_id)
157 -{
158 - return phy_id != 0x10 && phy_id != 0x11;
159 -}
160 -
161 -static unsigned int i2c_mii_phy_addr(int phy_id)
162 -{
163 - return phy_id + 0x40;
164 -}
165 -
166 static int i2c_mii_read(struct mii_bus *bus, int phy_id, int reg)
167 {
168 struct i2c_adapter *i2c = bus->priv;