Skip to content

Commit 2e8d243

Browse files
hjelmelanddavem330
authored andcommitted
net: dsa: lan9303: Protect ALR operations with mutex
ALR table operations are a sequence of related register operations which should be protected from concurrent access. The alr_cache should also be protected. Add alr_mutex doing that. Signed-off-by: Egil Hjelmeland <[email protected]> Reviewed-by: Andrew Lunn <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent df45bf8 commit 2e8d243

File tree

2 files changed

+13
-2
lines changed

2 files changed

+13
-2
lines changed

drivers/net/dsa/lan9303-core.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -583,6 +583,7 @@ static void lan9303_alr_loop(struct lan9303 *chip, alr_loop_cb_t *cb, void *ctx)
583583
{
584584
int i;
585585

586+
mutex_lock(&chip->alr_mutex);
586587
lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD,
587588
LAN9303_ALR_CMD_GET_FIRST);
588589
lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, 0);
@@ -606,6 +607,7 @@ static void lan9303_alr_loop(struct lan9303 *chip, alr_loop_cb_t *cb, void *ctx)
606607
LAN9303_ALR_CMD_GET_NEXT);
607608
lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, 0);
608609
}
610+
mutex_unlock(&chip->alr_mutex);
609611
}
610612

611613
static void alr_reg_to_mac(u32 dat0, u32 dat1, u8 mac[6])
@@ -694,16 +696,20 @@ static int lan9303_alr_add_port(struct lan9303 *chip, const u8 *mac, int port,
694696
{
695697
struct lan9303_alr_cache_entry *entr;
696698

699+
mutex_lock(&chip->alr_mutex);
697700
entr = lan9303_alr_cache_find_mac(chip, mac);
698701
if (!entr) { /*New entry */
699702
entr = lan9303_alr_cache_find_free(chip);
700-
if (!entr)
703+
if (!entr) {
704+
mutex_unlock(&chip->alr_mutex);
701705
return -ENOSPC;
706+
}
702707
ether_addr_copy(entr->mac_addr, mac);
703708
}
704709
entr->port_map |= BIT(port);
705710
entr->stp_override = stp_override;
706711
lan9303_alr_set_entry(chip, mac, entr->port_map, stp_override);
712+
mutex_unlock(&chip->alr_mutex);
707713

708714
return 0;
709715
}
@@ -713,15 +719,18 @@ static int lan9303_alr_del_port(struct lan9303 *chip, const u8 *mac, int port)
713719
{
714720
struct lan9303_alr_cache_entry *entr;
715721

722+
mutex_lock(&chip->alr_mutex);
716723
entr = lan9303_alr_cache_find_mac(chip, mac);
717724
if (!entr)
718-
return 0; /* no static entry found */
725+
goto out; /* no static entry found */
719726

720727
entr->port_map &= ~BIT(port);
721728
if (entr->port_map == 0) /* zero means its free again */
722729
eth_zero_addr(entr->mac_addr);
723730
lan9303_alr_set_entry(chip, mac, entr->port_map, entr->stp_override);
724731

732+
out:
733+
mutex_unlock(&chip->alr_mutex);
725734
return 0;
726735
}
727736

@@ -1323,6 +1332,7 @@ int lan9303_probe(struct lan9303 *chip, struct device_node *np)
13231332
int ret;
13241333

13251334
mutex_init(&chip->indirect_mutex);
1335+
mutex_init(&chip->alr_mutex);
13261336

13271337
lan9303_probe_reset_gpio(chip, np);
13281338

include/linux/dsa/lan9303.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ struct lan9303 {
2626
bool phy_addr_sel_strap;
2727
struct dsa_switch *ds;
2828
struct mutex indirect_mutex; /* protect indexed register access */
29+
struct mutex alr_mutex; /* protect ALR access */
2930
const struct lan9303_phy_ops *ops;
3031
bool is_bridged; /* true if port 1 and 2 are bridged */
3132

0 commit comments

Comments
 (0)