Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[cascardo/linux.git] / drivers / net / dsa / mv88e6171.c
1 /* net/dsa/mv88e6171.c - Marvell 88e6171/8826172 switch chip support
2  * Copyright (c) 2008-2009 Marvell Semiconductor
3  * Copyright (c) 2014 Claudio Leite <leitec@staticky.com>
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 static char *mv88e6171_probe(struct device *host_dev, int sw_addr)
21 {
22         struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev);
23         int ret;
24
25         if (bus == NULL)
26                 return NULL;
27
28         ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), 0x03);
29         if (ret >= 0) {
30                 if ((ret & 0xfff0) == 0x1710)
31                         return "Marvell 88E6171";
32                 if ((ret & 0xfff0) == 0x1720)
33                         return "Marvell 88E6172";
34         }
35
36         return NULL;
37 }
38
39 static int mv88e6171_switch_reset(struct dsa_switch *ds)
40 {
41         int i;
42         int ret;
43         unsigned long timeout;
44
45         /* Set all ports to the disabled state. */
46         for (i = 0; i < 8; i++) {
47                 ret = REG_READ(REG_PORT(i), 0x04);
48                 REG_WRITE(REG_PORT(i), 0x04, ret & 0xfffc);
49         }
50
51         /* Wait for transmit queues to drain. */
52         usleep_range(2000, 4000);
53
54         /* Reset the switch. */
55         REG_WRITE(REG_GLOBAL, 0x04, 0xc400);
56
57         /* Wait up to one second for reset to complete. */
58         timeout = jiffies + 1 * HZ;
59         while (time_before(jiffies, timeout)) {
60                 ret = REG_READ(REG_GLOBAL, 0x00);
61                 if ((ret & 0xc800) == 0xc800)
62                         break;
63
64                 usleep_range(1000, 2000);
65         }
66         if (time_after(jiffies, timeout))
67                 return -ETIMEDOUT;
68
69         /* Enable ports not under DSA, e.g. WAN port */
70         for (i = 0; i < 8; i++) {
71                 if (dsa_is_cpu_port(ds, i) || ds->phys_port_mask & (1 << i))
72                         continue;
73
74                 ret = REG_READ(REG_PORT(i), 0x04);
75                 REG_WRITE(REG_PORT(i), 0x04, ret | 0x03);
76         }
77
78         return 0;
79 }
80
81 static int mv88e6171_setup_global(struct dsa_switch *ds)
82 {
83         int ret;
84         int i;
85
86         /* Disable the PHY polling unit (since there won't be any
87          * external PHYs to poll), don't discard packets with
88          * excessive collisions, and mask all interrupt sources.
89          */
90         REG_WRITE(REG_GLOBAL, 0x04, 0x0000);
91
92         /* Set the default address aging time to 5 minutes, and
93          * enable address learn messages to be sent to all message
94          * ports.
95          */
96         REG_WRITE(REG_GLOBAL, 0x0a, 0x0148);
97
98         /* Configure the priority mapping registers. */
99         ret = mv88e6xxx_config_prio(ds);
100         if (ret < 0)
101                 return ret;
102
103         /* Configure the upstream port, and configure the upstream
104          * port as the port to which ingress and egress monitor frames
105          * are to be sent.
106          */
107         if (REG_READ(REG_PORT(0), 0x03) == 0x1710)
108                 REG_WRITE(REG_GLOBAL, 0x1a, (dsa_upstream_port(ds) * 0x1111));
109         else
110                 REG_WRITE(REG_GLOBAL, 0x1a, (dsa_upstream_port(ds) * 0x1110));
111
112         /* Disable remote management for now, and set the switch's
113          * DSA device number.
114          */
115         REG_WRITE(REG_GLOBAL, 0x1c, ds->index & 0x1f);
116
117         /* Send all frames with destination addresses matching
118          * 01:80:c2:00:00:2x to the CPU port.
119          */
120         REG_WRITE(REG_GLOBAL2, 0x02, 0xffff);
121
122         /* Send all frames with destination addresses matching
123          * 01:80:c2:00:00:0x to the CPU port.
124          */
125         REG_WRITE(REG_GLOBAL2, 0x03, 0xffff);
126
127         /* Disable the loopback filter, disable flow control
128          * messages, disable flood broadcast override, disable
129          * removing of provider tags, disable ATU age violation
130          * interrupts, disable tag flow control, force flow
131          * control priority to the highest, and send all special
132          * multicast frames to the CPU at the highest priority.
133          */
134         REG_WRITE(REG_GLOBAL2, 0x05, 0x00ff);
135
136         /* Program the DSA routing table. */
137         for (i = 0; i < 32; i++) {
138                 int nexthop;
139
140                 nexthop = 0x1f;
141                 if (i != ds->index && i < ds->dst->pd->nr_chips)
142                         nexthop = ds->pd->rtable[i] & 0x1f;
143
144                 REG_WRITE(REG_GLOBAL2, 0x06, 0x8000 | (i << 8) | nexthop);
145         }
146
147         /* Clear all trunk masks. */
148         for (i = 0; i < 8; i++)
149                 REG_WRITE(REG_GLOBAL2, 0x07, 0x8000 | (i << 12) | 0xff);
150
151         /* Clear all trunk mappings. */
152         for (i = 0; i < 16; i++)
153                 REG_WRITE(REG_GLOBAL2, 0x08, 0x8000 | (i << 11));
154
155         /* Disable ingress rate limiting by resetting all ingress
156          * rate limit registers to their initial state.
157          */
158         for (i = 0; i < 6; i++)
159                 REG_WRITE(REG_GLOBAL2, 0x09, 0x9000 | (i << 8));
160
161         /* Initialise cross-chip port VLAN table to reset defaults. */
162         REG_WRITE(REG_GLOBAL2, 0x0b, 0x9000);
163
164         /* Clear the priority override table. */
165         for (i = 0; i < 16; i++)
166                 REG_WRITE(REG_GLOBAL2, 0x0f, 0x8000 | (i << 8));
167
168         /* @@@ initialise AVB (22/23) watchdog (27) sdet (29) registers */
169
170         return 0;
171 }
172
173 static int mv88e6171_setup_port(struct dsa_switch *ds, int p)
174 {
175         int addr = REG_PORT(p);
176         u16 val;
177
178         /* MAC Forcing register: don't force link, speed, duplex
179          * or flow control state to any particular values on physical
180          * ports, but force the CPU port and all DSA ports to 1000 Mb/s
181          * full duplex.
182          */
183         val = REG_READ(addr, 0x01);
184         if (dsa_is_cpu_port(ds, p) || ds->dsa_port_mask & (1 << p))
185                 REG_WRITE(addr, 0x01, val | 0x003e);
186         else
187                 REG_WRITE(addr, 0x01, val | 0x0003);
188
189         /* Do not limit the period of time that this port can be
190          * paused for by the remote end or the period of time that
191          * this port can pause the remote end.
192          */
193         REG_WRITE(addr, 0x02, 0x0000);
194
195         /* Port Control: disable Drop-on-Unlock, disable Drop-on-Lock,
196          * disable Header mode, enable IGMP/MLD snooping, disable VLAN
197          * tunneling, determine priority by looking at 802.1p and IP
198          * priority fields (IP prio has precedence), and set STP state
199          * to Forwarding.
200          *
201          * If this is the CPU link, use DSA or EDSA tagging depending
202          * on which tagging mode was configured.
203          *
204          * If this is a link to another switch, use DSA tagging mode.
205          *
206          * If this is the upstream port for this switch, enable
207          * forwarding of unknown unicasts and multicasts.
208          */
209         val = 0x0433;
210         if (dsa_is_cpu_port(ds, p)) {
211                 if (ds->dst->tag_protocol == DSA_TAG_PROTO_EDSA)
212                         val |= 0x3300;
213                 else
214                         val |= 0x0100;
215         }
216         if (ds->dsa_port_mask & (1 << p))
217                 val |= 0x0100;
218         if (p == dsa_upstream_port(ds))
219                 val |= 0x000c;
220         REG_WRITE(addr, 0x04, val);
221
222         /* Port Control 1: disable trunking.  Also, if this is the
223          * CPU port, enable learn messages to be sent to this port.
224          */
225         REG_WRITE(addr, 0x05, dsa_is_cpu_port(ds, p) ? 0x8000 : 0x0000);
226
227         /* Port based VLAN map: give each port its own address
228          * database, allow the CPU port to talk to each of the 'real'
229          * ports, and allow each of the 'real' ports to only talk to
230          * the upstream port.
231          */
232         val = (p & 0xf) << 12;
233         if (dsa_is_cpu_port(ds, p))
234                 val |= ds->phys_port_mask;
235         else
236                 val |= 1 << dsa_upstream_port(ds);
237         REG_WRITE(addr, 0x06, val);
238
239         /* Default VLAN ID and priority: don't set a default VLAN
240          * ID, and set the default packet priority to zero.
241          */
242         REG_WRITE(addr, 0x07, 0x0000);
243
244         /* Port Control 2: don't force a good FCS, set the maximum
245          * frame size to 10240 bytes, don't let the switch add or
246          * strip 802.1q tags, don't discard tagged or untagged frames
247          * on this port, do a destination address lookup on all
248          * received packets as usual, disable ARP mirroring and don't
249          * send a copy of all transmitted/received frames on this port
250          * to the CPU.
251          */
252         REG_WRITE(addr, 0x08, 0x2080);
253
254         /* Egress rate control: disable egress rate control. */
255         REG_WRITE(addr, 0x09, 0x0001);
256
257         /* Egress rate control 2: disable egress rate control. */
258         REG_WRITE(addr, 0x0a, 0x0000);
259
260         /* Port Association Vector: when learning source addresses
261          * of packets, add the address to the address database using
262          * a port bitmap that has only the bit for this port set and
263          * the other bits clear.
264          */
265         REG_WRITE(addr, 0x0b, 1 << p);
266
267         /* Port ATU control: disable limiting the number of address
268          * database entries that this port is allowed to use.
269          */
270         REG_WRITE(addr, 0x0c, 0x0000);
271
272         /* Priority Override: disable DA, SA and VTU priority override. */
273         REG_WRITE(addr, 0x0d, 0x0000);
274
275         /* Port Ethertype: use the Ethertype DSA Ethertype value. */
276         REG_WRITE(addr, 0x0f, ETH_P_EDSA);
277
278         /* Tag Remap: use an identity 802.1p prio -> switch prio
279          * mapping.
280          */
281         REG_WRITE(addr, 0x18, 0x3210);
282
283         /* Tag Remap 2: use an identity 802.1p prio -> switch prio
284          * mapping.
285          */
286         REG_WRITE(addr, 0x19, 0x7654);
287
288         return 0;
289 }
290
291 static int mv88e6171_setup(struct dsa_switch *ds)
292 {
293         struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
294         int i;
295         int ret;
296
297         mutex_init(&ps->smi_mutex);
298         mutex_init(&ps->stats_mutex);
299
300         ret = mv88e6171_switch_reset(ds);
301         if (ret < 0)
302                 return ret;
303
304         /* @@@ initialise vtu and atu */
305
306         ret = mv88e6171_setup_global(ds);
307         if (ret < 0)
308                 return ret;
309
310         for (i = 0; i < 8; i++) {
311                 if (!(dsa_is_cpu_port(ds, i) || ds->phys_port_mask & (1 << i)))
312                         continue;
313
314                 ret = mv88e6171_setup_port(ds, i);
315                 if (ret < 0)
316                         return ret;
317         }
318
319         return 0;
320 }
321
322 static int mv88e6171_port_to_phy_addr(int port)
323 {
324         if (port >= 0 && port <= 4)
325                 return port;
326         return -1;
327 }
328
329 static int
330 mv88e6171_phy_read(struct dsa_switch *ds, int port, int regnum)
331 {
332         int addr = mv88e6171_port_to_phy_addr(port);
333
334         return mv88e6xxx_phy_read(ds, addr, regnum);
335 }
336
337 static int
338 mv88e6171_phy_write(struct dsa_switch *ds,
339                     int port, int regnum, u16 val)
340 {
341         int addr = mv88e6171_port_to_phy_addr(port);
342
343         return mv88e6xxx_phy_write(ds, addr, regnum, val);
344 }
345
346 static struct mv88e6xxx_hw_stat mv88e6171_hw_stats[] = {
347         { "in_good_octets", 8, 0x00, },
348         { "in_bad_octets", 4, 0x02, },
349         { "in_unicast", 4, 0x04, },
350         { "in_broadcasts", 4, 0x06, },
351         { "in_multicasts", 4, 0x07, },
352         { "in_pause", 4, 0x16, },
353         { "in_undersize", 4, 0x18, },
354         { "in_fragments", 4, 0x19, },
355         { "in_oversize", 4, 0x1a, },
356         { "in_jabber", 4, 0x1b, },
357         { "in_rx_error", 4, 0x1c, },
358         { "in_fcs_error", 4, 0x1d, },
359         { "out_octets", 8, 0x0e, },
360         { "out_unicast", 4, 0x10, },
361         { "out_broadcasts", 4, 0x13, },
362         { "out_multicasts", 4, 0x12, },
363         { "out_pause", 4, 0x15, },
364         { "excessive", 4, 0x11, },
365         { "collisions", 4, 0x1e, },
366         { "deferred", 4, 0x05, },
367         { "single", 4, 0x14, },
368         { "multiple", 4, 0x17, },
369         { "out_fcs_error", 4, 0x03, },
370         { "late", 4, 0x1f, },
371         { "hist_64bytes", 4, 0x08, },
372         { "hist_65_127bytes", 4, 0x09, },
373         { "hist_128_255bytes", 4, 0x0a, },
374         { "hist_256_511bytes", 4, 0x0b, },
375         { "hist_512_1023bytes", 4, 0x0c, },
376         { "hist_1024_max_bytes", 4, 0x0d, },
377 };
378
379 static void
380 mv88e6171_get_strings(struct dsa_switch *ds, int port, uint8_t *data)
381 {
382         mv88e6xxx_get_strings(ds, ARRAY_SIZE(mv88e6171_hw_stats),
383                               mv88e6171_hw_stats, port, data);
384 }
385
386 static void
387 mv88e6171_get_ethtool_stats(struct dsa_switch *ds,
388                             int port, uint64_t *data)
389 {
390         mv88e6xxx_get_ethtool_stats(ds, ARRAY_SIZE(mv88e6171_hw_stats),
391                                     mv88e6171_hw_stats, port, data);
392 }
393
394 static int mv88e6171_get_sset_count(struct dsa_switch *ds)
395 {
396         return ARRAY_SIZE(mv88e6171_hw_stats);
397 }
398
399 struct dsa_switch_driver mv88e6171_switch_driver = {
400         .tag_protocol           = DSA_TAG_PROTO_EDSA,
401         .priv_size              = sizeof(struct mv88e6xxx_priv_state),
402         .probe                  = mv88e6171_probe,
403         .setup                  = mv88e6171_setup,
404         .set_addr               = mv88e6xxx_set_addr_indirect,
405         .phy_read               = mv88e6171_phy_read,
406         .phy_write              = mv88e6171_phy_write,
407         .poll_link              = mv88e6xxx_poll_link,
408         .get_strings            = mv88e6171_get_strings,
409         .get_ethtool_stats      = mv88e6171_get_ethtool_stats,
410         .get_sset_count         = mv88e6171_get_sset_count,
411 };
412
413 MODULE_ALIAS("platform:mv88e6171");
414 MODULE_ALIAS("platform:mv88e6172");