aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Lunn <andrew@lunn.ch>2016-04-14 17:47:12 -0400
committerDavid S. Miller <davem@davemloft.net>2016-04-16 19:23:45 -0400
commit48ace4ef4c3f99ebf6f801c9a8326a4a39f31dbf (patch)
treea743037cc79c8ae42da8dcc63a5d19c2c7065e4c
parent756ca874417695f77941948a77e9b8562635cc0a (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.c13
-rw-r--r--drivers/net/dsa/mv88e6131.c41
-rw-r--r--drivers/net/dsa/mv88e6171.c16
-rw-r--r--drivers/net/dsa/mv88e6352.c15
-rw-r--r--drivers/net/dsa/mv88e6xxx.c241
-rw-r--r--drivers/net/dsa/mv88e6xxx.h21
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
74static int mv88e6123_setup(struct dsa_switch *ds) 77static 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
92static int mv88e6131_setup(struct dsa_switch *ds) 99static 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
70static int mv88e6171_setup(struct dsa_switch *ds) 74static 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
82static int mv88e6352_setup(struct dsa_switch *ds) 85static 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
181int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr) 181int 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
190int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr) 199int 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
252static int mv88e6xxx_ppu_enable(struct dsa_switch *ds) 276static 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)
2677int mv88e6xxx_setup_global(struct dsa_switch *ds) 2712int 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);
2791unlock: 2879unlock:
2792 mutex_unlock(&ps->smi_mutex); 2880 mutex_unlock(&ps->smi_mutex);
2793 2881
2794 return ret; 2882 return err;
2795} 2883}
2796 2884
2797int mv88e6xxx_switch_reset(struct dsa_switch *ds, bool ppu_active) 2885int 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;
2945unlock:
2946 mutex_unlock(&ps->smi_mutex);
2842 2947
2843 return 0; 2948 return ret;
2844} 2949}
2845 2950
2846int mv88e6xxx_phy_page_read(struct dsa_switch *ds, int port, int page, int reg) 2951int 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;
542extern struct dsa_switch_driver mv88e6352_switch_driver; 542extern struct dsa_switch_driver mv88e6352_switch_driver;
543extern struct dsa_switch_driver mv88e6171_switch_driver; 543extern 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