* [PATCH] wcn36xx: Disable 5GHz for wcn3610
From: Ramon Fried @ 2018-03-29 6:20 UTC (permalink / raw)
To: kvalo, loic.poulain
Cc: wcn36xx, linux-wireless, netdev, linux-kernel, Ramon Fried
wcn3610 can only operate on 2.4GHz band due to RF limitation.
If wcn36xx digital block is associated with an external IRIS
RF module, retrieve the id and disable 5GHz band in case of
wcn3610 id.
Signed-off-by: Ramon Fried <rfried@codeaurora.org>
---
drivers/net/wireless/ath/wcn36xx/main.c | 4 +++-
drivers/net/wireless/ath/wcn36xx/wcn36xx.h | 1 +
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c
index ab5be6d2c691..833531a68c95 100644
--- a/drivers/net/wireless/ath/wcn36xx/main.c
+++ b/drivers/net/wireless/ath/wcn36xx/main.c
@@ -1146,7 +1146,7 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
BIT(NL80211_IFTYPE_MESH_POINT);
wcn->hw->wiphy->bands[NL80211_BAND_2GHZ] = &wcn_band_2ghz;
- if (wcn->rf_id != RF_IRIS_WCN3620)
+ if (wcn->rf_id != RF_IRIS_WCN3610 && wcn->rf_id != RF_IRIS_WCN3620)
wcn->hw->wiphy->bands[NL80211_BAND_5GHZ] = &wcn_band_5ghz;
wcn->hw->wiphy->max_scan_ssids = WCN36XX_MAX_SCAN_SSIDS;
@@ -1248,6 +1248,8 @@ static int wcn36xx_platform_get_resources(struct wcn36xx *wcn,
if (iris_node) {
if (of_device_is_compatible(iris_node, "qcom,wcn3620"))
wcn->rf_id = RF_IRIS_WCN3620;
+ else if (of_device_is_compatible(iris_node, "qcom,wcn3610"))
+ wcn->rf_id = RF_IRIS_WCN3620;
of_node_put(iris_node);
}
diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
index 81017e6703b4..bc4d1a10d90e 100644
--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
+++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h
@@ -95,6 +95,7 @@ enum wcn36xx_ampdu_state {
#define WCN36XX_MAX_POWER(__wcn) (__wcn->hw->conf.chandef.chan->max_power)
#define RF_UNKNOWN 0x0000
+#define RF_IRIS_WCN3610 0x3610
#define RF_IRIS_WCN3620 0x3620
static inline void buff_to_be(u32 *buf, size_t len)
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply related
* Re: [RFC PATCH v2 00/14] Introducing AF_XDP support
From: Björn Töpel @ 2018-03-29 6:16 UTC (permalink / raw)
To: Eric Leblond
Cc: Karlsson, Magnus, Duyck, Alexander H, Alexander Duyck,
John Fastabend, Alexei Starovoitov, Jesper Dangaard Brouer,
Willem de Bruijn, Daniel Borkmann, Netdev, Björn Töpel,
michael.lundkvist, Brandeburg, Jesse, Singhai, Anjali,
Zhang, Qi Z, ravineet.singh
In-Reply-To: <047ba6b20383140529812e3f2579a8a2bfe1906b.camel@regit.org>
2018-03-28 23:18 GMT+02:00 Eric Leblond <eric@regit.org>:
> Hello,
>
> On Tue, 2018-03-27 at 18:59 +0200, Björn Töpel wrote:
>> From: Björn Töpel <bjorn.topel@intel.com>
>>
>>
> optimized for high performance packet processing and, in upcoming
>> patch sets, zero-copy semantics. In this v2 version, we have removed
>> all zero-copy related code in order to make it smaller, simpler and
>> hopefully more review friendly. This RFC only supports copy-mode for
>> the generic XDP path (XDP_SKB) for both RX and TX and copy-mode for
>> RX
>>
>
> ...
>>
>> How is then packets distributed between these two XSK? We have
>> introduced a new BPF map called XSKMAP (or BPF_MAP_TYPE_XSKMAP in
>> full). The user-space application can place an XSK at an arbitrary
>> place in this map. The XDP program can then redirect a packet to a
>> specific index in this map and at this point XDP validates that the
>> XSK in that map was indeed bound to that device and queue number. If
>> not, the packet is dropped. If the map is empty at that index, the
>> packet is also dropped. This also means that it is currently
>> mandatory
>> to have an XDP program loaded (and one XSK in the XSKMAP) to be able
>> to get any traffic to user space through the XSK.
>
> If I get it correctly, this feature will have to be used to bound
> multiple sockets to a single queue and the eBPF filter will be
> responsible of the load balancing. Am I correct ?
>
Exactly! The XDP program executing for a certain Rx queue will
distribute the packets to the socket(s) in the xskmap.
>> AF_XDP can operate in two different modes: XDP_SKB and XDP_DRV. If
>> the
>> driver does not have support for XDP, or XDP_SKB is explicitly chosen
> ...
>
> Thanks a lot for this work, I'm gonna try to implement this in
> Suricata.
>
Thanks for trying it out! All input is very much appreciated
(clunkiness of API, crashes...)!
Björn
> Best regards,
> --
> Eric Leblond
^ permalink raw reply
* RE: [EXT] [PATCH net-next v2 2/2] sfp/phylink: move module EEPROM ethtool access into netdev core ethtool
From: Yan Markman @ 2018-03-29 5:59 UTC (permalink / raw)
To: Florian Fainelli, netdev@vger.kernel.org
Cc: Russell King, Thomas Petazzoni, Andrew Lunn, David S. Miller,
open list, Antoine Tenart, Stefan Chulski, Maxime Chevallier,
Miquel Raynal, Marcin Wojtas, Yelena Krivosheev
In-Reply-To: <20180328224416.6981-3-f.fainelli@gmail.com>
Hi Florian
Please keep CC Yelena Krivosheev <yelena@marvell.com>
for changes with drivers/net/ethernet/marvell/mvneta.c
Thanks
Yan Markman
Tel. 05-44732819
-----Original Message-----
From: Florian Fainelli [mailto:f.fainelli@gmail.com]
Sent: Thursday, March 29, 2018 1:44 AM
To: netdev@vger.kernel.org
Cc: Russell King <rmk+kernel@armlinux.org.uk>; Florian Fainelli <f.fainelli@gmail.com>; Thomas Petazzoni <thomas.petazzoni@free-electrons.com>; Andrew Lunn <andrew@lunn.ch>; David S. Miller <davem@davemloft.net>; open list <linux-kernel@vger.kernel.org>; Antoine Tenart <antoine.tenart@bootlin.com>; Yan Markman <ymarkman@marvell.com>; Stefan Chulski <stefanc@marvell.com>; Maxime Chevallier <maxime.chevallier@bootlin.com>; Miquel Raynal <miquel.raynal@free-electrons.com>; Marcin Wojtas <mw@semihalf.com>
Subject: [EXT] [PATCH net-next v2 2/2] sfp/phylink: move module EEPROM ethtool access into netdev core ethtool
External Email
----------------------------------------------------------------------
From: Russell King <rmk+kernel@armlinux.org.uk>
Provide a pointer to the SFP bus in struct net_device, so that the ethtool module EEPROM methods can access the SFP directly, rather than needing every user to provide a hook for it.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/ethernet/marvell/mvneta.c | 18 ------------------
drivers/net/phy/phylink.c | 28 ----------------------------
drivers/net/phy/sfp-bus.c | 6 ++----
include/linux/netdevice.h | 3 +++
include/linux/phylink.h | 3 ---
net/core/ethtool.c | 7 +++++++
6 files changed, 12 insertions(+), 53 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index cd09bde55596..25ced96750bf 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -4075,22 +4075,6 @@ static int mvneta_ethtool_set_wol(struct net_device *dev,
return ret;
}
-static int mvneta_ethtool_get_module_info(struct net_device *dev,
- struct ethtool_modinfo *modinfo)
-{
- struct mvneta_port *pp = netdev_priv(dev);
-
- return phylink_ethtool_get_module_info(pp->phylink, modinfo);
-}
-
-static int mvneta_ethtool_get_module_eeprom(struct net_device *dev,
- struct ethtool_eeprom *ee, u8 *buf)
-{
- struct mvneta_port *pp = netdev_priv(dev);
-
- return phylink_ethtool_get_module_eeprom(pp->phylink, ee, buf);
-}
-
static int mvneta_ethtool_get_eee(struct net_device *dev,
struct ethtool_eee *eee)
{
@@ -4165,8 +4149,6 @@ static const struct ethtool_ops mvneta_eth_tool_ops = {
.set_link_ksettings = mvneta_ethtool_set_link_ksettings,
.get_wol = mvneta_ethtool_get_wol,
.set_wol = mvneta_ethtool_set_wol,
- .get_module_info = mvneta_ethtool_get_module_info,
- .get_module_eeprom = mvneta_ethtool_get_module_eeprom,
.get_eee = mvneta_ethtool_get_eee,
.set_eee = mvneta_ethtool_set_eee,
};
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index 9b1e4721ea3a..c582b2d7546c 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1250,34 +1250,6 @@ int phylink_ethtool_set_pauseparam(struct phylink *pl, } EXPORT_SYMBOL_GPL(phylink_ethtool_set_pauseparam);
-int phylink_ethtool_get_module_info(struct phylink *pl,
- struct ethtool_modinfo *modinfo)
-{
- int ret = -EOPNOTSUPP;
-
- WARN_ON(!lockdep_rtnl_is_held());
-
- if (pl->sfp_bus)
- ret = sfp_get_module_info(pl->sfp_bus, modinfo);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(phylink_ethtool_get_module_info);
-
-int phylink_ethtool_get_module_eeprom(struct phylink *pl,
- struct ethtool_eeprom *ee, u8 *buf)
-{
- int ret = -EOPNOTSUPP;
-
- WARN_ON(!lockdep_rtnl_is_held());
-
- if (pl->sfp_bus)
- ret = sfp_get_module_eeprom(pl->sfp_bus, ee, buf);
-
- return ret;
-}
-EXPORT_SYMBOL_GPL(phylink_ethtool_get_module_eeprom);
-
/**
* phylink_ethtool_get_eee_err() - read the energy efficient ethernet error
* counter
diff --git a/drivers/net/phy/sfp-bus.c b/drivers/net/phy/sfp-bus.c index 3d4ff5d0d2a6..0381da78d228 100644
--- a/drivers/net/phy/sfp-bus.c
+++ b/drivers/net/phy/sfp-bus.c
@@ -342,6 +342,7 @@ static int sfp_register_bus(struct sfp_bus *bus)
}
if (bus->started)
bus->socket_ops->start(bus->sfp);
+ bus->netdev->sfp_bus = bus;
bus->registered = true;
return 0;
}
@@ -356,6 +357,7 @@ static void sfp_unregister_bus(struct sfp_bus *bus)
if (bus->phydev && ops && ops->disconnect_phy)
ops->disconnect_phy(bus->upstream);
}
+ bus->netdev->sfp_bus = NULL;
bus->registered = false;
}
@@ -371,8 +373,6 @@ static void sfp_unregister_bus(struct sfp_bus *bus)
*/
int sfp_get_module_info(struct sfp_bus *bus, struct ethtool_modinfo *modinfo) {
- if (!bus->registered)
- return -ENOIOCTLCMD;
return bus->socket_ops->module_info(bus->sfp, modinfo); } EXPORT_SYMBOL_GPL(sfp_get_module_info);
@@ -391,8 +391,6 @@ EXPORT_SYMBOL_GPL(sfp_get_module_info);
int sfp_get_module_eeprom(struct sfp_bus *bus, struct ethtool_eeprom *ee,
u8 *data)
{
- if (!bus->registered)
- return -ENOIOCTLCMD;
return bus->socket_ops->module_eeprom(bus->sfp, ee, data); } EXPORT_SYMBOL_GPL(sfp_get_module_eeprom);
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 2a2d9cf50aa2..53f0cd64676b 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -58,6 +58,7 @@ struct device;
struct phy_device;
struct dsa_port;
+struct sfp_bus;
/* 802.11 specific */
struct wireless_dev;
/* 802.15.4 specific */
@@ -1662,6 +1663,7 @@ enum netdev_priv_flags {
* @priomap: XXX: need comments on this one
* @phydev: Physical device may attach itself
* for hardware timestamping
+ * @sfp_bus: attached &struct sfp_bus structure.
*
* @qdisc_tx_busylock: lockdep class annotating Qdisc->busylock spinlock
* @qdisc_running_key: lockdep class annotating Qdisc->running seqcount
@@ -1945,6 +1947,7 @@ struct net_device {
struct netprio_map __rcu *priomap;
#endif
struct phy_device *phydev;
+ struct sfp_bus *sfp_bus;
struct lock_class_key *qdisc_tx_busylock;
struct lock_class_key *qdisc_running_key;
bool proto_down;
diff --git a/include/linux/phylink.h b/include/linux/phylink.h index e95cc12030fa..50eeae025f1e 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -219,9 +219,6 @@ void phylink_ethtool_get_pauseparam(struct phylink *,
struct ethtool_pauseparam *);
int phylink_ethtool_set_pauseparam(struct phylink *,
struct ethtool_pauseparam *);
-int phylink_ethtool_get_module_info(struct phylink *, struct ethtool_modinfo *); -int phylink_ethtool_get_module_eeprom(struct phylink *,
- struct ethtool_eeprom *, u8 *);
int phylink_get_eee_err(struct phylink *); int phylink_ethtool_get_eee(struct phylink *, struct ethtool_eee *); int phylink_ethtool_set_eee(struct phylink *, struct ethtool_eee *); diff --git a/net/core/ethtool.c b/net/core/ethtool.c index bb6e498c6e3d..eb55252ca1fb 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -22,6 +22,7 @@
#include <linux/bitops.h>
#include <linux/uaccess.h>
#include <linux/vmalloc.h>
+#include <linux/sfp.h>
#include <linux/slab.h>
#include <linux/rtnetlink.h>
#include <linux/sched/signal.h>
@@ -2245,6 +2246,9 @@ static int __ethtool_get_module_info(struct net_device *dev,
const struct ethtool_ops *ops = dev->ethtool_ops;
struct phy_device *phydev = dev->phydev;
+ if (dev->sfp_bus)
+ return sfp_get_module_info(dev->sfp_bus, modinfo);
+
if (phydev && phydev->drv && phydev->drv->module_info)
return phydev->drv->module_info(phydev, modinfo);
@@ -2279,6 +2283,9 @@ static int __ethtool_get_module_eeprom(struct net_device *dev,
const struct ethtool_ops *ops = dev->ethtool_ops;
struct phy_device *phydev = dev->phydev;
+ if (dev->sfp_bus)
+ return sfp_get_module_eeprom(dev->sfp_bus, ee, data);
+
if (phydev && phydev->drv && phydev->drv->module_eeprom)
return phydev->drv->module_eeprom(phydev, ee, data);
--
2.14.1
^ permalink raw reply related
* RE: [EXT] [PATCH net-next v2 1/2] net: phy: phylink: Provide PHY interface to mac_link_{up,down}
From: Yan Markman @ 2018-03-29 5:59 UTC (permalink / raw)
To: Florian Fainelli, netdev@vger.kernel.org
Cc: Thomas Petazzoni, Andrew Lunn, David S. Miller, Russell King,
open list, Antoine Tenart, Stefan Chulski, Maxime Chevallier,
Miquel Raynal, Marcin Wojtas, Yelena Krivosheev
In-Reply-To: <20180328224416.6981-2-f.fainelli@gmail.com>
Hi Florian
Please keep CC Yelena Krivosheev <yelena@marvell.com>
for changes with drivers/net/ethernet/marvell/mvneta.c
Thanks
Yan Markman
Tel. 05-44732819
-----Original Message-----
From: Florian Fainelli [mailto:f.fainelli@gmail.com]
Sent: Thursday, March 29, 2018 1:44 AM
To: netdev@vger.kernel.org
Cc: Florian Fainelli <f.fainelli@gmail.com>; Thomas Petazzoni <thomas.petazzoni@free-electrons.com>; Andrew Lunn <andrew@lunn.ch>; David S. Miller <davem@davemloft.net>; Russell King <rmk+kernel@armlinux.org.uk>; open list <linux-kernel@vger.kernel.org>; Antoine Tenart <antoine.tenart@bootlin.com>; Yan Markman <ymarkman@marvell.com>; Stefan Chulski <stefanc@marvell.com>; Maxime Chevallier <maxime.chevallier@bootlin.com>; Miquel Raynal <miquel.raynal@free-electrons.com>; Marcin Wojtas <mw@semihalf.com>
Subject: [EXT] [PATCH net-next v2 1/2] net: phy: phylink: Provide PHY interface to mac_link_{up,down}
External Email
----------------------------------------------------------------------
In preparation for having DSA transition entirely to PHYLINK, we need to pass a PHY interface type to the mac_link_{up,down} callbacks because we may have to make decisions on that (e.g: turn on/off RGMII interfaces etc.). We do not pass an entire phylink_link_state because not all parameters (pause, duplex etc.) are defined when the link is down, only link and interface are.
Update mvneta accordingly since it currently implements phylink_mac_ops.
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
drivers/net/ethernet/marvell/mvneta.c | 4 +++-
drivers/net/phy/phylink.c | 4 +++-
include/linux/phylink.h | 14 +++++++++++---
3 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index eaa4bb80f1c9..cd09bde55596 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -3396,7 +3396,8 @@ static void mvneta_set_eee(struct mvneta_port *pp, bool enable)
mvreg_write(pp, MVNETA_LPI_CTRL_1, lpi_ctl1); }
-static void mvneta_mac_link_down(struct net_device *ndev, unsigned int mode)
+static void mvneta_mac_link_down(struct net_device *ndev, unsigned int mode,
+ phy_interface_t interface)
{
struct mvneta_port *pp = netdev_priv(ndev);
u32 val;
@@ -3415,6 +3416,7 @@ static void mvneta_mac_link_down(struct net_device *ndev, unsigned int mode) }
static void mvneta_mac_link_up(struct net_device *ndev, unsigned int mode,
+ phy_interface_t interface,
struct phy_device *phy)
{
struct mvneta_port *pp = netdev_priv(ndev); diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index 51a011a349fe..9b1e4721ea3a 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -470,10 +470,12 @@ static void phylink_resolve(struct work_struct *w)
if (link_state.link != netif_carrier_ok(ndev)) {
if (!link_state.link) {
netif_carrier_off(ndev);
- pl->ops->mac_link_down(ndev, pl->link_an_mode);
+ pl->ops->mac_link_down(ndev, pl->link_an_mode,
+ pl->phy_state.interface);
netdev_info(ndev, "Link is Down\n");
} else {
pl->ops->mac_link_up(ndev, pl->link_an_mode,
+ pl->phy_state.interface,
pl->phydev);
netif_carrier_on(ndev);
diff --git a/include/linux/phylink.h b/include/linux/phylink.h index bd137c273d38..e95cc12030fa 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -73,8 +73,10 @@ struct phylink_mac_ops {
void (*mac_config)(struct net_device *ndev, unsigned int mode,
const struct phylink_link_state *state);
void (*mac_an_restart)(struct net_device *ndev);
- void (*mac_link_down)(struct net_device *ndev, unsigned int mode);
+ void (*mac_link_down)(struct net_device *ndev, unsigned int mode,
+ phy_interface_t interface);
void (*mac_link_up)(struct net_device *ndev, unsigned int mode,
+ phy_interface_t interface,
struct phy_device *phy);
};
@@ -161,25 +163,31 @@ void mac_an_restart(struct net_device *ndev);
* mac_link_down() - take the link down
* @ndev: a pointer to a &struct net_device for the MAC.
* @mode: link autonegotiation mode
+ * @interface: link &typedef phy_interface_t mode
*
* If @mode is not an in-band negotiation mode (as defined by
* phylink_autoneg_inband()), force the link down and disable any
- * Energy Efficient Ethernet MAC configuration.
+ * Energy Efficient Ethernet MAC configuration. Interface type
+ * selection must be done in mac_config().
*/
-void mac_link_down(struct net_device *ndev, unsigned int mode);
+void mac_link_down(struct net_device *ndev, unsigned int mode,
+ phy_interface_t interface);
/**
* mac_link_up() - allow the link to come up
* @ndev: a pointer to a &struct net_device for the MAC.
* @mode: link autonegotiation mode
+ * @interface: link &typedef phy_interface_t mode
* @phy: any attached phy
*
* If @mode is not an in-band negotiation mode (as defined by
* phylink_autoneg_inband()), allow the link to come up. If @phy
* is non-%NULL, configure Energy Efficient Ethernet by calling
* phy_init_eee() and perform appropriate MAC configuration for EEE.
+ * Interface type selection must be done in mac_config().
*/
void mac_link_up(struct net_device *ndev, unsigned int mode,
+ phy_interface_t interface,
struct phy_device *phy);
#endif
--
2.14.1
^ permalink raw reply related
* RE: [EXT] [PATCH net-next v2 0/2] phylink: API changes
From: Yan Markman @ 2018-03-29 5:58 UTC (permalink / raw)
To: Florian Fainelli, netdev@vger.kernel.org
Cc: Thomas Petazzoni, Andrew Lunn, David S. Miller, Russell King,
open list, Antoine Tenart, Stefan Chulski, Maxime Chevallier,
Miquel Raynal, Marcin Wojtas, Yelena Krivosheev
In-Reply-To: <20180328224416.6981-1-f.fainelli@gmail.com>
Hi Florian
Please keep CC Yelena Krivosheev <yelena@marvell.com>
for changes with drivers/net/ethernet/marvell/mvneta.c
Thanks
Yan Markman
Tel. 05-44732819
-----Original Message-----
From: Florian Fainelli [mailto:f.fainelli@gmail.com]
Sent: Thursday, March 29, 2018 1:44 AM
To: netdev@vger.kernel.org
Cc: Florian Fainelli <f.fainelli@gmail.com>; Thomas Petazzoni <thomas.petazzoni@free-electrons.com>; Andrew Lunn <andrew@lunn.ch>; David S. Miller <davem@davemloft.net>; Russell King <rmk+kernel@armlinux.org.uk>; open list <linux-kernel@vger.kernel.org>; Antoine Tenart <antoine.tenart@bootlin.com>; Yan Markman <ymarkman@marvell.com>; Stefan Chulski <stefanc@marvell.com>; Maxime Chevallier <maxime.chevallier@bootlin.com>; Miquel Raynal <miquel.raynal@free-electrons.com>; Marcin Wojtas <mw@semihalf.com>
Subject: [EXT] [PATCH net-next v2 0/2] phylink: API changes
External Email
----------------------------------------------------------------------
Hi all,
This patch series contains two API changes to PHYLINK which will later be used by DSA to migrate to PHYLINK. Because these are API changes that impact other outstanding work (e.g: MVPP2) I would rather get them included sooner to minimize conflicts.
Thank you!
Changes in v2:
- added missing documentation to mac_link_{up,down} that the interface
must be configured in mac_config()
- added Russell's, Andrew's and my tags
Florian Fainelli (1):
net: phy: phylink: Provide PHY interface to mac_link_{up,down}
Russell King (1):
sfp/phylink: move module EEPROM ethtool access into netdev core
ethtool
drivers/net/ethernet/marvell/mvneta.c | 22 +++-------------------
drivers/net/phy/phylink.c | 32 +++-----------------------------
drivers/net/phy/sfp-bus.c | 6 ++----
include/linux/netdevice.h | 3 +++
include/linux/phylink.h | 17 +++++++++++------
net/core/ethtool.c | 7 +++++++
6 files changed, 29 insertions(+), 58 deletions(-)
--
2.14.1
^ permalink raw reply
* Re: [PATCH 2/2] rhashtable: improve rhashtable_walk stability when stop/start used.
From: Herbert Xu @ 2018-03-29 5:50 UTC (permalink / raw)
To: NeilBrown; +Cc: Thomas Graf, netdev, linux-kernel
In-Reply-To: <152228634999.16370.13957181774415446375.stgit@noble>
On Thu, Mar 29, 2018 at 12:19:10PM +1100, NeilBrown wrote:
> When a walk of an rhashtable is interrupted with rhastable_walk_stop()
> and then rhashtable_walk_start(), the location to restart from is based
> on a 'skip' count in the current hash chain, and this can be incorrect
> if insertions or deletions have happened. This does not happen when
> the walk is not stopped and started as iter->p is a placeholder which
> is safe to use while holding the RCU read lock.
>
> In rhashtable_walk_start() we can revalidate that 'p' is still in the
> same hash chain. If it isn't then the current method is still used.
>
> With this patch, if a rhashtable walker ensures that the current
> object remains in the table over a stop/start period (possibly by
> elevating the reference count if that is sufficient), it can be sure
> that a walk will not miss objects that were in the hashtable for the
> whole time of the walk.
>
> rhashtable_walk_start() may not find the object even though it is
> still in the hashtable if a rehash has moved it to a new table. In
> this case it will (eventually) get -EAGAIN and will need to proceed
> through the whole table again to be sure to see everything at least
> once.
>
> Signed-off-by: NeilBrown <neilb@suse.com>
Very nice!
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH 1/2] rhashtable: fix insertion of in rhltable when duplicate found.
From: Herbert Xu @ 2018-03-29 5:40 UTC (permalink / raw)
To: NeilBrown; +Cc: Thomas Graf, netdev, linux-kernel
In-Reply-To: <152228634995.16370.12793320017578882447.stgit@noble>
On Thu, Mar 29, 2018 at 12:19:09PM +1100, NeilBrown wrote:
> When rhltable_insert() finds an entry with the same key,
> it splices the new entry at the start of a list of entries with the
> same key.
> It stores the address of the new object in *pprev, but in general this
> is *not* the location where the match was found (though in a common
> case where the hash chain has one element, it will be).
> To fix this, pprev should be updated every time we find an object that
> doesn't match.
>
> This patch changes the behaviour for non-slow insertion in that now
> insertion happens at the end of a chain rather than at the head.
> I don't think this is an important change.
>
> Signed-off-by: NeilBrown <neilb@suse.com>
Thanks. But Paul Blakey beat you to it :)
https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/commit/?id=d3dcf8eb615537526bd42ff27a081d46d337816e
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH v3 1/2] of_net: Implement of_get_nvmem_mac_address helper
From: Mike Looijmans @ 2018-03-29 5:31 UTC (permalink / raw)
To: Florian Fainelli, netdev
Cc: linux-kernel, devicetree, andrew, robh+dt, frowand.list
In-Reply-To: <8623d20b-5a01-b2bd-39f2-900177f96595@gmail.com>
On 28-03-18 00:50, Florian Fainelli wrote:
> On 03/27/2018 02:52 AM, Mike Looijmans wrote:
>> It's common practice to store MAC addresses for network interfaces into
>> nvmem devices. However the code to actually do this in the kernel lacks,
>> so this patch adds of_get_nvmem_mac_address() for drivers to obtain the
>> address from an nvmem cell provider.
>>
>> This is particulary useful on devices where the ethernet interface cannot
>> be configured by the bootloader, for example because it's in an FPGA.
>>
>> Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
>> ---
>> Documentation/devicetree/bindings/net/ethernet.txt | 2 ++
>> drivers/of/of_net.c | 40 ++++++++++++++++++++++
>> include/linux/of_net.h | 6 ++++
>> 3 files changed, 48 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/net/ethernet.txt b/Documentation/devicetree/bindings/net/ethernet.txt
>> index 2974e63..cfc376b 100644
>> --- a/Documentation/devicetree/bindings/net/ethernet.txt
>> +++ b/Documentation/devicetree/bindings/net/ethernet.txt
>> @@ -10,6 +10,8 @@ Documentation/devicetree/bindings/phy/phy-bindings.txt.
>> the boot program; should be used in cases where the MAC address assigned to
>> the device by the boot program is different from the "local-mac-address"
>> property;
>> +- nvmem-cells: phandle, reference to an nvmem node for the MAC address;
>> +- nvmem-cell-names: string, should be "mac-address" if nvmem is to be used;
>> - max-speed: number, specifies maximum speed in Mbit/s supported by the device;
>> - max-frame-size: number, maximum transfer unit (IEEE defined MTU), rather than
>> the maximum frame size (there's contradiction in the Devicetree
>> diff --git a/drivers/of/of_net.c b/drivers/of/of_net.c
>> index d820f3e..1c5d372 100644
>> --- a/drivers/of/of_net.c
>> +++ b/drivers/of/of_net.c
>> @@ -7,6 +7,7 @@
>> */
>> #include <linux/etherdevice.h>
>> #include <linux/kernel.h>
>> +#include <linux/nvmem-consumer.h>
>> #include <linux/of_net.h>
>> #include <linux/phy.h>
>> #include <linux/export.h>
>> @@ -80,3 +81,42 @@ const void *of_get_mac_address(struct device_node *np)
>> return of_get_mac_addr(np, "address");
>> }
>> EXPORT_SYMBOL(of_get_mac_address);
>> +
>> +/**
>> + * Obtain the MAC address from an nvmem provider named 'mac-address' through
>> + * device tree.
>> + * On success, copies the new address into memory pointed to by addr and
>> + * returns 0. Returns a negative error code otherwise.
>> + * @np: Device tree node containing the nvmem-cells phandle
>> + * @addr: Pointer to receive the MAC address using ether_addr_copy()
>> + */
>> +int of_get_nvmem_mac_address(struct device_node *np, void *addr)
>> +{
>> + struct nvmem_cell *cell;
>> + const void *mac;
>> + size_t len;
>> + int ret;
>> +
>> + cell = of_nvmem_cell_get(np, "mac-address");
>> + if (IS_ERR(cell))
>> + return PTR_ERR(cell);
>> +
>> + mac = nvmem_cell_read(cell, &len);
>> +
>> + nvmem_cell_put(cell);
>> +
>> + if (IS_ERR(mac))
>> + return PTR_ERR(mac);
>> +
>> + if (len < 6 || !is_valid_ether_addr(mac)) {
>> + ret = -EINVAL;
>
> Just one nit here, can you use ETH_ALEN instead of 6? With that fixed:
>
> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
>
Ok, implemented and tested it, and v4 is on the way with that change.
Kind regards,
Mike Looijmans
System Expert
TOPIC Products
Materiaalweg 4, NL-5681 RJ Best
Postbus 440, NL-5680 AK Best
Telefoon: +31 (0) 499 33 69 79
E-mail: mike.looijmans@topicproducts.com
Website: www.topicproducts.com
Please consider the environment before printing this e-mail
^ permalink raw reply
* [PATCH v4 2/2] net: macb: Try to retrieve MAC addess from nvmem provider
From: Mike Looijmans @ 2018-03-29 5:29 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, devicetree, andrew, f.fainelli, robh+dt,
frowand.list, Mike Looijmans
In-Reply-To: <1522301389-11034-1-git-send-email-mike.looijmans@topic.nl>
Call of_get_nvmem_mac_address() to fetch the MAC address from an nvmem
cell, if one is provided in the device tree. This allows the address to
be stored in an I2C EEPROM device for example.
Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com>
---
drivers/net/ethernet/cadence/macb_main.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index e84afcf..eabe14f 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -3950,10 +3950,16 @@ static int macb_probe(struct platform_device *pdev)
dev->max_mtu = ETH_DATA_LEN;
mac = of_get_mac_address(np);
- if (mac)
+ if (mac) {
ether_addr_copy(bp->dev->dev_addr, mac);
- else
- macb_get_hwaddr(bp);
+ } else {
+ err = of_get_nvmem_mac_address(np, bp->dev->dev_addr);
+ if (err) {
+ if (err == -EPROBE_DEFER)
+ goto err_out_free_netdev;
+ macb_get_hwaddr(bp);
+ }
+ }
err = of_get_phy_mode(np);
if (err < 0) {
--
1.9.1
^ permalink raw reply related
* [PATCH v4 1/2] of_net: Implement of_get_nvmem_mac_address helper
From: Mike Looijmans @ 2018-03-29 5:29 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, devicetree, andrew, f.fainelli, robh+dt,
frowand.list, Mike Looijmans
In-Reply-To: <1522301389-11034-1-git-send-email-mike.looijmans@topic.nl>
It's common practice to store MAC addresses for network interfaces into
nvmem devices. However the code to actually do this in the kernel lacks,
so this patch adds of_get_nvmem_mac_address() for drivers to obtain the
address from an nvmem cell provider.
This is particulary useful on devices where the ethernet interface cannot
be configured by the bootloader, for example because it's in an FPGA.
Signed-off-by: Mike Looijmans <mike.looijmans@topic.nl>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
Documentation/devicetree/bindings/net/ethernet.txt | 2 ++
drivers/of/of_net.c | 40 ++++++++++++++++++++++
include/linux/of_net.h | 6 ++++
3 files changed, 48 insertions(+)
diff --git a/Documentation/devicetree/bindings/net/ethernet.txt b/Documentation/devicetree/bindings/net/ethernet.txt
index 2974e63..cfc376b 100644
--- a/Documentation/devicetree/bindings/net/ethernet.txt
+++ b/Documentation/devicetree/bindings/net/ethernet.txt
@@ -10,6 +10,8 @@ Documentation/devicetree/bindings/phy/phy-bindings.txt.
the boot program; should be used in cases where the MAC address assigned to
the device by the boot program is different from the "local-mac-address"
property;
+- nvmem-cells: phandle, reference to an nvmem node for the MAC address;
+- nvmem-cell-names: string, should be "mac-address" if nvmem is to be used;
- max-speed: number, specifies maximum speed in Mbit/s supported by the device;
- max-frame-size: number, maximum transfer unit (IEEE defined MTU), rather than
the maximum frame size (there's contradiction in the Devicetree
diff --git a/drivers/of/of_net.c b/drivers/of/of_net.c
index d820f3e..53189d4 100644
--- a/drivers/of/of_net.c
+++ b/drivers/of/of_net.c
@@ -7,6 +7,7 @@
*/
#include <linux/etherdevice.h>
#include <linux/kernel.h>
+#include <linux/nvmem-consumer.h>
#include <linux/of_net.h>
#include <linux/phy.h>
#include <linux/export.h>
@@ -80,3 +81,42 @@ const void *of_get_mac_address(struct device_node *np)
return of_get_mac_addr(np, "address");
}
EXPORT_SYMBOL(of_get_mac_address);
+
+/**
+ * Obtain the MAC address from an nvmem provider named 'mac-address' through
+ * device tree.
+ * On success, copies the new address into memory pointed to by addr and
+ * returns 0. Returns a negative error code otherwise.
+ * @np: Device tree node containing the nvmem-cells phandle
+ * @addr: Pointer to receive the MAC address using ether_addr_copy()
+ */
+int of_get_nvmem_mac_address(struct device_node *np, void *addr)
+{
+ struct nvmem_cell *cell;
+ const void *mac;
+ size_t len;
+ int ret;
+
+ cell = of_nvmem_cell_get(np, "mac-address");
+ if (IS_ERR(cell))
+ return PTR_ERR(cell);
+
+ mac = nvmem_cell_read(cell, &len);
+
+ nvmem_cell_put(cell);
+
+ if (IS_ERR(mac))
+ return PTR_ERR(mac);
+
+ if (len < ETH_ALEN || !is_valid_ether_addr(mac)) {
+ ret = -EINVAL;
+ } else {
+ ether_addr_copy(addr, mac);
+ ret = 0;
+ }
+
+ kfree(mac);
+
+ return ret;
+}
+EXPORT_SYMBOL(of_get_nvmem_mac_address);
diff --git a/include/linux/of_net.h b/include/linux/of_net.h
index 9cd72aa..90d81ee 100644
--- a/include/linux/of_net.h
+++ b/include/linux/of_net.h
@@ -13,6 +13,7 @@
struct net_device;
extern int of_get_phy_mode(struct device_node *np);
extern const void *of_get_mac_address(struct device_node *np);
+extern int of_get_nvmem_mac_address(struct device_node *np, void *addr);
extern struct net_device *of_find_net_device_by_node(struct device_node *np);
#else
static inline int of_get_phy_mode(struct device_node *np)
@@ -25,6 +26,11 @@ static inline const void *of_get_mac_address(struct device_node *np)
return NULL;
}
+static inline int of_get_nvmem_mac_address(struct device_node *np, void *addr)
+{
+ return -ENODEV;
+}
+
static inline struct net_device *of_find_net_device_by_node(struct device_node *np)
{
return NULL;
--
1.9.1
^ permalink raw reply related
* [PATCH v4 0/2] of_net: Implement of_get_nvmem_mac_address helper
From: Mike Looijmans @ 2018-03-29 5:29 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, devicetree, andrew, f.fainelli, robh+dt,
frowand.list, Mike Looijmans
In-Reply-To: <1522144346-32367-1-git-send-email-mike.looijmans@topic.nl>
Posted this as a small set now, with an (optional) second patch that shows
how the changes work and what I've used to test the code on a Topic Miami board.
I've taken the liberty to add appropriate "Acked" and "Review" tags.
v4: Replaced "6" with ETH_ALEN
v3: Add patch that implements mac in nvmem for the Cadence MACB controller
Remove the integrated of_get_mac_address call
v2: Use of_nvmem_cell_get to avoid needing the assiciated device
Use void* instead of char*
Add devicetree binding doc
Mike Looijmans (2):
of_net: Implement of_get_nvmem_mac_address helper
net: macb: Try to retrieve MAC addess from nvmem provider
Documentation/devicetree/bindings/net/ethernet.txt | 2 ++
drivers/net/ethernet/cadence/macb_main.c | 12 +++++--
drivers/of/of_net.c | 40 ++++++++++++++++++++++
include/linux/of_net.h | 6 ++++
4 files changed, 57 insertions(+), 3 deletions(-)
--
1.9.1
^ permalink raw reply
* Re: [PATCH 5/6] rhashtable: support guaranteed successful insertion.
From: Herbert Xu @ 2018-03-29 5:22 UTC (permalink / raw)
To: NeilBrown
Cc: Thomas Graf, netdev, linux-kernel, David S. Miller, Eric Dumazet
In-Reply-To: <87370j51tu.fsf@notabene.neil.brown.name>
On Thu, Mar 29, 2018 at 08:26:21AM +1100, NeilBrown wrote:
>
> I say "astronomically unlikely", you say "probability .. is extremely
> low". I think we are in agreement here.
>
> The point remains that if an error *can* be returned then I have to
> write code to handle it and test that code. I'd rather not.
You have be able to handle errors anyway because of memory allocation
failures. Ultimately if you keep inserting you will eventually
fail with ENOMEM. So I don't see the issue with an additional
error value.
> > Even if it does happen we won't fail because we will perform
> > an immediate rehash. We only fail if it happens right away
> > after the rehash (that is, at least another 16 elements have
> > been inserted and you're trying to insert a 17th element, all
> > while the new hash table has not been completely populated),
> > which means that somebody has figured out our hash secret and
> > failing in that case makes sense.
BTW, you didn't acknowledge this bit which I think is crucial to
how likely such an error is.
> I never suggested retrying, but I would have to handle it somehow. I'd
> rather not.
...
> While I have no doubt that there are hashtables where someone could try
> to attack the hash, I am quite sure there are others where is such an
> attack is meaningless - any code which could generate the required range of
> keys, could do far worse things more easily.
Our network hashtable has to be secure against adversaries. I
understand that this may not be important to your use-case. However,
given the fact that the failure would only occur if an adversary
is present and actively attacking your hash table, I don't think
it has that much of a negative effect on your use-case either.
Of course if you can reproduce the EBUSY error without your
disable_count patch or even after you have fixed the issue I
have pointed out in your disable_count patch you can still reproduce
it then that would suggest a real bug and we would need to fix it,
for everyone.
> Yes, storing a sharded count in the spinlock table does seem like an
> appropriate granularity. However that leads me to ask: why do we have
> the spinlock table? Why not bit spinlocks in the hashchain head like
> include/linux/list_bl uses?
The spinlock table predates rhashtable. Perhaps Thomas/Eric/Dave
can elucidate this.
> I don't understand how it can ever be "too late", though I appreciate
> that in some cases "sooner" is better than "later"
> If we give up on the single atomic_t counter, then we must accept that
> the number of elements could exceed any given value. The only promise
> we can provide is that it wont exceed N% of the table size for more than
> T seconds.
Sure. However, assuming we use an estimate that is hash-based,
that *should* be fairly accurate assuming that your hash function
is working in the first place. It's completely different vs.
estimating based on a per-cpu count which could be wildly inaccurate.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [PATCH][next] wil6210: fix potential null dereference of ndev before null check
From: Kalle Valo @ 2018-03-29 4:53 UTC (permalink / raw)
To: merez
Cc: Colin King, linux-wireless, wil6210, netdev, kernel-janitors,
linux-kernel
In-Reply-To: <49ef31bc36217349a4801dc2eba4735c@codeaurora.org>
merez@codeaurora.org writes:
> On 2018-03-28 20:40, Colin King wrote:
>> From: Colin Ian King <colin.king@canonical.com>
>>
>> The pointer ndev is being dereferenced before it is being null checked,
>> hence there is a potential null pointer deference. Fix this by only
>> dereferencing ndev after it has been null checked
>>
>> Detected by CoverityScan, CID#1467010 ("Dereference before null check")
>>
>> Fixes: e00243fab84b ("wil6210: infrastructure for multiple virtual
>> interfaces")
>> Signed-off-by: Colin Ian King <colin.king@canonical.com>
[...]
> Reviewed-by: Maya Erez <merez@codeaurora.org>
Maya, as you are the wil6210 maintainer you can actually use Acked-by
instead of Reviewed-by. Not that it really matters which one you use,
both of them indicate me that you have checked and agree the patch, but
wanted to point out this anyway :)
--
Kalle Valo
^ permalink raw reply
* how to disable DIFS and Backoff in 802.11 ath9k or ath5k driver
From: YIN Wei @ 2018-03-29 4:33 UTC (permalink / raw)
To: linux-wireless, netdev
Dear All,
I am a researcher on 802.11 network security. I am doing a project
where the first two stations are communicating and the third station
tries to inject an forged 802.11 ACK if the last data frame is lost.
The ACK must be arrived to the data sender before the ACK timer
expires. Therefore the third station should not wait for a DIFS and a
random backoff to send out the ACK.
I am using ath9k driver, I found two functions
ath9k_hw_set_sifs_time() and ath9k_hw_setslottime() in the Hw.c file
in the ath9k directory, which set the SIFS and backoff slot time in
the registers.. I search all the ath9k files and found no register is
for setting the DIFS. but the DIFS is can be calculated by DIFS = SIFS
+ 2 * Slot Time. Therefore I thought the wireless chips should
calculate DIFS this way. I used to believe that I solved the problem
by just setting the two registers. However,when I capture the raw
frames using the airdump-ng ( an aircrack-ng module) and found that it
takes more than 80 microseconds to appear after the data, which is
much longer than the ACK timer out. The ACK timeout is usually 30
microseconds. So the third station is forced by me to send out a
forged ACK at around 25 microsecond.
Can any one tell me whether I am doing the right way to make the third
station not follow the 802.11 backoff. any suggestion would be much
appreciated. Thank you.
Regards,
Wei
^ permalink raw reply
* Re: [Xen-devel] [PATCH v2 1/1] xen-netback: process malformed sk_buff correctly to avoid BUG_ON()
From: Dongli Zhang @ 2018-03-29 4:24 UTC (permalink / raw)
To: Eric Dumazet; +Cc: xen-devel, linux-kernel, netdev, paul.durrant, wei.liu2
In-Reply-To: <2c741a81-23b3-fa26-89b2-6c3d94b20b96@gmail.com>
Hi Eric,
On 03/29/2018 12:03 PM, Eric Dumazet wrote:
>
>
> On 03/28/2018 08:51 PM, Dongli Zhang wrote:
>> The "BUG_ON(!frag_iter)" in function xenvif_rx_next_chunk() is triggered if
>> the received sk_buff is malformed, that is, when the sk_buff has pattern
>> (skb->data_len && !skb_shinfo(skb)->nr_frags). Below is a sample call
>> stack:
>>
>> ...
>
>
>>
>> The issue is hit by xen-netback when there is bug with other networking
>> interface (e.g., dom0 physical NIC), who has generated and forwarded
>> malformed sk_buff to dom0 vifX.Y. It is possible to reproduce the issue on
>> purpose with below sample code in a kernel module:
>>
>> skb->dev = dev; // dev of vifX.Y
>> skb->len = 386;
>> skb->data_len = 352;
>> skb->tail = 98;
>> skb->end = 384;
>> skb_shinfo(skb)->nr_frags = 0;
>> dev->netdev_ops->ndo_start_xmit(skb, dev);
>>
>
> This would be a serious bug in the provider of such skb.
/nods
>
> Are you sure you do not have instead an skb with a chain of skbs ?
>
> (skb_shinfo(skb)->frag_list would be not NULL)
I am sure the skb_shinfo(skb)->frag_list is NULL.
>
> Maybe your driver is wrongly advertising NETIF_F_FRAGLIST
>
> commit 2167ca029c244901831 would be the bug origin then...
Unlike the new linux version (whose BUG_ON() does not panic the server), the
BUG_ON() in prior old kernel version would panic xen dom0 server and then people
would always blame xen paravirtual driver.
Indeed, xen-netback did not process the malformed sk_buff appropriately on rx
path. The issue is not hit with old dom0 kernel, when I am running the debug
module (as shown in below link) to generate a malformed sk_buff on purpose.
https://lists.xenproject.org/archives/html/xen-devel/2018-03/msg03176.html
Dongli Zhang
^ permalink raw reply
* Re: [PATCH net V2] vhost: correctly remove wait queue during poll failure
From: Michael S. Tsirkin @ 2018-03-29 4:20 UTC (permalink / raw)
To: Jason Wang; +Cc: kvm, virtualization, netdev, linux-kernel, Darren Kenny
In-Reply-To: <1522155052-13347-1-git-send-email-jasowang@redhat.com>
On Tue, Mar 27, 2018 at 08:50:52PM +0800, Jason Wang wrote:
> We tried to remove vq poll from wait queue, but do not check whether
> or not it was in a list before. This will lead double free. Fixing
> this by switching to use vhost_poll_stop() which zeros poll->wqh after
> removing poll from waitqueue to make sure it won't be freed twice.
>
> Cc: Darren Kenny <darren.kenny@oracle.com>
> Reported-by: syzbot+c0272972b01b872e604a@syzkaller.appspotmail.com
> Fixes: 2b8b328b61c79 ("vhost_net: handle polling errors when setting backend")
> Signed-off-by: Jason Wang <jasowang@redhat.com>
OK with this the only bug we have is where get user pages returns 0
(Reported-by: syzbot+6304bf97ef436580fede@syzkaller.appspotmail.com)
> ---
> Changes from V1:
> - tweak the commit log for to match the code
> ---
> drivers/vhost/vhost.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
> index 1b3e8d2d..5d5a9d9 100644
> --- a/drivers/vhost/vhost.c
> +++ b/drivers/vhost/vhost.c
> @@ -212,8 +212,7 @@ int vhost_poll_start(struct vhost_poll *poll, struct file *file)
> if (mask)
> vhost_poll_wakeup(&poll->wait, 0, 0, poll_to_key(mask));
> if (mask & EPOLLERR) {
> - if (poll->wqh)
> - remove_wait_queue(poll->wqh, &poll->wait);
> + vhost_poll_stop(poll);
> ret = -EINVAL;
> }
>
> --
> 2.7.4
^ permalink raw reply
* Re: [PATCH v2 1/1] xen-netback: process malformed sk_buff correctly to avoid BUG_ON()
From: Eric Dumazet @ 2018-03-29 4:03 UTC (permalink / raw)
To: Dongli Zhang, xen-devel, linux-kernel; +Cc: netdev, paul.durrant, wei.liu2
In-Reply-To: <1522295463-469-1-git-send-email-dongli.zhang@oracle.com>
On 03/28/2018 08:51 PM, Dongli Zhang wrote:
> The "BUG_ON(!frag_iter)" in function xenvif_rx_next_chunk() is triggered if
> the received sk_buff is malformed, that is, when the sk_buff has pattern
> (skb->data_len && !skb_shinfo(skb)->nr_frags). Below is a sample call
> stack:
>
>...
>
> The issue is hit by xen-netback when there is bug with other networking
> interface (e.g., dom0 physical NIC), who has generated and forwarded
> malformed sk_buff to dom0 vifX.Y. It is possible to reproduce the issue on
> purpose with below sample code in a kernel module:
>
> skb->dev = dev; // dev of vifX.Y
> skb->len = 386;
> skb->data_len = 352;
> skb->tail = 98;
> skb->end = 384;
> skb_shinfo(skb)->nr_frags = 0;
> dev->netdev_ops->ndo_start_xmit(skb, dev);
>
This would be a serious bug in the provider of such skb.
Are you sure you do not have instead an skb with a chain of skbs ?
(skb_shinfo(skb)->frag_list would be not NULL)
Maybe your driver is wrongly advertising NETIF_F_FRAGLIST
commit 2167ca029c244901831 would be the bug origin then...
^ permalink raw reply
* [PATCH v2 1/1] xen-netback: process malformed sk_buff correctly to avoid BUG_ON()
From: Dongli Zhang @ 2018-03-29 3:51 UTC (permalink / raw)
To: xen-devel, linux-kernel; +Cc: netdev, paul.durrant, wei.liu2
The "BUG_ON(!frag_iter)" in function xenvif_rx_next_chunk() is triggered if
the received sk_buff is malformed, that is, when the sk_buff has pattern
(skb->data_len && !skb_shinfo(skb)->nr_frags). Below is a sample call
stack:
[ 438.652658] ------------[ cut here ]------------
[ 438.652660] kernel BUG at drivers/net/xen-netback/rx.c:325!
[ 438.652714] invalid opcode: 0000 [#1] SMP NOPTI
[ 438.652813] CPU: 0 PID: 2492 Comm: vif1.0-q0-guest Tainted: G O 4.16.0-rc6+ #1
[ 438.652896] RIP: e030:xenvif_rx_skb+0x3c2/0x5e0 [xen_netback]
[ 438.652926] RSP: e02b:ffffc90040877dc8 EFLAGS: 00010246
[ 438.652956] RAX: 0000000000000160 RBX: 0000000000000022 RCX: 0000000000000001
[ 438.652993] RDX: ffffc900402890d0 RSI: 0000000000000000 RDI: ffffc90040889000
[ 438.653029] RBP: ffff88002b460040 R08: ffffc90040877de0 R09: 0100000000000000
[ 438.653065] R10: 0000000000007ff0 R11: 0000000000000002 R12: ffffc90040889000
[ 438.653100] R13: ffffffff80000000 R14: 0000000000000022 R15: 0000000080000000
[ 438.653149] FS: 00007f15603778c0(0000) GS:ffff880030400000(0000) knlGS:0000000000000000
[ 438.653188] CS: e033 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 438.653219] CR2: 0000000001832a08 CR3: 0000000029c12000 CR4: 0000000000042660
[ 438.653262] Call Trace:
[ 438.653284] ? xen_hypercall_event_channel_op+0xa/0x20
[ 438.653313] xenvif_rx_action+0x41/0x80 [xen_netback]
[ 438.653341] xenvif_kthread_guest_rx+0xb2/0x2a8 [xen_netback]
[ 438.653374] ? __schedule+0x352/0x700
[ 438.653398] ? wait_woken+0x80/0x80
[ 438.653421] kthread+0xf3/0x130
[ 438.653442] ? xenvif_rx_action+0x80/0x80 [xen_netback]
[ 438.653470] ? kthread_destroy_worker+0x40/0x40
[ 438.653497] ret_from_fork+0x35/0x40
The issue is hit by xen-netback when there is bug with other networking
interface (e.g., dom0 physical NIC), who has generated and forwarded
malformed sk_buff to dom0 vifX.Y. It is possible to reproduce the issue on
purpose with below sample code in a kernel module:
skb->dev = dev; // dev of vifX.Y
skb->len = 386;
skb->data_len = 352;
skb->tail = 98;
skb->end = 384;
skb_shinfo(skb)->nr_frags = 0;
dev->netdev_ops->ndo_start_xmit(skb, dev);
This patch stops processing sk_buff immediately if it is detected as
malformed, that is, pkt->frag_iter is NULL but there is still remaining
pkt->remaining_len.
Signed-off-by: Dongli Zhang <dongli.zhang@oracle.com>
---
Changed since v1:
* return XEN_NETIF_RSP_ERROR in response to netfront
drivers/net/xen-netback/rx.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/net/xen-netback/rx.c b/drivers/net/xen-netback/rx.c
index b1cf7c6..a3d8ee9 100644
--- a/drivers/net/xen-netback/rx.c
+++ b/drivers/net/xen-netback/rx.c
@@ -358,6 +358,7 @@ static void xenvif_rx_data_slot(struct xenvif_queue *queue,
{
unsigned int offset = 0;
unsigned int flags;
+ bool err = false;
do {
size_t len;
@@ -369,6 +370,15 @@ static void xenvif_rx_data_slot(struct xenvif_queue *queue,
offset += len;
pkt->remaining_len -= len;
+ if (unlikely(!pkt->frag_iter && pkt->remaining_len)) {
+ pkt->remaining_len = 0;
+ pkt->extra_count = 0;
+ err = true;
+ pr_err_ratelimited("malformed sk_buff at %s\n",
+ queue->name);
+ break;
+ }
+
} while (offset < XEN_PAGE_SIZE && pkt->remaining_len > 0);
if (pkt->remaining_len > 0)
@@ -392,7 +402,7 @@ static void xenvif_rx_data_slot(struct xenvif_queue *queue,
rsp->offset = 0;
rsp->flags = flags;
rsp->id = req->id;
- rsp->status = (s16)offset;
+ rsp->status = likely(!err) ? (s16)offset : XEN_NETIF_RSP_ERROR;
}
static void xenvif_rx_extra_slot(struct xenvif_queue *queue,
--
2.7.4
^ permalink raw reply related
* Re: [PATCH iproute2-next 0/2] more JSON support
From: David Ahern @ 2018-03-29 3:37 UTC (permalink / raw)
To: Stephen Hemminger, netdev; +Cc: Stephen Hemminger
In-Reply-To: <20180328010745.15270-1-stephen@networkplumber.org>
On 3/27/18 7:07 PM, Stephen Hemminger wrote:
> From: Stephen Hemminger <sthemmin@microsoft.com>
>
> Add JSON to ILA and L2TP display
>
> Stephen Hemminger (2):
> ip/ila: support json and color
> ip/l2tp: add JSON support
>
> ip/ipila.c | 76 +++++++++++++++---------------
> ip/ipl2tp.c | 152 ++++++++++++++++++++++++++++++++++++++++--------------------
> 2 files changed, 140 insertions(+), 88 deletions(-)
>
applied to iproute2-next. Thanks,
^ permalink raw reply
* Re: [iproute2 0/1] iproute2: add TIPC statistics support in ss
From: David Ahern @ 2018-03-29 3:30 UTC (permalink / raw)
To: GhantaKrishnamurthy MohanKrishna, tipc-discussion, jon.maloy,
maloy, ying.xue, netdev, stephen
In-Reply-To: <1521813662-9954-1-git-send-email-mohan.krishna.ghanta.krishnamurthy@ericsson.com>
On 3/23/18 8:01 AM, GhantaKrishnamurthy MohanKrishna wrote:
> The following patchset add user space TIPC socket diagnostics support
> in ss tool of iproute2. It requires the sock_diag framework
> for AF_TIPC support in the kernel, commit id: c30b70deb5f
> (tipc: implement socket diagnostics for AF_TIPC).
>
> tipc socket stats are requested with the "--tipc" option. Additional
> tipc specific info are requested with "--tipcinfo" option.
>
> This patchset is based on top of iproute2 v4.15.0-100-g4f63187
> commitid: f85adc6. It has been co-authored by
> Parthasarathy Bhuvaragan.
>
applied to iproute2-next.
^ permalink raw reply
* Re: [PATCH bpf-next 00/14] nfp: bpf: add updates, deletes, atomic ops, prandom and packet cache
From: Alexei Starovoitov @ 2018-03-29 2:45 UTC (permalink / raw)
To: Jakub Kicinski; +Cc: daniel, netdev, oss-drivers, Jan Gossens
In-Reply-To: <20180329004839.4506-1-jakub.kicinski@netronome.com>
On Wed, Mar 28, 2018 at 05:48:24PM -0700, Jakub Kicinski wrote:
> Hi!
>
> This set adds support for update and delete calls from the datapath,
> as well as XADD instructions (32 and 64 bit) and pseudo random numbers.
> The XADD support depends on verifier enforcing alignment which Daniel
> recently added. XADD uses NFP's atomic engine which requires values
> to be in big endian, therefore we need to keep track of which parts of
> the values are used as atomics and byte swap them accordingly. Pseudo
> random numbers are generated using NFP's HW pseudo random number
> generator.
>
> Jiong tackles initial implementation of packet cache, which he describes
> as follows:
>
> Memory reads on NFP would first fetch data from memory to transfer-in
> registers, then move them from transfer-in to general registers.
>
> Given NFP is rich on transfer-in registers, they could serve as memory
> cache.
>
> This patch tries to identify a sequence of packet data read (BPF_LDX) that
> are executed sequentially, then the total access range of the sequence is
> calculated and attached to each read instruction, the first instruction
> in this sequence is marked with an cache init flag so the execution of
> it would bring in the whole range of packet data for the sequence.
>
> All later packet reads in this sequence would fetch data from transfer-in
> registers directly, no need to JIT NFP memory access.
>
> Function call, non-packet-data memory read, packet write and memcpy will
> invalidate the cache and start a new cache range.
>
> Cache invalidation could be improved in the future, for example packet
> write doesn't need to invalidate the cache if the the write destination
> won't be read again.
Looks exciting.
Applied to bpf-next, thank you Jakub.
^ permalink raw reply
* Re: [PATCH] vhost-net: add time limitation for tx polling(Internet mail)
From: Jason Wang @ 2018-03-29 2:00 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: haibinzhang(张海斌), kvm@vger.kernel.org,
virtualization@lists.linux-foundation.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org,
lidongchen(陈立东),
yunfangtai(台运方)
In-Reply-To: <20180328182813-mutt-send-email-mst@kernel.org>
On 2018年03月28日 23:31, Michael S. Tsirkin wrote:
> On Wed, Mar 28, 2018 at 02:37:04PM +0800, Jason Wang wrote:
>>
>> On 2018年03月28日 12:01, haibinzhang(张海斌) wrote:
>>> On 2018年03月27日 19:26, Jason wrote
>>> On 2018年03月27日 17:12, haibinzhang wrote:
>>>>> handle_tx() will delay rx for a long time when busy tx polling udp packets
>>>>> with short length(ie: 1byte udp payload), because setting VHOST_NET_WEIGHT
>>>>> takes into account only sent-bytes but no time.
>>>> Interesting.
>>>>
>>>> Looking at vhost_can_busy_poll() it tries to poke pending vhost work and
>>>> exit the busy loop if it found one. So I believe something block the
>>>> work queuing. E.g did reverting 8241a1e466cd56e6c10472cac9c1ad4e54bc65db
>>>> fix the issue?
>>> "busy tx polling" means using netperf send udp packets with 1 bytes payload(total 47bytes frame lenght),
>>> and handle_tx() will be busy sending packets continuously.
>>>
>>>>> It's not fair for handle_rx(),
>>>>> so needs to limit max time of tx polling.
>>>>>
>>>>> ---
>>>>> drivers/vhost/net.c | 3 ++-
>>>>> 1 file changed, 2 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
>>>>> index 8139bc70ad7d..dc9218a3a75b 100644
>>>>> --- a/drivers/vhost/net.c
>>>>> +++ b/drivers/vhost/net.c
>>>>> @@ -473,6 +473,7 @@ static void handle_tx(struct vhost_net *net)
>>>>> struct socket *sock;
>>>>> struct vhost_net_ubuf_ref *uninitialized_var(ubufs);
>>>>> bool zcopy, zcopy_used;
>>>>> + unsigned long start = jiffies;
>>>> Checking jiffies is tricky, need to convert it to ms or whatever others.
>>>>
>>>>> mutex_lock(&vq->mutex);
>>>>> sock = vq->private_data;
>>>>> @@ -580,7 +581,7 @@ static void handle_tx(struct vhost_net *net)
>>>>> else
>>>>> vhost_zerocopy_signal_used(net, vq);
>>>>> vhost_net_tx_packet(net);
>>>>> - if (unlikely(total_len >= VHOST_NET_WEIGHT)) {
>>>>> + if (unlikely(total_len >= VHOST_NET_WEIGHT) || unlikely(jiffies - start >= 1)) {
>>>> How value 1 is determined here? And we need a complete test to make sure
>>>> this won't affect other use cases.
>>> We just want <1ms ping latency, but actually we are not sure what value is reasonable.
>>> We have some test results using netperf before this patch as follow,
>>>
>>> Udp payload 1byte 100bytes 1000bytes 1400bytes
>>> Ping avg latency 25ms 10ms 2ms 1.5ms
>>>
>>> What is other testcases?
>> Something like https://patchwork.kernel.org/patch/10151645/.
>>
>> Btw, you need use time_before() to properly handle jiffies overflow and I
>> would also suggest you to try something like #packets limit (e.g 64).
> Maybe a ring size?
Yes or a factor of ring size.
>
>> For long term, we definitely need more worker threads.
>>
>> Thanks
> Only helps when you have spare CPUs.
Right.
Thanks
>>>> Another thought is introduce another limit of #packets, but this need
>>>> benchmark too.
>>>>
>>>> Thanks
>>>>
>>>>> vhost_poll_queue(&vq->poll);
>>>>> break;
>>>>> }
^ permalink raw reply
* [PATCH net-next 2/2] nfp: flower: offload phys port MTU change
From: Jakub Kicinski @ 2018-03-29 1:50 UTC (permalink / raw)
To: davem; +Cc: netdev, oss-drivers, John Hurley
In-Reply-To: <20180329015007.19496-1-jakub.kicinski@netronome.com>
From: John Hurley <john.hurley@netronome.com>
Trigger a port mod message to request an MTU change on the NIC when any
physical port representor is assigned a new MTU value. The driver waits
10 msec for an ack that the FW has set the MTU. If no ack is received the
request is rejected and an appropriate warning flagged.
Rather than maintain an MTU queue per repr, one is maintained per app.
Because the MTU ndo is protected by the rtnl lock, there can never be
contention here. Portmod messages from the NIC are also protected by
rtnl so we first check if the portmod is an ack and, if so, handle outside
rtnl and the cmsg work queue.
Acks are detected by the marking of a bit in a portmod response. They are
then verfied by checking the port number and MTU value expected by the
app. If the expected MTU is 0 then no acks are currently expected.
Also, ensure that the packet headroom reserved by the flower firmware is
considered when accepting an MTU change on any repr.
Signed-off-by: John Hurley <john.hurley@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
drivers/net/ethernet/netronome/nfp/flower/cmsg.c | 41 ++++++++++-
drivers/net/ethernet/netronome/nfp/flower/cmsg.h | 4 +-
drivers/net/ethernet/netronome/nfp/flower/main.c | 87 +++++++++++++++++++++++-
drivers/net/ethernet/netronome/nfp/flower/main.h | 19 ++++++
4 files changed, 146 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c
index baaea6f1a9d8..3735c09d2112 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.c
@@ -104,7 +104,8 @@ nfp_flower_cmsg_mac_repr_add(struct sk_buff *skb, unsigned int idx,
msg->ports[idx].phys_port = phys_port;
}
-int nfp_flower_cmsg_portmod(struct nfp_repr *repr, bool carrier_ok)
+int nfp_flower_cmsg_portmod(struct nfp_repr *repr, bool carrier_ok,
+ unsigned int mtu, bool mtu_only)
{
struct nfp_flower_cmsg_portmod *msg;
struct sk_buff *skb;
@@ -118,7 +119,11 @@ int nfp_flower_cmsg_portmod(struct nfp_repr *repr, bool carrier_ok)
msg->portnum = cpu_to_be32(repr->dst->u.port_info.port_id);
msg->reserved = 0;
msg->info = carrier_ok;
- msg->mtu = cpu_to_be16(repr->netdev->mtu);
+
+ if (mtu_only)
+ msg->info |= NFP_FLOWER_CMSG_PORTMOD_MTU_CHANGE_ONLY;
+
+ msg->mtu = cpu_to_be16(mtu);
nfp_ctrl_tx(repr->app->ctrl, skb);
@@ -146,6 +151,34 @@ int nfp_flower_cmsg_portreify(struct nfp_repr *repr, bool exists)
return 0;
}
+static bool
+nfp_flower_process_mtu_ack(struct nfp_app *app, struct sk_buff *skb)
+{
+ struct nfp_flower_priv *app_priv = app->priv;
+ struct nfp_flower_cmsg_portmod *msg;
+
+ msg = nfp_flower_cmsg_get_data(skb);
+
+ if (!(msg->info & NFP_FLOWER_CMSG_PORTMOD_MTU_CHANGE_ONLY))
+ return false;
+
+ spin_lock_bh(&app_priv->mtu_conf.lock);
+ if (!app_priv->mtu_conf.requested_val ||
+ app_priv->mtu_conf.portnum != be32_to_cpu(msg->portnum) ||
+ be16_to_cpu(msg->mtu) != app_priv->mtu_conf.requested_val) {
+ /* Not an ack for requested MTU change. */
+ spin_unlock_bh(&app_priv->mtu_conf.lock);
+ return false;
+ }
+
+ app_priv->mtu_conf.ack = true;
+ app_priv->mtu_conf.requested_val = 0;
+ wake_up(&app_priv->mtu_conf.wait_q);
+ spin_unlock_bh(&app_priv->mtu_conf.lock);
+
+ return true;
+}
+
static void
nfp_flower_cmsg_portmod_rx(struct nfp_app *app, struct sk_buff *skb)
{
@@ -269,6 +302,10 @@ void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb)
/* We need to deal with stats updates from HW asap */
nfp_flower_rx_flow_stats(app, skb);
dev_consume_skb_any(skb);
+ } else if (cmsg_hdr->type == NFP_FLOWER_CMSG_TYPE_PORT_MOD &&
+ nfp_flower_process_mtu_ack(app, skb)) {
+ /* Handle MTU acks outside wq to prevent RTNL conflict. */
+ dev_consume_skb_any(skb);
} else {
skb_queue_tail(&priv->cmsg_skbs, skb);
schedule_work(&priv->cmsg_work);
diff --git a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
index 3f46d836d1b8..96bc0e33980c 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/cmsg.h
@@ -397,6 +397,7 @@ struct nfp_flower_cmsg_portmod {
};
#define NFP_FLOWER_CMSG_PORTMOD_INFO_LINK BIT(0)
+#define NFP_FLOWER_CMSG_PORTMOD_MTU_CHANGE_ONLY BIT(1)
/* NFP_FLOWER_CMSG_TYPE_PORT_REIFY */
struct nfp_flower_cmsg_portreify {
@@ -464,7 +465,8 @@ void
nfp_flower_cmsg_mac_repr_add(struct sk_buff *skb, unsigned int idx,
unsigned int nbi, unsigned int nbi_port,
unsigned int phys_port);
-int nfp_flower_cmsg_portmod(struct nfp_repr *repr, bool carrier_ok);
+int nfp_flower_cmsg_portmod(struct nfp_repr *repr, bool carrier_ok,
+ unsigned int mtu, bool mtu_only);
int nfp_flower_cmsg_portreify(struct nfp_repr *repr, bool exists);
void nfp_flower_cmsg_process_rx(struct work_struct *work);
void nfp_flower_cmsg_rx(struct nfp_app *app, struct sk_buff *skb);
diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.c b/drivers/net/ethernet/netronome/nfp/flower/main.c
index 742d6f1575b5..6357e0720f43 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/main.c
+++ b/drivers/net/ethernet/netronome/nfp/flower/main.c
@@ -52,6 +52,8 @@
#define NFP_FLOWER_ALLOWED_VER 0x0001000000010000UL
+#define NFP_FLOWER_FRAME_HEADROOM 158
+
static const char *nfp_flower_extra_cap(struct nfp_app *app, struct nfp_net *nn)
{
return "FLOWER";
@@ -157,7 +159,7 @@ nfp_flower_repr_netdev_open(struct nfp_app *app, struct nfp_repr *repr)
{
int err;
- err = nfp_flower_cmsg_portmod(repr, true);
+ err = nfp_flower_cmsg_portmod(repr, true, repr->netdev->mtu, false);
if (err)
return err;
@@ -171,7 +173,7 @@ nfp_flower_repr_netdev_stop(struct nfp_app *app, struct nfp_repr *repr)
{
netif_tx_disable(repr->netdev);
- return nfp_flower_cmsg_portmod(repr, false);
+ return nfp_flower_cmsg_portmod(repr, false, repr->netdev->mtu, false);
}
static int
@@ -521,6 +523,9 @@ static int nfp_flower_init(struct nfp_app *app)
INIT_WORK(&app_priv->cmsg_work, nfp_flower_cmsg_process_rx);
init_waitqueue_head(&app_priv->reify_wait_queue);
+ init_waitqueue_head(&app_priv->mtu_conf.wait_q);
+ spin_lock_init(&app_priv->mtu_conf.lock);
+
err = nfp_flower_metadata_init(app);
if (err)
goto err_free_app_priv;
@@ -552,6 +557,81 @@ static void nfp_flower_clean(struct nfp_app *app)
app->priv = NULL;
}
+static int
+nfp_flower_check_mtu(struct nfp_app *app, struct net_device *netdev,
+ int new_mtu)
+{
+ /* The flower fw reserves NFP_FLOWER_FRAME_HEADROOM bytes of the
+ * supported max MTU to allow for appending tunnel headers. To prevent
+ * unexpected behaviour this needs to be accounted for.
+ */
+ if (new_mtu > netdev->max_mtu - NFP_FLOWER_FRAME_HEADROOM) {
+ nfp_err(app->cpp, "New MTU (%d) is not valid\n", new_mtu);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static bool nfp_flower_check_ack(struct nfp_flower_priv *app_priv)
+{
+ bool ret;
+
+ spin_lock_bh(&app_priv->mtu_conf.lock);
+ ret = app_priv->mtu_conf.ack;
+ spin_unlock_bh(&app_priv->mtu_conf.lock);
+
+ return ret;
+}
+
+static int
+nfp_flower_repr_change_mtu(struct nfp_app *app, struct net_device *netdev,
+ int new_mtu)
+{
+ struct nfp_flower_priv *app_priv = app->priv;
+ struct nfp_repr *repr = netdev_priv(netdev);
+ int err, ack;
+
+ /* Only need to config FW for physical port MTU change. */
+ if (repr->port->type != NFP_PORT_PHYS_PORT)
+ return 0;
+
+ if (!(app_priv->flower_ext_feats & NFP_FL_NBI_MTU_SETTING)) {
+ nfp_err(app->cpp, "Physical port MTU setting not supported\n");
+ return -EINVAL;
+ }
+
+ spin_lock_bh(&app_priv->mtu_conf.lock);
+ app_priv->mtu_conf.ack = false;
+ app_priv->mtu_conf.requested_val = new_mtu;
+ app_priv->mtu_conf.portnum = repr->dst->u.port_info.port_id;
+ spin_unlock_bh(&app_priv->mtu_conf.lock);
+
+ err = nfp_flower_cmsg_portmod(repr, netif_carrier_ok(netdev), new_mtu,
+ true);
+ if (err) {
+ spin_lock_bh(&app_priv->mtu_conf.lock);
+ app_priv->mtu_conf.requested_val = 0;
+ spin_unlock_bh(&app_priv->mtu_conf.lock);
+ return err;
+ }
+
+ /* Wait for fw to ack the change. */
+ ack = wait_event_timeout(app_priv->mtu_conf.wait_q,
+ nfp_flower_check_ack(app_priv),
+ msecs_to_jiffies(10));
+
+ if (!ack) {
+ spin_lock_bh(&app_priv->mtu_conf.lock);
+ app_priv->mtu_conf.requested_val = 0;
+ spin_unlock_bh(&app_priv->mtu_conf.lock);
+ nfp_warn(app->cpp, "MTU change not verified with fw\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
static int nfp_flower_start(struct nfp_app *app)
{
return nfp_tunnel_config_start(app);
@@ -574,6 +654,9 @@ const struct nfp_app_type app_flower = {
.init = nfp_flower_init,
.clean = nfp_flower_clean,
+ .check_mtu = nfp_flower_check_mtu,
+ .repr_change_mtu = nfp_flower_repr_change_mtu,
+
.vnic_alloc = nfp_flower_vnic_alloc,
.vnic_init = nfp_flower_vnic_init,
.vnic_clean = nfp_flower_vnic_clean,
diff --git a/drivers/net/ethernet/netronome/nfp/flower/main.h b/drivers/net/ethernet/netronome/nfp/flower/main.h
index c5cebf6fb1d3..e030b3ce4510 100644
--- a/drivers/net/ethernet/netronome/nfp/flower/main.h
+++ b/drivers/net/ethernet/netronome/nfp/flower/main.h
@@ -65,6 +65,7 @@ struct nfp_app;
/* Extra features bitmap. */
#define NFP_FL_FEATS_GENEVE BIT(0)
+#define NFP_FL_NBI_MTU_SETTING BIT(1)
struct nfp_fl_mask_id {
struct circ_buf mask_id_free_list;
@@ -78,6 +79,22 @@ struct nfp_fl_stats_id {
u8 repeated_em_count;
};
+/**
+ * struct nfp_mtu_conf - manage MTU setting
+ * @portnum: NFP port number of repr with requested MTU change
+ * @requested_val: MTU value requested for repr
+ * @ack: Received ack that MTU has been correctly set
+ * @wait_q: Wait queue for MTU acknowledgements
+ * @lock: Lock for setting/reading MTU variables
+ */
+struct nfp_mtu_conf {
+ u32 portnum;
+ unsigned int requested_val;
+ bool ack;
+ wait_queue_head_t wait_q;
+ spinlock_t lock;
+};
+
/**
* struct nfp_flower_priv - Flower APP per-vNIC priv data
* @app: Back pointer to app
@@ -106,6 +123,7 @@ struct nfp_fl_stats_id {
* @reify_replies: atomically stores the number of replies received
* from firmware for repr reify
* @reify_wait_queue: wait queue for repr reify response counting
+ * @mtu_conf: Configuration of repr MTU value
*/
struct nfp_flower_priv {
struct nfp_app *app;
@@ -133,6 +151,7 @@ struct nfp_flower_priv {
struct notifier_block nfp_tun_neigh_nb;
atomic_t reify_replies;
wait_queue_head_t reify_wait_queue;
+ struct nfp_mtu_conf mtu_conf;
};
struct nfp_fl_key_ls {
--
2.16.2
^ permalink raw reply related
* [PATCH net-next 1/2] nfp: modify app MTU setting callbacks
From: Jakub Kicinski @ 2018-03-29 1:50 UTC (permalink / raw)
To: davem; +Cc: netdev, oss-drivers, John Hurley
In-Reply-To: <20180329015007.19496-1-jakub.kicinski@netronome.com>
From: John Hurley <john.hurley@netronome.com>
Rename the 'change_mtu' app callback to 'check_mtu'. This is called
whenever an MTU change is requested on a netdev. It can reject the
change but is not responsible for implementing it.
Introduce a new 'repr_change_mtu' app callback that is hit when the MTU
of a repr is to be changed. This is responsible for performing the MTU
change and verifying it.
Signed-off-by: John Hurley <john.hurley@netronome.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
---
drivers/net/ethernet/netronome/nfp/bpf/main.c | 4 ++--
drivers/net/ethernet/netronome/nfp/nfp_app.h | 25 ++++++++++++++++------
.../net/ethernet/netronome/nfp/nfp_net_common.c | 2 +-
drivers/net/ethernet/netronome/nfp/nfp_net_repr.c | 13 ++++++++++-
4 files changed, 33 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.c b/drivers/net/ethernet/netronome/nfp/bpf/main.c
index f2214101a1b5..1dc424685f4e 100644
--- a/drivers/net/ethernet/netronome/nfp/bpf/main.c
+++ b/drivers/net/ethernet/netronome/nfp/bpf/main.c
@@ -221,7 +221,7 @@ static int nfp_bpf_setup_tc(struct nfp_app *app, struct net_device *netdev,
}
static int
-nfp_bpf_change_mtu(struct nfp_app *app, struct net_device *netdev, int new_mtu)
+nfp_bpf_check_mtu(struct nfp_app *app, struct net_device *netdev, int new_mtu)
{
struct nfp_net *nn = netdev_priv(netdev);
unsigned int max_mtu;
@@ -431,7 +431,7 @@ const struct nfp_app_type app_bpf = {
.init = nfp_bpf_init,
.clean = nfp_bpf_clean,
- .change_mtu = nfp_bpf_change_mtu,
+ .check_mtu = nfp_bpf_check_mtu,
.extra_cap = nfp_bpf_extra_cap,
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_app.h b/drivers/net/ethernet/netronome/nfp/nfp_app.h
index 20546ae67909..2d9cb2528fc7 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_app.h
+++ b/drivers/net/ethernet/netronome/nfp/nfp_app.h
@@ -86,8 +86,8 @@ extern const struct nfp_app_type app_flower;
* @repr_clean: representor about to be unregistered
* @repr_open: representor netdev open callback
* @repr_stop: representor netdev stop callback
- * @change_mtu: MTU change on a netdev has been requested (veto-only, change
- * is not guaranteed to be committed)
+ * @check_mtu: MTU change request on a netdev (verify it is valid)
+ * @repr_change_mtu: MTU change request on repr (make and verify change)
* @start: start application logic
* @stop: stop application logic
* @ctrl_msg_rx: control message handler
@@ -124,8 +124,10 @@ struct nfp_app_type {
int (*repr_open)(struct nfp_app *app, struct nfp_repr *repr);
int (*repr_stop)(struct nfp_app *app, struct nfp_repr *repr);
- int (*change_mtu)(struct nfp_app *app, struct net_device *netdev,
- int new_mtu);
+ int (*check_mtu)(struct nfp_app *app, struct net_device *netdev,
+ int new_mtu);
+ int (*repr_change_mtu)(struct nfp_app *app, struct net_device *netdev,
+ int new_mtu);
int (*start)(struct nfp_app *app);
void (*stop)(struct nfp_app *app);
@@ -247,11 +249,20 @@ nfp_app_repr_clean(struct nfp_app *app, struct net_device *netdev)
}
static inline int
-nfp_app_change_mtu(struct nfp_app *app, struct net_device *netdev, int new_mtu)
+nfp_app_check_mtu(struct nfp_app *app, struct net_device *netdev, int new_mtu)
{
- if (!app || !app->type->change_mtu)
+ if (!app || !app->type->check_mtu)
return 0;
- return app->type->change_mtu(app, netdev, new_mtu);
+ return app->type->check_mtu(app, netdev, new_mtu);
+}
+
+static inline int
+nfp_app_repr_change_mtu(struct nfp_app *app, struct net_device *netdev,
+ int new_mtu)
+{
+ if (!app || !app->type->repr_change_mtu)
+ return 0;
+ return app->type->repr_change_mtu(app, netdev, new_mtu);
}
static inline int nfp_app_start(struct nfp_app *app, struct nfp_net *ctrl)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
index a05be0ab2713..43a9c207a049 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c
@@ -3066,7 +3066,7 @@ static int nfp_net_change_mtu(struct net_device *netdev, int new_mtu)
struct nfp_net_dp *dp;
int err;
- err = nfp_app_change_mtu(nn->app, netdev, new_mtu);
+ err = nfp_app_check_mtu(nn->app, netdev, new_mtu);
if (err)
return err;
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
index 619570524d2a..0cd077addb26 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_repr.c
@@ -196,8 +196,19 @@ nfp_repr_get_offload_stats(int attr_id, const struct net_device *dev,
static int nfp_repr_change_mtu(struct net_device *netdev, int new_mtu)
{
struct nfp_repr *repr = netdev_priv(netdev);
+ int err;
- return nfp_app_change_mtu(repr->app, netdev, new_mtu);
+ err = nfp_app_check_mtu(repr->app, netdev, new_mtu);
+ if (err)
+ return err;
+
+ err = nfp_app_repr_change_mtu(repr->app, netdev, new_mtu);
+ if (err)
+ return err;
+
+ netdev->mtu = new_mtu;
+
+ return 0;
}
static netdev_tx_t nfp_repr_xmit(struct sk_buff *skb, struct net_device *netdev)
--
2.16.2
^ permalink raw reply related
* [PATCH net-next 0/2] nfp: flower: handle MTU changes
From: Jakub Kicinski @ 2018-03-29 1:50 UTC (permalink / raw)
To: davem; +Cc: netdev, oss-drivers, Jakub Kicinski
Hi!
This set improves MTU handling for flower offload. The max MTU is
correctly capped and physical port MTU is communicated to the FW
(and indirectly HW).
John Hurley (2):
nfp: app: modify app MTU setting callbacks
nfp: flower: offload phys port MTU change
drivers/net/ethernet/netronome/nfp/bpf/main.c | 4 +-
drivers/net/ethernet/netronome/nfp/flower/cmsg.c | 41 +++++++++-
drivers/net/ethernet/netronome/nfp/flower/cmsg.h | 4 +-
drivers/net/ethernet/netronome/nfp/flower/main.c | 87 +++++++++++++++++++++-
drivers/net/ethernet/netronome/nfp/flower/main.h | 19 +++++
drivers/net/ethernet/netronome/nfp/nfp_app.h | 25 +++++--
.../net/ethernet/netronome/nfp/nfp_net_common.c | 2 +-
drivers/net/ethernet/netronome/nfp/nfp_net_repr.c | 13 +++-
8 files changed, 179 insertions(+), 16 deletions(-)
--
2.16.2
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox