bf8bf5e20fafe12aa472a4480bde55b111f295ad
[linux-2.6-microblaze.git] / drivers / net / mdio / mdio-i2c.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * MDIO I2C bridge
4  *
5  * Copyright (C) 2015-2016 Russell King
6  * Copyright (C) 2021 Marek Behun
7  *
8  * Network PHYs can appear on I2C buses when they are part of SFP module.
9  * This driver exposes these PHYs to the networking PHY code, allowing
10  * our PHY drivers access to these PHYs, and so allowing configuration
11  * of their settings.
12  */
13 #include <linux/i2c.h>
14 #include <linux/mdio/mdio-i2c.h>
15 #include <linux/phy.h>
16 #include <linux/sfp.h>
17
18 /*
19  * I2C bus addresses 0x50 and 0x51 are normally an EEPROM, which is
20  * specified to be present in SFP modules.  These correspond with PHY
21  * addresses 16 and 17.  Disallow access to these "phy" addresses.
22  */
23 static bool i2c_mii_valid_phy_id(int phy_id)
24 {
25         return phy_id != 0x10 && phy_id != 0x11;
26 }
27
28 static unsigned int i2c_mii_phy_addr(int phy_id)
29 {
30         return phy_id + 0x40;
31 }
32
33 static int i2c_mii_read_default(struct mii_bus *bus, int phy_id, int reg)
34 {
35         struct i2c_adapter *i2c = bus->priv;
36         struct i2c_msg msgs[2];
37         u8 addr[3], data[2], *p;
38         int bus_addr, ret;
39
40         if (!i2c_mii_valid_phy_id(phy_id))
41                 return 0xffff;
42
43         p = addr;
44         if (reg & MII_ADDR_C45) {
45                 *p++ = 0x20 | ((reg >> 16) & 31);
46                 *p++ = reg >> 8;
47         }
48         *p++ = reg;
49
50         bus_addr = i2c_mii_phy_addr(phy_id);
51         msgs[0].addr = bus_addr;
52         msgs[0].flags = 0;
53         msgs[0].len = p - addr;
54         msgs[0].buf = addr;
55         msgs[1].addr = bus_addr;
56         msgs[1].flags = I2C_M_RD;
57         msgs[1].len = sizeof(data);
58         msgs[1].buf = data;
59
60         ret = i2c_transfer(i2c, msgs, ARRAY_SIZE(msgs));
61         if (ret != ARRAY_SIZE(msgs))
62                 return 0xffff;
63
64         return data[0] << 8 | data[1];
65 }
66
67 static int i2c_mii_write_default(struct mii_bus *bus, int phy_id, int reg,
68                                  u16 val)
69 {
70         struct i2c_adapter *i2c = bus->priv;
71         struct i2c_msg msg;
72         int ret;
73         u8 data[5], *p;
74
75         if (!i2c_mii_valid_phy_id(phy_id))
76                 return 0;
77
78         p = data;
79         if (reg & MII_ADDR_C45) {
80                 *p++ = (reg >> 16) & 31;
81                 *p++ = reg >> 8;
82         }
83         *p++ = reg;
84         *p++ = val >> 8;
85         *p++ = val;
86
87         msg.addr = i2c_mii_phy_addr(phy_id);
88         msg.flags = 0;
89         msg.len = p - data;
90         msg.buf = data;
91
92         ret = i2c_transfer(i2c, &msg, 1);
93
94         return ret < 0 ? ret : 0;
95 }
96
97 /* RollBall SFPs do not access internal PHY via I2C address 0x56, but
98  * instead via address 0x51, when SFP page is set to 0x03 and password to
99  * 0xffffffff.
100  *
101  * address  size  contents  description
102  * -------  ----  --------  -----------
103  * 0x80     1     CMD       0x01/0x02/0x04 for write/read/done
104  * 0x81     1     DEV       Clause 45 device
105  * 0x82     2     REG       Clause 45 register
106  * 0x84     2     VAL       Register value
107  */
108 #define ROLLBALL_PHY_I2C_ADDR           0x51
109
110 #define ROLLBALL_PASSWORD               (SFP_VSL + 3)
111
112 #define ROLLBALL_CMD_ADDR               0x80
113 #define ROLLBALL_DATA_ADDR              0x81
114
115 #define ROLLBALL_CMD_WRITE              0x01
116 #define ROLLBALL_CMD_READ               0x02
117 #define ROLLBALL_CMD_DONE               0x04
118
119 #define SFP_PAGE_ROLLBALL_MDIO          3
120
121 static int __i2c_transfer_err(struct i2c_adapter *i2c, struct i2c_msg *msgs,
122                               int num)
123 {
124         int ret;
125
126         ret = __i2c_transfer(i2c, msgs, num);
127         if (ret < 0)
128                 return ret;
129         else if (ret != num)
130                 return -EIO;
131         else
132                 return 0;
133 }
134
135 static int __i2c_rollball_get_page(struct i2c_adapter *i2c, int bus_addr,
136                                    u8 *page)
137 {
138         struct i2c_msg msgs[2];
139         u8 addr = SFP_PAGE;
140
141         msgs[0].addr = bus_addr;
142         msgs[0].flags = 0;
143         msgs[0].len = 1;
144         msgs[0].buf = &addr;
145
146         msgs[1].addr = bus_addr;
147         msgs[1].flags = I2C_M_RD;
148         msgs[1].len = 1;
149         msgs[1].buf = page;
150
151         return __i2c_transfer_err(i2c, msgs, 2);
152 }
153
154 static int __i2c_rollball_set_page(struct i2c_adapter *i2c, int bus_addr,
155                                    u8 page)
156 {
157         struct i2c_msg msg;
158         u8 buf[2];
159
160         buf[0] = SFP_PAGE;
161         buf[1] = page;
162
163         msg.addr = bus_addr;
164         msg.flags = 0;
165         msg.len = 2;
166         msg.buf = buf;
167
168         return __i2c_transfer_err(i2c, &msg, 1);
169 }
170
171 /* In order to not interfere with other SFP code (which possibly may manipulate
172  * SFP_PAGE), for every transfer we do this:
173  *   1. lock the bus
174  *   2. save content of SFP_PAGE
175  *   3. set SFP_PAGE to 3
176  *   4. do the transfer
177  *   5. restore original SFP_PAGE
178  *   6. unlock the bus
179  * Note that one might think that steps 2 to 5 could be theoretically done all
180  * in one call to i2c_transfer (by constructing msgs array in such a way), but
181  * unfortunately tests show that this does not work :-( Changed SFP_PAGE does
182  * not take into account until i2c_transfer() is done.
183  */
184 static int i2c_transfer_rollball(struct i2c_adapter *i2c,
185                                  struct i2c_msg *msgs, int num)
186 {
187         int ret, main_err = 0;
188         u8 saved_page;
189
190         i2c_lock_bus(i2c, I2C_LOCK_SEGMENT);
191
192         /* save original page */
193         ret = __i2c_rollball_get_page(i2c, msgs->addr, &saved_page);
194         if (ret)
195                 goto unlock;
196
197         /* change to RollBall MDIO page */
198         ret = __i2c_rollball_set_page(i2c, msgs->addr, SFP_PAGE_ROLLBALL_MDIO);
199         if (ret)
200                 goto unlock;
201
202         /* do the transfer; we try to restore original page if this fails */
203         ret = __i2c_transfer_err(i2c, msgs, num);
204         if (ret)
205                 main_err = ret;
206
207         /* restore original page */
208         ret = __i2c_rollball_set_page(i2c, msgs->addr, saved_page);
209
210 unlock:
211         i2c_unlock_bus(i2c, I2C_LOCK_SEGMENT);
212
213         return main_err ? : ret;
214 }
215
216 static int i2c_rollball_mii_poll(struct mii_bus *bus, int bus_addr, u8 *buf,
217                                  size_t len)
218 {
219         struct i2c_adapter *i2c = bus->priv;
220         struct i2c_msg msgs[2];
221         u8 cmd_addr, tmp, *res;
222         int i, ret;
223
224         cmd_addr = ROLLBALL_CMD_ADDR;
225
226         res = buf ? buf : &tmp;
227         len = buf ? len : 1;
228
229         msgs[0].addr = bus_addr;
230         msgs[0].flags = 0;
231         msgs[0].len = 1;
232         msgs[0].buf = &cmd_addr;
233
234         msgs[1].addr = bus_addr;
235         msgs[1].flags = I2C_M_RD;
236         msgs[1].len = len;
237         msgs[1].buf = res;
238
239         /* By experiment it takes up to 70 ms to access a register for these
240          * SFPs. Sleep 20ms between iterations and try 10 times.
241          */
242         i = 10;
243         do {
244                 msleep(20);
245
246                 ret = i2c_transfer_rollball(i2c, msgs, ARRAY_SIZE(msgs));
247                 if (ret)
248                         return ret;
249
250                 if (*res == ROLLBALL_CMD_DONE)
251                         return 0;
252         } while (i-- > 0);
253
254         dev_dbg(&bus->dev, "poll timed out\n");
255
256         return -ETIMEDOUT;
257 }
258
259 static int i2c_rollball_mii_cmd(struct mii_bus *bus, int bus_addr, u8 cmd,
260                                 u8 *data, size_t len)
261 {
262         struct i2c_adapter *i2c = bus->priv;
263         struct i2c_msg msgs[2];
264         u8 cmdbuf[2];
265
266         cmdbuf[0] = ROLLBALL_CMD_ADDR;
267         cmdbuf[1] = cmd;
268
269         msgs[0].addr = bus_addr;
270         msgs[0].flags = 0;
271         msgs[0].len = len;
272         msgs[0].buf = data;
273
274         msgs[1].addr = bus_addr;
275         msgs[1].flags = 0;
276         msgs[1].len = sizeof(cmdbuf);
277         msgs[1].buf = cmdbuf;
278
279         return i2c_transfer_rollball(i2c, msgs, ARRAY_SIZE(msgs));
280 }
281
282 static int i2c_mii_read_rollball(struct mii_bus *bus, int phy_id, int reg)
283 {
284         u8 buf[4], res[6];
285         int bus_addr, ret;
286         u16 val;
287
288         if (!(reg & MII_ADDR_C45))
289                 return -EOPNOTSUPP;
290
291         bus_addr = i2c_mii_phy_addr(phy_id);
292         if (bus_addr != ROLLBALL_PHY_I2C_ADDR)
293                 return 0xffff;
294
295         buf[0] = ROLLBALL_DATA_ADDR;
296         buf[1] = (reg >> 16) & 0x1f;
297         buf[2] = (reg >> 8) & 0xff;
298         buf[3] = reg & 0xff;
299
300         ret = i2c_rollball_mii_cmd(bus, bus_addr, ROLLBALL_CMD_READ, buf,
301                                    sizeof(buf));
302         if (ret < 0)
303                 return ret;
304
305         ret = i2c_rollball_mii_poll(bus, bus_addr, res, sizeof(res));
306         if (ret == -ETIMEDOUT)
307                 return 0xffff;
308         else if (ret < 0)
309                 return ret;
310
311         val = res[4] << 8 | res[5];
312
313         return val;
314 }
315
316 static int i2c_mii_write_rollball(struct mii_bus *bus, int phy_id, int reg,
317                                   u16 val)
318 {
319         int bus_addr, ret;
320         u8 buf[6];
321
322         if (!(reg & MII_ADDR_C45))
323                 return -EOPNOTSUPP;
324
325         bus_addr = i2c_mii_phy_addr(phy_id);
326         if (bus_addr != ROLLBALL_PHY_I2C_ADDR)
327                 return 0;
328
329         buf[0] = ROLLBALL_DATA_ADDR;
330         buf[1] = (reg >> 16) & 0x1f;
331         buf[2] = (reg >> 8) & 0xff;
332         buf[3] = reg & 0xff;
333         buf[4] = val >> 8;
334         buf[5] = val & 0xff;
335
336         ret = i2c_rollball_mii_cmd(bus, bus_addr, ROLLBALL_CMD_WRITE, buf,
337                                    sizeof(buf));
338         if (ret < 0)
339                 return ret;
340
341         ret = i2c_rollball_mii_poll(bus, bus_addr, NULL, 0);
342         if (ret < 0)
343                 return ret;
344
345         return 0;
346 }
347
348 static int i2c_mii_init_rollball(struct i2c_adapter *i2c)
349 {
350         struct i2c_msg msg;
351         u8 pw[5];
352         int ret;
353
354         pw[0] = ROLLBALL_PASSWORD;
355         pw[1] = 0xff;
356         pw[2] = 0xff;
357         pw[3] = 0xff;
358         pw[4] = 0xff;
359
360         msg.addr = ROLLBALL_PHY_I2C_ADDR;
361         msg.flags = 0;
362         msg.len = sizeof(pw);
363         msg.buf = pw;
364
365         ret = i2c_transfer(i2c, &msg, 1);
366         if (ret < 0)
367                 return ret;
368         else if (ret != 1)
369                 return -EIO;
370         else
371                 return 0;
372 }
373
374 struct mii_bus *mdio_i2c_alloc(struct device *parent, struct i2c_adapter *i2c,
375                                enum mdio_i2c_proto protocol)
376 {
377         struct mii_bus *mii;
378         int ret;
379
380         if (!i2c_check_functionality(i2c, I2C_FUNC_I2C))
381                 return ERR_PTR(-EINVAL);
382
383         mii = mdiobus_alloc();
384         if (!mii)
385                 return ERR_PTR(-ENOMEM);
386
387         snprintf(mii->id, MII_BUS_ID_SIZE, "i2c:%s", dev_name(parent));
388         mii->parent = parent;
389         mii->priv = i2c;
390
391         switch (protocol) {
392         case MDIO_I2C_ROLLBALL:
393                 ret = i2c_mii_init_rollball(i2c);
394                 if (ret < 0) {
395                         dev_err(parent,
396                                 "Cannot initialize RollBall MDIO I2C protocol: %d\n",
397                                 ret);
398                         mdiobus_free(mii);
399                         return ERR_PTR(ret);
400                 }
401
402                 mii->read = i2c_mii_read_rollball;
403                 mii->write = i2c_mii_write_rollball;
404                 break;
405         default:
406                 mii->read = i2c_mii_read_default;
407                 mii->write = i2c_mii_write_default;
408                 break;
409         }
410
411         return mii;
412 }
413 EXPORT_SYMBOL_GPL(mdio_i2c_alloc);
414
415 MODULE_AUTHOR("Russell King");
416 MODULE_DESCRIPTION("MDIO I2C bridge library");
417 MODULE_LICENSE("GPL v2");