Commit | Line | Data |
---|---|---|
1636d883 | 1 | /* net/dsa/mv88e6171.c - Marvell 88e6171 switch chip support |
42f27253 AL |
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 | ||
b4d2394d | 20 | static char *mv88e6171_probe(struct device *host_dev, int sw_addr) |
42f27253 | 21 | { |
b4d2394d | 22 | struct mii_bus *bus = dsa_host_dev_to_mii_bus(host_dev); |
42f27253 AL |
23 | int ret; |
24 | ||
b4d2394d AD |
25 | if (bus == NULL) |
26 | return NULL; | |
27 | ||
cca8b133 | 28 | ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), PORT_SWITCH_ID); |
42f27253 | 29 | if (ret >= 0) { |
cca8b133 | 30 | if ((ret & 0xfff0) == PORT_SWITCH_ID_6171) |
42f27253 AL |
31 | return "Marvell 88E6171"; |
32 | } | |
33 | ||
34 | return NULL; | |
35 | } | |
36 | ||
42f27253 AL |
37 | static int mv88e6171_setup_global(struct dsa_switch *ds) |
38 | { | |
15966a2a | 39 | u32 upstream_port = dsa_upstream_port(ds); |
42f27253 | 40 | int ret; |
1636d883 | 41 | u32 reg; |
54d792f2 AL |
42 | |
43 | ret = mv88e6xxx_setup_global(ds); | |
44 | if (ret) | |
45 | return ret; | |
42f27253 | 46 | |
4c732668 AL |
47 | /* Discard packets with excessive collisions, mask all |
48 | * interrupt sources, enable PPU. | |
42f27253 | 49 | */ |
15966a2a AL |
50 | REG_WRITE(REG_GLOBAL, GLOBAL_CONTROL, |
51 | GLOBAL_CONTROL_PPU_ENABLE | GLOBAL_CONTROL_DISCARD_EXCESS); | |
42f27253 | 52 | |
42f27253 AL |
53 | /* Configure the upstream port, and configure the upstream |
54 | * port as the port to which ingress and egress monitor frames | |
55 | * are to be sent. | |
56 | */ | |
1636d883 AL |
57 | reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | |
58 | upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | | |
59 | upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT | | |
60 | upstream_port << GLOBAL_MONITOR_CONTROL_MIRROR_SHIFT; | |
61 | REG_WRITE(REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); | |
42f27253 AL |
62 | |
63 | /* Disable remote management for now, and set the switch's | |
64 | * DSA device number. | |
65 | */ | |
15966a2a | 66 | REG_WRITE(REG_GLOBAL, GLOBAL_CONTROL_2, ds->index & 0x1f); |
42f27253 | 67 | |
42f27253 AL |
68 | return 0; |
69 | } | |
70 | ||
42f27253 AL |
71 | static int mv88e6171_setup(struct dsa_switch *ds) |
72 | { | |
44e50ddb | 73 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); |
42f27253 AL |
74 | int ret; |
75 | ||
acdaffcc GR |
76 | ret = mv88e6xxx_setup_common(ds); |
77 | if (ret < 0) | |
78 | return ret; | |
42f27253 | 79 | |
44e50ddb AL |
80 | ps->num_ports = 7; |
81 | ||
143a8307 | 82 | ret = mv88e6xxx_switch_reset(ds, true); |
42f27253 AL |
83 | if (ret < 0) |
84 | return ret; | |
85 | ||
42f27253 AL |
86 | ret = mv88e6171_setup_global(ds); |
87 | if (ret < 0) | |
88 | return ret; | |
89 | ||
dbde9e66 | 90 | return mv88e6xxx_setup_ports(ds); |
42f27253 AL |
91 | } |
92 | ||
42f27253 | 93 | struct dsa_switch_driver mv88e6171_switch_driver = { |
c146b778 | 94 | .tag_protocol = DSA_TAG_PROTO_EDSA, |
42f27253 AL |
95 | .priv_size = sizeof(struct mv88e6xxx_priv_state), |
96 | .probe = mv88e6171_probe, | |
97 | .setup = mv88e6171_setup, | |
98 | .set_addr = mv88e6xxx_set_addr_indirect, | |
fd3a0ee4 AL |
99 | .phy_read = mv88e6xxx_phy_read_indirect, |
100 | .phy_write = mv88e6xxx_phy_write_indirect, | |
42f27253 | 101 | .poll_link = mv88e6xxx_poll_link, |
e413e7e1 AL |
102 | .get_strings = mv88e6xxx_get_strings, |
103 | .get_ethtool_stats = mv88e6xxx_get_ethtool_stats, | |
104 | .get_sset_count = mv88e6xxx_get_sset_count, | |
4dd38cdb AL |
105 | #ifdef CONFIG_NET_DSA_HWMON |
106 | .get_temp = mv88e6xxx_get_temp, | |
107 | #endif | |
03d6faa9 AL |
108 | .get_regs_len = mv88e6xxx_get_regs_len, |
109 | .get_regs = mv88e6xxx_get_regs, | |
b2a6b93a AL |
110 | .port_join_bridge = mv88e6xxx_join_bridge, |
111 | .port_leave_bridge = mv88e6xxx_leave_bridge, | |
112 | .port_stp_update = mv88e6xxx_port_stp_update, | |
113 | .fdb_add = mv88e6xxx_port_fdb_add, | |
114 | .fdb_del = mv88e6xxx_port_fdb_del, | |
115 | .fdb_getnext = mv88e6xxx_port_fdb_getnext, | |
42f27253 AL |
116 | }; |
117 | ||
118 | MODULE_ALIAS("platform:mv88e6171"); |