* [RFC net-next v2 0/5] PHY converter driver for DW xPCS IP
From: Ong Boon Leong @ 2019-08-28 17:47 UTC (permalink / raw)
To: davem, linux, mcoquelin.stm32, joabreu, f.fainelli, andrew
Cc: netdev, linux-kernel, peppe.cavallaro, alexandre.torgue,
weifeng.voon
My apology for sending RFC v1 with incorrect email for
peppe.cavallaro@st.com. Please use RFC v2 for discussion. Thanks.
Following review comment from Florian and discussion in below thread:-
https://patchwork.ozlabs.org/patch/1109777/
This RFC is to solicit feedback on the implementation of PHY converter
driver for DW xPCS and some changes in the mdiobus API to prepare for
mdio device registration during driver open() instead of probe() phase
for non-DT platform. The implementation in this Phy Converter has DT
registration for future expansion, however, it is not tested in our
current platform.
The 1st three patches involve changes in existing mdiobus API:-
1) Make mdiobus_create_device() function callable from Ethernet driver
2) Introduce new API mdiobus_get_mdio_device()
3) Add private data for struct mdio_device so that DW xPCS specific
private data can be established between the pairing Ethernet
controller for non-DT way.
The reason for changes for mdiobus_create_device() &
mdiobus_get_mdio_device() is to allow Eth driver to be able to create
mdio device for PHY converter driver when Ethernet driver open() is
called. Existing way for registering mdio device for non-DT appraoch
is through mdiobus_register_board_info() and the mdio device creation
happens inside Ethernet probe() whereby IRQ is not setup. The mdio
device registration happens in mdiobus_register() -->
mdiobus_setup_mdiodevfrom_board_info(), and it becomes an issue for
Phy Converter such as dwxpcs that requires IRQ setup before, i.e.
inside Ethernet controller open().
The 4th patch is for PHY Converter driver for DW xPCS.
Large portion of main logics of this code has been reviewed in the
past in above review thread and all review inputs have been factored.
First, the loading of PHY converter driver is through ACPI Device ID.
The current implementation also has logics for DT style, but since
we don't have such platform, we the DT implementation as place-holder
for anyone that needs in future. The DT implementation follows the
design of drivers/net/phy/xilinx_gmii2rgmii.c closely.
What is extra is setup for DW xPCS IRQ request. In current EHL & TGL
implementation, the IRQ is routed from MAC controller. For non-DT way,
the IRQ line is tied to Ethernet driver (PCI enum), and we need a
way to pass IRQ info from Ethernet driver to PHY converter driver
during the creation of mdio device. Therefore, this is the reason
for the 1st 3 patches. All the ISR does is to kick the workqueue to
process the IRQ as we cannot call mdio_read() and mdio_write() inside
ISR.
The 5th (last) patch shows how the associated PHY converter mdio device
is setup in Ethernet controller open() function and removed during
stop(). The implementation is done in stmmac pci driver.
With this implementation, now, we have dwxpcs implemented as PHY driver
and the hook from stmmac driver for non-DT style is done through
platform-specific data related to EHL & TGL when SGMII interface is
selected. The PHY converter driver will still be beneficial for other
platform that would need it and may use DT to enable the PHY converter
driver and mdio device through DT definition.
Please kindly review this RFC and provide any feedback/concern that
the community may have. Appreciate your time here.
Thanks
Boon Leong
Ong Boon Leong (5):
net: phy: make mdiobus_create_device() function callable from Eth
driver
net: phy: introduce mdiobus_get_mdio_device
net: phy: add private data to mdio_device
net: phy: introducing support for DWC xPCS logics for EHL & TGL
net: stmmac: add dwxpcs boardinfo for mdio_device registration
drivers/net/ethernet/stmicro/stmmac/Kconfig | 1 +
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 +
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 25 ++
.../net/ethernet/stmicro/stmmac/stmmac_pci.c | 45 +-
drivers/net/phy/Kconfig | 9 +
drivers/net/phy/Makefile | 1 +
drivers/net/phy/dwxpcs.c | 417 ++++++++++++++++++
drivers/net/phy/mdio_bus.c | 11 +-
include/linux/dwxpcs.h | 16 +
include/linux/mdio.h | 3 +
include/linux/phy.h | 7 +
include/linux/stmmac.h | 3 +
12 files changed, 537 insertions(+), 3 deletions(-)
create mode 100644 drivers/net/phy/dwxpcs.c
create mode 100644 include/linux/dwxpcs.h
--
2.17.0
^ permalink raw reply
* [RFC net-next v2 1/5] net: phy: make mdiobus_create_device() function callable from Eth driver
From: Ong Boon Leong @ 2019-08-28 17:47 UTC (permalink / raw)
To: davem, linux, mcoquelin.stm32, joabreu, f.fainelli, andrew
Cc: netdev, linux-kernel, peppe.cavallaro, alexandre.torgue,
weifeng.voon
In-Reply-To: <20190828174722.6726-1-boon.leong.ong@intel.com>
PHY converter and external PHY drivers depend on MDIO functions of Eth
driver and such MDIO read/write completion may fire IRQ. The ISR for MDIO
completion IRQ is done in the open() function of driver.
For PHY converter mdio driver that registers ISR event that uses MDIO
read/write function during its probe() function, the MDIO ISR should have
been performed a head of time before mdio driver probe() is called. It is
for reason as such, the mdio device creation and registration will need
to be callable from Eth driver open() function.
Why existing way to register mdio_device for PHY converter that is done
via mdiobus_register_board_info() is not feasible is the mdio device
creation and registration happens inside Eth driver probe() function,
specifically in mdiobus_setup_mdiodevfrom_board_info() that is called
by mdiobus_register().
Therefore, to fulfill the need mentioned above, we make mdiobus_create_
device() to be callable from Eth driver open().
Signed-off-by: Ong Boon Leong <boon.leong.ong@intel.com>
---
drivers/net/phy/mdio_bus.c | 5 +++--
include/linux/phy.h | 7 +++++++
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index bd04fe762056..06658d9197a1 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -338,8 +338,8 @@ static inline void of_mdiobus_link_mdiodev(struct mii_bus *mdio,
*
* Returns 0 on success or < 0 on error.
*/
-static int mdiobus_create_device(struct mii_bus *bus,
- struct mdio_board_info *bi)
+int mdiobus_create_device(struct mii_bus *bus,
+ struct mdio_board_info *bi)
{
struct mdio_device *mdiodev;
int ret = 0;
@@ -359,6 +359,7 @@ static int mdiobus_create_device(struct mii_bus *bus,
return ret;
}
+EXPORT_SYMBOL(mdiobus_create_device);
/**
* __mdiobus_register - bring up all the PHYs on a given bus and attach them to bus
diff --git a/include/linux/phy.h b/include/linux/phy.h
index d26779f1fb6b..4524db57fe0b 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -1249,12 +1249,19 @@ struct mdio_board_info {
#if IS_ENABLED(CONFIG_MDIO_DEVICE)
int mdiobus_register_board_info(const struct mdio_board_info *info,
unsigned int n);
+int mdiobus_create_device(struct mii_bus *bus, struct mdio_board_info *bi);
#else
static inline int mdiobus_register_board_info(const struct mdio_board_info *i,
unsigned int n)
{
return 0;
}
+
+static inline int mdiobus_create_device(struct mii_bus *bus,
+ struct mdio_board_info *bi)
+{
+ return 0;
+}
#endif
--
2.17.0
^ permalink raw reply related
* [RFC net-next v2 4/5] net: phy: introducing support for DWC xPCS logics for EHL & TGL
From: Ong Boon Leong @ 2019-08-28 17:47 UTC (permalink / raw)
To: davem, linux, mcoquelin.stm32, joabreu, f.fainelli, andrew
Cc: netdev, linux-kernel, peppe.cavallaro, alexandre.torgue,
weifeng.voon
In-Reply-To: <20190828174722.6726-1-boon.leong.ong@intel.com>
xPCS is DWC Ethernet Physical Coding Sublayer that can be integrated with
Ethernet MAC controller and acts as converter between GMII and SGMII. An
example is as shown below whereby DWC xPCS is integrated with DW EQoS MAC
to form GbE Controller.
<-----------------GbE Controller---------->|<--External PHY chip-->
+----------+ +----+ +---+ +--------------+
| EQoS | <-GMII->| DW |<-->|PHY| <-- SGMII --> | External GbE |
| MAC | |xPCS| |IF | | PHY Chip |
+----------+ +----+ +---+ +--------------+
^ ^ ^
| | |
+---------------------MDIO-------------------------+
xPCS is a Clause-45 MDIO Manageable Device (MMD) and supports basic
functionalities for initializing xPCS and configuring auto negotiation(AN),
loopback, link status, AN advertisement and Link Partner ability are
implemented. The implementation supports the C37 AN for 1000BASE-X and
SGMII (MAC side SGMII only).
Tested-by: Tan, Tee Min <tee.min.tan@intel.com>
Reviewed-by: Voon Weifeng <weifeng.voon@intel.com>
Reviewed-by: Kweh Hock Leong <hock.leong.kweh@intel.com>
Signed-off-by: Ong Boon Leong <boon.leong.ong@intel.com>
---
drivers/net/phy/Kconfig | 9 +
drivers/net/phy/Makefile | 1 +
drivers/net/phy/dwxpcs.c | 417 +++++++++++++++++++++++++++++++++++++++
include/linux/dwxpcs.h | 16 ++
4 files changed, 443 insertions(+)
create mode 100644 drivers/net/phy/dwxpcs.c
create mode 100644 include/linux/dwxpcs.h
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 03be30cde552..fd037f5366d8 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -364,6 +364,15 @@ config DP83867_PHY
---help---
Currently supports the DP83867 PHY.
+config DWXPCS
+ tristate "Synopsys DesignWare PCS converter driver"
+ help
+ This driver supports DW PCS IP that provides the Serial Gigabit
+ Media Independent Interface(SGMII) between Ethernet physical media
+ devices and the Gigabit Ethernet controller.
+
+ Currently tested with stmmac.
+
config FIXED_PHY
tristate "MDIO Bus/PHY emulation with fixed speed/link PHYs"
depends on PHYLIB
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index a03437e091f3..5def985ae3ca 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -70,6 +70,7 @@ obj-$(CONFIG_DP83822_PHY) += dp83822.o
obj-$(CONFIG_DP83TC811_PHY) += dp83tc811.o
obj-$(CONFIG_DP83848_PHY) += dp83848.o
obj-$(CONFIG_DP83867_PHY) += dp83867.o
+obj-$(CONFIG_DWXPCS) += dwxpcs.o
obj-$(CONFIG_FIXED_PHY) += fixed_phy.o
obj-$(CONFIG_ICPLUS_PHY) += icplus.o
obj-$(CONFIG_INTEL_XWAY_PHY) += intel-xway.o
diff --git a/drivers/net/phy/dwxpcs.c b/drivers/net/phy/dwxpcs.c
new file mode 100644
index 000000000000..f0003cec6871
--- /dev/null
+++ b/drivers/net/phy/dwxpcs.c
@@ -0,0 +1,417 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2019, Intel Corporation.
+ * DWC Ethernet Physical Coding Sublayer for GMII2SGMII Converter
+ */
+#include <linux/acpi.h>
+#include <linux/bitops.h>
+#include <linux/dwxpcs.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mdio.h>
+#include <linux/module.h>
+#include <linux/of_mdio.h>
+#include <linux/phy.h>
+
+/* XPCS MII MMD Device Addresses */
+#define XPCS_MDIO_MII_MMD MDIO_MMD_VEND2
+
+/* MII MMD registers offsets */
+#define MDIO_MII_MMD_DIGITAL_CTRL_1 0x8000 /* Digital Control 1 */
+#define MDIO_MII_MMD_AN_CTRL 0x8001 /* AN Control */
+#define MDIO_MII_MMD_AN_STAT 0x8002 /* AN Status */
+
+/* MII MMD SR AN Advertisement & Link Partner Ability are slightly
+ * different from MII_ADVERTISEMENT & MII_LPA in below fields:
+ */
+#define MDIO_MII_MMD_HD BIT(6) /* Half duplex */
+#define MDIO_MII_MMD_FD BIT(5) /* Full duplex */
+#define MDIO_MII_MMD_PSE_SHIFT 7 /* Pause Ability shift */
+#define MDIO_MII_MMD_PSE GENMASK(8, 7) /* Pause Ability */
+#define MDIO_MII_MMD_PSE_NO 0x0
+#define MDIO_MII_MMD_PSE_ASYM 0x1
+#define MDIO_MII_MMD_PSE_SYM 0x2
+#define MDIO_MII_MMD_PSE_BOTH 0x3
+
+/* Automatic Speed Mode Change for MAC side SGMII AN */
+#define MDIO_MII_MMD_DIGI_CTRL_1_MAC_AUTO_SW BIT(9)
+
+/* MII MMD AN Control defines */
+#define MDIO_MII_MMD_AN_CTRL_TX_CONFIG_SHIFT 3 /* TX Config shift */
+#define AN_CTRL_TX_CONF_PHY_SIDE_SGMII 0x1 /* PHY side SGMII mode */
+#define AN_CTRL_TX_CONF_MAC_SIDE_SGMII 0x0 /* MAC side SGMII mode */
+#define MDIO_MII_MMD_AN_CTRL_PCS_MD_SHIFT 1 /* PCS Mode shift */
+#define MDIO_MII_MMD_AN_CTRL_PCS_MD GENMASK(2, 1) /* PCS Mode */
+#define AN_CTRL_PCS_MD_C37_1000BASEX 0x0 /* C37 AN for 1000BASE-X */
+#define AN_CTRL_PCS_MD_C37_SGMII 0x2 /* C37 AN for SGMII */
+#define MDIO_MII_MMD_AN_CTRL_AN_INTR_EN BIT(0) /* AN Complete Intr Enable */
+
+/* MII MMD AN Status defines for SGMII AN Status */
+#define AN_STAT_C37_AN_CMPLT BIT(0) /* AN Complete Intr */
+#define AN_STAT_SGMII_AN_FD BIT(1) /* Full Duplex */
+#define AN_STAT_SGMII_AN_SPEED_SHIFT 2 /* AN Speed shift */
+#define AN_STAT_SGMII_AN_SPEED GENMASK(3, 2) /* AN Speed */
+#define AN_STAT_SGMII_AN_10MBPS 0x0 /* 10 Mbps */
+#define AN_STAT_SGMII_AN_100MBPS 0x1 /* 100 Mbps */
+#define AN_STAT_SGMII_AN_1000MBPS 0x2 /* 1000 Mbps */
+#define AN_STAT_SGMII_AN_LNKSTS BIT(4) /* Link Status */
+
+enum dwxpcs_state_t {
+ __DWXPCS_REMOVING,
+ __DWXPCS_TASK_SCHED,
+};
+
+struct pcs_stats {
+ int link;
+ int speed;
+ int duplex;
+};
+
+struct dwxpcs_priv {
+ struct phy_device *phy_dev;
+ struct phy_driver *phy_drv;
+ struct phy_device cached_phy_dev;
+ struct phy_driver conv_phy_drv;
+ struct mdio_device *mdiodev;
+ struct pcs_stats stats;
+ struct dwxpcs_platform_data *pdata;
+ char int_name[IFNAMSIZ];
+ unsigned long state;
+ struct workqueue_struct *int_wq;
+ struct work_struct an_task;
+};
+
+/* DW xPCS mdiobus_read and mdiobus_write helper functions */
+#define xpcs_read(dev, reg) \
+ mdiobus_read(bus, xpcs_addr, \
+ MII_ADDR_C45 | (reg) | \
+ ((dev) << MII_DEVADDR_C45_SHIFT))
+#define xpcs_write(dev, reg, val) \
+ mdiobus_write(bus, xpcs_addr, \
+ MII_ADDR_C45 | (reg) | \
+ ((dev) << MII_DEVADDR_C45_SHIFT), val)
+
+static void dwxpcs_init(struct dwxpcs_priv *priv)
+{
+ struct mii_bus *bus = priv->mdiodev->bus;
+ int xpcs_addr = priv->mdiodev->addr;
+ int pcs_mode = priv->pdata->mode;
+ int phydata;
+
+ if (pcs_mode == DWXPCS_MODE_SGMII_AN) {
+ /* For AN for SGMII mode, the settings are :-
+ * 1) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 10b (SGMII AN)
+ * 2) VR_MII_AN_CTRL Bit(3) [TX_CONFIG] = 0b (MAC side SGMII)
+ * DW xPCS used with DW EQoS MAC is always MAC
+ * side SGMII.
+ * 3) VR_MII_AN_CTRL Bit(0) [AN_INTR_EN] = 1b (AN Interrupt
+ * enabled)
+ * 4) VR_MII_DIG_CTRL1 Bit(9) [MAC_AUTO_SW] = 1b (Automatic
+ * speed/duplex mode change by HW after SGMII AN complete)
+ * Note: Since it is MAC side SGMII, there is no need to set
+ * SR_MII_AN_ADV. MAC side SGMII receives AN Tx Config
+ * from PHY about the link state change after C28 AN
+ * is completed between PHY and Link Partner.
+ */
+ phydata = xpcs_read(XPCS_MDIO_MII_MMD, MDIO_MII_MMD_AN_CTRL);
+ phydata &= ~MDIO_MII_MMD_AN_CTRL_PCS_MD;
+
+ phydata |= MDIO_MII_MMD_AN_CTRL_AN_INTR_EN |
+ (AN_CTRL_PCS_MD_C37_SGMII <<
+ MDIO_MII_MMD_AN_CTRL_PCS_MD_SHIFT &
+ MDIO_MII_MMD_AN_CTRL_PCS_MD) |
+ (AN_CTRL_TX_CONF_MAC_SIDE_SGMII <<
+ MDIO_MII_MMD_AN_CTRL_TX_CONFIG_SHIFT);
+ xpcs_write(XPCS_MDIO_MII_MMD, MDIO_MII_MMD_AN_CTRL, phydata);
+
+ phydata = xpcs_read(XPCS_MDIO_MII_MMD,
+ MDIO_MII_MMD_DIGITAL_CTRL_1);
+ phydata |= MDIO_MII_MMD_DIGI_CTRL_1_MAC_AUTO_SW;
+ xpcs_write(XPCS_MDIO_MII_MMD, MDIO_MII_MMD_DIGITAL_CTRL_1,
+ phydata);
+ } else {
+ /* For AN for 1000BASE-X mode, the settings are :-
+ * 1) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 00b (1000BASE-X C37)
+ * 2) VR_MII_AN_CTRL Bit(0) [AN_INTR_EN] = 1b (AN Interrupt
+ * enabled)
+ * 3) SR_MII_AN_ADV Bit(6)[FD] = 1b (Full Duplex)
+ * Note: Half Duplex is rarely used, so don't advertise.
+ * 4) SR_MII_AN_ADV Bit(8:7)[PSE] = 11b (Sym & Asym Pause)
+ */
+ phydata = xpcs_read(XPCS_MDIO_MII_MMD, MDIO_MII_MMD_AN_CTRL);
+ phydata &= ~MDIO_MII_MMD_AN_CTRL_PCS_MD;
+ phydata |= MDIO_MII_MMD_AN_CTRL_AN_INTR_EN |
+ (AN_CTRL_PCS_MD_C37_1000BASEX <<
+ MDIO_MII_MMD_AN_CTRL_PCS_MD_SHIFT &
+ MDIO_MII_MMD_AN_CTRL_PCS_MD);
+ xpcs_write(XPCS_MDIO_MII_MMD, MDIO_MII_MMD_AN_CTRL, phydata);
+
+ phydata = xpcs_read(XPCS_MDIO_MII_MMD, MII_ADVERTISE);
+ phydata |= MDIO_MII_MMD_FD |
+ (MDIO_MII_MMD_PSE_BOTH << MDIO_MII_MMD_PSE_SHIFT);
+ xpcs_write(XPCS_MDIO_MII_MMD, MII_ADVERTISE, phydata);
+ }
+}
+
+static int dwxpcs_read_status(struct phy_device *phydev)
+{
+ struct dwxpcs_priv *priv = (struct dwxpcs_priv *)phydev->priv;
+ struct mii_bus *bus = priv->mdiodev->bus;
+ int xpcs_addr = priv->mdiodev->addr;
+ int pcs_mode = priv->pdata->mode;
+ int phydata;
+ int err;
+
+ if (priv->phy_drv->read_status)
+ err = priv->phy_drv->read_status(phydev);
+ else
+ err = genphy_read_status(phydev);
+
+ if (err < 0)
+ return err;
+
+ /* For SGMII AN, we are done as the speed/duplex are automatically
+ * set because we have initialized 'MAC_AUTO_SW' for MAC side SGMII.
+ */
+ if (pcs_mode == DWXPCS_MODE_1000BASEX_AN) {
+ /* For 1000BASE-X AN, we need to adjust duplex mode according
+ * to link partner. No need to update speed as it is always
+ * 1000Mbps.
+ */
+ phydata = xpcs_read(XPCS_MDIO_MII_MMD, MII_BMCR);
+ phydata &= ~BMCR_FULLDPLX;
+ phydata |= phydev->duplex ? BMCR_FULLDPLX : 0;
+ xpcs_write(XPCS_MDIO_MII_MMD, MII_BMCR, phydata);
+ }
+
+ return 0;
+}
+
+static void dwxpcs_get_linkstatus(struct dwxpcs_priv *priv, int an_stat)
+{
+ struct mii_bus *bus = priv->mdiodev->bus;
+ struct pcs_stats *stats = &priv->stats;
+ int xpcs_addr = priv->mdiodev->addr;
+ int pcs_mode = priv->pdata->mode;
+
+ if (pcs_mode == DWXPCS_MODE_SGMII_AN) {
+ /* Check the SGMII AN link status */
+ if (an_stat & AN_STAT_SGMII_AN_LNKSTS) {
+ int speed_value;
+
+ stats->link = 1;
+
+ speed_value = ((an_stat & AN_STAT_SGMII_AN_SPEED) >>
+ AN_STAT_SGMII_AN_SPEED_SHIFT);
+ if (speed_value == AN_STAT_SGMII_AN_1000MBPS)
+ stats->speed = SPEED_1000;
+ else if (speed_value == AN_STAT_SGMII_AN_100MBPS)
+ stats->speed = SPEED_100;
+ else
+ stats->speed = SPEED_10;
+
+ if (an_stat & AN_STAT_SGMII_AN_FD)
+ stats->duplex = 1;
+ else
+ stats->duplex = 0;
+ } else {
+ stats->link = 0;
+ }
+ } else if (pcs_mode == DWXPCS_MODE_1000BASEX_AN) {
+ /* For 1000BASE-X AN, 1000BASE-X is always 1000Mbps.
+ * For duplex mode, we read from BMCR_FULLDPLX which is
+ * only valid if BMCR_ANENABLE is not enabeld.
+ */
+ int phydata = xpcs_read(XPCS_MDIO_MII_MMD, MII_BMCR);
+
+ stats->link = 1;
+ stats->speed = SPEED_1000;
+ if (!(phydata & BMCR_ANENABLE))
+ stats->duplex = phydata & BMCR_FULLDPLX ? 1 : 0;
+ }
+}
+
+static void dwxpcs_irq_handle(struct dwxpcs_priv *priv)
+{
+ struct mii_bus *bus = priv->mdiodev->bus;
+ struct device *dev = &priv->mdiodev->dev;
+ int xpcs_addr = priv->mdiodev->addr;
+ int an_stat;
+
+ /* AN status */
+ an_stat = xpcs_read(XPCS_MDIO_MII_MMD, MDIO_MII_MMD_AN_STAT);
+
+ if (an_stat & AN_STAT_C37_AN_CMPLT) {
+ struct pcs_stats *stats = &priv->stats;
+
+ dwxpcs_get_linkstatus(priv, an_stat);
+
+ /* Clear C37 AN complete status by writing zero */
+ xpcs_write(XPCS_MDIO_MII_MMD, MDIO_MII_MMD_AN_STAT, 0);
+
+ dev_info(dev, "%s: Link = %d - %d/%s\n",
+ __func__,
+ stats->link,
+ stats->speed,
+ stats->duplex ? "Full" : "Half");
+ }
+}
+
+static void dwxpcs_an_task(struct work_struct *work)
+{
+ struct dwxpcs_priv *priv = container_of(work,
+ struct dwxpcs_priv,
+ an_task);
+ dwxpcs_irq_handle(priv);
+
+ clear_bit(__DWXPCS_TASK_SCHED, &priv->state);
+}
+
+static irqreturn_t dwxpcs_interrupt(int irq, void *dev_id)
+{
+ struct dwxpcs_priv *priv = (struct dwxpcs_priv *)dev_id;
+
+ /* Handle the clearing of AN status outside of interrupt context
+ * as it involves mdiobus_read() & mdiobus_write().
+ */
+ if (!test_bit(__DWXPCS_REMOVING, &priv->state) &&
+ !test_and_set_bit(__DWXPCS_TASK_SCHED, &priv->state)) {
+ queue_work(priv->int_wq, &priv->an_task);
+
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+#ifdef CONFIG_ACPI
+static const struct acpi_device_id dwxpcs_acpi_match[] = {
+ { "INTC1033" }, /* EHL Ethernet PCS */
+ { "INTC1034" }, /* TGL Ethernet PCS */
+ { },
+};
+
+MODULE_DEVICE_TABLE(acpi, dwxpcs_acpi_match);
+#endif // CONFIG_ACPI
+
+static int dwxpcs_probe(struct mdio_device *mdiodev)
+{
+ struct device_node *phy_node;
+ struct dwxpcs_priv *priv;
+ struct device_node *np;
+ struct device *dev;
+ int ret;
+
+ dev = &mdiodev->dev;
+ np = dev->of_node;
+
+ priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ if (np) {
+ /* Handle mdio_device registered through devicetree */
+ phy_node = of_parse_phandle(np, "phy-handle", 0);
+ if (!phy_node) {
+ dev_err(dev, "Couldn't parse phy-handle\n");
+ return -ENODEV;
+ }
+
+ priv->phy_dev = of_phy_find_device(phy_node);
+ of_node_put(phy_node);
+ if (!priv->phy_dev) {
+ dev_info(dev, "Couldn't find phydev\n");
+ return -EPROBE_DEFER;
+ }
+ } else {
+ /* Handle mdio_device registered through mdio_board_info */
+ priv->pdata = (struct dwxpcs_platform_data *)dev->platform_data;
+
+ priv->phy_dev = mdiobus_get_phy(mdiodev->bus,
+ priv->pdata->ext_phy_addr);
+ }
+
+ if (!priv->phy_dev) {
+ dev_info(dev, "Couldn't find phydev\n");
+ return -EPROBE_DEFER;
+ }
+
+ if (!priv->phy_dev->drv) {
+ dev_info(dev, "Attached phy not ready\n");
+ return -EPROBE_DEFER;
+ }
+
+ priv->mdiodev = mdiodev;
+
+ /* Initialize DW XPCS */
+ dwxpcs_init(priv);
+
+ priv->phy_drv = priv->phy_dev->drv;
+ memcpy(&priv->conv_phy_drv, priv->phy_dev->drv,
+ sizeof(struct phy_driver));
+ priv->conv_phy_drv.read_status = dwxpcs_read_status;
+ /* Store a copy of phy_dev info for remove() later */
+ priv->cached_phy_dev.priv = priv->phy_dev->priv;
+ priv->cached_phy_dev.drv = priv->phy_dev->drv;
+ priv->phy_dev->priv = priv;
+ priv->phy_dev->drv = &priv->conv_phy_drv;
+
+ if (priv->pdata->irq > 0) {
+ char *int_name;
+
+ INIT_WORK(&priv->an_task, dwxpcs_an_task);
+ clear_bit(__DWXPCS_TASK_SCHED, &priv->state);
+
+ int_name = priv->int_name;
+ sprintf(int_name, "%s-%d", "dwxpcs", priv->mdiodev->dev.id);
+ priv->int_wq = create_singlethread_workqueue(int_name);
+ if (!priv->int_wq) {
+ dev_err(dev, "%s: Failed to create workqueue\n",
+ int_name);
+ return -ENOMEM;
+ }
+
+ ret = request_irq(priv->pdata->irq, dwxpcs_interrupt,
+ IRQF_SHARED, int_name, priv);
+ if (unlikely(ret < 0)) {
+ destroy_workqueue(priv->int_wq);
+ dev_err(dev, "%s: Allocating DW XPCS IRQ %d (%d)\n",
+ __func__, priv->pdata->irq, ret);
+ return ret;
+ }
+ }
+ dev_info(dev, "%s: DW XPCS mdio device (IRQ: %d) probed successful\n",
+ __func__, priv->pdata->irq);
+
+ mdiodev->priv = priv;
+
+ return 0;
+}
+
+static void dwxpcs_remove(struct mdio_device *mdiodev)
+{
+ struct dwxpcs_priv *priv = (struct dwxpcs_priv *)mdiodev->priv;
+
+ set_bit(__DWXPCS_REMOVING, &priv->state);
+
+ /* Restore the original phy_device info */
+ priv->phy_dev->priv = priv->cached_phy_dev.priv;
+ priv->phy_dev->drv = priv->cached_phy_dev.drv;
+
+ free_irq(priv->pdata->irq, priv);
+ if (priv->int_wq)
+ destroy_workqueue(priv->int_wq);
+}
+
+static struct mdio_driver dwxpcs_driver = {
+ .probe = dwxpcs_probe,
+ .remove = dwxpcs_remove,
+ .mdiodrv.driver = {
+ .name = "dwxpcs",
+ .acpi_match_table = ACPI_PTR(dwxpcs_acpi_match),
+ },
+};
+
+mdio_module_driver(dwxpcs_driver);
+
+MODULE_DESCRIPTION("DW xPCS converter driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/dwxpcs.h b/include/linux/dwxpcs.h
new file mode 100644
index 000000000000..2082e800ee04
--- /dev/null
+++ b/include/linux/dwxpcs.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_DWXPCS_H
+#define __LINUX_DWXPCS_H
+
+enum dwxpcs_pcs_mode {
+ DWXPCS_MODE_SGMII_AN,
+ DWXPCS_MODE_1000BASEX_AN,
+};
+
+struct dwxpcs_platform_data {
+ int irq;
+ enum dwxpcs_pcs_mode mode;
+ int ext_phy_addr;
+};
+
+#endif
--
2.17.0
^ permalink raw reply related
* [RFC net-next v2 2/5] net: phy: introduce mdiobus_get_mdio_device
From: Ong Boon Leong @ 2019-08-28 17:47 UTC (permalink / raw)
To: davem, linux, mcoquelin.stm32, joabreu, f.fainelli, andrew
Cc: netdev, linux-kernel, peppe.cavallaro, alexandre.torgue,
weifeng.voon
In-Reply-To: <20190828174722.6726-1-boon.leong.ong@intel.com>
Add the function to get mdio_device based on the mdio addr.
Signed-off-by: Ong Boon Leong <boon.leong.ong@intel.com>
---
drivers/net/phy/mdio_bus.c | 6 ++++++
include/linux/mdio.h | 1 +
2 files changed, 7 insertions(+)
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 06658d9197a1..96ef94f87ff1 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -130,6 +130,12 @@ struct phy_device *mdiobus_get_phy(struct mii_bus *bus, int addr)
}
EXPORT_SYMBOL(mdiobus_get_phy);
+struct mdio_device *mdiobus_get_mdio_device(struct mii_bus *bus, int addr)
+{
+ return bus->mdio_map[addr];
+}
+EXPORT_SYMBOL(mdiobus_get_mdio_device);
+
bool mdiobus_is_registered_device(struct mii_bus *bus, int addr)
{
return bus->mdio_map[addr];
diff --git a/include/linux/mdio.h b/include/linux/mdio.h
index e8242ad88c81..e0ccd56a7ac0 100644
--- a/include/linux/mdio.h
+++ b/include/linux/mdio.h
@@ -315,6 +315,7 @@ int mdiobus_register_device(struct mdio_device *mdiodev);
int mdiobus_unregister_device(struct mdio_device *mdiodev);
bool mdiobus_is_registered_device(struct mii_bus *bus, int addr);
struct phy_device *mdiobus_get_phy(struct mii_bus *bus, int addr);
+struct mdio_device *mdiobus_get_mdio_device(struct mii_bus *bus, int addr);
/**
* mdio_module_driver() - Helper macro for registering mdio drivers
--
2.17.0
^ permalink raw reply related
* [RFC net-next v2 3/5] net: phy: add private data to mdio_device
From: Ong Boon Leong @ 2019-08-28 17:47 UTC (permalink / raw)
To: davem, linux, mcoquelin.stm32, joabreu, f.fainelli, andrew
Cc: netdev, linux-kernel, peppe.cavallaro, alexandre.torgue,
weifeng.voon
In-Reply-To: <20190828174722.6726-1-boon.leong.ong@intel.com>
PHY converter device is represented as mdio_device and requires private
data. So, we add pointer for private data to mdio_device struct.
Signed-off-by: Ong Boon Leong <boon.leong.ong@intel.com>
---
include/linux/mdio.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/linux/mdio.h b/include/linux/mdio.h
index e0ccd56a7ac0..fc7dfbe75006 100644
--- a/include/linux/mdio.h
+++ b/include/linux/mdio.h
@@ -40,6 +40,8 @@ struct mdio_device {
struct reset_control *reset_ctrl;
unsigned int reset_assert_delay;
unsigned int reset_deassert_delay;
+ /* Private data */
+ void *priv;
};
#define to_mdio_device(d) container_of(d, struct mdio_device, dev)
--
2.17.0
^ permalink raw reply related
* [RFC net-next v2 5/5] net: stmmac: add dwxpcs boardinfo for mdio_device registration
From: Ong Boon Leong @ 2019-08-28 17:47 UTC (permalink / raw)
To: davem, linux, mcoquelin.stm32, joabreu, f.fainelli, andrew
Cc: netdev, linux-kernel, peppe.cavallaro, alexandre.torgue,
weifeng.voon
In-Reply-To: <20190828174722.6726-1-boon.leong.ong@intel.com>
For EHL & TGL Ethernet PCS, the mdio bus address is the same across all
TSN controller instances. External PHY is using default mdio bus address of
0x0. As Ethernet DW PCS is only applicable for SGMII interface, we only
register setup_intel_mgbe_phy_conv() for all TSN controller with SGMII
interface only.
Also introduce callback for remove mdio_device for unloading driver.
Signed-off-by: Ong Boon Leong <boon.leong.ong@intel.com>
---
drivers/net/ethernet/stmicro/stmmac/Kconfig | 1 +
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 +
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 25 +++++++++++
.../net/ethernet/stmicro/stmmac/stmmac_pci.c | 45 ++++++++++++++++++-
include/linux/stmmac.h | 3 ++
5 files changed, 75 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/Kconfig b/drivers/net/ethernet/stmicro/stmmac/Kconfig
index 2325b40dff6e..db4332863611 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Kconfig
+++ b/drivers/net/ethernet/stmicro/stmmac/Kconfig
@@ -200,6 +200,7 @@ endif
config STMMAC_PCI
tristate "STMMAC PCI bus support"
depends on STMMAC_ETH && PCI
+ select DWXPCS
---help---
This selects the platform specific bus support for the stmmac driver.
This driver was tested on XLINX XC2V3000 FF1152AMT0221
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index dcb2e29a5717..d4e232223941 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -29,6 +29,7 @@ struct stmmac_resources {
int wol_irq;
int lpi_irq;
int irq;
+ int phy_conv_irq;
};
struct stmmac_tx_info {
@@ -203,6 +204,7 @@ struct stmmac_priv {
void __iomem *mmcaddr;
void __iomem *ptpaddr;
unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
+ int phy_conv_irq;
#ifdef CONFIG_DEBUG_FS
struct dentry *dbgfs_dir;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 06ccd216ae90..43e3d3799581 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2726,11 +2726,23 @@ static int stmmac_open(struct net_device *dev)
}
}
+ /* Start phy converter after MDIO bus IRQ handling is up */
+ if (priv->plat->setup_phy_conv) {
+ ret = priv->plat->setup_phy_conv(priv->mii, priv->phy_conv_irq);
+ if (ret < 0) {
+ netdev_err(priv->dev,
+ "%s: ERROR: setup phy conv (error: %d)\n",
+ __func__, ret);
+ goto phy_conv_error;
+ }
+ }
+
stmmac_enable_all_queues(priv);
stmmac_start_all_queues(priv);
return 0;
+phy_conv_error:
lpiirq_error:
if (priv->wol_irq != dev->irq)
free_irq(priv->wol_irq, dev);
@@ -2760,6 +2772,7 @@ static int stmmac_release(struct net_device *dev)
{
struct stmmac_priv *priv = netdev_priv(dev);
u32 chan;
+ int ret;
if (priv->eee_enabled)
del_timer_sync(&priv->eee_ctrl_timer);
@@ -2782,6 +2795,17 @@ static int stmmac_release(struct net_device *dev)
if (priv->lpi_irq > 0)
free_irq(priv->lpi_irq, dev);
+ /* Start phy converter after MDIO bus IRQ handling is up */
+ if (priv->plat->remove_phy_conv) {
+ ret = priv->plat->remove_phy_conv(priv->mii);
+ if (ret < 0) {
+ netdev_err(priv->dev,
+ "%s: ERROR: remove phy conv (error: %d)\n",
+ __func__, ret);
+ return 0;
+ }
+ }
+
/* Stop TX/RX DMA and clear the descriptors */
stmmac_stop_all_dma(priv);
@@ -4424,6 +4448,7 @@ int stmmac_dvr_probe(struct device *device,
priv->dev->irq = res->irq;
priv->wol_irq = res->wol_irq;
priv->lpi_irq = res->lpi_irq;
+ priv->phy_conv_irq = res->phy_conv_irq;
if (!IS_ERR_OR_NULL(res->mac))
memcpy(priv->dev->dev_addr, res->mac, ETH_ALEN);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
index 20906287b6d4..c3dfb0e9b025 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
@@ -10,9 +10,10 @@
*******************************************************************************/
#include <linux/clk-provider.h>
+#include <linux/phy.h>
#include <linux/pci.h>
#include <linux/dmi.h>
-
+#include <linux/dwxpcs.h>
#include "stmmac.h"
/*
@@ -109,6 +110,42 @@ static const struct stmmac_pci_info stmmac_pci_info = {
.setup = stmmac_default_data,
};
+static struct dwxpcs_platform_data intel_mgbe_pdata = {
+ .mode = DWXPCS_MODE_SGMII_AN,
+ .ext_phy_addr = 0x0,
+};
+
+static struct mdio_board_info intel_mgbe_bdinfo = {
+ .bus_id = "stmmac-1",
+ .modalias = "dwxpcs",
+ .mdio_addr = 0x16,
+ .platform_data = &intel_mgbe_pdata,
+};
+
+static int setup_intel_mgbe_phy_conv(struct mii_bus *bus, int irq)
+{
+ struct dwxpcs_platform_data *pdata = &intel_mgbe_pdata;
+
+ pdata->irq = irq;
+
+ return mdiobus_create_device(bus, &intel_mgbe_bdinfo);
+}
+
+static int remove_intel_mgbe_phy_conv(struct mii_bus *bus)
+{
+ struct mdio_board_info *bdinfo = &intel_mgbe_bdinfo;
+ struct mdio_device *mdiodev;
+
+ mdiodev = mdiobus_get_mdio_device(bus, bdinfo->mdio_addr);
+
+ if (!mdiodev)
+ return -1;
+
+ mdio_device_remove(mdiodev);
+
+ return 0;
+}
+
static int intel_mgbe_common_data(struct pci_dev *pdev,
struct plat_stmmacenet_data *plat)
{
@@ -197,6 +234,11 @@ static int intel_mgbe_common_data(struct pci_dev *pdev,
/* Set the maxmtu to a default of JUMBO_LEN */
plat->maxmtu = JUMBO_LEN;
+ if (plat->interface == PHY_INTERFACE_MODE_SGMII) {
+ plat->setup_phy_conv = setup_intel_mgbe_phy_conv;
+ plat->remove_phy_conv = remove_intel_mgbe_phy_conv;
+ }
+
return 0;
}
@@ -441,6 +483,7 @@ static int stmmac_pci_probe(struct pci_dev *pdev,
res.addr = pcim_iomap_table(pdev)[i];
res.wol_irq = pdev->irq;
res.irq = pdev->irq;
+ res.phy_conv_irq = res.irq;
return stmmac_dvr_probe(&pdev->dev, plat, &res);
}
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index 7ad7ae35cf88..9ffd0e9c21b1 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -12,6 +12,7 @@
#ifndef __STMMAC_PLATFORM_DATA
#define __STMMAC_PLATFORM_DATA
+#include <linux/phy.h>
#include <linux/platform_device.h>
#define MTL_MAX_RX_QUEUES 8
@@ -162,6 +163,8 @@ struct plat_stmmacenet_data {
int (*init)(struct platform_device *pdev, void *priv);
void (*exit)(struct platform_device *pdev, void *priv);
struct mac_device_info *(*setup)(void *priv);
+ int (*setup_phy_conv)(struct mii_bus *bus, int irq);
+ int (*remove_phy_conv)(struct mii_bus *bus);
void *bsp_priv;
struct clk *stmmac_clk;
struct clk *pclk;
--
2.17.0
^ permalink raw reply related
* Re: [PATCH v2] riscv: add support for SECCOMP and SECCOMP_FILTER
From: Andy Lutomirski @ 2019-08-28 17:52 UTC (permalink / raw)
To: Kees Cook
Cc: David Abdurachmanov, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Oleg Nesterov, Will Drewry, Shuah Khan, Alexei Starovoitov,
Daniel Borkmann, Martin KaFai Lau, Song Liu, Yonghong Song,
David Abdurachmanov, Thomas Gleixner, Allison Randal,
Alexios Zavras, Anup Patel, Vincent Chen, Alan Kao, linux-riscv,
linux-kernel, linux-kselftest, netdev, bpf, me
In-Reply-To: <201908251451.73C6812E8@keescook>
> On Aug 25, 2019, at 2:59 PM, Kees Cook <keescook@chromium.org> wrote:
>
>> On Thu, Aug 22, 2019 at 01:55:22PM -0700, David Abdurachmanov wrote:
>> This patch was extensively tested on Fedora/RISCV (applied by default on
>> top of 5.2-rc7 kernel for <2 months). The patch was also tested with 5.3-rc
>> on QEMU and SiFive Unleashed board.
>
> Oops, I see the mention of QEMU here. Where's the best place to find
> instructions on creating a qemu riscv image/environment?
I don’t suppose one of you riscv folks would like to contribute riscv support to virtme? virtme-run —arch=riscv would be quite nice, and the total patch should be just a couple lines. Unfortunately, it helps a lot to understand the subtleties of booting the architecture to write those couple lines :)
^ permalink raw reply
* Re: [PATCH v2] riscv: add support for SECCOMP and SECCOMP_FILTER
From: Kees Cook @ 2019-08-28 18:01 UTC (permalink / raw)
To: Andy Lutomirski
Cc: David Abdurachmanov, Paul Walmsley, Palmer Dabbelt, Albert Ou,
Oleg Nesterov, Will Drewry, Shuah Khan, Alexei Starovoitov,
Daniel Borkmann, Martin KaFai Lau, Song Liu, Yonghong Song,
David Abdurachmanov, Thomas Gleixner, Allison Randal,
Alexios Zavras, Anup Patel, Vincent Chen, Alan Kao, linux-riscv,
linux-kernel, linux-kselftest, netdev, bpf, me
In-Reply-To: <419CB0D1-E51C-49D5-9745-7771C863462F@amacapital.net>
On Wed, Aug 28, 2019 at 10:52:05AM -0700, Andy Lutomirski wrote:
>
>
> > On Aug 25, 2019, at 2:59 PM, Kees Cook <keescook@chromium.org> wrote:
> >
> >> On Thu, Aug 22, 2019 at 01:55:22PM -0700, David Abdurachmanov wrote:
> >> This patch was extensively tested on Fedora/RISCV (applied by default on
> >> top of 5.2-rc7 kernel for <2 months). The patch was also tested with 5.3-rc
> >> on QEMU and SiFive Unleashed board.
> >
> > Oops, I see the mention of QEMU here. Where's the best place to find
> > instructions on creating a qemu riscv image/environment?
>
> I don’t suppose one of you riscv folks would like to contribute riscv support to virtme? virtme-run —arch=riscv would be quite nice, and the total patch should be just a couple lines. Unfortunately, it helps a lot to understand the subtleties of booting the architecture to write those couple lines :)
As it turns out, this is where I'm stuck. All the instructions I can
find are about booting a kernel off a disk image. :(
--
Kees Cook
^ permalink raw reply
* Re: [RFC net-next v2 3/5] net: phy: add private data to mdio_device
From: Andrew Lunn @ 2019-08-28 18:06 UTC (permalink / raw)
To: Ong Boon Leong
Cc: davem, linux, mcoquelin.stm32, joabreu, f.fainelli, netdev,
linux-kernel, peppe.cavallaro, alexandre.torgue, weifeng.voon
In-Reply-To: <20190828174722.6726-4-boon.leong.ong@intel.com>
On Thu, Aug 29, 2019 at 01:47:20AM +0800, Ong Boon Leong wrote:
> PHY converter device is represented as mdio_device and requires private
> data. So, we add pointer for private data to mdio_device struct.
Hi Ong
This was discussed recently with regard to the xilinx_gmii2rgmii.c
driver. You can use the usual dev_get_drvdata() to get private data
associated to the device. I did suggest adding wrappers, so you can
pass a phydev, or and mdiodev.
Andrew
^ permalink raw reply
* Re: [PATCH] igb: add rx drop enable attribute
From: Alexander Duyck @ 2019-08-28 18:32 UTC (permalink / raw)
To: Robert Beckett; +Cc: intel-wired-lan, Jeff Kirsher, David S. Miller, Netdev
In-Reply-To: <20190828173912.29293-1-bob.beckett@collabora.com>
On Wed, Aug 28, 2019 at 10:40 AM Robert Beckett
<bob.beckett@collabora.com> wrote:
>
> To allow userland to enable or disable dropping packets when descriptor
> ring is exhausted, add an adapter rx_drop_en attribute.
>
> This can be used in conjunction with flow control to mitigate packet storms
> (e.g. due to network loop or DoS) by forcing the network adapter to send
> pause frames whenever the ring is close to exhaustion.
>
> By default this will maintain previous behaviour of enabling dropping of
> packets during ring buffer exhaustion.
> Some use cases prefer to not drop packets upon exhaustion, but instead
> use flow control to limit ingress rates and ensure no dropped packets.
> This is useful when the host CPU cannot keep up with packet delivery,
> but data delivery is more important than throughput via multiple queues.
>
> Userland can write 0 to rx_drop_en to disable packet dropping via udev.
>
> Signed-off-by: Robert Beckett <bob.beckett@collabora.com>
Instead of doing this as a sysfs file it might be better to just do
this as an ethtool private flag like what I did for "legacy-rx".
> ---
> drivers/net/ethernet/intel/igb/igb.h | 1 +
> drivers/net/ethernet/intel/igb/igb_main.c | 60 ++++++++++++++++++++++-
> 2 files changed, 60 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
> index ca54e268d157..efada57a05e1 100644
> --- a/drivers/net/ethernet/intel/igb/igb.h
> +++ b/drivers/net/ethernet/intel/igb/igb.h
> @@ -594,6 +594,7 @@ struct igb_adapter {
> struct igb_mac_addr *mac_table;
> struct vf_mac_filter vf_macs;
> struct vf_mac_filter *vf_mac_list;
> + bool rx_drop_enable; /* drop packets when descriptor ring exhausted */
> };
>
> /* flags controlling PTP/1588 function */
> diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
> index 105b0624081a..5b499130c3f5 100644
> --- a/drivers/net/ethernet/intel/igb/igb_main.c
> +++ b/drivers/net/ethernet/intel/igb/igb_main.c
> @@ -2982,6 +2982,54 @@ static s32 igb_init_i2c(struct igb_adapter *adapter)
> return status;
> }
>
> +static ssize_t rx_drop_en_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +
> +{
> + struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
> + struct igb_adapter *adapter = netdev_priv(netdev);
> +
> + if (adapter->rx_drop_enable)
> + return sprintf(buf, "1\n");
> + else
> + return sprintf(buf, "0\n");
> +}
> +
> +static ssize_t rx_drop_en_store(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf, size_t count)
> +{
> + struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
> + struct igb_adapter *adapter = netdev_priv(netdev);
> + struct e1000_hw *hw = &adapter->hw;
> + int queue_idx, reg_idx;
> + bool val;
> + u32 srrctl;
> + int ret;
> +
> + ret = kstrtobool(buf, &val);
> + if (ret < 0)
> + return ret;
> +
> + adapter->rx_drop_enable = val;
> +
> + /* set for each currently active ring */
> + for (queue_idx = 0; queue_idx < adapter->num_rx_queues; queue_idx++) {
> + reg_idx = adapter->rx_ring[queue_idx]->reg_idx;
> + srrctl = rd32(E1000_SRRCTL(reg_idx));
> + if (val == 0)
> + srrctl &= ~E1000_SRRCTL_DROP_EN;
> + else
> + srrctl |= E1000_SRRCTL_DROP_EN;
> + wr32(E1000_SRRCTL(reg_idx), srrctl);
> + }
> +
> + return count;
> +}
> +
> +static DEVICE_ATTR_RW(rx_drop_en);
> +
> /**
> * igb_probe - Device Initialization Routine
> * @pdev: PCI device information struct
> @@ -3329,6 +3377,9 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> goto err_eeprom;
> }
>
> + /* Add adapter attributes */
> + device_create_file(&pdev->dev, &dev_attr_rx_drop_en);
> +
> /* let the f/w know that the h/w is now under the control of the
> * driver.
> */
> @@ -3655,6 +3706,9 @@ static void igb_remove(struct pci_dev *pdev)
> */
> igb_release_hw_control(adapter);
>
> + /* Remove addapter attributes */
> + device_remove_file(&pdev->dev, &dev_attr_rx_drop_en);
> +
> #ifdef CONFIG_PCI_IOV
> igb_disable_sriov(pdev);
> #endif
> @@ -3753,6 +3807,9 @@ static void igb_init_queue_configuration(struct igb_adapter *adapter)
> max_rss_queues = igb_get_max_rss_queues(adapter);
> adapter->rss_queues = min_t(u32, max_rss_queues, num_online_cpus());
>
> + if (adapter->vfs_allocated_count || adapter->rss_queues > 1)
> + adapter->rx_drop_enable = true;
> +
> igb_set_flag_queue_pairs(adapter, max_rss_queues);
> }
>
> @@ -4504,7 +4561,8 @@ void igb_configure_rx_ring(struct igb_adapter *adapter,
> if (hw->mac.type >= e1000_82580)
> srrctl |= E1000_SRRCTL_TIMESTAMP;
> /* Only set Drop Enable if we are supporting multiple queues */
> - if (adapter->vfs_allocated_count || adapter->num_rx_queues > 1)
> + if (adapter->rx_drop_enable &&
> + (adapter->vfs_allocated_count || adapter->num_rx_queues > 1))
Isn't this redundant due to the code above where you were overriding
the value and setting it to true based on the vfs_allocated_count and
num_rx_queues? You could probably just use rx_drop_enable by itself.
> srrctl |= E1000_SRRCTL_DROP_EN;
>
> wr32(E1000_SRRCTL(reg_idx), srrctl);
> --
> 2.18.0
>
^ permalink raw reply
* [PATCH net-next] net: dsa: mv88e6xxx: fix freeing unused SERDES IRQ
From: Vivien Didelot @ 2019-08-28 18:55 UTC (permalink / raw)
To: netdev; +Cc: davem, Marek Behún, f.fainelli, andrew, Vivien Didelot
Now mv88e6xxx does not enable its ports at setup itself and let
the DSA core handle this, unused ports are disabled without being
powered on first. While that is expected, the SERDES powering code
was assuming that a port was already set up before powering it down,
resulting in freeing an unused IRQ. The patch fixes this assumption.
Fixes: b759f528ca3d ("net: dsa: mv88e6xxx: enable SERDES after setup")
Signed-off-by: Vivien Didelot <vivien.didelot@gmail.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 6525075f6bd3..c648f9fbfa59 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2070,7 +2070,8 @@ static int mv88e6xxx_serdes_power(struct mv88e6xxx_chip *chip, int port,
if (chip->info->ops->serdes_irq_setup)
err = chip->info->ops->serdes_irq_setup(chip, port);
} else {
- if (chip->info->ops->serdes_irq_free)
+ if (chip->info->ops->serdes_irq_free &&
+ chip->ports[port].serdes_irq)
chip->info->ops->serdes_irq_free(chip, port);
err = chip->info->ops->serdes_power(chip, port, false);
--
2.23.0
^ permalink raw reply related
* [net-next v2 5/8] net/mlx5e: Change function's position to a more fitting file
From: Saeed Mahameed @ 2019-08-28 18:57 UTC (permalink / raw)
To: David S. Miller
Cc: netdev@vger.kernel.org, Aya Levin, Tariq Toukan, Saeed Mahameed
In-Reply-To: <20190828185720.2300-1-saeedm@mellanox.com>
From: Aya Levin <ayal@mellanox.com>
Move function which indicates whether tunnel inner flow table is
supported from en.h to en_fs.c. It fits better right after tunnel
protocol rules definitions.
Signed-off-by: Aya Levin <ayal@mellanox.com>
Reviewed-by: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en.h | 6 ------
drivers/net/ethernet/mellanox/mlx5/core/en/fs.h | 2 ++
drivers/net/ethernet/mellanox/mlx5/core/en_fs.c | 6 ++++++
3 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index e03f973c962f..8d76452cacdc 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -1065,12 +1065,6 @@ int mlx5e_modify_sq(struct mlx5_core_dev *mdev, u32 sqn,
void mlx5e_activate_txqsq(struct mlx5e_txqsq *sq);
void mlx5e_tx_disable_queue(struct netdev_queue *txq);
-static inline bool mlx5e_tunnel_inner_ft_supported(struct mlx5_core_dev *mdev)
-{
- return (MLX5_CAP_ETH(mdev, tunnel_stateless_gre) &&
- MLX5_CAP_FLOWTABLE_NIC_RX(mdev, ft_field_support.inner_ip_version));
-}
-
static inline bool mlx5_tx_swp_supported(struct mlx5_core_dev *mdev)
{
return MLX5_CAP_ETH(mdev, swp) &&
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h b/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
index ca2161b42c7f..5acd982ff228 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
@@ -98,6 +98,8 @@ enum mlx5e_tunnel_types {
MLX5E_NUM_TUNNEL_TT,
};
+bool mlx5e_tunnel_inner_ft_supported(struct mlx5_core_dev *mdev);
+
/* L3/L4 traffic type classifier */
struct mlx5e_ttc_table {
struct mlx5e_flow_table ft;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
index 76cc10e44080..a8340e4fb0b9 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
@@ -749,6 +749,12 @@ static struct mlx5e_etype_proto ttc_tunnel_rules[] = {
},
};
+bool mlx5e_tunnel_inner_ft_supported(struct mlx5_core_dev *mdev)
+{
+ return (MLX5_CAP_ETH(mdev, tunnel_stateless_gre) &&
+ MLX5_CAP_FLOWTABLE_NIC_RX(mdev, ft_field_support.inner_ip_version));
+}
+
static u8 mlx5e_etype_to_ipv(u16 ethertype)
{
if (ethertype == ETH_P_IP)
--
2.21.0
^ permalink raw reply related
* [pull request][net-next v2 0/8] Mellanox, mlx5 updates 2019-08-22
From: Saeed Mahameed @ 2019-08-28 18:57 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev@vger.kernel.org, Saeed Mahameed
This series provides some misc updates to mlx5 driver.
For more information please see tag log below.
Please pull and let me know if there is any problem.
Please note that the series starts with a merge of mlx5-next branch,
to resolve and avoid dependency with rdma tree.
v2:
- Change statistics counter name to dev_internal_queue_oob as
suggested by Jakub.
- Fixed an issue with IP-in-IP TSO patch, found by regression testing.
Thanks,
Saeed.
---
The following changes since commit 537f321097d03c21f46c56741cda0dfa6eeffcdd:
Merge branch 'mlx5-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mellanox/linux (2019-08-28 11:48:56 -0700)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux.git tags/mlx5-updates-2019-08-22
for you to fetch changes up to 25948b87dda284664edeb3b3dab689df0a7dc889:
net/mlx5e: Support TSO and TX checksum offloads for IP-in-IP tunnels (2019-08-28 11:49:05 -0700)
----------------------------------------------------------------
mlx5-updates-2019-08-22
Misc updates for mlx5e net device driver
1) Maxim and Tariq add the support for LAG TX port affinity distribution
When VF LAG is enabled, VFs netdevs will round-robin the TX affinity
of their tx queues among the different LAG ports.
2) Aya adds the support for ip-in-ip RSS.
3) Marina adds the support for ip-in-ip TX TSO and checksum offloads.
4) Moshe adds a device internal drop counter to mlx5 ethtool stats.
----------------------------------------------------------------
Aya Levin (2):
net/mlx5e: Change function's position to a more fitting file
net/mlx5e: Support RSS for IP-in-IP and IPv6 tunneled packets
Erez Alfasi (1):
net/mlx5e: ethtool, Fix a typo in WOL function names
Marina Varshaver (2):
net/mlx5e: Improve stateless offload capability check
net/mlx5e: Support TSO and TX checksum offloads for IP-in-IP tunnels
Maxim Mikityanskiy (1):
net/mlx5e: Support LAG TX port affinity distribution
Moshe Shemesh (1):
net/mlx5e: Add device out of buffer counter
Tariq Toukan (1):
net/mlx5e: Expose new function for TIS destroy loop
drivers/net/ethernet/mellanox/mlx5/core/en.h | 18 +++--
drivers/net/ethernet/mellanox/mlx5/core/en/fs.h | 9 +++
.../net/ethernet/mellanox/mlx5/core/en_ethtool.c | 8 +--
drivers/net/ethernet/mellanox/mlx5/core/en_fs.c | 50 ++++++++++++++
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 76 ++++++++++++++++------
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 9 +--
drivers/net/ethernet/mellanox/mlx5/core/en_stats.c | 38 +++++++----
.../net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c | 4 +-
.../ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c | 6 +-
9 files changed, 164 insertions(+), 54 deletions(-)
^ permalink raw reply
* [net-next v2 6/8] net/mlx5e: Support RSS for IP-in-IP and IPv6 tunneled packets
From: Saeed Mahameed @ 2019-08-28 18:57 UTC (permalink / raw)
To: David S. Miller
Cc: netdev@vger.kernel.org, Aya Levin, Tariq Toukan, Saeed Mahameed
In-Reply-To: <20190828185720.2300-1-saeedm@mellanox.com>
From: Aya Levin <ayal@mellanox.com>
Add support for inner header RSS on IP-in-IP and IPv6 tunneled packets.
Add rules to the steering table regarding outer IP header, with
IPv4/6->IP-in-IP. Tunneled packets with protocol numbers: 0x4 (IP-in-IP)
and 0x29 (IPv6) are RSS-ed on the inner IP header.
Separate FW dependencies between flow table inner IP capabilities and
GRE offload support. Allowing this feature even if GRE offload is not
supported. Tested with multi stream TCP traffic tunneled with IPnIP.
Verified that:
Without this patch, only a single RX ring was processing the traffic.
With this patch, multiple RX rings were processing the traffic.
Verified with and without GRE offload support.
Signed-off-by: Aya Levin <ayal@mellanox.com>
Reviewed-by: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
.../net/ethernet/mellanox/mlx5/core/en/fs.h | 4 ++
.../net/ethernet/mellanox/mlx5/core/en_fs.c | 46 ++++++++++++++++++-
2 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h b/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
index 5acd982ff228..5aae3a7a5497 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
@@ -95,6 +95,10 @@ struct mlx5e_tirc_config {
enum mlx5e_tunnel_types {
MLX5E_TT_IPV4_GRE,
MLX5E_TT_IPV6_GRE,
+ MLX5E_TT_IPV4_IPIP,
+ MLX5E_TT_IPV6_IPIP,
+ MLX5E_TT_IPV4_IPV6,
+ MLX5E_TT_IPV6_IPV6,
MLX5E_NUM_TUNNEL_TT,
};
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
index a8340e4fb0b9..b99b17957543 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
@@ -747,11 +747,52 @@ static struct mlx5e_etype_proto ttc_tunnel_rules[] = {
.etype = ETH_P_IPV6,
.proto = IPPROTO_GRE,
},
+ [MLX5E_TT_IPV4_IPIP] = {
+ .etype = ETH_P_IP,
+ .proto = IPPROTO_IPIP,
+ },
+ [MLX5E_TT_IPV6_IPIP] = {
+ .etype = ETH_P_IPV6,
+ .proto = IPPROTO_IPIP,
+ },
+ [MLX5E_TT_IPV4_IPV6] = {
+ .etype = ETH_P_IP,
+ .proto = IPPROTO_IPV6,
+ },
+ [MLX5E_TT_IPV6_IPV6] = {
+ .etype = ETH_P_IPV6,
+ .proto = IPPROTO_IPV6,
+ },
+
};
+static bool mlx5e_tunnel_proto_supported(struct mlx5_core_dev *mdev, u8 proto_type)
+{
+ switch (proto_type) {
+ case IPPROTO_GRE:
+ return MLX5_CAP_ETH(mdev, tunnel_stateless_gre);
+ case IPPROTO_IPIP:
+ case IPPROTO_IPV6:
+ return MLX5_CAP_ETH(mdev, tunnel_stateless_ip_over_ip);
+ default:
+ return false;
+ }
+}
+
+static bool mlx5e_any_tunnel_proto_supported(struct mlx5_core_dev *mdev)
+{
+ int tt;
+
+ for (tt = 0; tt < MLX5E_NUM_TUNNEL_TT; tt++) {
+ if (mlx5e_tunnel_proto_supported(mdev, ttc_tunnel_rules[tt].proto))
+ return true;
+ }
+ return false;
+}
+
bool mlx5e_tunnel_inner_ft_supported(struct mlx5_core_dev *mdev)
{
- return (MLX5_CAP_ETH(mdev, tunnel_stateless_gre) &&
+ return (mlx5e_any_tunnel_proto_supported(mdev) &&
MLX5_CAP_FLOWTABLE_NIC_RX(mdev, ft_field_support.inner_ip_version));
}
@@ -844,6 +885,9 @@ static int mlx5e_generate_ttc_table_rules(struct mlx5e_priv *priv,
dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE;
dest.ft = params->inner_ttc->ft.t;
for (tt = 0; tt < MLX5E_NUM_TUNNEL_TT; tt++) {
+ if (!mlx5e_tunnel_proto_supported(priv->mdev,
+ ttc_tunnel_rules[tt].proto))
+ continue;
rules[tt] = mlx5e_generate_ttc_rule(priv, ft, &dest,
ttc_tunnel_rules[tt].etype,
ttc_tunnel_rules[tt].proto);
--
2.21.0
^ permalink raw reply related
* [net-next v2 1/8] net/mlx5e: ethtool, Fix a typo in WOL function names
From: Saeed Mahameed @ 2019-08-28 18:57 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev@vger.kernel.org, Erez Alfasi, Saeed Mahameed
In-Reply-To: <20190828185720.2300-1-saeedm@mellanox.com>
From: Erez Alfasi <ereza@mellanox.com>
Fix a typo in 'mlx5e_refomrat_wol_mode_mlx5_to_linux' and
'mlx5e_refomrat_wol_mode_linux_to_mlx5' function names:
"refomrat" -> "reformat".
Fixes: 928cfe8745a6 ("net/mlx5e: Wake On LAN support")
Signed-off-by: Erez Alfasi <ereza@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
index 7347d673f448..c5a9c20d7f00 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -1431,7 +1431,7 @@ static __u32 mlx5e_get_wol_supported(struct mlx5_core_dev *mdev)
return ret;
}
-static __u32 mlx5e_refomrat_wol_mode_mlx5_to_linux(u8 mode)
+static __u32 mlx5e_reformat_wol_mode_mlx5_to_linux(u8 mode)
{
__u32 ret = 0;
@@ -1459,7 +1459,7 @@ static __u32 mlx5e_refomrat_wol_mode_mlx5_to_linux(u8 mode)
return ret;
}
-static u8 mlx5e_refomrat_wol_mode_linux_to_mlx5(__u32 mode)
+static u8 mlx5e_reformat_wol_mode_linux_to_mlx5(__u32 mode)
{
u8 ret = 0;
@@ -1505,7 +1505,7 @@ static void mlx5e_get_wol(struct net_device *netdev,
if (err)
return;
- wol->wolopts = mlx5e_refomrat_wol_mode_mlx5_to_linux(mlx5_wol_mode);
+ wol->wolopts = mlx5e_reformat_wol_mode_mlx5_to_linux(mlx5_wol_mode);
}
static int mlx5e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
@@ -1521,7 +1521,7 @@ static int mlx5e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
if (wol->wolopts & ~wol_supported)
return -EINVAL;
- mlx5_wol_mode = mlx5e_refomrat_wol_mode_linux_to_mlx5(wol->wolopts);
+ mlx5_wol_mode = mlx5e_reformat_wol_mode_linux_to_mlx5(wol->wolopts);
return mlx5_set_port_wol(mdev, mlx5_wol_mode);
}
--
2.21.0
^ permalink raw reply related
* [net-next v2 2/8] net/mlx5e: Expose new function for TIS destroy loop
From: Saeed Mahameed @ 2019-08-28 18:57 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev@vger.kernel.org, Tariq Toukan, Saeed Mahameed
In-Reply-To: <20190828185720.2300-1-saeedm@mellanox.com>
From: Tariq Toukan <tariqt@mellanox.com>
For better modularity and code sharing.
Function internal change to be introduced in the next patches.
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en.h | 1 +
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 13 +++++++++----
drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 9 +++------
3 files changed, 13 insertions(+), 10 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 446792799125..491c281416d0 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -1107,6 +1107,7 @@ int mlx5e_create_tis(struct mlx5_core_dev *mdev, void *in, u32 *tisn);
void mlx5e_destroy_tis(struct mlx5_core_dev *mdev, u32 tisn);
int mlx5e_create_tises(struct mlx5e_priv *priv);
+void mlx5e_destroy_tises(struct mlx5e_priv *priv);
int mlx5e_update_nic_rx(struct mlx5e_priv *priv);
void mlx5e_update_carrier(struct mlx5e_priv *priv);
int mlx5e_close(struct net_device *netdev);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 8592b98d0e70..390e614ac46e 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -3179,6 +3179,14 @@ void mlx5e_destroy_tis(struct mlx5_core_dev *mdev, u32 tisn)
mlx5_core_destroy_tis(mdev, tisn);
}
+void mlx5e_destroy_tises(struct mlx5e_priv *priv)
+{
+ int tc;
+
+ for (tc = 0; tc < priv->profile->max_tc; tc++)
+ mlx5e_destroy_tis(priv->mdev, priv->tisn[tc]);
+}
+
int mlx5e_create_tises(struct mlx5e_priv *priv)
{
int err;
@@ -3208,10 +3216,7 @@ int mlx5e_create_tises(struct mlx5e_priv *priv)
static void mlx5e_cleanup_nic_tx(struct mlx5e_priv *priv)
{
- int tc;
-
- for (tc = 0; tc < priv->profile->max_tc; tc++)
- mlx5e_destroy_tis(priv->mdev, priv->tisn[tc]);
+ mlx5e_destroy_tises(priv);
}
static void mlx5e_build_indir_tir_ctx_common(struct mlx5e_priv *priv,
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
index e7ac6233037d..1623cd32f303 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -1621,7 +1621,7 @@ static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)
{
struct mlx5e_rep_priv *rpriv = priv->ppriv;
struct mlx5_rep_uplink_priv *uplink_priv;
- int tc, err;
+ int err;
err = mlx5e_create_tises(priv);
if (err) {
@@ -1657,18 +1657,15 @@ static int mlx5e_init_rep_tx(struct mlx5e_priv *priv)
tc_esw_cleanup:
mlx5e_tc_esw_cleanup(&uplink_priv->tc_ht);
destroy_tises:
- for (tc = 0; tc < priv->profile->max_tc; tc++)
- mlx5e_destroy_tis(priv->mdev, priv->tisn[tc]);
+ mlx5e_destroy_tises(priv);
return err;
}
static void mlx5e_cleanup_rep_tx(struct mlx5e_priv *priv)
{
struct mlx5e_rep_priv *rpriv = priv->ppriv;
- int tc;
- for (tc = 0; tc < priv->profile->max_tc; tc++)
- mlx5e_destroy_tis(priv->mdev, priv->tisn[tc]);
+ mlx5e_destroy_tises(priv);
if (rpriv->rep->vport == MLX5_VPORT_UPLINK) {
/* clean indirect TC block notifications */
--
2.21.0
^ permalink raw reply related
* [net-next v2 4/8] net/mlx5e: Add device out of buffer counter
From: Saeed Mahameed @ 2019-08-28 18:57 UTC (permalink / raw)
To: David S. Miller; +Cc: netdev@vger.kernel.org, Moshe Shemesh, Saeed Mahameed
In-Reply-To: <20190828185720.2300-1-saeedm@mellanox.com>
From: Moshe Shemesh <moshe@mellanox.com>
Added the following packets drop counter:
Device out of buffer - counts packets which were dropped due to full
device internal receive queue.
This counter will be shown on ethtool as a new counter called
dev_out_of_buffer.
The counter is read from FW by command QUERY_VNIC_ENV.
Signed-off-by: Moshe Shemesh <moshe@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
.../ethernet/mellanox/mlx5/core/en_stats.c | 38 ++++++++++++-------
1 file changed, 25 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
index 18e4c162256a..f1065e78086a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
@@ -369,17 +369,27 @@ static void mlx5e_grp_q_update_stats(struct mlx5e_priv *priv)
}
#define VNIC_ENV_OFF(c) MLX5_BYTE_OFF(query_vnic_env_out, c)
-static const struct counter_desc vnic_env_stats_desc[] = {
+static const struct counter_desc vnic_env_stats_steer_desc[] = {
{ "rx_steer_missed_packets",
VNIC_ENV_OFF(vport_env.nic_receive_steering_discard) },
};
-#define NUM_VNIC_ENV_COUNTERS ARRAY_SIZE(vnic_env_stats_desc)
+static const struct counter_desc vnic_env_stats_dev_oob_desc[] = {
+ { "dev_internal_queue_oob",
+ VNIC_ENV_OFF(vport_env.internal_rq_out_of_buffer) },
+};
+
+#define NUM_VNIC_ENV_STEER_COUNTERS(dev) \
+ (MLX5_CAP_GEN(dev, nic_receive_steering_discard) ? \
+ ARRAY_SIZE(vnic_env_stats_steer_desc) : 0)
+#define NUM_VNIC_ENV_DEV_OOB_COUNTERS(dev) \
+ (MLX5_CAP_GEN(dev, vnic_env_int_rq_oob) ? \
+ ARRAY_SIZE(vnic_env_stats_dev_oob_desc) : 0)
static int mlx5e_grp_vnic_env_get_num_stats(struct mlx5e_priv *priv)
{
- return MLX5_CAP_GEN(priv->mdev, nic_receive_steering_discard) ?
- NUM_VNIC_ENV_COUNTERS : 0;
+ return NUM_VNIC_ENV_STEER_COUNTERS(priv->mdev) +
+ NUM_VNIC_ENV_DEV_OOB_COUNTERS(priv->mdev);
}
static int mlx5e_grp_vnic_env_fill_strings(struct mlx5e_priv *priv, u8 *data,
@@ -387,12 +397,13 @@ static int mlx5e_grp_vnic_env_fill_strings(struct mlx5e_priv *priv, u8 *data,
{
int i;
- if (!MLX5_CAP_GEN(priv->mdev, nic_receive_steering_discard))
- return idx;
+ for (i = 0; i < NUM_VNIC_ENV_STEER_COUNTERS(priv->mdev); i++)
+ strcpy(data + (idx++) * ETH_GSTRING_LEN,
+ vnic_env_stats_steer_desc[i].format);
- for (i = 0; i < NUM_VNIC_ENV_COUNTERS; i++)
+ for (i = 0; i < NUM_VNIC_ENV_DEV_OOB_COUNTERS(priv->mdev); i++)
strcpy(data + (idx++) * ETH_GSTRING_LEN,
- vnic_env_stats_desc[i].format);
+ vnic_env_stats_dev_oob_desc[i].format);
return idx;
}
@@ -401,12 +412,13 @@ static int mlx5e_grp_vnic_env_fill_stats(struct mlx5e_priv *priv, u64 *data,
{
int i;
- if (!MLX5_CAP_GEN(priv->mdev, nic_receive_steering_discard))
- return idx;
-
- for (i = 0; i < NUM_VNIC_ENV_COUNTERS; i++)
+ for (i = 0; i < NUM_VNIC_ENV_STEER_COUNTERS(priv->mdev); i++)
data[idx++] = MLX5E_READ_CTR64_BE(priv->stats.vnic.query_vnic_env_out,
- vnic_env_stats_desc, i);
+ vnic_env_stats_steer_desc, i);
+
+ for (i = 0; i < NUM_VNIC_ENV_DEV_OOB_COUNTERS(priv->mdev); i++)
+ data[idx++] = MLX5E_READ_CTR32_BE(priv->stats.vnic.query_vnic_env_out,
+ vnic_env_stats_dev_oob_desc, i);
return idx;
}
--
2.21.0
^ permalink raw reply related
* [net-next v2 7/8] net/mlx5e: Improve stateless offload capability check
From: Saeed Mahameed @ 2019-08-28 18:57 UTC (permalink / raw)
To: David S. Miller
Cc: netdev@vger.kernel.org, Marina Varshaver, Aya Levin,
Saeed Mahameed
In-Reply-To: <20190828185720.2300-1-saeedm@mellanox.com>
From: Marina Varshaver <marinav@mellanox.com>
Use generic function for checking tunnel stateless offload capability
instead of separate macros.
Signed-off-by: Marina Varshaver <marinav@mellanox.com>
Reviewed-by: Aya Levin <ayal@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en/fs.h | 3 +++
drivers/net/ethernet/mellanox/mlx5/core/en_fs.c | 4 ++--
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 4 ++--
3 files changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h b/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
index 5aae3a7a5497..68d593074f6c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/fs.h
@@ -238,5 +238,8 @@ void mlx5e_disable_cvlan_filter(struct mlx5e_priv *priv);
int mlx5e_create_flow_steering(struct mlx5e_priv *priv);
void mlx5e_destroy_flow_steering(struct mlx5e_priv *priv);
+bool mlx5e_tunnel_proto_supported(struct mlx5_core_dev *mdev, u8 proto_type);
+bool mlx5e_any_tunnel_proto_supported(struct mlx5_core_dev *mdev);
+
#endif /* __MLX5E_FLOW_STEER_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
index b99b17957543..15b7f0f1427c 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_fs.c
@@ -766,7 +766,7 @@ static struct mlx5e_etype_proto ttc_tunnel_rules[] = {
};
-static bool mlx5e_tunnel_proto_supported(struct mlx5_core_dev *mdev, u8 proto_type)
+bool mlx5e_tunnel_proto_supported(struct mlx5_core_dev *mdev, u8 proto_type)
{
switch (proto_type) {
case IPPROTO_GRE:
@@ -779,7 +779,7 @@ static bool mlx5e_tunnel_proto_supported(struct mlx5_core_dev *mdev, u8 proto_ty
}
}
-static bool mlx5e_any_tunnel_proto_supported(struct mlx5_core_dev *mdev)
+bool mlx5e_any_tunnel_proto_supported(struct mlx5_core_dev *mdev)
{
int tt;
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 2786f5b8057d..327c90d936e9 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -4879,7 +4879,7 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
netdev->hw_features |= NETIF_F_HW_VLAN_STAG_TX;
if (mlx5_vxlan_allowed(mdev->vxlan) || mlx5_geneve_tx_allowed(mdev) ||
- MLX5_CAP_ETH(mdev, tunnel_stateless_gre)) {
+ mlx5e_any_tunnel_proto_supported(mdev)) {
netdev->hw_enc_features |= NETIF_F_HW_CSUM;
netdev->hw_enc_features |= NETIF_F_TSO;
netdev->hw_enc_features |= NETIF_F_TSO6;
@@ -4894,7 +4894,7 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
netdev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM;
}
- if (MLX5_CAP_ETH(mdev, tunnel_stateless_gre)) {
+ if (mlx5e_tunnel_proto_supported(mdev, IPPROTO_GRE)) {
netdev->hw_features |= NETIF_F_GSO_GRE |
NETIF_F_GSO_GRE_CSUM;
netdev->hw_enc_features |= NETIF_F_GSO_GRE |
--
2.21.0
^ permalink raw reply related
* [net-next v2 3/8] net/mlx5e: Support LAG TX port affinity distribution
From: Saeed Mahameed @ 2019-08-28 18:57 UTC (permalink / raw)
To: David S. Miller
Cc: netdev@vger.kernel.org, Maxim Mikityanskiy, Tariq Toukan,
Mark Bloch, Saeed Mahameed
In-Reply-To: <20190828185720.2300-1-saeedm@mellanox.com>
From: Maxim Mikityanskiy <maximmi@mellanox.com>
When the VF LAG is in use, round-robin the TX affinity of channels among
the different ports, if supported by the firmware. Create a set of TISes
per port, while doing round-robin of the channels over the different
sets. Let all SQs of a channel share the same set of TISes.
If lag_tx_port_affinity HCA cap bit is supported, num_lag_ports > 1 and
we aren't the LACP owner (PF in the regular use), assign the affinities,
otherwise use tx_affinity == 0 in TIS context to let the FW assign the
affinities itself. The TISes of the LACP owner are mapped only to the
native physical port.
For VFs, the starting port for round-robin is determined by its vhca_id,
because a VF may have only one channel if attached to a single-core VM.
Signed-off-by: Maxim Mikityanskiy <maximmi@mellanox.com>
Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: Mark Bloch <markb@mellanox.com>
Reviewed-by: Tariq Toukan <tariqt@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en.h | 11 +++-
.../net/ethernet/mellanox/mlx5/core/en_main.c | 54 +++++++++++++------
.../ethernet/mellanox/mlx5/core/ipoib/ipoib.c | 4 +-
.../mellanox/mlx5/core/ipoib/ipoib_vlan.c | 6 +--
4 files changed, 53 insertions(+), 22 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en.h b/drivers/net/ethernet/mellanox/mlx5/core/en.h
index 491c281416d0..e03f973c962f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
@@ -163,6 +163,14 @@ enum mlx5e_rq_group {
#define MLX5E_NUM_RQ_GROUPS(g) (1 + MLX5E_RQ_GROUP_##g)
};
+static inline u8 mlx5e_get_num_lag_ports(struct mlx5_core_dev *mdev)
+{
+ if (mlx5_lag_is_lacp_owner(mdev))
+ return 1;
+
+ return clamp_t(u8, MLX5_CAP_GEN(mdev, num_lag_ports), 1, MLX5_MAX_PORTS);
+}
+
static inline u16 mlx5_min_rx_wqes(int wq_type, u32 wq_size)
{
switch (wq_type) {
@@ -705,6 +713,7 @@ struct mlx5e_channel {
struct net_device *netdev;
__be32 mkey_be;
u8 num_tc;
+ u8 lag_port;
/* XDP_REDIRECT */
struct mlx5e_xdpsq xdpsq;
@@ -818,7 +827,7 @@ struct mlx5e_priv {
struct mlx5e_rq drop_rq;
struct mlx5e_channels channels;
- u32 tisn[MLX5E_MAX_NUM_TC];
+ u32 tisn[MLX5_MAX_PORTS][MLX5E_MAX_NUM_TC];
struct mlx5e_rqt indir_rqt;
struct mlx5e_tir indir_tir[MLX5E_NUM_INDIR_TIRS];
struct mlx5e_tir inner_indir_tir[MLX5E_NUM_INDIR_TIRS];
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 390e614ac46e..2786f5b8057d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -1442,7 +1442,7 @@ int mlx5e_open_xdpsq(struct mlx5e_channel *c, struct mlx5e_params *params,
return err;
csp.tis_lst_sz = 1;
- csp.tisn = c->priv->tisn[0]; /* tc = 0 */
+ csp.tisn = c->priv->tisn[c->lag_port][0]; /* tc = 0 */
csp.cqn = sq->cq.mcq.cqn;
csp.wq_ctrl = &sq->wq_ctrl;
csp.min_inline_mode = sq->min_inline_mode;
@@ -1692,7 +1692,7 @@ static int mlx5e_open_sqs(struct mlx5e_channel *c,
for (tc = 0; tc < params->num_tc; tc++) {
int txq_ix = c->ix + tc * priv->max_nch;
- err = mlx5e_open_txqsq(c, c->priv->tisn[tc], txq_ix,
+ err = mlx5e_open_txqsq(c, c->priv->tisn[c->lag_port][tc], txq_ix,
params, &cparam->sq, &c->sq[tc], tc);
if (err)
goto err_close_sqs;
@@ -1926,6 +1926,13 @@ static void mlx5e_close_queues(struct mlx5e_channel *c)
mlx5e_close_cq(&c->icosq.cq);
}
+static u8 mlx5e_enumerate_lag_port(struct mlx5_core_dev *mdev, int ix)
+{
+ u16 port_aff_bias = mlx5_core_is_pf(mdev) ? 0 : MLX5_CAP_GEN(mdev, vhca_id);
+
+ return (ix + port_aff_bias) % mlx5e_get_num_lag_ports(mdev);
+}
+
static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
struct mlx5e_params *params,
struct mlx5e_channel_param *cparam,
@@ -1960,6 +1967,7 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
c->xdp = !!params->xdp_prog;
c->stats = &priv->channel_stats[ix].ch;
c->irq_desc = irq_to_desc(irq);
+ c->lag_port = mlx5e_enumerate_lag_port(priv->mdev, ix);
err = mlx5e_alloc_xps_cpumask(c, params);
if (err)
@@ -3181,35 +3189,49 @@ void mlx5e_destroy_tis(struct mlx5_core_dev *mdev, u32 tisn)
void mlx5e_destroy_tises(struct mlx5e_priv *priv)
{
- int tc;
+ int tc, i;
- for (tc = 0; tc < priv->profile->max_tc; tc++)
- mlx5e_destroy_tis(priv->mdev, priv->tisn[tc]);
+ for (i = 0; i < mlx5e_get_num_lag_ports(priv->mdev); i++)
+ for (tc = 0; tc < priv->profile->max_tc; tc++)
+ mlx5e_destroy_tis(priv->mdev, priv->tisn[i][tc]);
+}
+
+static bool mlx5e_lag_should_assign_affinity(struct mlx5_core_dev *mdev)
+{
+ return MLX5_CAP_GEN(mdev, lag_tx_port_affinity) && mlx5e_get_num_lag_ports(mdev) > 1;
}
int mlx5e_create_tises(struct mlx5e_priv *priv)
{
+ int tc, i;
int err;
- int tc;
- for (tc = 0; tc < priv->profile->max_tc; tc++) {
- u32 in[MLX5_ST_SZ_DW(create_tis_in)] = {};
- void *tisc;
+ for (i = 0; i < mlx5e_get_num_lag_ports(priv->mdev); i++) {
+ for (tc = 0; tc < priv->profile->max_tc; tc++) {
+ u32 in[MLX5_ST_SZ_DW(create_tis_in)] = {};
+ void *tisc;
- tisc = MLX5_ADDR_OF(create_tis_in, in, ctx);
+ tisc = MLX5_ADDR_OF(create_tis_in, in, ctx);
- MLX5_SET(tisc, tisc, prio, tc << 1);
+ MLX5_SET(tisc, tisc, prio, tc << 1);
- err = mlx5e_create_tis(priv->mdev, in, &priv->tisn[tc]);
- if (err)
- goto err_close_tises;
+ if (mlx5e_lag_should_assign_affinity(priv->mdev))
+ MLX5_SET(tisc, tisc, lag_tx_port_affinity, i + 1);
+
+ err = mlx5e_create_tis(priv->mdev, in, &priv->tisn[i][tc]);
+ if (err)
+ goto err_close_tises;
+ }
}
return 0;
err_close_tises:
- for (tc--; tc >= 0; tc--)
- mlx5e_destroy_tis(priv->mdev, priv->tisn[tc]);
+ for (; i >= 0; i--) {
+ for (tc--; tc >= 0; tc--)
+ mlx5e_destroy_tis(priv->mdev, priv->tisn[i][tc]);
+ tc = priv->profile->max_tc;
+ }
return err;
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
index 1a2560e3bf7c..3ed8ab2d703d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib.c
@@ -279,7 +279,7 @@ static int mlx5i_init_tx(struct mlx5e_priv *priv)
return err;
}
- err = mlx5i_create_tis(priv->mdev, ipriv->qp.qpn, &priv->tisn[0]);
+ err = mlx5i_create_tis(priv->mdev, ipriv->qp.qpn, &priv->tisn[0][0]);
if (err) {
mlx5_core_warn(priv->mdev, "create tis failed, %d\n", err);
goto err_destroy_underlay_qp;
@@ -296,7 +296,7 @@ static void mlx5i_cleanup_tx(struct mlx5e_priv *priv)
{
struct mlx5i_priv *ipriv = priv->ppriv;
- mlx5e_destroy_tis(priv->mdev, priv->tisn[0]);
+ mlx5e_destroy_tis(priv->mdev, priv->tisn[0][0]);
mlx5i_destroy_underlay_qp(priv->mdev, &ipriv->qp);
}
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c
index c5a491e22e55..96e64187c089 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/ipoib/ipoib_vlan.c
@@ -210,7 +210,7 @@ static int mlx5i_pkey_open(struct net_device *netdev)
goto err_unint_underlay_qp;
}
- err = mlx5i_create_tis(mdev, ipriv->qp.qpn, &epriv->tisn[0]);
+ err = mlx5i_create_tis(mdev, ipriv->qp.qpn, &epriv->tisn[0][0]);
if (err) {
mlx5_core_warn(mdev, "create child tis failed, %d\n", err);
goto err_remove_rx_uderlay_qp;
@@ -228,7 +228,7 @@ static int mlx5i_pkey_open(struct net_device *netdev)
return 0;
err_clear_state_opened_flag:
- mlx5e_destroy_tis(mdev, epriv->tisn[0]);
+ mlx5e_destroy_tis(mdev, epriv->tisn[0][0]);
err_remove_rx_uderlay_qp:
mlx5_fs_remove_rx_underlay_qpn(mdev, ipriv->qp.qpn);
err_unint_underlay_qp:
@@ -257,7 +257,7 @@ static int mlx5i_pkey_close(struct net_device *netdev)
mlx5i_uninit_underlay_qp(priv);
mlx5e_deactivate_priv_channels(priv);
mlx5e_close_channels(&priv->channels);
- mlx5e_destroy_tis(mdev, priv->tisn[0]);
+ mlx5e_destroy_tis(mdev, priv->tisn[0][0]);
unlock:
mutex_unlock(&priv->state_lock);
return 0;
--
2.21.0
^ permalink raw reply related
* [net-next v2 8/8] net/mlx5e: Support TSO and TX checksum offloads for IP-in-IP tunnels
From: Saeed Mahameed @ 2019-08-28 18:57 UTC (permalink / raw)
To: David S. Miller
Cc: netdev@vger.kernel.org, Marina Varshaver, Avihu Hagag, Aya Levin,
Saeed Mahameed
In-Reply-To: <20190828185720.2300-1-saeedm@mellanox.com>
From: Marina Varshaver <marinav@mellanox.com>
Add TX offloads support for IP-in-IP tunneled packets by reporting
the needed netdev features.
Signed-off-by: Marina Varshaver <marinav@mellanox.com>
Signed-off-by: Avihu Hagag <avihuh@mellanox.com>
Reviewed-by: Aya Levin <ayal@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
---
drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 327c90d936e9..9ff28e2d72cd 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -4243,6 +4243,8 @@ static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv,
switch (proto) {
case IPPROTO_GRE:
+ case IPPROTO_IPIP:
+ case IPPROTO_IPV6:
return features;
case IPPROTO_UDP:
udph = udp_hdr(skb);
@@ -4903,6 +4905,15 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
NETIF_F_GSO_GRE_CSUM;
}
+ if (mlx5e_tunnel_proto_supported(mdev, IPPROTO_IPIP)) {
+ netdev->hw_features |= NETIF_F_GSO_IPXIP4 |
+ NETIF_F_GSO_IPXIP6;
+ netdev->hw_enc_features |= NETIF_F_GSO_IPXIP4 |
+ NETIF_F_GSO_IPXIP6;
+ netdev->gso_partial_features |= NETIF_F_GSO_IPXIP4 |
+ NETIF_F_GSO_IPXIP6;
+ }
+
netdev->hw_features |= NETIF_F_GSO_PARTIAL;
netdev->gso_partial_features |= NETIF_F_GSO_UDP_L4;
netdev->hw_features |= NETIF_F_GSO_UDP_L4;
--
2.21.0
^ permalink raw reply related
* Re: [bpf-next] bpf: fix error check in bpf_tcp_gen_syncookie
From: Song Liu @ 2019-08-28 19:15 UTC (permalink / raw)
To: Petar Penkov
Cc: Networking, bpf, David S . Miller, Alexei Starovoitov,
Daniel Borkmann, Petar Penkov, Stanislav Fomichev
In-Reply-To: <20190827234622.76209-1-ppenkov.kernel@gmail.com>
On Tue, Aug 27, 2019 at 4:46 PM Petar Penkov <ppenkov.kernel@gmail.com> wrote:
>
> From: Petar Penkov <ppenkov@google.com>
>
> If a SYN cookie is not issued by tcp_v#_gen_syncookie, then the return
> value will be exactly 0, rather than <= 0. Let's change the check to
> reflect that, especially since mss is an unsigned value and cannot be
> negative.
>
> Fixes: 70d66244317e ("bpf: add bpf_tcp_gen_syncookie helper")
> Reported-by: Stanislav Fomichev <sdf@google.com>
> Signed-off-by: Petar Penkov <ppenkov@google.com>
Acked-by: Song Liu <songliubraving@fb.com>
^ permalink raw reply
* KASAN: use-after-free Read in rxrpc_put_peer
From: syzbot @ 2019-08-28 19:48 UTC (permalink / raw)
To: davem, dhowells, linux-afs, linux-kernel, netdev, syzkaller-bugs
Hello,
syzbot found the following crash on:
HEAD commit: ed2393ca Add linux-next specific files for 20190827
git tree: linux-next
console output: https://syzkaller.appspot.com/x/log.txt?x=11b4a79c600000
kernel config: https://syzkaller.appspot.com/x/.config?x=2ef5940a07ed45f4
dashboard link: https://syzkaller.appspot.com/bug?extid=b9be979c55f2bea8ed30
compiler: gcc (GCC) 9.0.0 20181231 (experimental)
syz repro: https://syzkaller.appspot.com/x/repro.syz?x=13c73066600000
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+b9be979c55f2bea8ed30@syzkaller.appspotmail.com
==================================================================
BUG: KASAN: use-after-free in __rxrpc_put_peer net/rxrpc/peer_object.c:411
[inline]
BUG: KASAN: use-after-free in rxrpc_put_peer+0x685/0x6a0
net/rxrpc/peer_object.c:435
Read of size 8 at addr ffff8880a05bd218 by task ksoftirqd/1/16
CPU: 1 PID: 16 Comm: ksoftirqd/1 Not tainted 5.3.0-rc6-next-20190827 #74
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x172/0x1f0 lib/dump_stack.c:113
print_address_description.constprop.0.cold+0xd4/0x30b mm/kasan/report.c:374
__kasan_report.cold+0x1b/0x41 mm/kasan/report.c:506
kasan_report+0x12/0x20 mm/kasan/common.c:634
__asan_report_load8_noabort+0x14/0x20 mm/kasan/generic_report.c:132
__rxrpc_put_peer net/rxrpc/peer_object.c:411 [inline]
rxrpc_put_peer+0x685/0x6a0 net/rxrpc/peer_object.c:435
rxrpc_rcu_destroy_call+0x5e/0x140 net/rxrpc/call_object.c:566
__rcu_reclaim kernel/rcu/rcu.h:222 [inline]
rcu_do_batch kernel/rcu/tree.c:2157 [inline]
rcu_core+0x581/0x1560 kernel/rcu/tree.c:2377
rcu_core_si+0x9/0x10 kernel/rcu/tree.c:2386
__do_softirq+0x262/0x98c kernel/softirq.c:292
run_ksoftirqd kernel/softirq.c:603 [inline]
run_ksoftirqd+0x8e/0x110 kernel/softirq.c:595
smpboot_thread_fn+0x6a3/0xa40 kernel/smpboot.c:165
kthread+0x361/0x430 kernel/kthread.c:255
ret_from_fork+0x24/0x30 arch/x86/entry/entry_64.S:352
Allocated by task 17189:
save_stack+0x23/0x90 mm/kasan/common.c:69
set_track mm/kasan/common.c:77 [inline]
__kasan_kmalloc mm/kasan/common.c:510 [inline]
__kasan_kmalloc.constprop.0+0xcf/0xe0 mm/kasan/common.c:483
kasan_kmalloc+0x9/0x10 mm/kasan/common.c:524
kmem_cache_alloc_trace+0x158/0x790 mm/slab.c:3550
kmalloc include/linux/slab.h:552 [inline]
kzalloc include/linux/slab.h:686 [inline]
rxrpc_alloc_local net/rxrpc/local_object.c:79 [inline]
rxrpc_lookup_local+0x562/0x1ba0 net/rxrpc/local_object.c:277
rxrpc_sendmsg+0x379/0x5f0 net/rxrpc/af_rxrpc.c:566
sock_sendmsg_nosec net/socket.c:637 [inline]
sock_sendmsg+0xd7/0x130 net/socket.c:657
___sys_sendmsg+0x3e2/0x920 net/socket.c:2311
__sys_sendmmsg+0x1bf/0x4d0 net/socket.c:2413
__do_sys_sendmmsg net/socket.c:2442 [inline]
__se_sys_sendmmsg net/socket.c:2439 [inline]
__x64_sys_sendmmsg+0x9d/0x100 net/socket.c:2439
do_syscall_64+0xfa/0x760 arch/x86/entry/common.c:290
entry_SYSCALL_64_after_hwframe+0x49/0xbe
Freed by task 9:
save_stack+0x23/0x90 mm/kasan/common.c:69
set_track mm/kasan/common.c:77 [inline]
kasan_set_free_info mm/kasan/common.c:332 [inline]
__kasan_slab_free+0x102/0x150 mm/kasan/common.c:471
kasan_slab_free+0xe/0x10 mm/kasan/common.c:480
__cache_free mm/slab.c:3425 [inline]
kfree+0x10a/0x2c0 mm/slab.c:3756
rxrpc_local_rcu+0x62/0x80 net/rxrpc/local_object.c:499
__rcu_reclaim kernel/rcu/rcu.h:222 [inline]
rcu_do_batch kernel/rcu/tree.c:2157 [inline]
rcu_core+0x581/0x1560 kernel/rcu/tree.c:2377
rcu_core_si+0x9/0x10 kernel/rcu/tree.c:2386
__do_softirq+0x262/0x98c kernel/softirq.c:292
The buggy address belongs to the object at ffff8880a05bd200
which belongs to the cache kmalloc-1k of size 1024
The buggy address is located 24 bytes inside of
1024-byte region [ffff8880a05bd200, ffff8880a05bd600)
The buggy address belongs to the page:
page:ffffea0002816f00 refcount:1 mapcount:0 mapping:ffff8880aa400c40
index:0xffff8880a05bcd80 compound_mapcount: 0
flags: 0x1fffc0000010200(slab|head)
raw: 01fffc0000010200 ffffea00027c4588 ffffea0002381088 ffff8880aa400c40
raw: ffff8880a05bcd80 ffff8880a05bc000 0000000100000006 0000000000000000
page dumped because: kasan: bad access detected
Memory state around the buggy address:
ffff8880a05bd100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff8880a05bd180: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> ffff8880a05bd200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff8880a05bd280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff8880a05bd300: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================
---
This bug is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.
syzbot will keep track of this bug report. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.
syzbot can test patches for this bug, for details see:
https://goo.gl/tpsmEJ#testing-patches
^ permalink raw reply
* Re: [PATCH net-next 03/15] net: sgi: ioc3-eth: remove checkpatch errors/warning
From: Thomas Bogendoerfer @ 2019-08-28 19:55 UTC (permalink / raw)
To: Joe Perches
Cc: Ralf Baechle, Paul Burton, James Hogan, David S. Miller,
linux-mips, linux-kernel, netdev
In-Reply-To: <d0fd02c3634d187dcfe5487917099bc1905e3789.camel@perches.com>
On Wed, 28 Aug 2019 10:10:18 -0700
Joe Perches <joe@perches.com> wrote:
> On Wed, 2019-08-28 at 16:03 +0200, Thomas Bogendoerfer wrote:
> > Before massaging the driver further fix oddities found by checkpatch like
> > - wrong indention
> > - comment formatting
> > - use of printk instead or netdev_xxx/pr_xxx
>
> trivial notes:
>
> Please try to make the code better rather than merely
> shutting up checkpatch.
that's the overall goal.
>
> > diff --git a/drivers/net/ethernet/sgi/ioc3-eth.c b/drivers/net/ethernet/sgi/ioc3-eth.c
> []
> > @@ -209,8 +201,7 @@ static inline void nic_write_bit(u32 __iomem *mcr, int bit)
> > nic_wait(mcr);
> > }
> >
> > -/*
> > - * Read a byte from an iButton device
> > +/* Read a byte from an iButton device
> > */
>
> These comment styles would be simpler on a single line
>
> /* Read a byte from an iButton device */
>
> > static u32 nic_read_byte(u32 __iomem *mcr)
> > {
> > @@ -223,8 +214,7 @@ static u32 nic_read_byte(u32 __iomem *mcr)
> > return result;
> > }
> >
> > -/*
> > - * Write a byte to an iButton device
> > +/* Write a byte to an iButton device
> > */
>
> /* Write a byte to an iButton device */
>
> etc...
>
> []
> > @@ -323,16 +315,15 @@ static int nic_init(u32 __iomem *mcr)
> > break;
> > }
> >
> > - printk("Found %s NIC", type);
> > + pr_info("Found %s NIC", type);
> > if (type != unknown)
> > - printk (" registration number %pM, CRC %02x", serial, crc);
> > - printk(".\n");
> > + pr_cont(" registration number %pM, CRC %02x", serial, crc);
> > + pr_cont(".\n");
>
> This code would be more sensible as
>
> if (type != unknown)
> pr_info("Found %s NIC registration number %pM, CRC %02x\n",
> type, serial, crc);
> else
> pr_info("Found %s NIC\n", type);
>
> Though I don't know if registration number is actually a MAC
> address or something else. If it's just a 6 byte identifier
> that uses colon separation it should probably use "%6phC"
> instead of "%pM"
all of the code above will entirely go away with the conversion to MFD.
> > @@ -645,22 +636,21 @@ static inline void ioc3_tx(struct net_device *dev)
> > static void ioc3_error(struct net_device *dev, u32 eisr)
> > {
> > struct ioc3_private *ip = netdev_priv(dev);
> > - unsigned char *iface = dev->name;
> >
> > spin_lock(&ip->ioc3_lock);
> >
> > if (eisr & EISR_RXOFLO)
> > - printk(KERN_ERR "%s: RX overflow.\n", iface);
> > + netdev_err(dev, "RX overflow.\n");
> > if (eisr & EISR_RXBUFOFLO)
> > - printk(KERN_ERR "%s: RX buffer overflow.\n", iface);
> > + netdev_err(dev, "RX buffer overflow.\n");
> > if (eisr & EISR_RXMEMERR)
> > - printk(KERN_ERR "%s: RX PCI error.\n", iface);
> > + netdev_err(dev, "RX PCI error.\n");
> > if (eisr & EISR_RXPARERR)
> > - printk(KERN_ERR "%s: RX SSRAM parity error.\n", iface);
> > + netdev_err(dev, "RX SSRAM parity error.\n");
> > if (eisr & EISR_TXBUFUFLO)
> > - printk(KERN_ERR "%s: TX buffer underflow.\n", iface);
> > + netdev_err(dev, "TX buffer underflow.\n");
> > if (eisr & EISR_TXMEMERR)
> > - printk(KERN_ERR "%s: TX PCI error.\n", iface);
> > + netdev_err(dev, "TX PCI error.\n");
>
> All of these should probably be ratelimited() output.
good point, will change it.
Thanks,
Thomas.
--
SUSE Software Solutions Germany GmbH
HRB 247165 (AG München)
Geschäftsführer: Felix Imendörffer
^ permalink raw reply
* Re: [PATCH v2] ipv6: Not to probe neighbourless routes
From: David Miller @ 2019-08-28 19:55 UTC (permalink / raw)
To: wang.yi59
Cc: kuznet, yoshfuji, netdev, linux-kernel, xue.zhihong, wang.liang82,
cheng.lin130
In-Reply-To: <201908281650080034915@zte.com.cn>
From: <wang.yi59@zte.com.cn>
Date: Wed, 28 Aug 2019 16:50:08 +0800 (CST)
> We used an older version of the kernel, and found that configuring default
> route led to a lot of NS messages, which affected the real business.
>
> Although commit f547fac624be adds rate-limiting, there are still some
> unreasonable things.
>
> We have tested this change on CentOS 7.6 (3.10.0-957), whose rt6_probe()
> implementation is similar to the latest code. When remaking patch based on
> linux-5.3-rc5, a line of code was missed out with a mistack.
Therefore, you are not testing this patch on current kernels, so you are
sending a patch which is completely untested.
This is not appropriate nor accceptable.
^ permalink raw reply
* Re: [PATCH v2] ipv6: Not to probe neighbourless routes
From: David Miller @ 2019-08-28 19:55 UTC (permalink / raw)
To: wang.yi59
Cc: kuznet, yoshfuji, netdev, linux-kernel, xue.zhihong, wang.liang82,
cheng.lin130
In-Reply-To: <1566958765-1686-1-git-send-email-wang.yi59@zte.com.cn>
I am tossing this patch.
Resubmit it when you test it properly on current kernels.
^ 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