From patchwork Tue Feb 19 23:57:02 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: 1044968 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 443yMS17g0z9sDL for ; Wed, 20 Feb 2019 10:57:08 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728832AbfBSX5G (ORCPT ); Tue, 19 Feb 2019 18:57:06 -0500 Received: from esa5.microchip.iphmx.com ([216.71.150.166]:56000 "EHLO esa5.microchip.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728164AbfBSX5G (ORCPT ); Tue, 19 Feb 2019 18:57:06 -0500 X-IronPort-AV: E=Sophos;i="5.58,388,1544511600"; d="scan'208";a="24922065" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa5.microchip.iphmx.com with ESMTP/TLS/DHE-RSA-AES256-SHA; 19 Feb 2019 16:57:06 -0700 Received: from localhost.localdomain (10.10.76.4) by chn-sv-exch03.mchp-main.com (10.10.76.49) with Microsoft SMTP Server id 14.3.352.0; Tue, 19 Feb 2019 16:57:04 -0700 From: To: Sergio Paracuellos , Andrew Lunn , Florian Fainelli , Pavel Machek CC: Tristram Ha , , Subject: [PATCH v2 net-next 3/4] net: dsa: microchip: get port link status Date: Tue, 19 Feb 2019 15:57:02 -0800 Message-ID: <1550620623-13036-4-git-send-email-Tristram.Ha@microchip.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1550620623-13036-1-git-send-email-Tristram.Ha@microchip.com> References: <1550620623-13036-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 Get port link status to know whether to read MIB counters when the link is going down. Add port_cleanup function to read MIB counters the last time as after the port is disabled the PHY is also powered down. Signed-off-by: Tristram Ha --- drivers/net/dsa/microchip/ksz9477.c | 2 ++ drivers/net/dsa/microchip/ksz_common.c | 39 ++++++++++++++++++++++++++++++++-- drivers/net/dsa/microchip/ksz_common.h | 3 +++ drivers/net/dsa/microchip/ksz_priv.h | 1 + 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c index e2d74c7..6ad28e2 100644 --- a/drivers/net/dsa/microchip/ksz9477.c +++ b/drivers/net/dsa/microchip/ksz9477.c @@ -1191,6 +1191,7 @@ static int ksz9477_setup(struct dsa_switch *ds) .setup = ksz9477_setup, .phy_read = ksz9477_phy_read16, .phy_write = ksz9477_phy_write16, + .adjust_link = ksz_adjust_link, .port_enable = ksz_enable_port, .port_disable = ksz_disable_port, .get_strings = ksz9477_get_strings, @@ -1340,6 +1341,7 @@ static void ksz9477_switch_exit(struct ksz_device *dev) .cfg_port_member = ksz9477_cfg_port_member, .flush_dyn_mac_table = ksz9477_flush_dyn_mac_table, .phy_setup = ksz9477_phy_setup, + .port_cleanup = ksz_port_cleanup, .port_setup = ksz9477_port_setup, .r_mib_cnt = ksz9477_r_mib_cnt, .r_mib_pkt = ksz9477_r_mib_pkt, diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c index 9270570..c4bb67f 100644 --- a/drivers/net/dsa/microchip/ksz_common.c +++ b/drivers/net/dsa/microchip/ksz_common.c @@ -20,6 +20,22 @@ #include "ksz_priv.h" +void ksz_port_cleanup(struct ksz_device *dev, int port) +{ + /* Read all MIB counters when the link is going down. */ + if (dev->live_ports & (1 << port)) { + struct ksz_port *p = &dev->ports[port]; + + p->read = true; + schedule_work(&dev->mib_read); + } + + /* Common code for port cleanup. */ + dev->on_ports &= ~(1 << port); + dev->live_ports &= ~(1 << port); +} +EXPORT_SYMBOL_GPL(ksz_port_cleanup); + void ksz_update_port_member(struct ksz_device *dev, int port) { struct ksz_port *p; @@ -156,6 +172,26 @@ int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val) } EXPORT_SYMBOL_GPL(ksz_phy_write16); +void ksz_adjust_link(struct dsa_switch *ds, int port, + struct phy_device *phydev) +{ + struct ksz_device *dev = ds->priv; + struct ksz_port *p = &dev->ports[port]; + + if (!phydev->link) { + /* Read all MIB counters when the link is going down. */ + if (dev->live_ports & (1 << port)) { + p->read = true; + schedule_work(&dev->mib_read); + } + dev->live_ports &= ~(1 << port); + } else { + /* Remember which port is connected and active. */ + dev->live_ports |= (1 << port) & dev->on_ports; + } +} +EXPORT_SYMBOL_GPL(ksz_adjust_link); + int ksz_sset_count(struct dsa_switch *ds, int port, int sset) { struct ksz_device *dev = ds->priv; @@ -367,8 +403,7 @@ void ksz_disable_port(struct dsa_switch *ds, int port, struct phy_device *phy) { struct ksz_device *dev = ds->priv; - dev->on_ports &= ~(1 << port); - dev->live_ports &= ~(1 << port); + dev->dev_ops->port_cleanup(dev, port); /* port_stp_state_set() will be called after to disable the port so * there is no need to do anything. diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h index 0b0ed3d..ebe6f8e 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); @@ -14,6 +15,8 @@ int ksz_phy_read16(struct dsa_switch *ds, int addr, int reg); int ksz_phy_write16(struct dsa_switch *ds, int addr, int reg, u16 val); +void ksz_adjust_link(struct dsa_switch *ds, int port, + struct phy_device *phydev); int ksz_sset_count(struct dsa_switch *ds, int port, int sset); void ksz_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *buf); int ksz_port_bridge_join(struct dsa_switch *ds, int port, diff --git a/drivers/net/dsa/microchip/ksz_priv.h b/drivers/net/dsa/microchip/ksz_priv.h index 1d2d98f..a1d84c1 100644 --- a/drivers/net/dsa/microchip/ksz_priv.h +++ b/drivers/net/dsa/microchip/ksz_priv.h @@ -137,6 +137,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);