]> Pileus Git - ~andy/linux/blob - drivers/net/dsa/mv88e6131.c
Merge tag 'firewire-updates' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee139...
[~andy/linux] / drivers / net / dsa / mv88e6131.c
1 /*
2  * net/dsa/mv88e6131.c - Marvell 88e6095/6095f/6131 switch chip support
3  * Copyright (c) 2008-2009 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/list.h>
12 #include <linux/module.h>
13 #include <linux/netdevice.h>
14 #include <linux/phy.h>
15 #include <net/dsa.h>
16 #include "mv88e6xxx.h"
17
18 /*
19  * Switch product IDs
20  */
21 #define ID_6085         0x04a0
22 #define ID_6095         0x0950
23 #define ID_6131         0x1060
24
25 static char *mv88e6131_probe(struct mii_bus *bus, int sw_addr)
26 {
27         int ret;
28
29         ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), 0x03);
30         if (ret >= 0) {
31                 ret &= 0xfff0;
32                 if (ret == ID_6085)
33                         return "Marvell 88E6085";
34                 if (ret == ID_6095)
35                         return "Marvell 88E6095/88E6095F";
36                 if (ret == ID_6131)
37                         return "Marvell 88E6131";
38         }
39
40         return NULL;
41 }
42
43 static int mv88e6131_switch_reset(struct dsa_switch *ds)
44 {
45         int i;
46         int ret;
47
48         /*
49          * Set all ports to the disabled state.
50          */
51         for (i = 0; i < 11; i++) {
52                 ret = REG_READ(REG_PORT(i), 0x04);
53                 REG_WRITE(REG_PORT(i), 0x04, ret & 0xfffc);
54         }
55
56         /*
57          * Wait for transmit queues to drain.
58          */
59         msleep(2);
60
61         /*
62          * Reset the switch.
63          */
64         REG_WRITE(REG_GLOBAL, 0x04, 0xc400);
65
66         /*
67          * Wait up to one second for reset to complete.
68          */
69         for (i = 0; i < 1000; i++) {
70                 ret = REG_READ(REG_GLOBAL, 0x00);
71                 if ((ret & 0xc800) == 0xc800)
72                         break;
73
74                 msleep(1);
75         }
76         if (i == 1000)
77                 return -ETIMEDOUT;
78
79         return 0;
80 }
81
82 static int mv88e6131_setup_global(struct dsa_switch *ds)
83 {
84         int ret;
85         int i;
86
87         /*
88          * Enable the PHY polling unit, don't discard packets with
89          * excessive collisions, use a weighted fair queueing scheme
90          * to arbitrate between packet queues, set the maximum frame
91          * size to 1632, and mask all interrupt sources.
92          */
93         REG_WRITE(REG_GLOBAL, 0x04, 0x4400);
94
95         /*
96          * Set the default address aging time to 5 minutes, and
97          * enable address learn messages to be sent to all message
98          * ports.
99          */
100         REG_WRITE(REG_GLOBAL, 0x0a, 0x0148);
101
102         /*
103          * Configure the priority mapping registers.
104          */
105         ret = mv88e6xxx_config_prio(ds);
106         if (ret < 0)
107                 return ret;
108
109         /*
110          * Set the VLAN ethertype to 0x8100.
111          */
112         REG_WRITE(REG_GLOBAL, 0x19, 0x8100);
113
114         /*
115          * Disable ARP mirroring, and configure the upstream port as
116          * the port to which ingress and egress monitor frames are to
117          * be sent.
118          */
119         REG_WRITE(REG_GLOBAL, 0x1a, (dsa_upstream_port(ds) * 0x1100) | 0x00f0);
120
121         /*
122          * Disable cascade port functionality unless this device
123          * is used in a cascade configuration, and set the switch's
124          * DSA device number.
125          */
126         if (ds->dst->pd->nr_chips > 1)
127                 REG_WRITE(REG_GLOBAL, 0x1c, 0xf000 | (ds->index & 0x1f));
128         else
129                 REG_WRITE(REG_GLOBAL, 0x1c, 0xe000 | (ds->index & 0x1f));
130
131         /*
132          * Send all frames with destination addresses matching
133          * 01:80:c2:00:00:0x to the CPU port.
134          */
135         REG_WRITE(REG_GLOBAL2, 0x03, 0xffff);
136
137         /*
138          * Ignore removed tag data on doubly tagged packets, disable
139          * flow control messages, force flow control priority to the
140          * highest, and send all special multicast frames to the CPU
141          * port at the highest priority.
142          */
143         REG_WRITE(REG_GLOBAL2, 0x05, 0x00ff);
144
145         /*
146          * Program the DSA routing table.
147          */
148         for (i = 0; i < 32; i++) {
149                 int nexthop;
150
151                 nexthop = 0x1f;
152                 if (i != ds->index && i < ds->dst->pd->nr_chips)
153                         nexthop = ds->pd->rtable[i] & 0x1f;
154
155                 REG_WRITE(REG_GLOBAL2, 0x06, 0x8000 | (i << 8) | nexthop);
156         }
157
158         /*
159          * Clear all trunk masks.
160          */
161         for (i = 0; i < 8; i++)
162                 REG_WRITE(REG_GLOBAL2, 0x07, 0x8000 | (i << 12) | 0x7ff);
163
164         /*
165          * Clear all trunk mappings.
166          */
167         for (i = 0; i < 16; i++)
168                 REG_WRITE(REG_GLOBAL2, 0x08, 0x8000 | (i << 11));
169
170         /*
171          * Force the priority of IGMP/MLD snoop frames and ARP frames
172          * to the highest setting.
173          */
174         REG_WRITE(REG_GLOBAL2, 0x0f, 0x00ff);
175
176         return 0;
177 }
178
179 static int mv88e6131_setup_port(struct dsa_switch *ds, int p)
180 {
181         struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
182         int addr = REG_PORT(p);
183         u16 val;
184
185         /*
186          * MAC Forcing register: don't force link, speed, duplex
187          * or flow control state to any particular values on physical
188          * ports, but force the CPU port and all DSA ports to 1000 Mb/s
189          * (100 Mb/s on 6085) full duplex.
190          */
191         if (dsa_is_cpu_port(ds, p) || ds->dsa_port_mask & (1 << p))
192                 if (ps->id == ID_6085)
193                         REG_WRITE(addr, 0x01, 0x003d); /* 100 Mb/s */
194                 else
195                         REG_WRITE(addr, 0x01, 0x003e); /* 1000 Mb/s */
196         else
197                 REG_WRITE(addr, 0x01, 0x0003);
198
199         /*
200          * Port Control: disable Core Tag, disable Drop-on-Lock,
201          * transmit frames unmodified, disable Header mode,
202          * enable IGMP/MLD snoop, disable DoubleTag, disable VLAN
203          * tunneling, determine priority by looking at 802.1p and
204          * IP priority fields (IP prio has precedence), and set STP
205          * state to Forwarding.
206          *
207          * If this is the upstream port for this switch, enable
208          * forwarding of unknown unicasts, and enable DSA tagging
209          * mode.
210          *
211          * If this is the link to another switch, use DSA tagging
212          * mode, but do not enable forwarding of unknown unicasts.
213          */
214         val = 0x0433;
215         if (p == dsa_upstream_port(ds)) {
216                 val |= 0x0104;
217                 /*
218                  * On 6085, unknown multicast forward is controlled
219                  * here rather than in Port Control 2 register.
220                  */
221                 if (ps->id == ID_6085)
222                         val |= 0x0008;
223         }
224         if (ds->dsa_port_mask & (1 << p))
225                 val |= 0x0100;
226         REG_WRITE(addr, 0x04, val);
227
228         /*
229          * Port Control 1: disable trunking.  Also, if this is the
230          * CPU port, enable learn messages to be sent to this port.
231          */
232         REG_WRITE(addr, 0x05, dsa_is_cpu_port(ds, p) ? 0x8000 : 0x0000);
233
234         /*
235          * Port based VLAN map: give each port its own address
236          * database, allow the CPU port to talk to each of the 'real'
237          * ports, and allow each of the 'real' ports to only talk to
238          * the upstream port.
239          */
240         val = (p & 0xf) << 12;
241         if (dsa_is_cpu_port(ds, p))
242                 val |= ds->phys_port_mask;
243         else
244                 val |= 1 << dsa_upstream_port(ds);
245         REG_WRITE(addr, 0x06, val);
246
247         /*
248          * Default VLAN ID and priority: don't set a default VLAN
249          * ID, and set the default packet priority to zero.
250          */
251         REG_WRITE(addr, 0x07, 0x0000);
252
253         /*
254          * Port Control 2: don't force a good FCS, don't use
255          * VLAN-based, source address-based or destination
256          * address-based priority overrides, don't let the switch
257          * add or strip 802.1q tags, don't discard tagged or
258          * untagged frames on this port, do a destination address
259          * lookup on received packets as usual, don't send a copy
260          * of all transmitted/received frames on this port to the
261          * CPU, and configure the upstream port number.
262          *
263          * If this is the upstream port for this switch, enable
264          * forwarding of unknown multicast addresses.
265          */
266         if (ps->id == ID_6085)
267                 /*
268                  * on 6085, bits 3:0 are reserved, bit 6 control ARP
269                  * mirroring, and multicast forward is handled in
270                  * Port Control register.
271                  */
272                 REG_WRITE(addr, 0x08, 0x0080);
273         else {
274                 val = 0x0080 | dsa_upstream_port(ds);
275                 if (p == dsa_upstream_port(ds))
276                         val |= 0x0040;
277                 REG_WRITE(addr, 0x08, val);
278         }
279
280         /*
281          * Rate Control: disable ingress rate limiting.
282          */
283         REG_WRITE(addr, 0x09, 0x0000);
284
285         /*
286          * Rate Control 2: disable egress rate limiting.
287          */
288         REG_WRITE(addr, 0x0a, 0x0000);
289
290         /*
291          * Port Association Vector: when learning source addresses
292          * of packets, add the address to the address database using
293          * a port bitmap that has only the bit for this port set and
294          * the other bits clear.
295          */
296         REG_WRITE(addr, 0x0b, 1 << p);
297
298         /*
299          * Tag Remap: use an identity 802.1p prio -> switch prio
300          * mapping.
301          */
302         REG_WRITE(addr, 0x18, 0x3210);
303
304         /*
305          * Tag Remap 2: use an identity 802.1p prio -> switch prio
306          * mapping.
307          */
308         REG_WRITE(addr, 0x19, 0x7654);
309
310         return 0;
311 }
312
313 static int mv88e6131_setup(struct dsa_switch *ds)
314 {
315         struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
316         int i;
317         int ret;
318
319         mutex_init(&ps->smi_mutex);
320         mv88e6xxx_ppu_state_init(ds);
321         mutex_init(&ps->stats_mutex);
322
323         ps->id = REG_READ(REG_PORT(0), 0x03) & 0xfff0;
324
325         ret = mv88e6131_switch_reset(ds);
326         if (ret < 0)
327                 return ret;
328
329         /* @@@ initialise vtu and atu */
330
331         ret = mv88e6131_setup_global(ds);
332         if (ret < 0)
333                 return ret;
334
335         for (i = 0; i < 11; i++) {
336                 ret = mv88e6131_setup_port(ds, i);
337                 if (ret < 0)
338                         return ret;
339         }
340
341         return 0;
342 }
343
344 static int mv88e6131_port_to_phy_addr(int port)
345 {
346         if (port >= 0 && port <= 11)
347                 return port;
348         return -1;
349 }
350
351 static int
352 mv88e6131_phy_read(struct dsa_switch *ds, int port, int regnum)
353 {
354         int addr = mv88e6131_port_to_phy_addr(port);
355         return mv88e6xxx_phy_read_ppu(ds, addr, regnum);
356 }
357
358 static int
359 mv88e6131_phy_write(struct dsa_switch *ds,
360                               int port, int regnum, u16 val)
361 {
362         int addr = mv88e6131_port_to_phy_addr(port);
363         return mv88e6xxx_phy_write_ppu(ds, addr, regnum, val);
364 }
365
366 static struct mv88e6xxx_hw_stat mv88e6131_hw_stats[] = {
367         { "in_good_octets", 8, 0x00, },
368         { "in_bad_octets", 4, 0x02, },
369         { "in_unicast", 4, 0x04, },
370         { "in_broadcasts", 4, 0x06, },
371         { "in_multicasts", 4, 0x07, },
372         { "in_pause", 4, 0x16, },
373         { "in_undersize", 4, 0x18, },
374         { "in_fragments", 4, 0x19, },
375         { "in_oversize", 4, 0x1a, },
376         { "in_jabber", 4, 0x1b, },
377         { "in_rx_error", 4, 0x1c, },
378         { "in_fcs_error", 4, 0x1d, },
379         { "out_octets", 8, 0x0e, },
380         { "out_unicast", 4, 0x10, },
381         { "out_broadcasts", 4, 0x13, },
382         { "out_multicasts", 4, 0x12, },
383         { "out_pause", 4, 0x15, },
384         { "excessive", 4, 0x11, },
385         { "collisions", 4, 0x1e, },
386         { "deferred", 4, 0x05, },
387         { "single", 4, 0x14, },
388         { "multiple", 4, 0x17, },
389         { "out_fcs_error", 4, 0x03, },
390         { "late", 4, 0x1f, },
391         { "hist_64bytes", 4, 0x08, },
392         { "hist_65_127bytes", 4, 0x09, },
393         { "hist_128_255bytes", 4, 0x0a, },
394         { "hist_256_511bytes", 4, 0x0b, },
395         { "hist_512_1023bytes", 4, 0x0c, },
396         { "hist_1024_max_bytes", 4, 0x0d, },
397 };
398
399 static void
400 mv88e6131_get_strings(struct dsa_switch *ds, int port, uint8_t *data)
401 {
402         mv88e6xxx_get_strings(ds, ARRAY_SIZE(mv88e6131_hw_stats),
403                               mv88e6131_hw_stats, port, data);
404 }
405
406 static void
407 mv88e6131_get_ethtool_stats(struct dsa_switch *ds,
408                                   int port, uint64_t *data)
409 {
410         mv88e6xxx_get_ethtool_stats(ds, ARRAY_SIZE(mv88e6131_hw_stats),
411                                     mv88e6131_hw_stats, port, data);
412 }
413
414 static int mv88e6131_get_sset_count(struct dsa_switch *ds)
415 {
416         return ARRAY_SIZE(mv88e6131_hw_stats);
417 }
418
419 struct dsa_switch_driver mv88e6131_switch_driver = {
420         .tag_protocol           = cpu_to_be16(ETH_P_DSA),
421         .priv_size              = sizeof(struct mv88e6xxx_priv_state),
422         .probe                  = mv88e6131_probe,
423         .setup                  = mv88e6131_setup,
424         .set_addr               = mv88e6xxx_set_addr_direct,
425         .phy_read               = mv88e6131_phy_read,
426         .phy_write              = mv88e6131_phy_write,
427         .poll_link              = mv88e6xxx_poll_link,
428         .get_strings            = mv88e6131_get_strings,
429         .get_ethtool_stats      = mv88e6131_get_ethtool_stats,
430         .get_sset_count         = mv88e6131_get_sset_count,
431 };
432
433 MODULE_ALIAS("platform:mv88e6085");
434 MODULE_ALIAS("platform:mv88e6095");
435 MODULE_ALIAS("platform:mv88e6095f");
436 MODULE_ALIAS("platform:mv88e6131");