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