From patchwork Sat Feb 23 00:36:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tristram.Ha@microchip.com X-Patchwork-Id: 1047224 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@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=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=microchip.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 445q645G3Hz9s71 for ; Sat, 23 Feb 2019 11:37:00 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727532AbfBWAg7 (ORCPT ); Fri, 22 Feb 2019 19:36:59 -0500 Received: from esa6.microchip.iphmx.com ([216.71.154.253]:8700 "EHLO esa6.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727132AbfBWAg4 (ORCPT ); Fri, 22 Feb 2019 19:36:56 -0500 X-IronPort-AV: E=Sophos;i="5.58,401,1544511600"; d="scan'208";a="24330003" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa6.microchip.iphmx.com with ESMTP/TLS/DHE-RSA-AES256-SHA; 22 Feb 2019 17:36:56 -0700 Received: from localhost.localdomain (10.10.76.4) by chn-sv-exch07.mchp-main.com (10.10.76.108) with Microsoft SMTP Server id 14.3.352.0; Fri, 22 Feb 2019 17:36:55 -0700 From: To: Sergio Paracuellos , Andrew Lunn , Florian Fainelli , Pavel Machek CC: Tristram Ha , , Subject: [PATCH v4 net-next 5/5] net: dsa: microchip: add port_cleanup function Date: Fri, 22 Feb 2019 16:36:51 -0800 Message-ID: <1550882211-10381-6-git-send-email-Tristram.Ha@microchip.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1550882211-10381-1-git-send-email-Tristram.Ha@microchip.com> References: <1550882211-10381-1-git-send-email-Tristram.Ha@microchip.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Tristram Ha Add port_cleanup function to reset some device variables when the port is disabled. Add a mutex to make sure changing those variables is thread-safe. Signed-off-by: Tristram Ha Reviewed-by: Florian Fainelli --- drivers/net/dsa/microchip/ksz9477.c | 6 ++++++ drivers/net/dsa/microchip/ksz_common.c | 22 ++++++++++++++++++++++ drivers/net/dsa/microchip/ksz_common.h | 1 + drivers/net/dsa/microchip/ksz_priv.h | 2 ++ 4 files changed, 31 insertions(+) diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index b1b86b6..03de50e 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -450,12 +450,14 @@ static void ksz9477_port_stp_state_set(struct dsa_switch *ds, int port, break; member = dev->host_mask | p->vid_member; + mutex_lock(&dev->dev_mutex); /* Port is a member of a bridge. */ if (dev->br_member & (1 << port)) { dev->member |= (1 << port); member = dev->member; } + mutex_unlock(&dev->dev_mutex); break; case BR_STATE_BLOCKING: data |= PORT_LEARN_DISABLE; @@ -470,6 +472,7 @@ static void ksz9477_port_stp_state_set(struct dsa_switch *ds, int port, ksz_pwrite8(dev, port, P_STP_CTRL, data); p->stp_state = state; + mutex_lock(&dev->dev_mutex); if (data & PORT_RX_ENABLE) dev->rx_ports |= (1 << port); else @@ -494,6 +497,7 @@ static void ksz9477_port_stp_state_set(struct dsa_switch *ds, int port, */ if (forward != dev->member) ksz_update_port_member(dev, port); + mutex_unlock(&dev->dev_mutex); } static void ksz9477_flush_dyn_mac_table(struct ksz_device *dev, int port) @@ -1080,6 +1084,7 @@ static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port) ksz_pwrite8(dev, port, REG_PORT_XMII_CTRL_1, data8); p->phydev.duplex = 1; } + mutex_lock(&dev->dev_mutex); if (cpu_port) { member = dev->port_mask; dev->on_ports = dev->host_mask; @@ -1092,6 +1097,7 @@ static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port) if (p->phydev.link) dev->live_ports |= (1 << port); } + mutex_unlock(&dev->dev_mutex); ksz9477_cfg_port_member(dev, port, member); /* clear pending interrupts */ diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index 0589fc7..d89c977 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -20,6 +20,16 @@ #include "ksz_priv.h" +void ksz_port_cleanup(struct ksz_device *dev, int port) +{ + /* Common code for port cleanup. */ + mutex_lock(&dev->dev_mutex); + dev->on_ports &= ~(1 << port); + dev->live_ports &= ~(1 << port); + mutex_unlock(&dev->dev_mutex); +} +EXPORT_SYMBOL_GPL(ksz_port_cleanup); + void ksz_update_port_member(struct ksz_device *dev, int port) { struct ksz_port *p; @@ -151,6 +161,13 @@ void ksz_adjust_link(struct dsa_switch *ds, int port, p->read = true; schedule_work(&dev->mib_read); } + mutex_lock(&dev->dev_mutex); + if (!phydev->link) + dev->live_ports &= ~(1 << port); + else + /* Remember which port is connected and active. */ + dev->live_ports |= (1 << port) & dev->on_ports; + mutex_unlock(&dev->dev_mutex); } EXPORT_SYMBOL_GPL(ksz_adjust_link); @@ -188,7 +205,9 @@ int ksz_port_bridge_join(struct dsa_switch *ds, int port, { struct ksz_device *dev = ds->priv; + mutex_lock(&dev->dev_mutex); dev->br_member |= (1 << port); + mutex_unlock(&dev->dev_mutex); /* port_stp_state_set() will be called after to put the port in * appropriate state so there is no need to do anything. @@ -203,8 +222,10 @@ void ksz_port_bridge_leave(struct dsa_switch *ds, int port, { struct ksz_device *dev = ds->priv; + mutex_lock(&dev->dev_mutex); dev->br_member &= ~(1 << port); dev->member &= ~(1 << port); + mutex_unlock(&dev->dev_mutex); /* port_stp_state_set() will be called after to put the port in * forwarding state so there is no need to do anything. @@ -417,6 +438,7 @@ int ksz_switch_register(struct ksz_device *dev, gpiod_set_value(dev->reset_gpio, 0); } + mutex_init(&dev->dev_mutex); mutex_init(&dev->reg_mutex); mutex_init(&dev->stats_mutex); mutex_init(&dev->alu_mutex); diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index eb29bb0..0d25bc4 100644 --- a/drivers/net/dsa/microchip/ksz_common.h +++ b/drivers/net/dsa/microchip/ksz_common.h @@ -7,6 +7,7 @@ #ifndef __KSZ_COMMON_H #define __KSZ_COMMON_H +void ksz_port_cleanup(struct ksz_device *dev, int port); void ksz_update_port_member(struct ksz_device *dev, int port); void ksz_init_mib_timer(struct ksz_device *dev); diff --git a/drivers/net/dsa/microchip/ksz_priv.h b/drivers/net/dsa/microchip/ksz_priv.h index 1d2d98f..b52e5ca 100644 --- a/drivers/net/dsa/microchip/ksz_priv.h +++ b/drivers/net/dsa/microchip/ksz_priv.h @@ -48,6 +48,7 @@ struct ksz_device { struct ksz_platform_data *pdata; const char *name; + struct mutex dev_mutex; /* device access */ struct mutex reg_mutex; /* register access */ struct mutex stats_mutex; /* status access */ struct mutex alu_mutex; /* ALU access */ @@ -137,6 +138,7 @@ struct ksz_dev_ops { void (*flush_dyn_mac_table)(struct ksz_device *dev, int port); void (*phy_setup)(struct ksz_device *dev, int port, struct phy_device *phy); + void (*port_cleanup)(struct ksz_device *dev, int port); void (*port_setup)(struct ksz_device *dev, int port, bool cpu_port); void (*r_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 *val); void (*w_phy)(struct ksz_device *dev, u16 phy, u16 reg, u16 val);