ar71xx: add DSA driver for the AR7240 built-in ethernet switch
[openwrt.git] / target / linux / ar71xx / files / net / dsa / ar7240.c
1 /*
2  *  DSA driver for the built-in ethernet switch of the Atheros AR7240 SoC
3  *  Copyright (c) 2010 Gabor Juhos <juhosg@openwrt.org>
4  *
5  *  This file was based on:
6  *    net/dsa/mv88e6060.c - Driver for Marvell 88e6060 switch chips
7  *    Copyright (c) 2008 Marvell Semiconductor
8  *
9  *  This program is free software; you can redistribute it and/or modify it
10  *  under the terms of the GNU General Public License version 2 as published
11  *  by the Free Software Foundation.
12  *
13  */
14
15 #include <linux/etherdevice.h>
16 #include <linux/list.h>
17 #include <linux/netdevice.h>
18 #include <linux/phy.h>
19 #include <linux/mii.h>
20 #include <linux/bitops.h>
21
22 #include "dsa_priv.h"
23
24 #define BITM(_count)    (BIT(_count) - 1)
25
26 #define AR7240_REG_MASK_CTRL            0x00
27 #define AR7240_MASK_CTRL_REVISION_M     BITM(8)
28 #define AR7240_MASK_CTRL_VERSION_M      BITM(8)
29 #define AR7240_MASK_CTRL_VERSION_S      8
30 #define AR7240_MASK_CTRL_SOFT_RESET     BIT(31)
31
32 #define AR7240_REG_MAC_ADDR0            0x20
33 #define AR7240_REG_MAC_ADDR1            0x24
34
35 #define AR7240_REG_FLOOD_MASK           0x2c
36 #define AR7240_FLOOD_MASK_BROAD_TO_CPU  BIT(26)
37
38 #define AR7240_REG_GLOBAL_CTRL          0x30
39 #define AR7240_GLOBAL_CTRL_MTU_M        BITM(12)
40
41 #define AR7240_REG_AT_CTRL              0x5c
42 #define AR7240_AT_CTRL_ARP_EN           BIT(20)
43
44 #define AR7240_REG_TAG_PRIORITY         0x70
45
46 #define AR7240_REG_SERVICE_TAG          0x74
47 #define AR7240_SERVICE_TAG_M            BITM(16)
48
49 #define AR7240_REG_CPU_PORT             0x78
50 #define AR7240_MIRROR_PORT_S            4
51 #define AR7240_CPU_PORT_EN              BIT(8)
52
53 #define AR7240_REG_MIB_FUNCTION0        0x80
54 #define AR7240_MIB_TIMER_M              BITM(16)
55 #define AR7240_MIB_AT_HALF_EN           BIT(16)
56 #define AR7240_MIB_BUSY                 BIT(17)
57 #define AR7240_MIB_FUNC_S               24
58 #define AR7240_MIB_FUNC_NO_OP           0x0
59 #define AR7240_MIB_FUNC_FLUSH           0x1
60 #define AR7240_MIB_FUNC_CAPTURE         0x3
61
62 #define AR7240_REG_MDIO_CTRL            0x98
63 #define AR7240_MDIO_CTRL_DATA_M         BITM(16)
64 #define AR7240_MDIO_CTRL_REG_ADDR_S     16
65 #define AR7240_MDIO_CTRL_PHY_ADDR_S     21
66 #define AR7240_MDIO_CTRL_CMD_WRITE      0
67 #define AR7240_MDIO_CTRL_CMD_READ       BIT(27)
68 #define AR7240_MDIO_CTRL_MASTER_EN      BIT(30)
69 #define AR7240_MDIO_CTRL_BUSY           BIT(31)
70
71 #define AR7240_REG_PORT_BASE(_port)     (0x100 + (_port) * 0x100)
72
73 #define AR7240_REG_PORT_STATUS(_port)   (AR7240_REG_PORT_BASE((_port)) + 0x00)
74 #define AR7240_PORT_STATUS_SPEED_M      BITM(2)
75 #define AR7240_PORT_STATUS_SPEED_10     0
76 #define AR7240_PORT_STATUS_SPEED_100    1
77 #define AR7240_PORT_STATUS_SPEED_1000   2
78 #define AR7240_PORT_STATUS_TXMAC        BIT(2)
79 #define AR7240_PORT_STATUS_RXMAC        BIT(3)
80 #define AR7240_PORT_STATUS_TXFLOW       BIT(4)
81 #define AR7240_PORT_STATUS_RXFLOW       BIT(5)
82 #define AR7240_PORT_STATUS_DUPLEX       BIT(6)
83 #define AR7240_PORT_STATUS_LINK_UP      BIT(8)
84 #define AR7240_PORT_STATUS_LINK_AUTO    BIT(9)
85 #define AR7240_PORT_STATUS_LINK_PAUSE   BIT(10)
86
87 #define AR7240_REG_PORT_CTRL(_port)     (AR7240_REG_PORT_BASE((_port)) + 0x04)
88 #define AR7240_PORT_CTRL_STATE_M        BITM(3)
89 #define AR7240_PORT_CTRL_STATE_DISABLED 0
90 #define AR7240_PORT_CTRL_STATE_BLOCK    1
91 #define AR7240_PORT_CTRL_STATE_LISTEN   2
92 #define AR7240_PORT_CTRL_STATE_LEARN    3
93 #define AR7240_PORT_CTRL_STATE_FORWARD  4
94 #define AR7240_PORT_CTRL_LEARN_LOCK     BIT(7)
95 #define AR7240_PORT_CTRL_VLAN_MODE_S    8
96 #define AR7240_PORT_CTRL_VLAN_MODE_KEEP 0
97 #define AR7240_PORT_CTRL_VLAN_MODE_STRIP 1
98 #define AR7240_PORT_CTRL_VLAN_MODE_ADD  2
99 #define AR7240_PORT_CTRL_VLAN_MODE_DOUBLE_TAG 3
100 #define AR7240_PORT_CTRL_IGMP_SNOOP     BIT(10)
101 #define AR7240_PORT_CTRL_HEADER         BIT(11)
102 #define AR7240_PORT_CTRL_MAC_LOOP       BIT(12)
103 #define AR7240_PORT_CTRL_SINGLE_VLAN    BIT(13)
104 #define AR7240_PORT_CTRL_LEARN          BIT(14)
105 #define AR7240_PORT_CTRL_DOUBLE_TAG     BIT(15)
106 #define AR7240_PORT_CTRL_MIRROR_TX      BIT(16)
107 #define AR7240_PORT_CTRL_MIRROR_RX      BIT(17)
108
109 #define AR7240_REG_PORT_VLAN(_port)     (AR7240_REG_PORT_BASE((_port)) + 0x08)
110
111 #define AR7240_PORT_VLAN_DEFAULT_ID_S   0
112 #define AR7240_PORT_VLAN_DEST_PORTS_S   16
113
114 #define AR7240_REG_STATS_BASE(_port)    (0x20000 + (_port) * 0x100)
115
116 #define AR7240_STATS_RXBROAD            0x00
117 #define AR7240_STATS_RXPAUSE            0x04
118 #define AR7240_STATS_RXMULTI            0x08
119 #define AR7240_STATS_RXFCSERR           0x0c
120 #define AR7240_STATS_RXALIGNERR         0x10
121 #define AR7240_STATS_RXRUNT             0x14
122 #define AR7240_STATS_RXFRAGMENT         0x18
123 #define AR7240_STATS_RX64BYTE           0x1c
124 #define AR7240_STATS_RX128BYTE          0x20
125 #define AR7240_STATS_RX256BYTE          0x24
126 #define AR7240_STATS_RX512BYTE          0x28
127 #define AR7240_STATS_RX1024BYTE         0x2c
128 #define AR7240_STATS_RX1518BYTE         0x30
129 #define AR7240_STATS_RXMAXBYTE          0x34
130 #define AR7240_STATS_RXTOOLONG          0x38
131 #define AR7240_STATS_RXGOODBYTE         0x3c
132 #define AR7240_STATS_RXBADBYTE          0x44
133 #define AR7240_STATS_RXOVERFLOW         0x4c
134 #define AR7240_STATS_FILTERED           0x50
135 #define AR7240_STATS_TXBROAD            0x54
136 #define AR7240_STATS_TXPAUSE            0x58
137 #define AR7240_STATS_TXMULTI            0x5c
138 #define AR7240_STATS_TXUNDERRUN         0x60
139 #define AR7240_STATS_TX64BYTE           0x64
140 #define AR7240_STATS_TX128BYTE          0x68
141 #define AR7240_STATS_TX256BYTE          0x6c
142 #define AR7240_STATS_TX512BYTE          0x70
143 #define AR7240_STATS_TX1024BYTE         0x74
144 #define AR7240_STATS_TX1518BYTE         0x78
145 #define AR7240_STATS_TXMAXBYTE          0x7c
146 #define AR7240_STATS_TXOVERSIZE         0x80
147 #define AR7240_STATS_TXBYTE             0x84
148 #define AR7240_STATS_TXCOLLISION        0x8c
149 #define AR7240_STATS_TXABORTCOL         0x90
150 #define AR7240_STATS_TXMULTICOL         0x94
151 #define AR7240_STATS_TXSINGLECOL        0x98
152 #define AR7240_STATS_TXEXCDEFER         0x9c
153 #define AR7240_STATS_TXDEFER            0xa0
154 #define AR7240_STATS_TXLATECOL          0xa4
155
156 #define AR7240_PORT_CPU         0
157 #define AR7240_NUM_PORTS        6
158 #define AR7240_NUM_PHYS         5
159
160 #define AR7240_PHY_ID1          0x004d
161 #define AR7240_PHY_ID2          0xd041
162
163 #define AR7240_PORT_MASK(_port)         BIT((_port))
164 #define AR7240_PORT_MASK_ALL            BITM(AR7240_NUM_PORTS)
165 #define AR7240_PORT_MASK_BUT(_port)     (AR7240_PORT_MASK_ALL & ~BIT((_port)))
166
167 struct ar7240sw {
168         struct mii_bus  *mii_bus;
169         struct mutex    reg_mutex;
170         struct mutex    stats_mutex;
171 };
172
173 struct ar7240sw_hw_stat {
174         char string[ETH_GSTRING_LEN];
175         int sizeof_stat;
176         int reg;
177 };
178
179 static inline struct ar7240sw *dsa_to_ar7240sw(struct dsa_switch *ds)
180 {
181         return (struct ar7240sw *)(ds + 1);
182 }
183
184 static inline void ar7240sw_init(struct ar7240sw *as, struct mii_bus *mii)
185 {
186         as->mii_bus = mii;
187         mutex_init(&as->reg_mutex);
188         mutex_init(&as->stats_mutex);
189 }
190
191 static inline u16 mk_phy_addr(u32 reg)
192 {
193         return (0x17 & ((reg >> 4) | 0x10));
194 }
195
196 static inline u16 mk_phy_reg(u32 reg)
197 {
198         return ((reg << 1) & 0x1e);
199 }
200
201 static inline u16 mk_high_addr(u32 reg)
202 {
203         return ((reg >> 7) & 0x1ff);
204 }
205
206 static u32 __ar7240sw_reg_read(struct ar7240sw *as, u32 reg)
207 {
208         struct mii_bus *mii = as->mii_bus;
209         u16 phy_addr;
210         u16 phy_reg;
211         u32 hi, lo;
212
213         reg = (reg & 0xfffffffc) >> 2;
214
215         mdiobus_write(mii, 0x1f, 0x10, mk_high_addr(reg));
216
217         phy_addr = mk_phy_addr(reg);
218         phy_reg = mk_phy_reg(reg);
219
220         lo = (u32) mdiobus_read(mii, phy_addr, phy_reg);
221         hi = (u32) mdiobus_read(mii, phy_addr, phy_reg + 1);
222
223         return ((hi << 16) | lo);
224 }
225
226 static void __ar7240sw_reg_write(struct ar7240sw *as, u32 reg, u32 val)
227 {
228         struct mii_bus *mii = as->mii_bus;
229         u16 phy_addr;
230         u16 phy_reg;
231
232         reg = (reg & 0xfffffffc) >> 2;
233
234         mdiobus_write(mii, 0x1f, 0x10, mk_high_addr(reg));
235
236         phy_addr = mk_phy_addr(reg);
237         phy_reg = mk_phy_reg(reg);
238
239         mdiobus_write(mii, phy_addr, phy_reg + 1, (val >> 16));
240         mdiobus_write(mii, phy_addr, phy_reg, (val & 0xffff));
241 }
242
243 static u32 ar7240sw_reg_read(struct ar7240sw *as, u32 reg_addr)
244 {
245         u32 ret;
246
247         mutex_lock(&as->reg_mutex);
248         ret = __ar7240sw_reg_read(as, reg_addr);
249         mutex_unlock(&as->reg_mutex);
250
251         return ret;
252 }
253
254 static void ar7240sw_reg_write(struct ar7240sw *as, u32 reg_addr, u32 reg_val)
255 {
256         mutex_lock(&as->reg_mutex);
257         __ar7240sw_reg_write(as, reg_addr, reg_val);
258         mutex_unlock(&as->reg_mutex);
259 }
260
261 static u32 ar7240sw_reg_rmw(struct ar7240sw *as, u32 reg, u32 mask, u32 val)
262 {
263         u32 t;
264
265         mutex_lock(&as->reg_mutex);
266         t = __ar7240sw_reg_read(as, reg);
267         t &= ~mask;
268         t |= val;
269         __ar7240sw_reg_write(as, reg, t);
270         mutex_unlock(&as->reg_mutex);
271
272         return t;
273 }
274
275 static void ar7240sw_reg_set(struct ar7240sw *as, u32 reg, u32 val)
276 {
277         u32 t;
278
279         mutex_lock(&as->reg_mutex);
280         t = __ar7240sw_reg_read(as, reg);
281         t |= val;
282         __ar7240sw_reg_write(as, reg, t);
283         mutex_unlock(&as->reg_mutex);
284 }
285
286 static int ar7240sw_reg_wait(struct ar7240sw *as, u32 reg, u32 mask, u32 val,
287                              unsigned timeout)
288 {
289         int i;
290
291         for (i = 0; i < timeout; i++) {
292                 u32 t;
293
294                 t = ar7240sw_reg_read(as, reg);
295                 if ((t & mask) == val)
296                         return 0;
297
298                 msleep(1);
299         }
300
301         return -ETIMEDOUT;
302 }
303
304 static u16 ar7240sw_phy_read(struct ar7240sw *as, unsigned phy_addr,
305                              unsigned reg_addr)
306 {
307         u32 t;
308         int err;
309
310         if (phy_addr >= AR7240_NUM_PHYS)
311                 return 0xffff;
312
313         t = (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) |
314             (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) |
315             AR7240_MDIO_CTRL_MASTER_EN |
316             AR7240_MDIO_CTRL_BUSY |
317             AR7240_MDIO_CTRL_CMD_READ;
318
319         ar7240sw_reg_write(as, AR7240_REG_MDIO_CTRL, t);
320         err = ar7240sw_reg_wait(as, AR7240_REG_MDIO_CTRL,
321                                 AR7240_MDIO_CTRL_BUSY, 0, 5);
322         if (err)
323                 return 0xffff;
324
325         t = ar7240sw_reg_read(as, AR7240_REG_MDIO_CTRL);
326         return (t & AR7240_MDIO_CTRL_DATA_M);
327 }
328
329 static int ar7240sw_phy_write(struct ar7240sw *as, unsigned phy_addr,
330                               unsigned reg_addr, u16 reg_val)
331 {
332         u32 t;
333         int ret;
334
335         if (phy_addr >= AR7240_NUM_PHYS)
336                 return -EINVAL;
337
338         t = (phy_addr << AR7240_MDIO_CTRL_PHY_ADDR_S) |
339             (reg_addr << AR7240_MDIO_CTRL_REG_ADDR_S) |
340             AR7240_MDIO_CTRL_MASTER_EN |
341             AR7240_MDIO_CTRL_BUSY |
342             AR7240_MDIO_CTRL_CMD_WRITE |
343             reg_val;
344
345         ar7240sw_reg_write(as, AR7240_REG_MDIO_CTRL, t);
346         ret = ar7240sw_reg_wait(as, AR7240_REG_MDIO_CTRL,
347                                 AR7240_MDIO_CTRL_BUSY, 0, 5);
348         return ret;
349 }
350
351 static int ar7240sw_capture_stats(struct ar7240sw *as)
352 {
353         int ret;
354
355         /* Capture the hardware statistics for all ports */
356         ar7240sw_reg_write(as, AR7240_REG_MIB_FUNCTION0,
357                            (AR7240_MIB_FUNC_CAPTURE << AR7240_MIB_FUNC_S));
358
359         /* Wait for the capturing to complete. */
360         ret = ar7240sw_reg_wait(as, AR7240_REG_MIB_FUNCTION0,
361                                 AR7240_MIB_BUSY, 0, 10);
362         return ret;
363 }
364
365 static void ar7240sw_disable_port(struct ar7240sw *as, unsigned port)
366 {
367         ar7240sw_reg_write(as, AR7240_REG_PORT_CTRL(port),
368                            AR7240_PORT_CTRL_STATE_DISABLED);
369 }
370
371 static int ar7240sw_reset(struct ar7240sw *as)
372 {
373         int ret;
374         int i;
375
376         /* Set all ports to disabled state. */
377         for (i = 0; i < AR7240_NUM_PORTS; i++)
378                 ar7240sw_disable_port(as, i);
379
380         /* Wait for transmit queues to drain. */
381         msleep(2);
382
383         /* Reset the switch. */
384         ar7240sw_reg_write(as, AR7240_REG_MASK_CTRL,
385                            AR7240_MASK_CTRL_SOFT_RESET);
386
387         ret = ar7240sw_reg_wait(as, AR7240_REG_MASK_CTRL,
388                                 AR7240_MASK_CTRL_SOFT_RESET, 0, 1000);
389         return ret;
390 }
391
392 static void ar7240sw_setup(struct ar7240sw *as)
393 {
394         /* Enable CPU port, and disable mirror port */
395         ar7240sw_reg_write(as, AR7240_REG_CPU_PORT,
396                            AR7240_CPU_PORT_EN |
397                            (15 << AR7240_MIRROR_PORT_S));
398
399         /* Setup TAG priority mapping */
400         ar7240sw_reg_write(as, AR7240_REG_TAG_PRIORITY, 0xfa50);
401
402         /* Enable ARP frame acknowledge */
403         ar7240sw_reg_set(as, AR7240_REG_AT_CTRL, AR7240_AT_CTRL_ARP_EN);
404
405         /* Enable Broadcast frames transmitted to the CPU */
406         ar7240sw_reg_set(as, AR7240_REG_FLOOD_MASK,
407                          AR7240_FLOOD_MASK_BROAD_TO_CPU);
408
409         /* setup MTU */
410         ar7240sw_reg_rmw(as, AR7240_REG_GLOBAL_CTRL, AR7240_GLOBAL_CTRL_MTU_M,
411                          1536);
412
413         /* setup Service TAG */
414         ar7240sw_reg_rmw(as, AR7240_REG_SERVICE_TAG, AR7240_SERVICE_TAG_M,
415                          ETH_P_QINQ);
416 }
417
418 static void ar7240sw_setup_port(struct ar7240sw *as, unsigned port)
419 {
420         u32 ctrl;
421         u32 dest_ports;
422         u32 vlan;
423
424         ctrl = AR7240_PORT_CTRL_STATE_FORWARD;
425
426         if (port == AR7240_PORT_CPU) {
427                 ar7240sw_reg_write(as, AR7240_REG_PORT_STATUS(port),
428                                    AR7240_PORT_STATUS_SPEED_1000 |
429                                    AR7240_PORT_STATUS_TXFLOW |
430                                    AR7240_PORT_STATUS_RXFLOW |
431                                    AR7240_PORT_STATUS_TXMAC |
432                                    AR7240_PORT_STATUS_RXMAC |
433                                    AR7240_PORT_STATUS_DUPLEX);
434
435                 /* allow the CPU port to talk to each of the 'real' ports */
436                 dest_ports = AR7240_PORT_MASK_BUT(port);
437
438                 /* remove service tag from ingress frames */
439                 ctrl |= AR7240_PORT_CTRL_DOUBLE_TAG;
440         } else {
441                 ar7240sw_reg_write(as, AR7240_REG_PORT_STATUS(port),
442                                    AR7240_PORT_STATUS_LINK_AUTO);
443
444                 /*
445                  * allow each of the 'real' ports to only talk to the CPU
446                  * port.
447                  */
448                 dest_ports = AR7240_PORT_MASK(port) |
449                              AR7240_PORT_MASK(AR7240_PORT_CPU);
450
451                 /* add service tag to egress frames */
452                 ctrl |= (AR7240_PORT_CTRL_VLAN_MODE_DOUBLE_TAG <<
453                          AR7240_PORT_CTRL_VLAN_MODE_S);
454         }
455
456         /* set default VID and and destination ports for this VLAN */
457         vlan = port;
458         vlan |= (dest_ports << AR7240_PORT_VLAN_DEST_PORTS_S);
459
460         ar7240sw_reg_write(as, AR7240_REG_PORT_CTRL(port), ctrl);
461         ar7240sw_reg_write(as, AR7240_REG_PORT_VLAN(port), vlan);
462 }
463
464 static char *ar7240_dsa_probe(struct mii_bus *mii, int sw_addr)
465 {
466         struct ar7240sw as;
467         u32 ctrl;
468         u16 phy_id1;
469         u16 phy_id2;
470         u8 ver;
471
472         ar7240sw_init(&as, mii);
473
474         ctrl = ar7240sw_reg_read(&as, AR7240_REG_MASK_CTRL);
475
476         ver = (ctrl >> AR7240_MASK_CTRL_VERSION_S) & AR7240_MASK_CTRL_VERSION_M;
477         if (ver != 1) {
478                 pr_err("ar7240_dsa: unsupported chip, ctrl=%08x\n", ctrl);
479                 return NULL;
480         }
481
482         phy_id1 = ar7240sw_phy_read(&as, 0, MII_PHYSID1);
483         phy_id2 = ar7240sw_phy_read(&as, 0, MII_PHYSID2);
484         if (phy_id1 != AR7240_PHY_ID1 || phy_id2 != AR7240_PHY_ID2) {
485                 pr_err("ar7240_dsa: unknown phy id '%04x:%04x'\n",
486                        phy_id1, phy_id2);
487                 return NULL;
488         }
489
490         return "Atheros AR7240 built-in";
491 }
492
493 static int ar7240_dsa_setup(struct dsa_switch *ds)
494 {
495         struct ar7240sw *as = dsa_to_ar7240sw(ds);
496         int i;
497         int ret;
498
499         ar7240sw_init(as, ds->master_mii_bus);
500
501         ret = ar7240sw_reset(as);
502         if (ret)
503                 return ret;
504
505         ar7240sw_setup(as);
506
507         for (i = 0; i < AR7240_NUM_PORTS; i++) {
508                 if (dsa_is_cpu_port(ds, i) || (ds->phys_port_mask & (1 << i)))
509                         ar7240sw_setup_port(as, i);
510                 else
511                         ar7240sw_disable_port(as, i);
512         }
513
514         return 0;
515 }
516
517 static int ar7240_dsa_set_addr(struct dsa_switch *ds, u8 *addr)
518 {
519         struct ar7240sw *as = dsa_to_ar7240sw(ds);
520         u32 t;
521
522         t = (addr[4] << 8) | addr[5];
523         ar7240sw_reg_write(as, AR7240_REG_MAC_ADDR0, t);
524
525         t = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3];
526         ar7240sw_reg_write(as, AR7240_REG_MAC_ADDR0, t);
527
528         return 0;
529 }
530
531 static int ar7240_iort_to_phy_addr(int port)
532 {
533         if (port > 0 && port < AR7240_NUM_PORTS)
534                 return port - 1;
535
536         return -EINVAL;
537 }
538
539 static int ar7240_dsa_phy_read(struct dsa_switch *ds, int port, int regnum)
540 {
541         struct ar7240sw *as = dsa_to_ar7240sw(ds);
542         int phy_addr;
543
544         phy_addr = ar7240_iort_to_phy_addr(port);
545         if (phy_addr < 0)
546                 return 0xffff;
547
548         return ar7240sw_phy_read(as, phy_addr, regnum);
549 }
550
551 static int ar7240_dsa_phy_write(struct dsa_switch *ds, int port, int regnum,
552                                 u16 val)
553 {
554         struct ar7240sw *as = dsa_to_ar7240sw(ds);
555         int phy_addr;
556
557         phy_addr = ar7240_iort_to_phy_addr(port);
558         if (phy_addr < 0)
559                 return 0xffff;
560
561         return ar7240sw_phy_write(as, phy_addr, regnum, val);
562 }
563
564 static const char *ar7240sw_speed_str(unsigned speed)
565 {
566         switch (speed) {
567         case AR7240_PORT_STATUS_SPEED_10:
568                 return "10";
569         case AR7240_PORT_STATUS_SPEED_100:
570                 return "100";
571         case AR7240_PORT_STATUS_SPEED_1000:
572                 return "1000";
573         }
574
575         return "????";
576 }
577
578 static void ar7240_dsa_poll_link(struct dsa_switch *ds)
579 {
580         struct ar7240sw *as = dsa_to_ar7240sw(ds);
581         int i;
582
583         for (i = 0; i < DSA_MAX_PORTS; i++) {
584                 struct net_device *dev;
585                 u32 status;
586                 int link;
587                 unsigned speed;
588                 int duplex;
589
590                 dev = ds->ports[i];
591                 if (dev == NULL)
592                         continue;
593
594                 link = 0;
595                 if (dev->flags & IFF_UP) {
596                         status = ar7240sw_reg_read(as,
597                                                    AR7240_REG_PORT_STATUS(i));
598                         link = !!(status & AR7240_PORT_STATUS_LINK_UP);
599                 }
600
601                 if (!link) {
602                         if (netif_carrier_ok(dev)) {
603                                 pr_info("%s: link down\n", dev->name);
604                                 netif_carrier_off(dev);
605                         }
606                         continue;
607                 }
608
609                 speed = (status & AR7240_PORT_STATUS_SPEED_M);
610                 duplex = (status & AR7240_PORT_STATUS_DUPLEX) ? 1 : 0;
611                 if (!netif_carrier_ok(dev)) {
612                         pr_info("%s: link up, %sMb/s, %s duplex",
613                                 dev->name,
614                                 ar7240sw_speed_str(speed),
615                                 duplex ? "full" : "half");
616                         netif_carrier_on(dev);
617                 }
618         }
619 }
620
621 static const struct ar7240sw_hw_stat ar7240_hw_stats[] = {
622         { "rx_broadcast"        , 4, AR7240_STATS_RXBROAD, },
623         { "rx_pause"            , 4, AR7240_STATS_RXPAUSE, },
624         { "rx_multicast"        , 4, AR7240_STATS_RXMULTI, },
625         { "rx_fcs_error"        , 4, AR7240_STATS_RXFCSERR, },
626         { "rx_align_error"      , 4, AR7240_STATS_RXALIGNERR, },
627         { "rx_undersize"        , 4, AR7240_STATS_RXRUNT, },
628         { "rx_fragments"        , 4, AR7240_STATS_RXFRAGMENT, },
629         { "rx_64bytes"          , 4, AR7240_STATS_RX64BYTE, },
630         { "rx_65_127bytes"      , 4, AR7240_STATS_RX128BYTE, },
631         { "rx_128_255bytes"     , 4, AR7240_STATS_RX256BYTE, },
632         { "rx_256_511bytes"     , 4, AR7240_STATS_RX512BYTE, },
633         { "rx_512_1023bytes"    , 4, AR7240_STATS_RX1024BYTE, },
634         { "rx_1024_1518bytes"   , 4, AR7240_STATS_RX1518BYTE, },
635         { "rx_1519_max_bytes"   , 4, AR7240_STATS_RXMAXBYTE, },
636         { "rx_oversize"         , 4, AR7240_STATS_RXTOOLONG, },
637         { "rx_good_bytes"       , 8, AR7240_STATS_RXGOODBYTE, },
638         { "rx_bad_bytes"        , 8, AR7240_STATS_RXBADBYTE, },
639         { "rx_overflow"         , 4, AR7240_STATS_RXOVERFLOW, },
640         { "filtered"            , 4, AR7240_STATS_FILTERED, },
641         { "tx_broadcast"        , 4, AR7240_STATS_TXBROAD, },
642         { "tx_pause"            , 4, AR7240_STATS_TXPAUSE, },
643         { "tx_multicast"        , 4, AR7240_STATS_TXMULTI, },
644         { "tx_underrun"         , 4, AR7240_STATS_TXUNDERRUN, },
645         { "tx_64bytes"          , 4, AR7240_STATS_TX64BYTE, },
646         { "tx_65_127bytes"      , 4, AR7240_STATS_TX128BYTE, },
647         { "tx_128_255bytes"     , 4, AR7240_STATS_TX256BYTE, },
648         { "tx_256_511bytes"     , 4, AR7240_STATS_TX512BYTE, },
649         { "tx_512_1023bytes"    , 4, AR7240_STATS_TX1024BYTE, },
650         { "tx_1024_1518bytes"   , 4, AR7240_STATS_TX1518BYTE, },
651         { "tx_1519_max_bytes"   , 4, AR7240_STATS_TXMAXBYTE, },
652         { "tx_oversize"         , 4, AR7240_STATS_TXOVERSIZE, },
653         { "tx_bytes"            , 8, AR7240_STATS_TXBYTE, },
654         { "tx_collisions"       , 4, AR7240_STATS_TXCOLLISION, },
655         { "tx_abort_collisions" , 4, AR7240_STATS_TXABORTCOL, },
656         { "tx_multi_collisions" , 4, AR7240_STATS_TXMULTICOL, },
657         { "tx_single_collisions", 4, AR7240_STATS_TXSINGLECOL, },
658         { "tx_excessive_deferred", 4, AR7240_STATS_TXEXCDEFER, },
659         { "tx_deferred"         , 4, AR7240_STATS_TXDEFER, },
660         { "tx_late_collisions"  , 4, AR7240_STATS_TXLATECOL, },
661 };
662
663 static void ar7240_dsa_get_strings(struct dsa_switch *ds, int port,
664                                    uint8_t *data)
665 {
666         int i;
667
668         for (i = 0; i < ARRAY_SIZE(ar7240_hw_stats); i++) {
669                 memcpy(data + i * ETH_GSTRING_LEN,
670                        ar7240_hw_stats[i].string, ETH_GSTRING_LEN);
671         }
672 }
673
674 static void ar7240_dsa_get_ethtool_stats(struct dsa_switch *ds, int port,
675                                          uint64_t *data)
676 {
677         struct ar7240sw *as = dsa_to_ar7240sw(ds);
678         int err;
679         int i;
680
681         mutex_lock(&as->stats_mutex);
682
683         err = ar7240sw_capture_stats(as);
684         if (err)
685                 goto unlock;
686
687         for (i = 0; i < ARRAY_SIZE(ar7240_hw_stats); i++) {
688                 const struct ar7240sw_hw_stat *s = &ar7240_hw_stats[i];
689                 u32 reg = AR7240_REG_STATS_BASE(port);
690                 u32 low;
691                 u32 high;
692
693                 low = ar7240sw_reg_read(as, reg + s->reg);
694                 if (s->sizeof_stat == 8)
695                         high = ar7240sw_reg_read(as, reg + s->reg);
696                 else
697                         high = 0;
698
699                 data[i] = (((u64) high) << 32) | low;
700         }
701
702  unlock:
703         mutex_unlock(&as->stats_mutex);
704 }
705
706 static int ar7240_dsa_get_sset_count(struct dsa_switch *ds)
707 {
708         return ARRAY_SIZE(ar7240_hw_stats);
709 }
710
711 static struct dsa_switch_driver ar7240_dsa_driver = {
712         .tag_protocol           = htons(ETH_P_QINQ),
713         .priv_size              = sizeof(struct ar7240sw),
714         .probe                  = ar7240_dsa_probe,
715         .setup                  = ar7240_dsa_setup,
716         .set_addr               = ar7240_dsa_set_addr,
717         .phy_read               = ar7240_dsa_phy_read,
718         .phy_write              = ar7240_dsa_phy_write,
719         .poll_link              = ar7240_dsa_poll_link,
720         .get_strings            = ar7240_dsa_get_strings,
721         .get_ethtool_stats      = ar7240_dsa_get_ethtool_stats,
722         .get_sset_count         = ar7240_dsa_get_sset_count,
723 };
724
725 int __init dsa_ar7240_init(void)
726 {
727         register_switch_driver(&ar7240_dsa_driver);
728         return 0;
729 }
730 module_init(dsa_ar7240_init);
731
732 void __exit dsa_ar7240_cleanup(void)
733 {
734         unregister_switch_driver(&ar7240_dsa_driver);
735 }
736 module_exit(dsa_ar7240_cleanup);