1 /*
2  * net/dsa/mv88e6123_61_65.c - Marvell 88e6123/6161/6165 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 
mv88e6123_61_65_probe(struct device * host_dev,int sw_addr)20 static char *mv88e6123_61_65_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 		if (ret == PORT_SWITCH_ID_6123_A1)
31 			return "Marvell 88E6123 (A1)";
32 		if (ret == PORT_SWITCH_ID_6123_A2)
33 			return "Marvell 88E6123 (A2)";
34 		if ((ret & 0xfff0) == PORT_SWITCH_ID_6123)
35 			return "Marvell 88E6123";
36 
37 		if (ret == PORT_SWITCH_ID_6161_A1)
38 			return "Marvell 88E6161 (A1)";
39 		if (ret == PORT_SWITCH_ID_6161_A2)
40 			return "Marvell 88E6161 (A2)";
41 		if ((ret & 0xfff0) == PORT_SWITCH_ID_6161)
42 			return "Marvell 88E6161";
43 
44 		if (ret == PORT_SWITCH_ID_6165_A1)
45 			return "Marvell 88E6165 (A1)";
46 		if (ret == PORT_SWITCH_ID_6165_A2)
47 			return "Marvell 88e6165 (A2)";
48 		if ((ret & 0xfff0) == PORT_SWITCH_ID_6165)
49 			return "Marvell 88E6165";
50 	}
51 
52 	return NULL;
53 }
54 
mv88e6123_61_65_setup_global(struct dsa_switch * ds)55 static int mv88e6123_61_65_setup_global(struct dsa_switch *ds)
56 {
57 	int ret;
58 	int i;
59 
60 	/* Disable the PHY polling unit (since there won't be any
61 	 * external PHYs to poll), don't discard packets with
62 	 * excessive collisions, and mask all interrupt sources.
63 	 */
64 	REG_WRITE(REG_GLOBAL, 0x04, 0x0000);
65 
66 	/* Set the default address aging time to 5 minutes, and
67 	 * enable address learn messages to be sent to all message
68 	 * ports.
69 	 */
70 	REG_WRITE(REG_GLOBAL, 0x0a, 0x0148);
71 
72 	/* Configure the priority mapping registers. */
73 	ret = mv88e6xxx_config_prio(ds);
74 	if (ret < 0)
75 		return ret;
76 
77 	/* Configure the upstream port, and configure the upstream
78 	 * port as the port to which ingress and egress monitor frames
79 	 * are to be sent.
80 	 */
81 	REG_WRITE(REG_GLOBAL, 0x1a, (dsa_upstream_port(ds) * 0x1110));
82 
83 	/* Disable remote management for now, and set the switch's
84 	 * DSA device number.
85 	 */
86 	REG_WRITE(REG_GLOBAL, 0x1c, ds->index & 0x1f);
87 
88 	/* Send all frames with destination addresses matching
89 	 * 01:80:c2:00:00:2x to the CPU port.
90 	 */
91 	REG_WRITE(REG_GLOBAL2, 0x02, 0xffff);
92 
93 	/* Send all frames with destination addresses matching
94 	 * 01:80:c2:00:00:0x to the CPU port.
95 	 */
96 	REG_WRITE(REG_GLOBAL2, 0x03, 0xffff);
97 
98 	/* Disable the loopback filter, disable flow control
99 	 * messages, disable flood broadcast override, disable
100 	 * removing of provider tags, disable ATU age violation
101 	 * interrupts, disable tag flow control, force flow
102 	 * control priority to the highest, and send all special
103 	 * multicast frames to the CPU at the highest priority.
104 	 */
105 	REG_WRITE(REG_GLOBAL2, 0x05, 0x00ff);
106 
107 	/* Program the DSA routing table. */
108 	for (i = 0; i < 32; i++) {
109 		int nexthop;
110 
111 		nexthop = 0x1f;
112 		if (i != ds->index && i < ds->dst->pd->nr_chips)
113 			nexthop = ds->pd->rtable[i] & 0x1f;
114 
115 		REG_WRITE(REG_GLOBAL2, 0x06, 0x8000 | (i << 8) | nexthop);
116 	}
117 
118 	/* Clear all trunk masks. */
119 	for (i = 0; i < 8; i++)
120 		REG_WRITE(REG_GLOBAL2, 0x07, 0x8000 | (i << 12) | 0xff);
121 
122 	/* Clear all trunk mappings. */
123 	for (i = 0; i < 16; i++)
124 		REG_WRITE(REG_GLOBAL2, 0x08, 0x8000 | (i << 11));
125 
126 	/* Disable ingress rate limiting by resetting all ingress
127 	 * rate limit registers to their initial state.
128 	 */
129 	for (i = 0; i < 6; i++)
130 		REG_WRITE(REG_GLOBAL2, 0x09, 0x9000 | (i << 8));
131 
132 	/* Initialise cross-chip port VLAN table to reset defaults. */
133 	REG_WRITE(REG_GLOBAL2, 0x0b, 0x9000);
134 
135 	/* Clear the priority override table. */
136 	for (i = 0; i < 16; i++)
137 		REG_WRITE(REG_GLOBAL2, 0x0f, 0x8000 | (i << 8));
138 
139 	/* @@@ initialise AVB (22/23) watchdog (27) sdet (29) registers */
140 
141 	return 0;
142 }
143 
mv88e6123_61_65_setup_port(struct dsa_switch * ds,int p)144 static int mv88e6123_61_65_setup_port(struct dsa_switch *ds, int p)
145 {
146 	int addr = REG_PORT(p);
147 	u16 val;
148 
149 	/* MAC Forcing register: don't force link, speed, duplex
150 	 * or flow control state to any particular values on physical
151 	 * ports, but force the CPU port and all DSA ports to 1000 Mb/s
152 	 * full duplex.
153 	 */
154 	if (dsa_is_cpu_port(ds, p) || ds->dsa_port_mask & (1 << p))
155 		REG_WRITE(addr, 0x01, 0x003e);
156 	else
157 		REG_WRITE(addr, 0x01, 0x0003);
158 
159 	/* Do not limit the period of time that this port can be
160 	 * paused for by the remote end or the period of time that
161 	 * this port can pause the remote end.
162 	 */
163 	REG_WRITE(addr, 0x02, 0x0000);
164 
165 	/* Port Control: disable Drop-on-Unlock, disable Drop-on-Lock,
166 	 * disable Header mode, enable IGMP/MLD snooping, disable VLAN
167 	 * tunneling, determine priority by looking at 802.1p and IP
168 	 * priority fields (IP prio has precedence), and set STP state
169 	 * to Forwarding.
170 	 *
171 	 * If this is the CPU link, use DSA or EDSA tagging depending
172 	 * on which tagging mode was configured.
173 	 *
174 	 * If this is a link to another switch, use DSA tagging mode.
175 	 *
176 	 * If this is the upstream port for this switch, enable
177 	 * forwarding of unknown unicasts and multicasts.
178 	 */
179 	val = 0x0433;
180 	if (dsa_is_cpu_port(ds, p)) {
181 		if (ds->dst->tag_protocol == DSA_TAG_PROTO_EDSA)
182 			val |= 0x3300;
183 		else
184 			val |= 0x0100;
185 	}
186 	if (ds->dsa_port_mask & (1 << p))
187 		val |= 0x0100;
188 	if (p == dsa_upstream_port(ds))
189 		val |= 0x000c;
190 	REG_WRITE(addr, 0x04, val);
191 
192 	/* Port Control 2: don't force a good FCS, set the maximum
193 	 * frame size to 10240 bytes, don't let the switch add or
194 	 * strip 802.1q tags, don't discard tagged or untagged frames
195 	 * on this port, do a destination address lookup on all
196 	 * received packets as usual, disable ARP mirroring and don't
197 	 * send a copy of all transmitted/received frames on this port
198 	 * to the CPU.
199 	 */
200 	REG_WRITE(addr, 0x08, 0x2080);
201 
202 	/* Egress rate control: disable egress rate control. */
203 	REG_WRITE(addr, 0x09, 0x0001);
204 
205 	/* Egress rate control 2: disable egress rate control. */
206 	REG_WRITE(addr, 0x0a, 0x0000);
207 
208 	/* Port Association Vector: when learning source addresses
209 	 * of packets, add the address to the address database using
210 	 * a port bitmap that has only the bit for this port set and
211 	 * the other bits clear.
212 	 */
213 	REG_WRITE(addr, 0x0b, 1 << p);
214 
215 	/* Port ATU control: disable limiting the number of address
216 	 * database entries that this port is allowed to use.
217 	 */
218 	REG_WRITE(addr, 0x0c, 0x0000);
219 
220 	/* Priority Override: disable DA, SA and VTU priority override. */
221 	REG_WRITE(addr, 0x0d, 0x0000);
222 
223 	/* Port Ethertype: use the Ethertype DSA Ethertype value. */
224 	REG_WRITE(addr, 0x0f, ETH_P_EDSA);
225 
226 	/* Tag Remap: use an identity 802.1p prio -> switch prio
227 	 * mapping.
228 	 */
229 	REG_WRITE(addr, 0x18, 0x3210);
230 
231 	/* Tag Remap 2: use an identity 802.1p prio -> switch prio
232 	 * mapping.
233 	 */
234 	REG_WRITE(addr, 0x19, 0x7654);
235 
236 	return mv88e6xxx_setup_port_common(ds, p);
237 }
238 
mv88e6123_61_65_setup(struct dsa_switch * ds)239 static int mv88e6123_61_65_setup(struct dsa_switch *ds)
240 {
241 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
242 	int i;
243 	int ret;
244 
245 	ret = mv88e6xxx_setup_common(ds);
246 	if (ret < 0)
247 		return ret;
248 
249 	switch (ps->id) {
250 	case PORT_SWITCH_ID_6123:
251 		ps->num_ports = 3;
252 		break;
253 	case PORT_SWITCH_ID_6161:
254 	case PORT_SWITCH_ID_6165:
255 		ps->num_ports = 6;
256 		break;
257 	default:
258 		return -ENODEV;
259 	}
260 
261 	ret = mv88e6xxx_switch_reset(ds, false);
262 	if (ret < 0)
263 		return ret;
264 
265 	/* @@@ initialise vtu and atu */
266 
267 	ret = mv88e6123_61_65_setup_global(ds);
268 	if (ret < 0)
269 		return ret;
270 
271 	for (i = 0; i < ps->num_ports; i++) {
272 		ret = mv88e6123_61_65_setup_port(ds, i);
273 		if (ret < 0)
274 			return ret;
275 	}
276 
277 	return 0;
278 }
279 
280 struct dsa_switch_driver mv88e6123_61_65_switch_driver = {
281 	.tag_protocol		= DSA_TAG_PROTO_EDSA,
282 	.priv_size		= sizeof(struct mv88e6xxx_priv_state),
283 	.probe			= mv88e6123_61_65_probe,
284 	.setup			= mv88e6123_61_65_setup,
285 	.set_addr		= mv88e6xxx_set_addr_indirect,
286 	.phy_read		= mv88e6xxx_phy_read,
287 	.phy_write		= mv88e6xxx_phy_write,
288 	.poll_link		= mv88e6xxx_poll_link,
289 	.get_strings		= mv88e6xxx_get_strings,
290 	.get_ethtool_stats	= mv88e6xxx_get_ethtool_stats,
291 	.get_sset_count		= mv88e6xxx_get_sset_count,
292 #ifdef CONFIG_NET_DSA_HWMON
293 	.get_temp		= mv88e6xxx_get_temp,
294 #endif
295 	.get_regs_len		= mv88e6xxx_get_regs_len,
296 	.get_regs		= mv88e6xxx_get_regs,
297 };
298 
299 MODULE_ALIAS("platform:mv88e6123");
300 MODULE_ALIAS("platform:mv88e6161");
301 MODULE_ALIAS("platform:mv88e6165");
302