From patchwork Thu Dec 7 18:56:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Egil Hjelmeland X-Patchwork-Id: 845774 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3yt4TH4hlWz9s83 for ; Fri, 8 Dec 2017 05:56:35 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752462AbdLGS4W (ORCPT ); Thu, 7 Dec 2017 13:56:22 -0500 Received: from aibo.runbox.com ([91.220.196.211]:50722 "EHLO aibo.runbox.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752078AbdLGS4V (ORCPT ); Thu, 7 Dec 2017 13:56:21 -0500 Received: from [10.9.9.210] (helo=mailfront10.runbox.com) by mailtransmit02.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1eN1LE-0005vs-AO; Thu, 07 Dec 2017 19:56:16 +0100 Received: from 93.89.113.32.ip.vitnett.no ([93.89.113.32] helo=egil-desktop.zenitelcss.com) by mailfront10.runbox.com with esmtpsa (uid:646232 ) (TLS1.2:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.82) id 1eN1L9-0006iE-4j; Thu, 07 Dec 2017 19:56:11 +0100 From: Egil Hjelmeland To: andrew@lunn.ch, vivien.didelot@savoirfairelinux.com, f.fainelli@gmail.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Egil Hjelmeland Subject: [PATCH net-next] net: dsa: lan9303: Protect ALR operations with mutex Date: Thu, 7 Dec 2017 19:56:04 +0100 Message-Id: <20171207185604.30745-1-privat@egil-hjelmeland.no> X-Mailer: git-send-email 2.14.1 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org 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 Reviewed-by: Andrew Lunn --- drivers/net/dsa/lan9303-core.c | 14 ++++++++++++-- include/linux/dsa/lan9303.h | 1 + 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c index ea59dadefb33..c1b004fa64d9 100644 --- a/drivers/net/dsa/lan9303-core.c +++ b/drivers/net/dsa/lan9303-core.c @@ -583,6 +583,7 @@ static void lan9303_alr_loop(struct lan9303 *chip, alr_loop_cb_t *cb, void *ctx) { int i; + mutex_lock(&chip->alr_mutex); lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, LAN9303_ALR_CMD_GET_FIRST); 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) LAN9303_ALR_CMD_GET_NEXT); lan9303_write_switch_reg(chip, LAN9303_SWE_ALR_CMD, 0); } + mutex_unlock(&chip->alr_mutex); } 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, { struct lan9303_alr_cache_entry *entr; + mutex_lock(&chip->alr_mutex); entr = lan9303_alr_cache_find_mac(chip, mac); if (!entr) { /*New entry */ entr = lan9303_alr_cache_find_free(chip); - if (!entr) + if (!entr) { + mutex_unlock(&chip->alr_mutex); return -ENOSPC; + } ether_addr_copy(entr->mac_addr, mac); } entr->port_map |= BIT(port); entr->stp_override = stp_override; lan9303_alr_set_entry(chip, mac, entr->port_map, stp_override); + mutex_unlock(&chip->alr_mutex); return 0; } @@ -713,15 +719,18 @@ static int lan9303_alr_del_port(struct lan9303 *chip, const u8 *mac, int port) { struct lan9303_alr_cache_entry *entr; + mutex_lock(&chip->alr_mutex); entr = lan9303_alr_cache_find_mac(chip, mac); if (!entr) - return 0; /* no static entry found */ + goto out; /* no static entry found */ entr->port_map &= ~BIT(port); if (entr->port_map == 0) /* zero means its free again */ eth_zero_addr(entr->mac_addr); lan9303_alr_set_entry(chip, mac, entr->port_map, entr->stp_override); +out: + mutex_unlock(&chip->alr_mutex); return 0; } @@ -1323,6 +1332,7 @@ int lan9303_probe(struct lan9303 *chip, struct device_node *np) int ret; mutex_init(&chip->indirect_mutex); + mutex_init(&chip->alr_mutex); lan9303_probe_reset_gpio(chip, np); diff --git a/include/linux/dsa/lan9303.h b/include/linux/dsa/lan9303.h index f48a85c377de..b6514c29563f 100644 --- a/include/linux/dsa/lan9303.h +++ b/include/linux/dsa/lan9303.h @@ -26,6 +26,7 @@ struct lan9303 { bool phy_addr_sel_strap; struct dsa_switch *ds; struct mutex indirect_mutex; /* protect indexed register access */ + struct mutex alr_mutex; /* protect ALR access */ const struct lan9303_phy_ops *ops; bool is_bridged; /* true if port 1 and 2 are bridged */