[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1537276043-20666-1-git-send-email-arjun@chelsio.com>
Date: Tue, 18 Sep 2018 18:37:23 +0530
From: Arjun Vynipadath <arjun@...lsio.com>
To: netdev@...r.kernel.org, davem@...emloft.net
Cc: dt@...lsio.com, nirranjan@...lsio.com, indranil@...lsio.com,
Arjun Vynipadath <arjun@...lsio.com>,
Casey Leedom <leedom@...lsio.com>,
Ganesh Goudar <ganeshgr@...lsio.com>
Subject: [PATCH net-next] cxgb4vf: Add ethtool private flags for changing force_link_up
Forcing link up of virtual interfaces even when physical link is down
causes packet drops and ping failures during bonding failover. Hence
adding a ethtool private flag to toggle force_link_up whenever required.
Signed-off-by: Arjun Vynipadath <arjun@...lsio.com>
Signed-off-by: Casey Leedom <leedom@...lsio.com>
Signed-off-by: Ganesh Goudar <ganeshgr@...lsio.com>
---
drivers/net/ethernet/chelsio/cxgb4vf/adapter.h | 16 +++++++
.../net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c | 54 +++++++++++++++++++++-
2 files changed, 68 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
index 5883f09..444a5c8 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/adapter.h
@@ -78,6 +78,18 @@ enum {
MAX_EGRQ = MAX_ETH_QSETS*2,
};
+enum {
+ PRIV_FLAG_PORT_FORCE_LINKUP_BIT,
+};
+
+#define PRIV_FLAG_PORT_FORCE_LINKUP \
+ BIT(PRIV_FLAG_PORT_FORCE_LINKUP_BIT)
+
+#define PRIV_FLAGS_ADAP 0x0
+#define DEFAULT_PRIV_FLAGS_ADAP 0x0
+#define PRIV_FLAGS_PORT PRIV_FLAG_PORT_FORCE_LINKUP
+#define DEFAULT_PRIV_FLAGS_PORT PRIV_FLAG_PORT_FORCE_LINKUP
+
/*
* Forward structure definition references.
*/
@@ -103,6 +115,7 @@ struct port_info {
u8 port_id; /* physical port ID */
u8 nqsets; /* # of "Queue Sets" */
u8 first_qset; /* index of first "Queue Set" */
+ u32 eth_flags; /* ethtool private flags */
struct link_config link_cfg; /* physical port configuration */
};
@@ -374,6 +387,9 @@ struct adapter {
unsigned long flags;
struct adapter_params params;
+ /* ethtool private flags */
+ u32 eth_flags;
+
/* queue and interrupt resources */
struct {
unsigned short vec;
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
index ff84791..ac10b5b 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/cxgb4vf_main.c
@@ -138,6 +138,7 @@ static struct dentry *cxgb4vf_debugfs_root;
void t4vf_os_link_changed(struct adapter *adapter, int pidx, int link_ok)
{
struct net_device *dev = adapter->port[pidx];
+ const struct port_info *pi = netdev_priv(dev);
/*
* If the port is disabled or the current recorded "link up"
@@ -153,7 +154,9 @@ void t4vf_os_link_changed(struct adapter *adapter, int pidx, int link_ok)
if (link_ok) {
const char *s;
const char *fc;
- const struct port_info *pi = netdev_priv(dev);
+
+ if (!(pi->eth_flags & PRIV_FLAG_PORT_FORCE_LINKUP))
+ netif_carrier_on(dev);
switch (pi->link_cfg.speed) {
case 100:
@@ -200,6 +203,8 @@ void t4vf_os_link_changed(struct adapter *adapter, int pidx, int link_ok)
netdev_info(dev, "link up, %s, full-duplex, %s PAUSE\n", s, fc);
} else {
+ if (!(pi->eth_flags & PRIV_FLAG_PORT_FORCE_LINKUP))
+ netif_carrier_off(dev);
netdev_info(dev, "link down\n");
}
}
@@ -283,7 +288,7 @@ static int link_start(struct net_device *dev)
* no errors in enabling vi.
*/
- if (ret == 0)
+ if (ret == 0 && (pi->eth_flags & PRIV_FLAG_PORT_FORCE_LINKUP))
netif_carrier_on(dev);
return ret;
@@ -1502,6 +1507,10 @@ static int cxgb4vf_get_fecparam(struct net_device *dev,
return 0;
}
+static const char cxgb4vf_priv_flags_strings[][ETH_GSTRING_LEN] = {
+ [PRIV_FLAG_PORT_FORCE_LINKUP_BIT] = "port_force_linkup",
+};
+
/*
* Return our driver information.
*/
@@ -1524,6 +1533,7 @@ static void cxgb4vf_get_drvinfo(struct net_device *dev,
FW_HDR_FW_VER_MINOR_G(adapter->params.dev.tprev),
FW_HDR_FW_VER_MICRO_G(adapter->params.dev.tprev),
FW_HDR_FW_VER_BUILD_G(adapter->params.dev.tprev));
+ drvinfo->n_priv_flags = ARRAY_SIZE(cxgb4vf_priv_flags_strings);
}
/*
@@ -1728,6 +1738,8 @@ static int cxgb4vf_get_sset_count(struct net_device *dev, int sset)
switch (sset) {
case ETH_SS_STATS:
return ARRAY_SIZE(stats_strings);
+ case ETH_SS_PRIV_FLAGS:
+ return ARRAY_SIZE(cxgb4vf_priv_flags_strings);
default:
return -EOPNOTSUPP;
}
@@ -1745,6 +1757,10 @@ static void cxgb4vf_get_strings(struct net_device *dev,
case ETH_SS_STATS:
memcpy(data, stats_strings, sizeof(stats_strings));
break;
+ case ETH_SS_PRIV_FLAGS:
+ memcpy(data, cxgb4vf_priv_flags_strings,
+ sizeof(cxgb4vf_priv_flags_strings));
+ break;
}
}
@@ -1868,6 +1884,36 @@ static void cxgb4vf_get_wol(struct net_device *dev,
memset(&wol->sopass, 0, sizeof(wol->sopass));
}
+static u32 cxgb4vf_get_priv_flags(struct net_device *netdev)
+{
+ struct port_info *pi = netdev_priv(netdev);
+ struct adapter *adapter = pi->adapter;
+
+ return (adapter->eth_flags | pi->eth_flags);
+}
+
+/**
+ * set_flags - set/unset specified flags if passed in new_flags
+ * @cur_flags: pointer to current flags
+ * @new_flags: new incoming flags
+ * @flags: set of flags to set/unset
+ */
+static inline void set_flags(u32 *cur_flags, u32 new_flags, u32 flags)
+{
+ *cur_flags = (*cur_flags & ~flags) | (new_flags & flags);
+}
+
+static int cxgb4vf_set_priv_flags(struct net_device *netdev, u32 flags)
+{
+ struct port_info *pi = netdev_priv(netdev);
+ struct adapter *adapter = pi->adapter;
+
+ set_flags(&adapter->eth_flags, flags, PRIV_FLAGS_ADAP);
+ set_flags(&pi->eth_flags, flags, PRIV_FLAGS_PORT);
+
+ return 0;
+}
+
/*
* TCP Segmentation Offload flags which we support.
*/
@@ -1892,6 +1938,8 @@ static const struct ethtool_ops cxgb4vf_ethtool_ops = {
.get_regs_len = cxgb4vf_get_regs_len,
.get_regs = cxgb4vf_get_regs,
.get_wol = cxgb4vf_get_wol,
+ .get_priv_flags = cxgb4vf_get_priv_flags,
+ .set_priv_flags = cxgb4vf_set_priv_flags,
};
/*
@@ -3138,6 +3186,7 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev,
dev_info(&pdev->dev,
"Using assigned MAC ACL: %pM\n", mac);
}
+ pi->eth_flags = DEFAULT_PRIV_FLAGS_PORT;
}
/* See what interrupts we'll be using. If we've been configured to
@@ -3168,6 +3217,7 @@ static int cxgb4vf_pci_probe(struct pci_dev *pdev,
}
adapter->flags |= USING_MSI;
}
+ adapter->eth_flags = DEFAULT_PRIV_FLAGS_ADAP;
/* Now that we know how many "ports" we have and what interrupt
* mechanism we're going to use, we can configure our queue resources.
--
2.3.5
Powered by blists - more mailing lists