Skip to content

Commit 2d9deae

Browse files
viviendavem330
authored andcommitted
net: dsa: mv88e6xxx: rework port state setter
Apply a few non-functional changes on the port state setter: * add a dynamic debug message with state names to track changes * explicit states checking instead of assuming their numeric values * lock mutex only once when changing several port states * use bitmap macros to declare and access port_state_update_mask Signed-off-by: Vivien Didelot <[email protected]> Tested-by: Andrew Lunn <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 2a5a259 commit 2d9deae

File tree

2 files changed

+34
-22
lines changed

2 files changed

+34
-22
lines changed

drivers/net/dsa/mv88e6xxx.c

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,39 +1051,49 @@ static int _mv88e6xxx_atu_remove(struct dsa_switch *ds, u16 fid, int port,
10511051
return _mv88e6xxx_atu_move(ds, fid, port, 0x0f, static_too);
10521052
}
10531053

1054-
static int mv88e6xxx_set_port_state(struct dsa_switch *ds, int port, u8 state)
1054+
static const char * const mv88e6xxx_port_state_names[] = {
1055+
[PORT_CONTROL_STATE_DISABLED] = "Disabled",
1056+
[PORT_CONTROL_STATE_BLOCKING] = "Blocking/Listening",
1057+
[PORT_CONTROL_STATE_LEARNING] = "Learning",
1058+
[PORT_CONTROL_STATE_FORWARDING] = "Forwarding",
1059+
};
1060+
1061+
static int _mv88e6xxx_port_state(struct dsa_switch *ds, int port, u8 state)
10551062
{
1056-
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
10571063
int reg, ret = 0;
10581064
u8 oldstate;
10591065

1060-
mutex_lock(&ps->smi_mutex);
1061-
10621066
reg = _mv88e6xxx_reg_read(ds, REG_PORT(port), PORT_CONTROL);
1063-
if (reg < 0) {
1064-
ret = reg;
1065-
goto abort;
1066-
}
1067+
if (reg < 0)
1068+
return reg;
10671069

10681070
oldstate = reg & PORT_CONTROL_STATE_MASK;
1071+
10691072
if (oldstate != state) {
10701073
/* Flush forwarding database if we're moving a port
10711074
* from Learning or Forwarding state to Disabled or
10721075
* Blocking or Listening state.
10731076
*/
1074-
if (oldstate >= PORT_CONTROL_STATE_LEARNING &&
1075-
state <= PORT_CONTROL_STATE_BLOCKING) {
1077+
if ((oldstate == PORT_CONTROL_STATE_LEARNING ||
1078+
oldstate == PORT_CONTROL_STATE_FORWARDING)
1079+
&& (state == PORT_CONTROL_STATE_DISABLED ||
1080+
state == PORT_CONTROL_STATE_BLOCKING)) {
10761081
ret = _mv88e6xxx_atu_remove(ds, 0, port, false);
10771082
if (ret)
1078-
goto abort;
1083+
return ret;
10791084
}
1085+
10801086
reg = (reg & ~PORT_CONTROL_STATE_MASK) | state;
10811087
ret = _mv88e6xxx_reg_write(ds, REG_PORT(port), PORT_CONTROL,
10821088
reg);
1089+
if (ret)
1090+
return ret;
1091+
1092+
netdev_dbg(ds->ports[port], "PortState %s (was %s)\n",
1093+
mv88e6xxx_port_state_names[state],
1094+
mv88e6xxx_port_state_names[oldstate]);
10831095
}
10841096

1085-
abort:
1086-
mutex_unlock(&ps->smi_mutex);
10871097
return ret;
10881098
}
10891099

@@ -1146,13 +1156,11 @@ int mv88e6xxx_port_stp_update(struct dsa_switch *ds, int port, u8 state)
11461156
break;
11471157
}
11481158

1149-
netdev_dbg(ds->ports[port], "port state %d [%d]\n", state, stp_state);
1150-
11511159
/* mv88e6xxx_port_stp_update may be called with softirqs disabled,
11521160
* so we can not update the port state directly but need to schedule it.
11531161
*/
11541162
ps->ports[port].state = stp_state;
1155-
set_bit(port, &ps->port_state_update_mask);
1163+
set_bit(port, ps->port_state_update_mask);
11561164
schedule_work(&ps->bridge_work);
11571165

11581166
return 0;
@@ -2228,11 +2236,15 @@ static void mv88e6xxx_bridge_work(struct work_struct *work)
22282236
ps = container_of(work, struct mv88e6xxx_priv_state, bridge_work);
22292237
ds = ((struct dsa_switch *)ps) - 1;
22302238

2231-
while (ps->port_state_update_mask) {
2232-
port = __ffs(ps->port_state_update_mask);
2233-
clear_bit(port, &ps->port_state_update_mask);
2234-
mv88e6xxx_set_port_state(ds, port, ps->ports[port].state);
2235-
}
2239+
mutex_lock(&ps->smi_mutex);
2240+
2241+
for (port = 0; port < ps->num_ports; ++port)
2242+
if (test_and_clear_bit(port, ps->port_state_update_mask) &&
2243+
_mv88e6xxx_port_state(ds, port, ps->ports[port].state))
2244+
netdev_warn(ds->ports[port], "failed to update state to %s\n",
2245+
mv88e6xxx_port_state_names[ps->ports[port].state]);
2246+
2247+
mutex_unlock(&ps->smi_mutex);
22362248
}
22372249

22382250
static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)

drivers/net/dsa/mv88e6xxx.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ struct mv88e6xxx_priv_state {
426426

427427
struct mv88e6xxx_priv_port ports[DSA_MAX_PORTS];
428428

429-
unsigned long port_state_update_mask;
429+
DECLARE_BITMAP(port_state_update_mask, DSA_MAX_PORTS);
430430

431431
struct work_struct bridge_work;
432432
};

0 commit comments

Comments
 (0)