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/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 
mv88e6131_probe(struct device * host_dev,int sw_addr)20 static char *mv88e6131_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), PORT_SWITCH_ID);
29 	if (ret >= 0) {
30 		int ret_masked = ret & 0xfff0;
31 
32 		if (ret_masked == PORT_SWITCH_ID_6085)
33 			return "Marvell 88E6085";
34 		if (ret_masked == PORT_SWITCH_ID_6095)
35 			return "Marvell 88E6095/88E6095F";
36 		if (ret == PORT_SWITCH_ID_6131_B2)
37 			return "Marvell 88E6131 (B2)";
38 		if (ret_masked == PORT_SWITCH_ID_6131)
39 			return "Marvell 88E6131";
40 	}
41 
42 	return NULL;
43 }
44 
mv88e6131_setup_global(struct dsa_switch * ds)45 static int mv88e6131_setup_global(struct dsa_switch *ds)
46 {
47 	int ret;
48 	int i;
49 
50 	/* Enable the PHY polling unit, don't discard packets with
51 	 * excessive collisions, use a weighted fair queueing scheme
52 	 * to arbitrate between packet queues, set the maximum frame
53 	 * size to 1632, and mask all interrupt sources.
54 	 */
55 	REG_WRITE(REG_GLOBAL, 0x04, 0x4400);
56 
57 	/* Set the default address aging time to 5 minutes, and
58 	 * enable address learn messages to be sent to all message
59 	 * ports.
60 	 */
61 	REG_WRITE(REG_GLOBAL, 0x0a, 0x0148);
62 
63 	/* Configure the priority mapping registers. */
64 	ret = mv88e6xxx_config_prio(ds);
65 	if (ret < 0)
66 		return ret;
67 
68 	/* Set the VLAN ethertype to 0x8100. */
69 	REG_WRITE(REG_GLOBAL, 0x19, 0x8100);
70 
71 	/* Disable ARP mirroring, and configure the upstream port as
72 	 * the port to which ingress and egress monitor frames are to
73 	 * be sent.
74 	 */
75 	REG_WRITE(REG_GLOBAL, 0x1a, (dsa_upstream_port(ds) * 0x1100) | 0x00f0);
76 
77 	/* Disable cascade port functionality unless this device
78 	 * is used in a cascade configuration, and set the switch's
79 	 * DSA device number.
80 	 */
81 	if (ds->dst->pd->nr_chips > 1)
82 		REG_WRITE(REG_GLOBAL, 0x1c, 0xf000 | (ds->index & 0x1f));
83 	else
84 		REG_WRITE(REG_GLOBAL, 0x1c, 0xe000 | (ds->index & 0x1f));
85 
86 	/* Send all frames with destination addresses matching
87 	 * 01:80:c2:00:00:0x to the CPU port.
88 	 */
89 	REG_WRITE(REG_GLOBAL2, 0x03, 0xffff);
90 
91 	/* Ignore removed tag data on doubly tagged packets, disable
92 	 * flow control messages, force flow control priority to the
93 	 * highest, and send all special multicast frames to the CPU
94 	 * port at the highest priority.
95 	 */
96 	REG_WRITE(REG_GLOBAL2, 0x05, 0x00ff);
97 
98 	/* Program the DSA routing table. */
99 	for (i = 0; i < 32; i++) {
100 		int nexthop;
101 
102 		nexthop = 0x1f;
103 		if (ds->pd->rtable &&
104 		    i != ds->index && i < ds->dst->pd->nr_chips)
105 			nexthop = ds->pd->rtable[i] & 0x1f;
106 
107 		REG_WRITE(REG_GLOBAL2, 0x06, 0x8000 | (i << 8) | nexthop);
108 	}
109 
110 	/* Clear all trunk masks. */
111 	for (i = 0; i < 8; i++)
112 		REG_WRITE(REG_GLOBAL2, 0x07, 0x8000 | (i << 12) | 0x7ff);
113 
114 	/* Clear all trunk mappings. */
115 	for (i = 0; i < 16; i++)
116 		REG_WRITE(REG_GLOBAL2, 0x08, 0x8000 | (i << 11));
117 
118 	/* Force the priority of IGMP/MLD snoop frames and ARP frames
119 	 * to the highest setting.
120 	 */
121 	REG_WRITE(REG_GLOBAL2, 0x0f, 0x00ff);
122 
123 	return 0;
124 }
125 
mv88e6131_setup_port(struct dsa_switch * ds,int p)126 static int mv88e6131_setup_port(struct dsa_switch *ds, int p)
127 {
128 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
129 	int addr = REG_PORT(p);
130 	u16 val;
131 
132 	/* MAC Forcing register: don't force link, speed, duplex
133 	 * or flow control state to any particular values on physical
134 	 * ports, but force the CPU port and all DSA ports to 1000 Mb/s
135 	 * (100 Mb/s on 6085) full duplex.
136 	 */
137 	if (dsa_is_cpu_port(ds, p) || ds->dsa_port_mask & (1 << p))
138 		if (ps->id == PORT_SWITCH_ID_6085)
139 			REG_WRITE(addr, 0x01, 0x003d); /* 100 Mb/s */
140 		else
141 			REG_WRITE(addr, 0x01, 0x003e); /* 1000 Mb/s */
142 	else
143 		REG_WRITE(addr, 0x01, 0x0003);
144 
145 	/* Port Control: disable Core Tag, disable Drop-on-Lock,
146 	 * transmit frames unmodified, disable Header mode,
147 	 * enable IGMP/MLD snoop, disable DoubleTag, disable VLAN
148 	 * tunneling, determine priority by looking at 802.1p and
149 	 * IP priority fields (IP prio has precedence), and set STP
150 	 * state to Forwarding.
151 	 *
152 	 * If this is the upstream port for this switch, enable
153 	 * forwarding of unknown unicasts, and enable DSA tagging
154 	 * mode.
155 	 *
156 	 * If this is the link to another switch, use DSA tagging
157 	 * mode, but do not enable forwarding of unknown unicasts.
158 	 */
159 	val = 0x0433;
160 	if (p == dsa_upstream_port(ds)) {
161 		val |= 0x0104;
162 		/* On 6085, unknown multicast forward is controlled
163 		 * here rather than in Port Control 2 register.
164 		 */
165 		if (ps->id == PORT_SWITCH_ID_6085)
166 			val |= 0x0008;
167 	}
168 	if (ds->dsa_port_mask & (1 << p))
169 		val |= 0x0100;
170 	REG_WRITE(addr, 0x04, val);
171 
172 	/* Port Control 2: don't force a good FCS, don't use
173 	 * VLAN-based, source address-based or destination
174 	 * address-based priority overrides, don't let the switch
175 	 * add or strip 802.1q tags, don't discard tagged or
176 	 * untagged frames on this port, do a destination address
177 	 * lookup on received packets as usual, don't send a copy
178 	 * of all transmitted/received frames on this port to the
179 	 * CPU, and configure the upstream port number.
180 	 *
181 	 * If this is the upstream port for this switch, enable
182 	 * forwarding of unknown multicast addresses.
183 	 */
184 	if (ps->id == PORT_SWITCH_ID_6085)
185 		/* on 6085, bits 3:0 are reserved, bit 6 control ARP
186 		 * mirroring, and multicast forward is handled in
187 		 * Port Control register.
188 		 */
189 		REG_WRITE(addr, 0x08, 0x0080);
190 	else {
191 		val = 0x0080 | dsa_upstream_port(ds);
192 		if (p == dsa_upstream_port(ds))
193 			val |= 0x0040;
194 		REG_WRITE(addr, 0x08, val);
195 	}
196 
197 	/* Rate Control: disable ingress rate limiting. */
198 	REG_WRITE(addr, 0x09, 0x0000);
199 
200 	/* Rate Control 2: disable egress rate limiting. */
201 	REG_WRITE(addr, 0x0a, 0x0000);
202 
203 	/* Port Association Vector: when learning source addresses
204 	 * of packets, add the address to the address database using
205 	 * a port bitmap that has only the bit for this port set and
206 	 * the other bits clear.
207 	 */
208 	REG_WRITE(addr, 0x0b, 1 << p);
209 
210 	/* Tag Remap: use an identity 802.1p prio -> switch prio
211 	 * mapping.
212 	 */
213 	REG_WRITE(addr, 0x18, 0x3210);
214 
215 	/* Tag Remap 2: use an identity 802.1p prio -> switch prio
216 	 * mapping.
217 	 */
218 	REG_WRITE(addr, 0x19, 0x7654);
219 
220 	return mv88e6xxx_setup_port_common(ds, p);
221 }
222 
mv88e6131_setup(struct dsa_switch * ds)223 static int mv88e6131_setup(struct dsa_switch *ds)
224 {
225 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
226 	int i;
227 	int ret;
228 
229 	ret = mv88e6xxx_setup_common(ds);
230 	if (ret < 0)
231 		return ret;
232 
233 	mv88e6xxx_ppu_state_init(ds);
234 
235 	switch (ps->id) {
236 	case PORT_SWITCH_ID_6085:
237 		ps->num_ports = 10;
238 		break;
239 	case PORT_SWITCH_ID_6095:
240 		ps->num_ports = 11;
241 		break;
242 	case PORT_SWITCH_ID_6131:
243 	case PORT_SWITCH_ID_6131_B2:
244 		ps->num_ports = 8;
245 		break;
246 	default:
247 		return -ENODEV;
248 	}
249 
250 	ret = mv88e6xxx_switch_reset(ds, false);
251 	if (ret < 0)
252 		return ret;
253 
254 	/* @@@ initialise vtu and atu */
255 
256 	ret = mv88e6131_setup_global(ds);
257 	if (ret < 0)
258 		return ret;
259 
260 	for (i = 0; i < ps->num_ports; i++) {
261 		ret = mv88e6131_setup_port(ds, i);
262 		if (ret < 0)
263 			return ret;
264 	}
265 
266 	return 0;
267 }
268 
mv88e6131_port_to_phy_addr(struct dsa_switch * ds,int port)269 static int mv88e6131_port_to_phy_addr(struct dsa_switch *ds, int port)
270 {
271 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
272 
273 	if (port >= 0 && port < ps->num_ports)
274 		return port;
275 
276 	return -EINVAL;
277 }
278 
279 static int
mv88e6131_phy_read(struct dsa_switch * ds,int port,int regnum)280 mv88e6131_phy_read(struct dsa_switch *ds, int port, int regnum)
281 {
282 	int addr = mv88e6131_port_to_phy_addr(ds, port);
283 
284 	if (addr < 0)
285 		return addr;
286 
287 	return mv88e6xxx_phy_read_ppu(ds, addr, regnum);
288 }
289 
290 static int
mv88e6131_phy_write(struct dsa_switch * ds,int port,int regnum,u16 val)291 mv88e6131_phy_write(struct dsa_switch *ds,
292 			      int port, int regnum, u16 val)
293 {
294 	int addr = mv88e6131_port_to_phy_addr(ds, port);
295 
296 	if (addr < 0)
297 		return addr;
298 
299 	return mv88e6xxx_phy_write_ppu(ds, addr, regnum, val);
300 }
301 
302 struct dsa_switch_driver mv88e6131_switch_driver = {
303 	.tag_protocol		= DSA_TAG_PROTO_DSA,
304 	.priv_size		= sizeof(struct mv88e6xxx_priv_state),
305 	.probe			= mv88e6131_probe,
306 	.setup			= mv88e6131_setup,
307 	.set_addr		= mv88e6xxx_set_addr_direct,
308 	.phy_read		= mv88e6131_phy_read,
309 	.phy_write		= mv88e6131_phy_write,
310 	.poll_link		= mv88e6xxx_poll_link,
311 	.get_strings		= mv88e6xxx_get_strings,
312 	.get_ethtool_stats	= mv88e6xxx_get_ethtool_stats,
313 	.get_sset_count		= mv88e6xxx_get_sset_count,
314 };
315 
316 MODULE_ALIAS("platform:mv88e6085");
317 MODULE_ALIAS("platform:mv88e6095");
318 MODULE_ALIAS("platform:mv88e6095f");
319 MODULE_ALIAS("platform:mv88e6131");
320