diff options
author | Andrew Lunn <andrew@lunn.ch> | 2016-04-14 17:47:12 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-04-16 19:23:45 -0400 |
commit | 48ace4ef4c3f99ebf6f801c9a8326a4a39f31dbf (patch) | |
tree | a743037cc79c8ae42da8dcc63a5d19c2c7065e4c | |
parent | 756ca874417695f77941948a77e9b8562635cc0a (diff) |
dsa: mv88e6xxx: Kill the REG_READ and REG_WRITE macros
These macros hide a ds variable and a return statement on error, which
can lead to locking issues. Kill them off.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Tested-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/dsa/mv88e6123.c | 13 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6131.c | 41 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6171.c | 16 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6352.c | 15 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx.c | 241 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx.h | 21 |
6 files changed, 224 insertions, 123 deletions
diff --git a/drivers/net/dsa/mv88e6123.c b/drivers/net/dsa/mv88e6123.c index c34283d929c4..140e44e50e8a 100644 --- a/drivers/net/dsa/mv88e6123.c +++ b/drivers/net/dsa/mv88e6123.c | |||
@@ -52,7 +52,9 @@ static int mv88e6123_setup_global(struct dsa_switch *ds) | |||
52 | * external PHYs to poll), don't discard packets with | 52 | * external PHYs to poll), don't discard packets with |
53 | * excessive collisions, and mask all interrupt sources. | 53 | * excessive collisions, and mask all interrupt sources. |
54 | */ | 54 | */ |
55 | REG_WRITE(REG_GLOBAL, GLOBAL_CONTROL, 0x0000); | 55 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_CONTROL, 0x0000); |
56 | if (ret) | ||
57 | return ret; | ||
56 | 58 | ||
57 | /* Configure the upstream port, and configure the upstream | 59 | /* Configure the upstream port, and configure the upstream |
58 | * port as the port to which ingress and egress monitor frames | 60 | * port as the port to which ingress and egress monitor frames |
@@ -61,14 +63,15 @@ static int mv88e6123_setup_global(struct dsa_switch *ds) | |||
61 | reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | | 63 | reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | |
62 | upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | | 64 | upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | |
63 | upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT; | 65 | upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT; |
64 | REG_WRITE(REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); | 66 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); |
67 | if (ret) | ||
68 | return ret; | ||
65 | 69 | ||
66 | /* Disable remote management for now, and set the switch's | 70 | /* Disable remote management for now, and set the switch's |
67 | * DSA device number. | 71 | * DSA device number. |
68 | */ | 72 | */ |
69 | REG_WRITE(REG_GLOBAL, GLOBAL_CONTROL_2, ds->index & 0x1f); | 73 | return mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_CONTROL_2, |
70 | 74 | ds->index & 0x1f); | |
71 | return 0; | ||
72 | } | 75 | } |
73 | 76 | ||
74 | static int mv88e6123_setup(struct dsa_switch *ds) | 77 | static int mv88e6123_setup(struct dsa_switch *ds) |
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c index f5d75fce1e96..34d297b65040 100644 --- a/drivers/net/dsa/mv88e6131.c +++ b/drivers/net/dsa/mv88e6131.c | |||
@@ -49,11 +49,16 @@ static int mv88e6131_setup_global(struct dsa_switch *ds) | |||
49 | * to arbitrate between packet queues, set the maximum frame | 49 | * to arbitrate between packet queues, set the maximum frame |
50 | * size to 1632, and mask all interrupt sources. | 50 | * size to 1632, and mask all interrupt sources. |
51 | */ | 51 | */ |
52 | REG_WRITE(REG_GLOBAL, GLOBAL_CONTROL, | 52 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_CONTROL, |
53 | GLOBAL_CONTROL_PPU_ENABLE | GLOBAL_CONTROL_MAX_FRAME_1632); | 53 | GLOBAL_CONTROL_PPU_ENABLE | |
54 | GLOBAL_CONTROL_MAX_FRAME_1632); | ||
55 | if (ret) | ||
56 | return ret; | ||
54 | 57 | ||
55 | /* Set the VLAN ethertype to 0x8100. */ | 58 | /* Set the VLAN ethertype to 0x8100. */ |
56 | REG_WRITE(REG_GLOBAL, GLOBAL_CORE_TAG_TYPE, 0x8100); | 59 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_CORE_TAG_TYPE, 0x8100); |
60 | if (ret) | ||
61 | return ret; | ||
57 | 62 | ||
58 | /* Disable ARP mirroring, and configure the upstream port as | 63 | /* Disable ARP mirroring, and configure the upstream port as |
59 | * the port to which ingress and egress monitor frames are to | 64 | * the port to which ingress and egress monitor frames are to |
@@ -62,31 +67,33 @@ static int mv88e6131_setup_global(struct dsa_switch *ds) | |||
62 | reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | | 67 | reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | |
63 | upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | | 68 | upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | |
64 | GLOBAL_MONITOR_CONTROL_ARP_DISABLED; | 69 | GLOBAL_MONITOR_CONTROL_ARP_DISABLED; |
65 | REG_WRITE(REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); | 70 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); |
71 | if (ret) | ||
72 | return ret; | ||
66 | 73 | ||
67 | /* Disable cascade port functionality unless this device | 74 | /* Disable cascade port functionality unless this device |
68 | * is used in a cascade configuration, and set the switch's | 75 | * is used in a cascade configuration, and set the switch's |
69 | * DSA device number. | 76 | * DSA device number. |
70 | */ | 77 | */ |
71 | if (ds->dst->pd->nr_chips > 1) | 78 | if (ds->dst->pd->nr_chips > 1) |
72 | REG_WRITE(REG_GLOBAL, GLOBAL_CONTROL_2, | 79 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_CONTROL_2, |
73 | GLOBAL_CONTROL_2_MULTIPLE_CASCADE | | 80 | GLOBAL_CONTROL_2_MULTIPLE_CASCADE | |
74 | (ds->index & 0x1f)); | 81 | (ds->index & 0x1f)); |
75 | else | 82 | else |
76 | REG_WRITE(REG_GLOBAL, GLOBAL_CONTROL_2, | 83 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_CONTROL_2, |
77 | GLOBAL_CONTROL_2_NO_CASCADE | | 84 | GLOBAL_CONTROL_2_NO_CASCADE | |
78 | (ds->index & 0x1f)); | 85 | (ds->index & 0x1f)); |
86 | if (ret) | ||
87 | return ret; | ||
79 | 88 | ||
80 | /* Force the priority of IGMP/MLD snoop frames and ARP frames | 89 | /* Force the priority of IGMP/MLD snoop frames and ARP frames |
81 | * to the highest setting. | 90 | * to the highest setting. |
82 | */ | 91 | */ |
83 | REG_WRITE(REG_GLOBAL2, GLOBAL2_PRIO_OVERRIDE, | 92 | return mv88e6xxx_reg_write(ds, REG_GLOBAL2, GLOBAL2_PRIO_OVERRIDE, |
84 | GLOBAL2_PRIO_OVERRIDE_FORCE_SNOOP | | 93 | GLOBAL2_PRIO_OVERRIDE_FORCE_SNOOP | |
85 | 7 << GLOBAL2_PRIO_OVERRIDE_SNOOP_SHIFT | | 94 | 7 << GLOBAL2_PRIO_OVERRIDE_SNOOP_SHIFT | |
86 | GLOBAL2_PRIO_OVERRIDE_FORCE_ARP | | 95 | GLOBAL2_PRIO_OVERRIDE_FORCE_ARP | |
87 | 7 << GLOBAL2_PRIO_OVERRIDE_ARP_SHIFT); | 96 | 7 << GLOBAL2_PRIO_OVERRIDE_ARP_SHIFT); |
88 | |||
89 | return 0; | ||
90 | } | 97 | } |
91 | 98 | ||
92 | static int mv88e6131_setup(struct dsa_switch *ds) | 99 | static int mv88e6131_setup(struct dsa_switch *ds) |
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c index f5622506cdfa..b7af2b78f8ee 100644 --- a/drivers/net/dsa/mv88e6171.c +++ b/drivers/net/dsa/mv88e6171.c | |||
@@ -46,8 +46,11 @@ static int mv88e6171_setup_global(struct dsa_switch *ds) | |||
46 | /* Discard packets with excessive collisions, mask all | 46 | /* Discard packets with excessive collisions, mask all |
47 | * interrupt sources, enable PPU. | 47 | * interrupt sources, enable PPU. |
48 | */ | 48 | */ |
49 | REG_WRITE(REG_GLOBAL, GLOBAL_CONTROL, | 49 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_CONTROL, |
50 | GLOBAL_CONTROL_PPU_ENABLE | GLOBAL_CONTROL_DISCARD_EXCESS); | 50 | GLOBAL_CONTROL_PPU_ENABLE | |
51 | GLOBAL_CONTROL_DISCARD_EXCESS); | ||
52 | if (ret) | ||
53 | return ret; | ||
51 | 54 | ||
52 | /* Configure the upstream port, and configure the upstream | 55 | /* Configure the upstream port, and configure the upstream |
53 | * port as the port to which ingress and egress monitor frames | 56 | * port as the port to which ingress and egress monitor frames |
@@ -57,14 +60,15 @@ static int mv88e6171_setup_global(struct dsa_switch *ds) | |||
57 | upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | | 60 | upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | |
58 | upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT | | 61 | upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT | |
59 | upstream_port << GLOBAL_MONITOR_CONTROL_MIRROR_SHIFT; | 62 | upstream_port << GLOBAL_MONITOR_CONTROL_MIRROR_SHIFT; |
60 | REG_WRITE(REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); | 63 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); |
64 | if (ret) | ||
65 | return ret; | ||
61 | 66 | ||
62 | /* Disable remote management for now, and set the switch's | 67 | /* Disable remote management for now, and set the switch's |
63 | * DSA device number. | 68 | * DSA device number. |
64 | */ | 69 | */ |
65 | REG_WRITE(REG_GLOBAL, GLOBAL_CONTROL_2, ds->index & 0x1f); | 70 | return mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_CONTROL_2, |
66 | 71 | ds->index & 0x1f); | |
67 | return 0; | ||
68 | } | 72 | } |
69 | 73 | ||
70 | static int mv88e6171_setup(struct dsa_switch *ds) | 74 | static int mv88e6171_setup(struct dsa_switch *ds) |
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c index e54ee27db129..e8cb03fad21a 100644 --- a/drivers/net/dsa/mv88e6352.c +++ b/drivers/net/dsa/mv88e6352.c | |||
@@ -59,8 +59,11 @@ static int mv88e6352_setup_global(struct dsa_switch *ds) | |||
59 | /* Discard packets with excessive collisions, | 59 | /* Discard packets with excessive collisions, |
60 | * mask all interrupt sources, enable PPU (bit 14, undocumented). | 60 | * mask all interrupt sources, enable PPU (bit 14, undocumented). |
61 | */ | 61 | */ |
62 | REG_WRITE(REG_GLOBAL, GLOBAL_CONTROL, | 62 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_CONTROL, |
63 | GLOBAL_CONTROL_PPU_ENABLE | GLOBAL_CONTROL_DISCARD_EXCESS); | 63 | GLOBAL_CONTROL_PPU_ENABLE | |
64 | GLOBAL_CONTROL_DISCARD_EXCESS); | ||
65 | if (ret) | ||
66 | return ret; | ||
64 | 67 | ||
65 | /* Configure the upstream port, and configure the upstream | 68 | /* Configure the upstream port, and configure the upstream |
66 | * port as the port to which ingress and egress monitor frames | 69 | * port as the port to which ingress and egress monitor frames |
@@ -69,14 +72,14 @@ static int mv88e6352_setup_global(struct dsa_switch *ds) | |||
69 | reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | | 72 | reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | |
70 | upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | | 73 | upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT | |
71 | upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT; | 74 | upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT; |
72 | REG_WRITE(REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); | 75 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_MONITOR_CONTROL, reg); |
76 | if (ret) | ||
77 | return ret; | ||
73 | 78 | ||
74 | /* Disable remote management for now, and set the switch's | 79 | /* Disable remote management for now, and set the switch's |
75 | * DSA device number. | 80 | * DSA device number. |
76 | */ | 81 | */ |
77 | REG_WRITE(REG_GLOBAL, 0x1c, ds->index & 0x1f); | 82 | return mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x1c, ds->index & 0x1f); |
78 | |||
79 | return 0; | ||
80 | } | 83 | } |
81 | 84 | ||
82 | static int mv88e6352_setup(struct dsa_switch *ds) | 85 | static int mv88e6352_setup(struct dsa_switch *ds) |
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c index 9985a0cf31f1..b018f20829fb 100644 --- a/drivers/net/dsa/mv88e6xxx.c +++ b/drivers/net/dsa/mv88e6xxx.c | |||
@@ -180,28 +180,44 @@ int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val) | |||
180 | 180 | ||
181 | int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr) | 181 | int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr) |
182 | { | 182 | { |
183 | REG_WRITE(REG_GLOBAL, GLOBAL_MAC_01, (addr[0] << 8) | addr[1]); | 183 | int err; |
184 | REG_WRITE(REG_GLOBAL, GLOBAL_MAC_23, (addr[2] << 8) | addr[3]); | ||
185 | REG_WRITE(REG_GLOBAL, GLOBAL_MAC_45, (addr[4] << 8) | addr[5]); | ||
186 | 184 | ||
187 | return 0; | 185 | err = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_MAC_01, |
186 | (addr[0] << 8) | addr[1]); | ||
187 | if (err) | ||
188 | return err; | ||
189 | |||
190 | err = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_MAC_23, | ||
191 | (addr[2] << 8) | addr[3]); | ||
192 | if (err) | ||
193 | return err; | ||
194 | |||
195 | return mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_MAC_45, | ||
196 | (addr[4] << 8) | addr[5]); | ||
188 | } | 197 | } |
189 | 198 | ||
190 | int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr) | 199 | int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr) |
191 | { | 200 | { |
192 | int i; | ||
193 | int ret; | 201 | int ret; |
202 | int i; | ||
194 | 203 | ||
195 | for (i = 0; i < 6; i++) { | 204 | for (i = 0; i < 6; i++) { |
196 | int j; | 205 | int j; |
197 | 206 | ||
198 | /* Write the MAC address byte. */ | 207 | /* Write the MAC address byte. */ |
199 | REG_WRITE(REG_GLOBAL2, GLOBAL2_SWITCH_MAC, | 208 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL2, GLOBAL2_SWITCH_MAC, |
200 | GLOBAL2_SWITCH_MAC_BUSY | (i << 8) | addr[i]); | 209 | GLOBAL2_SWITCH_MAC_BUSY | |
210 | (i << 8) | addr[i]); | ||
211 | if (ret) | ||
212 | return ret; | ||
201 | 213 | ||
202 | /* Wait for the write to complete. */ | 214 | /* Wait for the write to complete. */ |
203 | for (j = 0; j < 16; j++) { | 215 | for (j = 0; j < 16; j++) { |
204 | ret = REG_READ(REG_GLOBAL2, GLOBAL2_SWITCH_MAC); | 216 | ret = mv88e6xxx_reg_read(ds, REG_GLOBAL2, |
217 | GLOBAL2_SWITCH_MAC); | ||
218 | if (ret < 0) | ||
219 | return ret; | ||
220 | |||
205 | if ((ret & GLOBAL2_SWITCH_MAC_BUSY) == 0) | 221 | if ((ret & GLOBAL2_SWITCH_MAC_BUSY) == 0) |
206 | break; | 222 | break; |
207 | } | 223 | } |
@@ -233,13 +249,21 @@ static int mv88e6xxx_ppu_disable(struct dsa_switch *ds) | |||
233 | int ret; | 249 | int ret; |
234 | unsigned long timeout; | 250 | unsigned long timeout; |
235 | 251 | ||
236 | ret = REG_READ(REG_GLOBAL, GLOBAL_CONTROL); | 252 | ret = mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_CONTROL); |
237 | REG_WRITE(REG_GLOBAL, GLOBAL_CONTROL, | 253 | if (ret < 0) |
238 | ret & ~GLOBAL_CONTROL_PPU_ENABLE); | 254 | return ret; |
255 | |||
256 | ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_CONTROL, | ||
257 | ret & ~GLOBAL_CONTROL_PPU_ENABLE); | ||
258 | if (ret) | ||
259 | return ret; | ||
239 | 260 | ||
240 | timeout = jiffies + 1 * HZ; | 261 | timeout = jiffies + 1 * HZ; |
241 | while (time_before(jiffies, timeout)) { | 262 | while (time_before(jiffies, timeout)) { |
242 | ret = REG_READ(REG_GLOBAL, GLOBAL_STATUS); | 263 | ret = mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_STATUS); |
264 | if (ret < 0) | ||
265 | return ret; | ||
266 | |||
243 | usleep_range(1000, 2000); | 267 | usleep_range(1000, 2000); |
244 | if ((ret & GLOBAL_STATUS_PPU_MASK) != | 268 | if ((ret & GLOBAL_STATUS_PPU_MASK) != |
245 | GLOBAL_STATUS_PPU_POLLING) | 269 | GLOBAL_STATUS_PPU_POLLING) |
@@ -251,15 +275,24 @@ static int mv88e6xxx_ppu_disable(struct dsa_switch *ds) | |||
251 | 275 | ||
252 | static int mv88e6xxx_ppu_enable(struct dsa_switch *ds) | 276 | static int mv88e6xxx_ppu_enable(struct dsa_switch *ds) |
253 | { | 277 | { |
254 | int ret; | 278 | int ret, err; |
255 | unsigned long timeout; | 279 | unsigned long timeout; |
256 | 280 | ||
257 | ret = REG_READ(REG_GLOBAL, GLOBAL_CONTROL); | 281 | ret = mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_CONTROL); |
258 | REG_WRITE(REG_GLOBAL, GLOBAL_CONTROL, ret | GLOBAL_CONTROL_PPU_ENABLE); | 282 | if (ret < 0) |
283 | return ret; | ||
284 | |||
285 | err = mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_CONTROL, | ||
286 | ret | GLOBAL_CONTROL_PPU_ENABLE); | ||
287 | if (err) | ||
288 | return err; | ||
259 | 289 | ||
260 | timeout = jiffies + 1 * HZ; | 290 | timeout = jiffies + 1 * HZ; |
261 | while (time_before(jiffies, timeout)) { | 291 | while (time_before(jiffies, timeout)) { |
262 | ret = REG_READ(REG_GLOBAL, GLOBAL_STATUS); | 292 | ret = mv88e6xxx_reg_read(ds, REG_GLOBAL, GLOBAL_STATUS); |
293 | if (ret < 0) | ||
294 | return ret; | ||
295 | |||
263 | usleep_range(1000, 2000); | 296 | usleep_range(1000, 2000); |
264 | if ((ret & GLOBAL_STATUS_PPU_MASK) == | 297 | if ((ret & GLOBAL_STATUS_PPU_MASK) == |
265 | GLOBAL_STATUS_PPU_POLLING) | 298 | GLOBAL_STATUS_PPU_POLLING) |
@@ -2667,7 +2700,9 @@ int mv88e6xxx_setup_common(struct dsa_switch *ds) | |||
2667 | ps->ds = ds; | 2700 | ps->ds = ds; |
2668 | mutex_init(&ps->smi_mutex); | 2701 | mutex_init(&ps->smi_mutex); |
2669 | 2702 | ||
2670 | ps->id = REG_READ(REG_PORT(0), PORT_SWITCH_ID) & 0xfff0; | 2703 | ps->id = mv88e6xxx_reg_read(ds, REG_PORT(0), PORT_SWITCH_ID) & 0xfff0; |
2704 | if (ps->id < 0) | ||
2705 | return ps->id; | ||
2671 | 2706 | ||
2672 | INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work); | 2707 | INIT_WORK(&ps->bridge_work, mv88e6xxx_bridge_work); |
2673 | 2708 | ||
@@ -2677,42 +2712,67 @@ int mv88e6xxx_setup_common(struct dsa_switch *ds) | |||
2677 | int mv88e6xxx_setup_global(struct dsa_switch *ds) | 2712 | int mv88e6xxx_setup_global(struct dsa_switch *ds) |
2678 | { | 2713 | { |
2679 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); | 2714 | struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); |
2680 | int ret; | 2715 | int err; |
2681 | int i; | 2716 | int i; |
2682 | 2717 | ||
2718 | mutex_lock(&ps->smi_mutex); | ||
2683 | /* Set the default address aging time to 5 minutes, and | 2719 | /* Set the default address aging time to 5 minutes, and |
2684 | * enable address learn messages to be sent to all message | 2720 | * enable address learn messages to be sent to all message |
2685 | * ports. | 2721 | * ports. |
2686 | */ | 2722 | */ |
2687 | REG_WRITE(REG_GLOBAL, GLOBAL_ATU_CONTROL, | 2723 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_ATU_CONTROL, |
2688 | 0x0140 | GLOBAL_ATU_CONTROL_LEARN2ALL); | 2724 | 0x0140 | GLOBAL_ATU_CONTROL_LEARN2ALL); |
2725 | if (err) | ||
2726 | goto unlock; | ||
2689 | 2727 | ||
2690 | /* Configure the IP ToS mapping registers. */ | 2728 | /* Configure the IP ToS mapping registers. */ |
2691 | REG_WRITE(REG_GLOBAL, GLOBAL_IP_PRI_0, 0x0000); | 2729 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_IP_PRI_0, 0x0000); |
2692 | REG_WRITE(REG_GLOBAL, GLOBAL_IP_PRI_1, 0x0000); | 2730 | if (err) |
2693 | REG_WRITE(REG_GLOBAL, GLOBAL_IP_PRI_2, 0x5555); | 2731 | goto unlock; |
2694 | REG_WRITE(REG_GLOBAL, GLOBAL_IP_PRI_3, 0x5555); | 2732 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_IP_PRI_1, 0x0000); |
2695 | REG_WRITE(REG_GLOBAL, GLOBAL_IP_PRI_4, 0xaaaa); | 2733 | if (err) |
2696 | REG_WRITE(REG_GLOBAL, GLOBAL_IP_PRI_5, 0xaaaa); | 2734 | goto unlock; |
2697 | REG_WRITE(REG_GLOBAL, GLOBAL_IP_PRI_6, 0xffff); | 2735 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_IP_PRI_2, 0x5555); |
2698 | REG_WRITE(REG_GLOBAL, GLOBAL_IP_PRI_7, 0xffff); | 2736 | if (err) |
2737 | goto unlock; | ||
2738 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_IP_PRI_3, 0x5555); | ||
2739 | if (err) | ||
2740 | goto unlock; | ||
2741 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_IP_PRI_4, 0xaaaa); | ||
2742 | if (err) | ||
2743 | goto unlock; | ||
2744 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_IP_PRI_5, 0xaaaa); | ||
2745 | if (err) | ||
2746 | goto unlock; | ||
2747 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_IP_PRI_6, 0xffff); | ||
2748 | if (err) | ||
2749 | goto unlock; | ||
2750 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_IP_PRI_7, 0xffff); | ||
2751 | if (err) | ||
2752 | goto unlock; | ||
2699 | 2753 | ||
2700 | /* Configure the IEEE 802.1p priority mapping register. */ | 2754 | /* Configure the IEEE 802.1p priority mapping register. */ |
2701 | REG_WRITE(REG_GLOBAL, GLOBAL_IEEE_PRI, 0xfa41); | 2755 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_IEEE_PRI, 0xfa41); |
2756 | if (err) | ||
2757 | goto unlock; | ||
2702 | 2758 | ||
2703 | /* Send all frames with destination addresses matching | 2759 | /* Send all frames with destination addresses matching |
2704 | * 01:80:c2:00:00:0x to the CPU port. | 2760 | * 01:80:c2:00:00:0x to the CPU port. |
2705 | */ | 2761 | */ |
2706 | REG_WRITE(REG_GLOBAL2, GLOBAL2_MGMT_EN_0X, 0xffff); | 2762 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL2, GLOBAL2_MGMT_EN_0X, 0xffff); |
2763 | if (err) | ||
2764 | goto unlock; | ||
2707 | 2765 | ||
2708 | /* Ignore removed tag data on doubly tagged packets, disable | 2766 | /* Ignore removed tag data on doubly tagged packets, disable |
2709 | * flow control messages, force flow control priority to the | 2767 | * flow control messages, force flow control priority to the |
2710 | * highest, and send all special multicast frames to the CPU | 2768 | * highest, and send all special multicast frames to the CPU |
2711 | * port at the highest priority. | 2769 | * port at the highest priority. |
2712 | */ | 2770 | */ |
2713 | REG_WRITE(REG_GLOBAL2, GLOBAL2_SWITCH_MGMT, | 2771 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL2, GLOBAL2_SWITCH_MGMT, |
2714 | 0x7 | GLOBAL2_SWITCH_MGMT_RSVD2CPU | 0x70 | | 2772 | 0x7 | GLOBAL2_SWITCH_MGMT_RSVD2CPU | 0x70 | |
2715 | GLOBAL2_SWITCH_MGMT_FORCE_FLOW_CTRL_PRI); | 2773 | GLOBAL2_SWITCH_MGMT_FORCE_FLOW_CTRL_PRI); |
2774 | if (err) | ||
2775 | goto unlock; | ||
2716 | 2776 | ||
2717 | /* Program the DSA routing table. */ | 2777 | /* Program the DSA routing table. */ |
2718 | for (i = 0; i < 32; i++) { | 2778 | for (i = 0; i < 32; i++) { |
@@ -2722,23 +2782,35 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds) | |||
2722 | i != ds->index && i < ds->dst->pd->nr_chips) | 2782 | i != ds->index && i < ds->dst->pd->nr_chips) |
2723 | nexthop = ds->pd->rtable[i] & 0x1f; | 2783 | nexthop = ds->pd->rtable[i] & 0x1f; |
2724 | 2784 | ||
2725 | REG_WRITE(REG_GLOBAL2, GLOBAL2_DEVICE_MAPPING, | 2785 | err = _mv88e6xxx_reg_write( |
2726 | GLOBAL2_DEVICE_MAPPING_UPDATE | | 2786 | ds, REG_GLOBAL2, |
2727 | (i << GLOBAL2_DEVICE_MAPPING_TARGET_SHIFT) | | 2787 | GLOBAL2_DEVICE_MAPPING, |
2728 | nexthop); | 2788 | GLOBAL2_DEVICE_MAPPING_UPDATE | |
2789 | (i << GLOBAL2_DEVICE_MAPPING_TARGET_SHIFT) | nexthop); | ||
2790 | if (err) | ||
2791 | goto unlock; | ||
2729 | } | 2792 | } |
2730 | 2793 | ||
2731 | /* Clear all trunk masks. */ | 2794 | /* Clear all trunk masks. */ |
2732 | for (i = 0; i < 8; i++) | 2795 | for (i = 0; i < 8; i++) { |
2733 | REG_WRITE(REG_GLOBAL2, GLOBAL2_TRUNK_MASK, | 2796 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL2, GLOBAL2_TRUNK_MASK, |
2734 | 0x8000 | (i << GLOBAL2_TRUNK_MASK_NUM_SHIFT) | | 2797 | 0x8000 | |
2735 | ((1 << ps->num_ports) - 1)); | 2798 | (i << GLOBAL2_TRUNK_MASK_NUM_SHIFT) | |
2799 | ((1 << ps->num_ports) - 1)); | ||
2800 | if (err) | ||
2801 | goto unlock; | ||
2802 | } | ||
2736 | 2803 | ||
2737 | /* Clear all trunk mappings. */ | 2804 | /* Clear all trunk mappings. */ |
2738 | for (i = 0; i < 16; i++) | 2805 | for (i = 0; i < 16; i++) { |
2739 | REG_WRITE(REG_GLOBAL2, GLOBAL2_TRUNK_MAPPING, | 2806 | err = _mv88e6xxx_reg_write( |
2740 | GLOBAL2_TRUNK_MAPPING_UPDATE | | 2807 | ds, REG_GLOBAL2, |
2741 | (i << GLOBAL2_TRUNK_MAPPING_ID_SHIFT)); | 2808 | GLOBAL2_TRUNK_MAPPING, |
2809 | GLOBAL2_TRUNK_MAPPING_UPDATE | | ||
2810 | (i << GLOBAL2_TRUNK_MAPPING_ID_SHIFT)); | ||
2811 | if (err) | ||
2812 | goto unlock; | ||
2813 | } | ||
2742 | 2814 | ||
2743 | if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || | 2815 | if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || |
2744 | mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) || | 2816 | mv88e6xxx_6165_family(ds) || mv88e6xxx_6097_family(ds) || |
@@ -2746,17 +2818,27 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds) | |||
2746 | /* Send all frames with destination addresses matching | 2818 | /* Send all frames with destination addresses matching |
2747 | * 01:80:c2:00:00:2x to the CPU port. | 2819 | * 01:80:c2:00:00:2x to the CPU port. |
2748 | */ | 2820 | */ |
2749 | REG_WRITE(REG_GLOBAL2, GLOBAL2_MGMT_EN_2X, 0xffff); | 2821 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL2, |
2822 | GLOBAL2_MGMT_EN_2X, 0xffff); | ||
2823 | if (err) | ||
2824 | goto unlock; | ||
2750 | 2825 | ||
2751 | /* Initialise cross-chip port VLAN table to reset | 2826 | /* Initialise cross-chip port VLAN table to reset |
2752 | * defaults. | 2827 | * defaults. |
2753 | */ | 2828 | */ |
2754 | REG_WRITE(REG_GLOBAL2, GLOBAL2_PVT_ADDR, 0x9000); | 2829 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL2, |
2830 | GLOBAL2_PVT_ADDR, 0x9000); | ||
2831 | if (err) | ||
2832 | goto unlock; | ||
2755 | 2833 | ||
2756 | /* Clear the priority override table. */ | 2834 | /* Clear the priority override table. */ |
2757 | for (i = 0; i < 16; i++) | 2835 | for (i = 0; i < 16; i++) { |
2758 | REG_WRITE(REG_GLOBAL2, GLOBAL2_PRIO_OVERRIDE, | 2836 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL2, |
2759 | 0x8000 | (i << 8)); | 2837 | GLOBAL2_PRIO_OVERRIDE, |
2838 | 0x8000 | (i << 8)); | ||
2839 | if (err) | ||
2840 | goto unlock; | ||
2841 | } | ||
2760 | } | 2842 | } |
2761 | 2843 | ||
2762 | if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || | 2844 | if (mv88e6xxx_6352_family(ds) || mv88e6xxx_6351_family(ds) || |
@@ -2767,31 +2849,37 @@ int mv88e6xxx_setup_global(struct dsa_switch *ds) | |||
2767 | * ingress rate limit registers to their initial | 2849 | * ingress rate limit registers to their initial |
2768 | * state. | 2850 | * state. |
2769 | */ | 2851 | */ |
2770 | for (i = 0; i < ps->num_ports; i++) | 2852 | for (i = 0; i < ps->num_ports; i++) { |
2771 | REG_WRITE(REG_GLOBAL2, GLOBAL2_INGRESS_OP, | 2853 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL2, |
2772 | 0x9000 | (i << 8)); | 2854 | GLOBAL2_INGRESS_OP, |
2855 | 0x9000 | (i << 8)); | ||
2856 | if (err) | ||
2857 | goto unlock; | ||
2858 | } | ||
2773 | } | 2859 | } |
2774 | 2860 | ||
2775 | /* Clear the statistics counters for all ports */ | 2861 | /* Clear the statistics counters for all ports */ |
2776 | REG_WRITE(REG_GLOBAL, GLOBAL_STATS_OP, GLOBAL_STATS_OP_FLUSH_ALL); | 2862 | err = _mv88e6xxx_reg_write(ds, REG_GLOBAL, GLOBAL_STATS_OP, |
2863 | GLOBAL_STATS_OP_FLUSH_ALL); | ||
2864 | if (err) | ||
2865 | goto unlock; | ||
2777 | 2866 | ||
2778 | /* Wait for the flush to complete. */ | 2867 | /* Wait for the flush to complete. */ |
2779 | mutex_lock(&ps->smi_mutex); | 2868 | err = _mv88e6xxx_stats_wait(ds); |
2780 | ret = _mv88e6xxx_stats_wait(ds); | 2869 | if (err < 0) |
2781 | if (ret < 0) | ||
2782 | goto unlock; | 2870 | goto unlock; |
2783 | 2871 | ||
2784 | /* Clear all ATU entries */ | 2872 | /* Clear all ATU entries */ |
2785 | ret = _mv88e6xxx_atu_flush(ds, 0, true); | 2873 | err = _mv88e6xxx_atu_flush(ds, 0, true); |
2786 | if (ret < 0) | 2874 | if (err < 0) |
2787 | goto unlock; | 2875 | goto unlock; |
2788 | 2876 | ||
2789 | /* Clear all the VTU and STU entries */ | 2877 | /* Clear all the VTU and STU entries */ |
2790 | ret = _mv88e6xxx_vtu_stu_flush(ds); | 2878 | err = _mv88e6xxx_vtu_stu_flush(ds); |
2791 | unlock: | 2879 | unlock: |
2792 | mutex_unlock(&ps->smi_mutex); | 2880 | mutex_unlock(&ps->smi_mutex); |
2793 | 2881 | ||
2794 | return ret; | 2882 | return err; |
2795 | } | 2883 | } |
2796 | 2884 | ||
2797 | int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active) | 2885 | int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active) |
@@ -2803,10 +2891,18 @@ int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active) | |||
2803 | int ret; | 2891 | int ret; |
2804 | int i; | 2892 | int i; |
2805 | 2893 | ||
2894 | mutex_lock(&ps->smi_mutex); | ||
2895 | |||
2806 | /* Set all ports to the disabled state. */ | 2896 | /* Set all ports to the disabled state. */ |
2807 | for (i = 0; i < ps->num_ports; i++) { | 2897 | for (i = 0; i < ps->num_ports; i++) { |
2808 | ret = REG_READ(REG_PORT(i), PORT_CONTROL); | 2898 | ret = _mv88e6xxx_reg_read(ds, REG_PORT(i), PORT_CONTROL); |
2809 | REG_WRITE(REG_PORT(i), PORT_CONTROL, ret & 0xfffc); | 2899 | if (ret < 0) |
2900 | goto unlock; | ||
2901 | |||
2902 | ret = _mv88e6xxx_reg_write(ds, REG_PORT(i), PORT_CONTROL, | ||
2903 | ret & 0xfffc); | ||
2904 | if (ret) | ||
2905 | goto unlock; | ||
2810 | } | 2906 | } |
2811 | 2907 | ||
2812 | /* Wait for transmit queues to drain. */ | 2908 | /* Wait for transmit queues to drain. */ |
@@ -2825,22 +2921,31 @@ int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active) | |||
2825 | * through global registers 0x18 and 0x19. | 2921 | * through global registers 0x18 and 0x19. |
2826 | */ | 2922 | */ |
2827 | if (ppu_active) | 2923 | if (ppu_active) |
2828 | REG_WRITE(REG_GLOBAL, 0x04, 0xc000); | 2924 | ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x04, 0xc000); |
2829 | else | 2925 | else |
2830 | REG_WRITE(REG_GLOBAL, 0x04, 0xc400); | 2926 | ret = _mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x04, 0xc400); |
2927 | if (ret) | ||
2928 | goto unlock; | ||
2831 | 2929 | ||
2832 | /* Wait up to one second for reset to complete. */ | 2930 | /* Wait up to one second for reset to complete. */ |
2833 | timeout = jiffies + 1 * HZ; | 2931 | timeout = jiffies + 1 * HZ; |
2834 | while (time_before(jiffies, timeout)) { | 2932 | while (time_before(jiffies, timeout)) { |
2835 | ret = REG_READ(REG_GLOBAL, 0x00); | 2933 | ret = _mv88e6xxx_reg_read(ds, REG_GLOBAL, 0x00); |
2934 | if (ret < 0) | ||
2935 | goto unlock; | ||
2936 | |||
2836 | if ((ret & is_reset) == is_reset) | 2937 | if ((ret & is_reset) == is_reset) |
2837 | break; | 2938 | break; |
2838 | usleep_range(1000, 2000); | 2939 | usleep_range(1000, 2000); |
2839 | } | 2940 | } |
2840 | if (time_after(jiffies, timeout)) | 2941 | if (time_after(jiffies, timeout)) |
2841 | return -ETIMEDOUT; | 2942 | ret = -ETIMEDOUT; |
2943 | else | ||
2944 | ret = 0; | ||
2945 | unlock: | ||
2946 | mutex_unlock(&ps->smi_mutex); | ||
2842 | 2947 | ||
2843 | return 0; | 2948 | return ret; |
2844 | } | 2949 | } |
2845 | 2950 | ||
2846 | int mv88e6xxx_phy_page_read(struct dsa_switch *ds, int port, int page, int reg) | 2951 | int mv88e6xxx_phy_page_read(struct dsa_switch *ds, int port, int page, int reg) |
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h index 5d27decc85cb..0debb9f3cf0a 100644 --- a/drivers/net/dsa/mv88e6xxx.h +++ b/drivers/net/dsa/mv88e6xxx.h | |||
@@ -542,25 +542,4 @@ extern struct dsa_switch_driver mv88e6123_switch_driver; | |||
542 | extern struct dsa_switch_driver mv88e6352_switch_driver; | 542 | extern struct dsa_switch_driver mv88e6352_switch_driver; |
543 | extern struct dsa_switch_driver mv88e6171_switch_driver; | 543 | extern struct dsa_switch_driver mv88e6171_switch_driver; |
544 | 544 | ||
545 | #define REG_READ(addr, reg) \ | ||
546 | ({ \ | ||
547 | int __ret; \ | ||
548 | \ | ||
549 | __ret = mv88e6xxx_reg_read(ds, addr, reg); \ | ||
550 | if (__ret < 0) \ | ||
551 | return __ret; \ | ||
552 | __ret; \ | ||
553 | }) | ||
554 | |||
555 | #define REG_WRITE(addr, reg, val) \ | ||
556 | ({ \ | ||
557 | int __ret; \ | ||
558 | \ | ||
559 | __ret = mv88e6xxx_reg_write(ds, addr, reg, val); \ | ||
560 | if (__ret < 0) \ | ||
561 | return __ret; \ | ||
562 | }) | ||
563 | |||
564 | |||
565 | |||
566 | #endif | 545 | #endif |