]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/net/dsa/mv88e6xxx.c
arm: imx6: defconfig: update tx6 defconfigs
[karo-tx-linux.git] / drivers / net / dsa / mv88e6xxx.c
1 /*
2  * net/dsa/mv88e6xxx.c - Marvell 88e6xxx switch chip support
3  * Copyright (c) 2008 Marvell Semiconductor
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  */
10
11 #include <linux/delay.h>
12 #include <linux/jiffies.h>
13 #include <linux/list.h>
14 #include <linux/module.h>
15 #include <linux/netdevice.h>
16 #include <linux/phy.h>
17 #include <net/dsa.h>
18 #include "mv88e6xxx.h"
19
20 /* If the switch's ADDR[4:0] strap pins are strapped to zero, it will
21  * use all 32 SMI bus addresses on its SMI bus, and all switch registers
22  * will be directly accessible on some {device address,register address}
23  * pair.  If the ADDR[4:0] pins are not strapped to zero, the switch
24  * will only respond to SMI transactions to that specific address, and
25  * an indirect addressing mechanism needs to be used to access its
26  * registers.
27  */
28 static int mv88e6xxx_reg_wait_ready(struct mii_bus *bus, int sw_addr)
29 {
30         int ret;
31         int i;
32
33         for (i = 0; i < 16; i++) {
34                 ret = mdiobus_read(bus, sw_addr, 0);
35                 if (ret < 0)
36                         return ret;
37
38                 if ((ret & 0x8000) == 0)
39                         return 0;
40         }
41
42         return -ETIMEDOUT;
43 }
44
45 int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr, int reg)
46 {
47         int ret;
48
49         if (sw_addr == 0)
50                 return mdiobus_read(bus, addr, reg);
51
52         /* Wait for the bus to become free. */
53         ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
54         if (ret < 0)
55                 return ret;
56
57         /* Transmit the read command. */
58         ret = mdiobus_write(bus, sw_addr, 0, 0x9800 | (addr << 5) | reg);
59         if (ret < 0)
60                 return ret;
61
62         /* Wait for the read command to complete. */
63         ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
64         if (ret < 0)
65                 return ret;
66
67         /* Read the data. */
68         ret = mdiobus_read(bus, sw_addr, 1);
69         if (ret < 0)
70                 return ret;
71
72         return ret & 0xffff;
73 }
74
75 int mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg)
76 {
77         struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
78         int ret;
79
80         mutex_lock(&ps->smi_mutex);
81         ret = __mv88e6xxx_reg_read(ds->master_mii_bus,
82                                    ds->pd->sw_addr, addr, reg);
83         mutex_unlock(&ps->smi_mutex);
84
85         return ret;
86 }
87
88 int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr,
89                           int reg, u16 val)
90 {
91         int ret;
92
93         if (sw_addr == 0)
94                 return mdiobus_write(bus, addr, reg, val);
95
96         /* Wait for the bus to become free. */
97         ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
98         if (ret < 0)
99                 return ret;
100
101         /* Transmit the data to write. */
102         ret = mdiobus_write(bus, sw_addr, 1, val);
103         if (ret < 0)
104                 return ret;
105
106         /* Transmit the write command. */
107         ret = mdiobus_write(bus, sw_addr, 0, 0x9400 | (addr << 5) | reg);
108         if (ret < 0)
109                 return ret;
110
111         /* Wait for the write command to complete. */
112         ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
113         if (ret < 0)
114                 return ret;
115
116         return 0;
117 }
118
119 int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
120 {
121         struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
122         int ret;
123
124         mutex_lock(&ps->smi_mutex);
125         ret = __mv88e6xxx_reg_write(ds->master_mii_bus,
126                                     ds->pd->sw_addr, addr, reg, val);
127         mutex_unlock(&ps->smi_mutex);
128
129         return ret;
130 }
131
132 int mv88e6xxx_config_prio(struct dsa_switch *ds)
133 {
134         /* Configure the IP ToS mapping registers. */
135         REG_WRITE(REG_GLOBAL, 0x10, 0x0000);
136         REG_WRITE(REG_GLOBAL, 0x11, 0x0000);
137         REG_WRITE(REG_GLOBAL, 0x12, 0x5555);
138         REG_WRITE(REG_GLOBAL, 0x13, 0x5555);
139         REG_WRITE(REG_GLOBAL, 0x14, 0xaaaa);
140         REG_WRITE(REG_GLOBAL, 0x15, 0xaaaa);
141         REG_WRITE(REG_GLOBAL, 0x16, 0xffff);
142         REG_WRITE(REG_GLOBAL, 0x17, 0xffff);
143
144         /* Configure the IEEE 802.1p priority mapping register. */
145         REG_WRITE(REG_GLOBAL, 0x18, 0xfa41);
146
147         return 0;
148 }
149
150 int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr)
151 {
152         REG_WRITE(REG_GLOBAL, 0x01, (addr[0] << 8) | addr[1]);
153         REG_WRITE(REG_GLOBAL, 0x02, (addr[2] << 8) | addr[3]);
154         REG_WRITE(REG_GLOBAL, 0x03, (addr[4] << 8) | addr[5]);
155
156         return 0;
157 }
158
159 int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr)
160 {
161         int i;
162         int ret;
163
164         for (i = 0; i < 6; i++) {
165                 int j;
166
167                 /* Write the MAC address byte. */
168                 REG_WRITE(REG_GLOBAL2, 0x0d, 0x8000 | (i << 8) | addr[i]);
169
170                 /* Wait for the write to complete. */
171                 for (j = 0; j < 16; j++) {
172                         ret = REG_READ(REG_GLOBAL2, 0x0d);
173                         if ((ret & 0x8000) == 0)
174                                 break;
175                 }
176                 if (j == 16)
177                         return -ETIMEDOUT;
178         }
179
180         return 0;
181 }
182
183 int mv88e6xxx_phy_read(struct dsa_switch *ds, int addr, int regnum)
184 {
185         if (addr >= 0)
186                 return mv88e6xxx_reg_read(ds, addr, regnum);
187         return 0xffff;
188 }
189
190 int mv88e6xxx_phy_write(struct dsa_switch *ds, int addr, int regnum, u16 val)
191 {
192         if (addr >= 0)
193                 return mv88e6xxx_reg_write(ds, addr, regnum, val);
194         return 0;
195 }
196
197 #ifdef CONFIG_NET_DSA_MV88E6XXX_NEED_PPU
198 static int mv88e6xxx_ppu_disable(struct dsa_switch *ds)
199 {
200         int ret;
201         unsigned long timeout;
202
203         ret = REG_READ(REG_GLOBAL, 0x04);
204         REG_WRITE(REG_GLOBAL, 0x04, ret & ~0x4000);
205
206         timeout = jiffies + 1 * HZ;
207         while (time_before(jiffies, timeout)) {
208                 ret = REG_READ(REG_GLOBAL, 0x00);
209                 usleep_range(1000, 2000);
210                 if ((ret & 0xc000) != 0xc000)
211                         return 0;
212         }
213
214         return -ETIMEDOUT;
215 }
216
217 static int mv88e6xxx_ppu_enable(struct dsa_switch *ds)
218 {
219         int ret;
220         unsigned long timeout;
221
222         ret = REG_READ(REG_GLOBAL, 0x04);
223         REG_WRITE(REG_GLOBAL, 0x04, ret | 0x4000);
224
225         timeout = jiffies + 1 * HZ;
226         while (time_before(jiffies, timeout)) {
227                 ret = REG_READ(REG_GLOBAL, 0x00);
228                 usleep_range(1000, 2000);
229                 if ((ret & 0xc000) == 0xc000)
230                         return 0;
231         }
232
233         return -ETIMEDOUT;
234 }
235
236 static void mv88e6xxx_ppu_reenable_work(struct work_struct *ugly)
237 {
238         struct mv88e6xxx_priv_state *ps;
239
240         ps = container_of(ugly, struct mv88e6xxx_priv_state, ppu_work);
241         if (mutex_trylock(&ps->ppu_mutex)) {
242                 struct dsa_switch *ds = ((struct dsa_switch *)ps) - 1;
243
244                 if (mv88e6xxx_ppu_enable(ds) == 0)
245                         ps->ppu_disabled = 0;
246                 mutex_unlock(&ps->ppu_mutex);
247         }
248 }
249
250 static void mv88e6xxx_ppu_reenable_timer(unsigned long _ps)
251 {
252         struct mv88e6xxx_priv_state *ps = (void *)_ps;
253
254         schedule_work(&ps->ppu_work);
255 }
256
257 static int mv88e6xxx_ppu_access_get(struct dsa_switch *ds)
258 {
259         struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
260         int ret;
261
262         mutex_lock(&ps->ppu_mutex);
263
264         /* If the PHY polling unit is enabled, disable it so that
265          * we can access the PHY registers.  If it was already
266          * disabled, cancel the timer that is going to re-enable
267          * it.
268          */
269         if (!ps->ppu_disabled) {
270                 ret = mv88e6xxx_ppu_disable(ds);
271                 if (ret < 0) {
272                         mutex_unlock(&ps->ppu_mutex);
273                         return ret;
274                 }
275                 ps->ppu_disabled = 1;
276         } else {
277                 del_timer(&ps->ppu_timer);
278                 ret = 0;
279         }
280
281         return ret;
282 }
283
284 static void mv88e6xxx_ppu_access_put(struct dsa_switch *ds)
285 {
286         struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
287
288         /* Schedule a timer to re-enable the PHY polling unit. */
289         mod_timer(&ps->ppu_timer, jiffies + msecs_to_jiffies(10));
290         mutex_unlock(&ps->ppu_mutex);
291 }
292
293 void mv88e6xxx_ppu_state_init(struct dsa_switch *ds)
294 {
295         struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
296
297         mutex_init(&ps->ppu_mutex);
298         INIT_WORK(&ps->ppu_work, mv88e6xxx_ppu_reenable_work);
299         init_timer(&ps->ppu_timer);
300         ps->ppu_timer.data = (unsigned long)ps;
301         ps->ppu_timer.function = mv88e6xxx_ppu_reenable_timer;
302 }
303
304 int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum)
305 {
306         int ret;
307
308         ret = mv88e6xxx_ppu_access_get(ds);
309         if (ret >= 0) {
310                 ret = mv88e6xxx_reg_read(ds, addr, regnum);
311                 mv88e6xxx_ppu_access_put(ds);
312         }
313
314         return ret;
315 }
316
317 int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr,
318                             int regnum, u16 val)
319 {
320         int ret;
321
322         ret = mv88e6xxx_ppu_access_get(ds);
323         if (ret >= 0) {
324                 ret = mv88e6xxx_reg_write(ds, addr, regnum, val);
325                 mv88e6xxx_ppu_access_put(ds);
326         }
327
328         return ret;
329 }
330 #endif
331
332 void mv88e6xxx_poll_link(struct dsa_switch *ds)
333 {
334         int i;
335
336         for (i = 0; i < DSA_MAX_PORTS; i++) {
337                 struct net_device *dev;
338                 int uninitialized_var(port_status);
339                 int link;
340                 int speed;
341                 int duplex;
342                 int fc;
343
344                 dev = ds->ports[i];
345                 if (dev == NULL)
346                         continue;
347
348                 link = 0;
349                 if (dev->flags & IFF_UP) {
350                         port_status = mv88e6xxx_reg_read(ds, REG_PORT(i), 0x00);
351                         if (port_status < 0)
352                                 continue;
353
354                         link = !!(port_status & 0x0800);
355                 }
356
357                 if (!link) {
358                         if (netif_carrier_ok(dev)) {
359                                 netdev_info(dev, "link down\n");
360                                 netif_carrier_off(dev);
361                         }
362                         continue;
363                 }
364
365                 switch (port_status & 0x0300) {
366                 case 0x0000:
367                         speed = 10;
368                         break;
369                 case 0x0100:
370                         speed = 100;
371                         break;
372                 case 0x0200:
373                         speed = 1000;
374                         break;
375                 default:
376                         speed = -1;
377                         break;
378                 }
379                 duplex = (port_status & 0x0400) ? 1 : 0;
380                 fc = (port_status & 0x8000) ? 1 : 0;
381
382                 if (!netif_carrier_ok(dev)) {
383                         netdev_info(dev,
384                                     "link up, %d Mb/s, %s duplex, flow control %sabled\n",
385                                     speed,
386                                     duplex ? "full" : "half",
387                                     fc ? "en" : "dis");
388                         netif_carrier_on(dev);
389                 }
390         }
391 }
392
393 static int mv88e6xxx_stats_wait(struct dsa_switch *ds)
394 {
395         int ret;
396         int i;
397
398         for (i = 0; i < 10; i++) {
399                 ret = REG_READ(REG_GLOBAL, 0x1d);
400                 if ((ret & 0x8000) == 0)
401                         return 0;
402         }
403
404         return -ETIMEDOUT;
405 }
406
407 static int mv88e6xxx_stats_snapshot(struct dsa_switch *ds, int port)
408 {
409         int ret;
410
411         /* Snapshot the hardware statistics counters for this port. */
412         REG_WRITE(REG_GLOBAL, 0x1d, 0xdc00 | port);
413
414         /* Wait for the snapshotting to complete. */
415         ret = mv88e6xxx_stats_wait(ds);
416         if (ret < 0)
417                 return ret;
418
419         return 0;
420 }
421
422 static void mv88e6xxx_stats_read(struct dsa_switch *ds, int stat, u32 *val)
423 {
424         u32 _val;
425         int ret;
426
427         *val = 0;
428
429         ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x1d, 0xcc00 | stat);
430         if (ret < 0)
431                 return;
432
433         ret = mv88e6xxx_stats_wait(ds);
434         if (ret < 0)
435                 return;
436
437         ret = mv88e6xxx_reg_read(ds, REG_GLOBAL, 0x1e);
438         if (ret < 0)
439                 return;
440
441         _val = ret << 16;
442
443         ret = mv88e6xxx_reg_read(ds, REG_GLOBAL, 0x1f);
444         if (ret < 0)
445                 return;
446
447         *val = _val | ret;
448 }
449
450 void mv88e6xxx_get_strings(struct dsa_switch *ds,
451                            int nr_stats, struct mv88e6xxx_hw_stat *stats,
452                            int port, uint8_t *data)
453 {
454         int i;
455
456         for (i = 0; i < nr_stats; i++) {
457                 memcpy(data + i * ETH_GSTRING_LEN,
458                        stats[i].string, ETH_GSTRING_LEN);
459         }
460 }
461
462 void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds,
463                                  int nr_stats, struct mv88e6xxx_hw_stat *stats,
464                                  int port, uint64_t *data)
465 {
466         struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
467         int ret;
468         int i;
469
470         mutex_lock(&ps->stats_mutex);
471
472         ret = mv88e6xxx_stats_snapshot(ds, port);
473         if (ret < 0) {
474                 mutex_unlock(&ps->stats_mutex);
475                 return;
476         }
477
478         /* Read each of the counters. */
479         for (i = 0; i < nr_stats; i++) {
480                 struct mv88e6xxx_hw_stat *s = stats + i;
481                 u32 low;
482                 u32 high;
483
484                 mv88e6xxx_stats_read(ds, s->reg, &low);
485                 if (s->sizeof_stat == 8)
486                         mv88e6xxx_stats_read(ds, s->reg + 1, &high);
487                 else
488                         high = 0;
489
490                 data[i] = (((u64)high) << 32) | low;
491         }
492
493         mutex_unlock(&ps->stats_mutex);
494 }
495
496 static int __init mv88e6xxx_init(void)
497 {
498 #if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
499         register_switch_driver(&mv88e6131_switch_driver);
500 #endif
501 #if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65)
502         register_switch_driver(&mv88e6123_61_65_switch_driver);
503 #endif
504         return 0;
505 }
506 module_init(mv88e6xxx_init);
507
508 static void __exit mv88e6xxx_cleanup(void)
509 {
510 #if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65)
511         unregister_switch_driver(&mv88e6123_61_65_switch_driver);
512 #endif
513 #if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
514         unregister_switch_driver(&mv88e6131_switch_driver);
515 #endif
516 }
517 module_exit(mv88e6xxx_cleanup);
518
519 MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>");
520 MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips");
521 MODULE_LICENSE("GPL");