Commit 99343cfa authored by Horatiu Vultur's avatar Horatiu Vultur Committed by Jakub Kicinski
Browse files

net: lan966x: Fix usage of lan966x->mac_lock when entry is removed



To remove an entry to the MAC table, it is required first to setup the
entry and then issue a command for the MAC to forget the entry.
So if it happens for two threads to remove simultaneously an entry
in MAC table then it would be a race condition.
Fix this by using lan966x->mac_lock to protect the HW access.

Fixes: e18aba89 ("net: lan966x: add mactable support")
Signed-off-by: default avatarHoratiu Vultur <horatiu.vultur@microchip.com>
Reviewed-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 43243bb3
Loading
Loading
Loading
Loading
+20 −4
Original line number Diff line number Diff line
@@ -119,11 +119,13 @@ int lan966x_mac_learn(struct lan966x *lan966x, int port,
	return __lan966x_mac_learn(lan966x, port, false, mac, vid, type);
}

int lan966x_mac_forget(struct lan966x *lan966x,
static int lan966x_mac_forget_locked(struct lan966x *lan966x,
				     const unsigned char mac[ETH_ALEN],
				     unsigned int vid,
				     enum macaccess_entry_type type)
{
	lockdep_assert_held(&lan966x->mac_lock);

	lan966x_mac_select(lan966x, mac, vid);

	/* Issue a forget command */
@@ -134,6 +136,20 @@ int lan966x_mac_forget(struct lan966x *lan966x,
	return lan966x_mac_wait_for_completion(lan966x);
}

int lan966x_mac_forget(struct lan966x *lan966x,
		       const unsigned char mac[ETH_ALEN],
		       unsigned int vid,
		       enum macaccess_entry_type type)
{
	int ret;

	spin_lock(&lan966x->mac_lock);
	ret = lan966x_mac_forget_locked(lan966x, mac, vid, type);
	spin_unlock(&lan966x->mac_lock);

	return ret;
}

int lan966x_mac_cpu_learn(struct lan966x *lan966x, const char *addr, u16 vid)
{
	return lan966x_mac_learn(lan966x, PGID_CPU, addr, vid, ENTRYTYPE_LOCKED);