* [PATCH v2 net-next 2/2] net: stmmac: Add support for DWMAC5 and implement Safety Features
From: Jose Abreu @ 2018-03-29 9:40 UTC (permalink / raw)
To: netdev
Cc: Jose Abreu, David S. Miller, Joao Pinto, Giuseppe Cavallaro,
Alexandre Torgue, Andrew Lunn
In-Reply-To: <cover.1522315930.git.joabreu@synopsys.com>
This adds initial suport for DWMAC5 and implements the Automotive Safety
Package which is available from core version 5.10.
The Automotive Safety Pacakge (also called Safety Features) offers us
with error protection in the core by implementing ECC Protection in
memories, on-chip data path parity protection, FSM parity and timeout
protection and Application/CSR interface timeout protection.
In case of an uncorrectable error we call stmmac_global_err() and
reconfigure the whole core.
Signed-off-by: Jose Abreu <joabreu@synopsys.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Joao Pinto <jpinto@synopsys.com>
Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Alexandre Torgue <alexandre.torgue@st.com>
Cc: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/ethernet/stmicro/stmmac/Makefile | 2 +-
drivers/net/ethernet/stmicro/stmmac/common.h | 22 ++
drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 4 +
drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 39 ++-
drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c | 6 +
drivers/net/ethernet/stmicro/stmmac/dwmac5.c | 298 +++++++++++++++++++++
drivers/net/ethernet/stmicro/stmmac/dwmac5.h | 52 ++++
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 1 +
.../net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 39 ++-
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 34 +++
10 files changed, 494 insertions(+), 3 deletions(-)
create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac5.c
create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac5.h
diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index ff3f83b8..972e4ef 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -4,7 +4,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o \
chain_mode.o dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \
dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o \
mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o \
- dwmac4_dma.o dwmac4_lib.o dwmac4_core.o $(stmmac-y)
+ dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o $(stmmac-y)
# Ordering matters. Generic driver must be last.
obj-$(CONFIG_STMMAC_PLATFORM) += stmmac-platform.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
index 2ffe76c..ad2388a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/common.h
+++ b/drivers/net/ethernet/stmicro/stmmac/common.h
@@ -38,6 +38,8 @@
#define DWMAC_CORE_3_40 0x34
#define DWMAC_CORE_3_50 0x35
#define DWMAC_CORE_4_00 0x40
+#define DWMAC_CORE_5_00 0x50
+#define DWMAC_CORE_5_10 0x51
#define STMMAC_CHAN0 0 /* Always supported and default for all chips */
/* These need to be power of two, and >= 4 */
@@ -174,6 +176,17 @@ struct stmmac_extra_stats {
unsigned long tx_tso_nfrags;
};
+/* Safety Feature statistics exposed by ethtool */
+struct stmmac_safety_stats {
+ unsigned long mac_errors[32];
+ unsigned long mtl_errors[32];
+ unsigned long dma_errors[32];
+};
+
+/* Number of fields in Safety Stats */
+#define STMMAC_SAFETY_FEAT_SIZE \
+ (sizeof(struct stmmac_safety_stats) / sizeof(unsigned long))
+
/* CSR Frequency Access Defines*/
#define CSR_F_35M 35000000
#define CSR_F_60M 60000000
@@ -336,6 +349,8 @@ struct dma_features {
/* TX and RX FIFO sizes */
unsigned int tx_fifo_size;
unsigned int rx_fifo_size;
+ /* Automotive Safety Package */
+ unsigned int asp;
};
/* GMAC TX FIFO is 8K, Rx FIFO is 16K */
@@ -532,6 +547,13 @@ struct stmmac_ops {
bool loopback);
void (*pcs_rane)(void __iomem *ioaddr, bool restart);
void (*pcs_get_adv_lp)(void __iomem *ioaddr, struct rgmii_adv *adv);
+ /* Safety Features */
+ int (*safety_feat_config)(void __iomem *ioaddr, unsigned int asp);
+ bool (*safety_feat_irq_status)(struct net_device *ndev,
+ void __iomem *ioaddr, unsigned int asp,
+ struct stmmac_safety_stats *stats);
+ const char *(*safety_feat_dump)(struct stmmac_safety_stats *stats,
+ int index, unsigned long *count);
};
/* PTP and HW Timer helpers */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
index 7761a26e..c7bff59 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
@@ -39,6 +39,7 @@
#define GMAC_HW_FEATURE0 0x0000011c
#define GMAC_HW_FEATURE1 0x00000120
#define GMAC_HW_FEATURE2 0x00000124
+#define GMAC_HW_FEATURE3 0x00000128
#define GMAC_MDIO_ADDR 0x00000200
#define GMAC_MDIO_DATA 0x00000204
#define GMAC_ADDR_HIGH(reg) (0x300 + reg * 8)
@@ -192,6 +193,9 @@ enum power_event {
#define GMAC_HW_FEAT_TXQCNT GENMASK(9, 6)
#define GMAC_HW_FEAT_RXQCNT GENMASK(3, 0)
+/* MAC HW features3 bitmap */
+#define GMAC_HW_FEAT_ASP GENMASK(29, 28)
+
/* MAC HW ADDR regs */
#define GMAC_HI_DCS GENMASK(18, 16)
#define GMAC_HI_DCS_SHIFT 16
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
index 46b9ae2..a3af92e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
@@ -20,6 +20,7 @@
#include <net/dsa.h>
#include "stmmac_pcs.h"
#include "dwmac4.h"
+#include "dwmac5.h"
static void dwmac4_core_init(struct mac_device_info *hw,
struct net_device *dev)
@@ -768,6 +769,40 @@ static const struct stmmac_ops dwmac410_ops = {
.set_filter = dwmac4_set_filter,
};
+static const struct stmmac_ops dwmac510_ops = {
+ .core_init = dwmac4_core_init,
+ .set_mac = stmmac_dwmac4_set_mac,
+ .rx_ipc = dwmac4_rx_ipc_enable,
+ .rx_queue_enable = dwmac4_rx_queue_enable,
+ .rx_queue_prio = dwmac4_rx_queue_priority,
+ .tx_queue_prio = dwmac4_tx_queue_priority,
+ .rx_queue_routing = dwmac4_rx_queue_routing,
+ .prog_mtl_rx_algorithms = dwmac4_prog_mtl_rx_algorithms,
+ .prog_mtl_tx_algorithms = dwmac4_prog_mtl_tx_algorithms,
+ .set_mtl_tx_queue_weight = dwmac4_set_mtl_tx_queue_weight,
+ .map_mtl_to_dma = dwmac4_map_mtl_dma,
+ .config_cbs = dwmac4_config_cbs,
+ .dump_regs = dwmac4_dump_regs,
+ .host_irq_status = dwmac4_irq_status,
+ .host_mtl_irq_status = dwmac4_irq_mtl_status,
+ .flow_ctrl = dwmac4_flow_ctrl,
+ .pmt = dwmac4_pmt,
+ .set_umac_addr = dwmac4_set_umac_addr,
+ .get_umac_addr = dwmac4_get_umac_addr,
+ .set_eee_mode = dwmac4_set_eee_mode,
+ .reset_eee_mode = dwmac4_reset_eee_mode,
+ .set_eee_timer = dwmac4_set_eee_timer,
+ .set_eee_pls = dwmac4_set_eee_pls,
+ .pcs_ctrl_ane = dwmac4_ctrl_ane,
+ .pcs_rane = dwmac4_rane,
+ .pcs_get_adv_lp = dwmac4_get_adv_lp,
+ .debug = dwmac4_debug,
+ .set_filter = dwmac4_set_filter,
+ .safety_feat_config = dwmac5_safety_feat_config,
+ .safety_feat_irq_status = dwmac5_safety_feat_irq_status,
+ .safety_feat_dump = dwmac5_safety_feat_dump,
+};
+
struct mac_device_info *dwmac4_setup(void __iomem *ioaddr, int mcbins,
int perfect_uc_entries, int *synopsys_id)
{
@@ -808,7 +843,9 @@ struct mac_device_info *dwmac4_setup(void __iomem *ioaddr, int mcbins,
else
mac->dma = &dwmac4_dma_ops;
- if (*synopsys_id >= DWMAC_CORE_4_00)
+ if (*synopsys_id >= DWMAC_CORE_5_10)
+ mac->mac = &dwmac510_ops;
+ else if (*synopsys_id >= DWMAC_CORE_4_00)
mac->mac = &dwmac410_ops;
else
mac->mac = &dwmac4_ops;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
index c110f68..d37d457 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c
@@ -373,6 +373,12 @@ static void dwmac4_get_hw_feature(void __iomem *ioaddr,
/* IEEE 1588-2002 */
dma_cap->time_stamp = 0;
+
+ /* MAC HW feature3 */
+ hw_cap = readl(ioaddr + GMAC_HW_FEATURE3);
+
+ /* 5.10 Features */
+ dma_cap->asp = (hw_cap & GMAC_HW_FEAT_ASP) >> 28;
}
/* Enable/disable TSO feature and set MSS */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac5.c b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c
new file mode 100644
index 0000000..860de39
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac5.c
@@ -0,0 +1,298 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+// Copyright (c) 2017 Synopsys, Inc. and/or its affiliates.
+// stmmac Support for 5.xx Ethernet QoS cores
+
+#include <linux/bitops.h>
+#include <linux/iopoll.h>
+#include "common.h"
+#include "dwmac4.h"
+#include "dwmac5.h"
+
+struct dwmac5_error_desc {
+ bool valid;
+ const char *desc;
+ const char *detailed_desc;
+};
+
+#define STAT_OFF(field) offsetof(struct stmmac_safety_stats, field)
+
+static void dwmac5_log_error(struct net_device *ndev, u32 value, bool corr,
+ const char *module_name, const struct dwmac5_error_desc *desc,
+ unsigned long field_offset, struct stmmac_safety_stats *stats)
+{
+ unsigned long loc, mask;
+ u8 *bptr = (u8 *)stats;
+ unsigned long *ptr;
+
+ ptr = (unsigned long *)(bptr + field_offset);
+
+ mask = value;
+ for_each_set_bit(loc, &mask, 32) {
+ netdev_err(ndev, "Found %s error in %s: '%s: %s'\n", corr ?
+ "correctable" : "uncorrectable", module_name,
+ desc[loc].desc, desc[loc].detailed_desc);
+
+ /* Update counters */
+ ptr[loc]++;
+ }
+}
+
+static const struct dwmac5_error_desc dwmac5_mac_errors[32]= {
+ { true, "ATPES", "Application Transmit Interface Parity Check Error" },
+ { true, "TPES", "TSO Data Path Parity Check Error" },
+ { true, "RDPES", "Read Descriptor Parity Check Error" },
+ { true, "MPES", "MTL Data Path Parity Check Error" },
+ { true, "MTSPES", "MTL TX Status Data Path Parity Check Error" },
+ { true, "ARPES", "Application Receive Interface Data Path Parity Check Error" },
+ { true, "CWPES", "CSR Write Data Path Parity Check Error" },
+ { true, "ASRPES", "AXI Slave Read Data Path Parity Check Error" },
+ { true, "TTES", "TX FSM Timeout Error" },
+ { true, "RTES", "RX FSM Timeout Error" },
+ { true, "CTES", "CSR FSM Timeout Error" },
+ { true, "ATES", "APP FSM Timeout Error" },
+ { true, "PTES", "PTP FSM Timeout Error" },
+ { true, "T125ES", "TX125 FSM Timeout Error" },
+ { true, "R125ES", "RX125 FSM Timeout Error" },
+ { true, "RVCTES", "REV MDC FSM Timeout Error" },
+ { true, "MSTTES", "Master Read/Write Timeout Error" },
+ { true, "SLVTES", "Slave Read/Write Timeout Error" },
+ { true, "ATITES", "Application Timeout on ATI Interface Error" },
+ { true, "ARITES", "Application Timeout on ARI Interface Error" },
+ { false, "UNKNOWN", "Unknown Error" }, /* 20 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 21 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 22 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 23 */
+ { true, "FSMPES", "FSM State Parity Error" },
+ { false, "UNKNOWN", "Unknown Error" }, /* 25 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 26 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 27 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 28 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 29 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 30 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 31 */
+};
+
+static void dwmac5_handle_mac_err(struct net_device *ndev,
+ void __iomem *ioaddr, bool correctable,
+ struct stmmac_safety_stats *stats)
+{
+ u32 value;
+
+ value = readl(ioaddr + MAC_DPP_FSM_INT_STATUS);
+ writel(value, ioaddr + MAC_DPP_FSM_INT_STATUS);
+
+ dwmac5_log_error(ndev, value, correctable, "MAC", dwmac5_mac_errors,
+ STAT_OFF(mac_errors), stats);
+}
+
+static const struct dwmac5_error_desc dwmac5_mtl_errors[32]= {
+ { true, "TXCES", "MTL TX Memory Error" },
+ { true, "TXAMS", "MTL TX Memory Address Mismatch Error" },
+ { true, "TXUES", "MTL TX Memory Error" },
+ { false, "UNKNOWN", "Unknown Error" }, /* 3 */
+ { true, "RXCES", "MTL RX Memory Error" },
+ { true, "RXAMS", "MTL RX Memory Address Mismatch Error" },
+ { true, "RXUES", "MTL RX Memory Error" },
+ { false, "UNKNOWN", "Unknown Error" }, /* 7 */
+ { true, "ECES", "MTL EST Memory Error" },
+ { true, "EAMS", "MTL EST Memory Address Mismatch Error" },
+ { true, "EUES", "MTL EST Memory Error" },
+ { false, "UNKNOWN", "Unknown Error" }, /* 11 */
+ { true, "RPCES", "MTL RX Parser Memory Error" },
+ { true, "RPAMS", "MTL RX Parser Memory Address Mismatch Error" },
+ { true, "RPUES", "MTL RX Parser Memory Error" },
+ { false, "UNKNOWN", "Unknown Error" }, /* 15 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 16 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 17 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 18 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 19 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 20 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 21 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 22 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 23 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 24 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 25 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 26 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 27 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 28 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 29 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 30 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 31 */
+};
+
+static void dwmac5_handle_mtl_err(struct net_device *ndev,
+ void __iomem *ioaddr, bool correctable,
+ struct stmmac_safety_stats *stats)
+{
+ u32 value;
+
+ value = readl(ioaddr + MTL_ECC_INT_STATUS);
+ writel(value, ioaddr + MTL_ECC_INT_STATUS);
+
+ dwmac5_log_error(ndev, value, correctable, "MTL", dwmac5_mtl_errors,
+ STAT_OFF(mtl_errors), stats);
+}
+
+static const struct dwmac5_error_desc dwmac5_dma_errors[32]= {
+ { true, "TCES", "DMA TSO Memory Error" },
+ { true, "TAMS", "DMA TSO Memory Address Mismatch Error" },
+ { true, "TUES", "DMA TSO Memory Error" },
+ { false, "UNKNOWN", "Unknown Error" }, /* 3 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 4 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 5 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 6 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 7 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 8 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 9 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 10 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 11 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 12 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 13 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 14 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 15 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 16 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 17 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 18 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 19 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 20 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 21 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 22 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 23 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 24 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 25 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 26 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 27 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 28 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 29 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 30 */
+ { false, "UNKNOWN", "Unknown Error" }, /* 31 */
+};
+
+static void dwmac5_handle_dma_err(struct net_device *ndev,
+ void __iomem *ioaddr, bool correctable,
+ struct stmmac_safety_stats *stats)
+{
+ u32 value;
+
+ value = readl(ioaddr + DMA_ECC_INT_STATUS);
+ writel(value, ioaddr + DMA_ECC_INT_STATUS);
+
+ dwmac5_log_error(ndev, value, correctable, "DMA", dwmac5_dma_errors,
+ STAT_OFF(dma_errors), stats);
+}
+
+int dwmac5_safety_feat_config(void __iomem *ioaddr, unsigned int asp)
+{
+ u32 value;
+
+ if (!asp)
+ return -EINVAL;
+
+ /* 1. Enable Safety Features */
+ value = readl(ioaddr + MTL_ECC_CONTROL);
+ value |= TSOEE; /* TSO ECC */
+ value |= MRXPEE; /* MTL RX Parser ECC */
+ value |= MESTEE; /* MTL EST ECC */
+ value |= MRXEE; /* MTL RX FIFO ECC */
+ value |= MTXEE; /* MTL TX FIFO ECC */
+ writel(value, ioaddr + MTL_ECC_CONTROL);
+
+ /* 2. Enable MTL Safety Interrupts */
+ value = readl(ioaddr + MTL_ECC_INT_ENABLE);
+ value |= RPCEIE; /* RX Parser Memory Correctable Error */
+ value |= ECEIE; /* EST Memory Correctable Error */
+ value |= RXCEIE; /* RX Memory Correctable Error */
+ value |= TXCEIE; /* TX Memory Correctable Error */
+ writel(value, ioaddr + MTL_ECC_INT_ENABLE);
+
+ /* 3. Enable DMA Safety Interrupts */
+ value = readl(ioaddr + DMA_ECC_INT_ENABLE);
+ value |= TCEIE; /* TSO Memory Correctable Error */
+ writel(value, ioaddr + DMA_ECC_INT_ENABLE);
+
+ /* Only ECC Protection for External Memory feature is selected */
+ if (asp <= 0x1)
+ return 0;
+
+ /* 5. Enable Parity and Timeout for FSM */
+ value = readl(ioaddr + MAC_FSM_CONTROL);
+ value |= PRTYEN; /* FSM Parity Feature */
+ value |= TMOUTEN; /* FSM Timeout Feature */
+ writel(value, ioaddr + MAC_FSM_CONTROL);
+
+ /* 4. Enable Data Parity Protection */
+ value = readl(ioaddr + MTL_DPP_CONTROL);
+ value |= EDPP;
+ writel(value, ioaddr + MTL_DPP_CONTROL);
+
+ /*
+ * All the Automotive Safety features are selected without the "Parity
+ * Port Enable for external interface" feature.
+ */
+ if (asp <= 0x2)
+ return 0;
+
+ value |= EPSI;
+ writel(value, ioaddr + MTL_DPP_CONTROL);
+ return 0;
+}
+
+bool dwmac5_safety_feat_irq_status(struct net_device *ndev,
+ void __iomem *ioaddr, unsigned int asp,
+ struct stmmac_safety_stats *stats)
+{
+ bool ret = false, err, corr;
+ u32 mtl, dma;
+
+ if (!asp)
+ return false;
+
+ mtl = readl(ioaddr + MTL_SAFETY_INT_STATUS);
+ dma = readl(ioaddr + DMA_SAFETY_INT_STATUS);
+
+ err = (mtl & MCSIS) || (dma & MCSIS);
+ corr = false;
+ if (err) {
+ dwmac5_handle_mac_err(ndev, ioaddr, corr, stats);
+ ret |= !corr;
+ }
+
+ err = (mtl & (MEUIS | MECIS)) || (dma & (MSUIS | MSCIS));
+ corr = (mtl & MECIS) || (dma & MSCIS);
+ if (err) {
+ dwmac5_handle_mtl_err(ndev, ioaddr, corr, stats);
+ ret |= !corr;
+ }
+
+ err = dma & (DEUIS | DECIS);
+ corr = dma & DECIS;
+ if (err) {
+ dwmac5_handle_dma_err(ndev, ioaddr, corr, stats);
+ ret |= !corr;
+ }
+
+ return ret;
+}
+
+static const struct dwmac5_error {
+ const struct dwmac5_error_desc *desc;
+} dwmac5_all_errors[] = {
+ { dwmac5_mac_errors },
+ { dwmac5_mtl_errors },
+ { dwmac5_dma_errors },
+};
+
+const char *dwmac5_safety_feat_dump(struct stmmac_safety_stats *stats,
+ int index, unsigned long *count)
+{
+ int module = index / 32, offset = index % 32;
+ unsigned long *ptr = (unsigned long *)stats;
+
+ if (module >= ARRAY_SIZE(dwmac5_all_errors))
+ return NULL;
+ if (!dwmac5_all_errors[module].desc[offset].valid)
+ return NULL;
+ if (count)
+ *count = *(ptr + index);
+ return dwmac5_all_errors[module].desc[offset].desc;
+}
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac5.h b/drivers/net/ethernet/stmicro/stmmac/dwmac5.h
new file mode 100644
index 0000000..a0d2c44
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac5.h
@@ -0,0 +1,52 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+// Copyright (c) 2017 Synopsys, Inc. and/or its affiliates.
+// stmmac Support for 5.xx Ethernet QoS cores
+
+#ifndef __DWMAC5_H__
+#define __DWMAC5_H__
+
+#define MAC_DPP_FSM_INT_STATUS 0x00000140
+#define MAC_AXI_SLV_DPE_ADDR_STATUS 0x00000144
+#define MAC_FSM_CONTROL 0x00000148
+#define PRTYEN BIT(1)
+#define TMOUTEN BIT(0)
+
+#define MTL_ECC_CONTROL 0x00000cc0
+#define TSOEE BIT(4)
+#define MRXPEE BIT(3)
+#define MESTEE BIT(2)
+#define MRXEE BIT(1)
+#define MTXEE BIT(0)
+
+#define MTL_SAFETY_INT_STATUS 0x00000cc4
+#define MCSIS BIT(31)
+#define MEUIS BIT(1)
+#define MECIS BIT(0)
+#define MTL_ECC_INT_ENABLE 0x00000cc8
+#define RPCEIE BIT(12)
+#define ECEIE BIT(8)
+#define RXCEIE BIT(4)
+#define TXCEIE BIT(0)
+#define MTL_ECC_INT_STATUS 0x00000ccc
+#define MTL_DPP_CONTROL 0x00000ce0
+#define EPSI BIT(2)
+#define OPE BIT(1)
+#define EDPP BIT(0)
+
+#define DMA_SAFETY_INT_STATUS 0x00001080
+#define MSUIS BIT(29)
+#define MSCIS BIT(28)
+#define DEUIS BIT(1)
+#define DECIS BIT(0)
+#define DMA_ECC_INT_ENABLE 0x00001084
+#define TCEIE BIT(0)
+#define DMA_ECC_INT_STATUS 0x00001088
+
+int dwmac5_safety_feat_config(void __iomem *ioaddr, unsigned int asp);
+bool dwmac5_safety_feat_irq_status(struct net_device *ndev,
+ void __iomem *ioaddr, unsigned int asp,
+ struct stmmac_safety_stats *stats);
+const char *dwmac5_safety_feat_dump(struct stmmac_safety_stats *stats,
+ int index, unsigned long *count);
+
+#endif /* __DWMAC5_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 1485d8f..da50451 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -114,6 +114,7 @@ struct stmmac_priv {
int mii_irq[PHY_MAX_ADDR];
struct stmmac_extra_stats xstats ____cacheline_aligned_in_smp;
+ struct stmmac_safety_stats sstats;
struct plat_stmmacenet_data *plat;
struct dma_features dma_cap;
struct stmmac_counters mmc;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
index af30b48..2c6ed47 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
@@ -523,11 +523,23 @@ stmmac_set_pauseparam(struct net_device *netdev,
static void stmmac_get_ethtool_stats(struct net_device *dev,
struct ethtool_stats *dummy, u64 *data)
{
+ const char *(*dump)(struct stmmac_safety_stats *stats, int index,
+ unsigned long *count);
struct stmmac_priv *priv = netdev_priv(dev);
u32 rx_queues_count = priv->plat->rx_queues_to_use;
u32 tx_queues_count = priv->plat->tx_queues_to_use;
+ unsigned long count;
int i, j = 0;
+ if (priv->dma_cap.asp && priv->hw->mac->safety_feat_dump) {
+ dump = priv->hw->mac->safety_feat_dump;
+
+ for (i = 0; i < STMMAC_SAFETY_FEAT_SIZE; i++) {
+ if (dump(&priv->sstats, i, &count))
+ data[j++] = count;
+ }
+ }
+
/* Update the DMA HW counters for dwmac10/100 */
if (priv->hw->dma->dma_diagnostic_fr)
priv->hw->dma->dma_diagnostic_fr(&dev->stats,
@@ -569,7 +581,9 @@ static void stmmac_get_ethtool_stats(struct net_device *dev,
static int stmmac_get_sset_count(struct net_device *netdev, int sset)
{
struct stmmac_priv *priv = netdev_priv(netdev);
- int len;
+ const char *(*dump)(struct stmmac_safety_stats *stats, int index,
+ unsigned long *count);
+ int i, len, safety_len = 0;
switch (sset) {
case ETH_SS_STATS:
@@ -577,6 +591,16 @@ static int stmmac_get_sset_count(struct net_device *netdev, int sset)
if (priv->dma_cap.rmon)
len += STMMAC_MMC_STATS_LEN;
+ if (priv->dma_cap.asp && priv->hw->mac->safety_feat_dump) {
+ dump = priv->hw->mac->safety_feat_dump;
+
+ for (i = 0; i < STMMAC_SAFETY_FEAT_SIZE; i++) {
+ if (dump(&priv->sstats, i, NULL))
+ safety_len++;
+ }
+
+ len += safety_len;
+ }
return len;
default:
@@ -589,9 +613,22 @@ static void stmmac_get_strings(struct net_device *dev, u32 stringset, u8 *data)
int i;
u8 *p = data;
struct stmmac_priv *priv = netdev_priv(dev);
+ const char *(*dump)(struct stmmac_safety_stats *stats, int index,
+ unsigned long *count);
switch (stringset) {
case ETH_SS_STATS:
+ if (priv->dma_cap.asp && priv->hw->mac->safety_feat_dump) {
+ dump = priv->hw->mac->safety_feat_dump;
+ for (i = 0; i < STMMAC_SAFETY_FEAT_SIZE; i++) {
+ const char *desc = dump(&priv->sstats, i, NULL);
+
+ if (desc) {
+ memcpy(p, desc, ETH_GSTRING_LEN);
+ p += ETH_GSTRING_LEN;
+ }
+ }
+ }
if (priv->dma_cap.rmon)
for (i = 0; i < STMMAC_MMC_STATS_LEN; i++) {
memcpy(p, stmmac_mmc[i].stat_string,
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index b75ecf3..9a16931 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2014,6 +2014,22 @@ static void stmmac_set_dma_operation_mode(struct stmmac_priv *priv, u32 txmode,
}
}
+static bool stmmac_safety_feat_interrupt(struct stmmac_priv *priv)
+{
+ bool ret = false;
+
+ /* Safety features are only available in cores >= 5.10 */
+ if (priv->synopsys_id < DWMAC_CORE_5_10)
+ return ret;
+ if (priv->hw->mac->safety_feat_irq_status)
+ ret = priv->hw->mac->safety_feat_irq_status(priv->dev,
+ priv->ioaddr, priv->dma_cap.asp, &priv->sstats);
+
+ if (ret)
+ stmmac_global_err(priv);
+ return ret;
+}
+
/**
* stmmac_dma_interrupt - DMA ISR
* @priv: driver private structure
@@ -2503,6 +2519,17 @@ static void stmmac_mtl_configuration(struct stmmac_priv *priv)
stmmac_mac_config_rx_queues_routing(priv);
}
+static void stmmac_safety_feat_configuration(struct stmmac_priv *priv)
+{
+ if (priv->hw->mac->safety_feat_config && priv->dma_cap.asp) {
+ netdev_info(priv->dev, "Enabling Safety Features\n");
+ priv->hw->mac->safety_feat_config(priv->ioaddr,
+ priv->dma_cap.asp);
+ } else {
+ netdev_info(priv->dev, "No Safety Features support found\n");
+ }
+}
+
/**
* stmmac_hw_setup - setup mac in a usable state.
* @dev : pointer to the device structure.
@@ -2554,6 +2581,10 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
if (priv->synopsys_id >= DWMAC_CORE_4_00)
stmmac_mtl_configuration(priv);
+ /* Initialize Safety Features */
+ if (priv->synopsys_id >= DWMAC_CORE_5_10)
+ stmmac_safety_feat_configuration(priv);
+
ret = priv->hw->mac->rx_ipc(priv->hw);
if (!ret) {
netdev_warn(priv->dev, "RX IPC Checksum Offload disabled\n");
@@ -3729,6 +3760,9 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
/* Check if adapter is up */
if (test_bit(STMMAC_DOWN, &priv->state))
return IRQ_HANDLED;
+ /* Check if a fatal error happened */
+ if (stmmac_safety_feat_interrupt(priv))
+ return IRQ_HANDLED;
/* To handle GMAC own interrupts */
if ((priv->plat->has_gmac) || (priv->plat->has_gmac4)) {
--
2.9.3
^ permalink raw reply related
* [PATCH v2 net-next 1/2] net: stmmac: Rework and fix TX Timeout code
From: Jose Abreu @ 2018-03-29 9:40 UTC (permalink / raw)
To: netdev
Cc: Jose Abreu, David S. Miller, Joao Pinto, Giuseppe Cavallaro,
Alexandre Torgue, Andrew Lunn
In-Reply-To: <cover.1522315930.git.joabreu@synopsys.com>
Currently TX Timeout handler does not behaves as expected and leads to
an unrecoverable state. Rework current implementation of TX Timeout
handling to actually perform a complete reset of the driver state and IP.
We use deferred work to init a task which will be responsible for
resetting the system.
Signed-off-by: Jose Abreu <joabreu@synopsys.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Joao Pinto <jpinto@synopsys.com>
Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Alexandre Torgue <alexandre.torgue@st.com>
Cc: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 11 ++++
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 67 +++++++++++++++++++++--
2 files changed, 73 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
index 75161e1..1485d8f 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h
@@ -145,6 +145,17 @@ struct stmmac_priv {
struct dentry *dbgfs_rings_status;
struct dentry *dbgfs_dma_cap;
#endif
+
+ unsigned long state;
+ struct workqueue_struct *wq;
+ struct work_struct service_task;
+};
+
+enum stmmac_state {
+ STMMAC_DOWN,
+ STMMAC_RESET_REQUESTED,
+ STMMAC_RESETING,
+ STMMAC_SERVICE_SCHED,
};
int stmmac_mdio_unregister(struct net_device *ndev);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 9f983dd..b75ecf3 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -196,6 +196,20 @@ static void stmmac_start_all_queues(struct stmmac_priv *priv)
netif_tx_start_queue(netdev_get_tx_queue(priv->dev, queue));
}
+static void stmmac_service_event_schedule(struct stmmac_priv *priv)
+{
+ if (!test_bit(STMMAC_DOWN, &priv->state) &&
+ !test_and_set_bit(STMMAC_SERVICE_SCHED, &priv->state))
+ queue_work(priv->wq, &priv->service_task);
+}
+
+static void stmmac_global_err(struct stmmac_priv *priv)
+{
+ netif_carrier_off(priv->dev);
+ set_bit(STMMAC_RESET_REQUESTED, &priv->state);
+ stmmac_service_event_schedule(priv);
+}
+
/**
* stmmac_clk_csr_set - dynamically set the MDC clock
* @priv: driver private structure
@@ -3587,12 +3601,8 @@ static int stmmac_poll(struct napi_struct *napi, int budget)
static void stmmac_tx_timeout(struct net_device *dev)
{
struct stmmac_priv *priv = netdev_priv(dev);
- u32 tx_count = priv->plat->tx_queues_to_use;
- u32 chan;
- /* Clear Tx resources and restart transmitting again */
- for (chan = 0; chan < tx_count; chan++)
- stmmac_tx_err(priv, chan);
+ stmmac_global_err(priv);
}
/**
@@ -3716,6 +3726,10 @@ static irqreturn_t stmmac_interrupt(int irq, void *dev_id)
return IRQ_NONE;
}
+ /* Check if adapter is up */
+ if (test_bit(STMMAC_DOWN, &priv->state))
+ return IRQ_HANDLED;
+
/* To handle GMAC own interrupts */
if ((priv->plat->has_gmac) || (priv->plat->has_gmac4)) {
int status = priv->hw->mac->host_irq_status(priv->hw,
@@ -4051,6 +4065,37 @@ static const struct net_device_ops stmmac_netdev_ops = {
.ndo_set_mac_address = stmmac_set_mac_address,
};
+static void stmmac_reset_subtask(struct stmmac_priv *priv)
+{
+ if (!test_and_clear_bit(STMMAC_RESET_REQUESTED, &priv->state))
+ return;
+ if (test_bit(STMMAC_DOWN, &priv->state))
+ return;
+
+ netdev_err(priv->dev, "Reset adapter.\n");
+
+ rtnl_lock();
+ netif_trans_update(priv->dev);
+ while (test_and_set_bit(STMMAC_RESETING, &priv->state))
+ usleep_range(1000, 2000);
+
+ set_bit(STMMAC_DOWN, &priv->state);
+ dev_close(priv->dev);
+ dev_open(priv->dev);
+ clear_bit(STMMAC_DOWN, &priv->state);
+ clear_bit(STMMAC_RESETING, &priv->state);
+ rtnl_unlock();
+}
+
+static void stmmac_service_task(struct work_struct *work)
+{
+ struct stmmac_priv *priv = container_of(work, struct stmmac_priv,
+ service_task);
+
+ stmmac_reset_subtask(priv);
+ clear_bit(STMMAC_SERVICE_SCHED, &priv->state);
+}
+
/**
* stmmac_hw_init - Init the MAC device
* @priv: driver private structure
@@ -4212,6 +4257,15 @@ int stmmac_dvr_probe(struct device *device,
/* Verify driver arguments */
stmmac_verify_args();
+ /* Allocate workqueue */
+ priv->wq = create_singlethread_workqueue("stmmac_wq");
+ if (!priv->wq) {
+ dev_err(priv->device, "failed to create workqueue\n");
+ goto error_wq;
+ }
+
+ INIT_WORK(&priv->service_task, stmmac_service_task);
+
/* Override with kernel parameters if supplied XXX CRS XXX
* this needs to have multiple instances
*/
@@ -4342,6 +4396,8 @@ int stmmac_dvr_probe(struct device *device,
netif_napi_del(&rx_q->napi);
}
error_hw_init:
+ destroy_workqueue(priv->wq);
+error_wq:
free_netdev(ndev);
return ret;
@@ -4374,6 +4430,7 @@ int stmmac_dvr_remove(struct device *dev)
priv->hw->pcs != STMMAC_PCS_TBI &&
priv->hw->pcs != STMMAC_PCS_RTBI)
stmmac_mdio_unregister(ndev);
+ destroy_workqueue(priv->wq);
free_netdev(ndev);
return 0;
--
2.9.3
^ permalink raw reply related
* [PATCH v2 net-next 0/2] Fix TX Timeout and implement Safety Features
From: Jose Abreu @ 2018-03-29 9:40 UTC (permalink / raw)
To: netdev
Cc: Jose Abreu, David S. Miller, Joao Pinto, Giuseppe Cavallaro,
Alexandre Torgue, Andrew Lunn
Fix the TX Timeout handler to correctly reconfigure the whole system and
start implementing features for DWMAC5 cores, specifically the Safety
Features.
Changes since v1:
- Display error stats in ethtool
Cc: David S. Miller <davem@davemloft.net>
Cc: Joao Pinto <jpinto@synopsys.com>
Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Alexandre Torgue <alexandre.torgue@st.com>
Cc: Andrew Lunn <andrew@lunn.ch>
Jose Abreu (2):
net: stmmac: Rework and fix TX Timeout code
net: stmmac: Add support for DWMAC5 and implement Safety Features
drivers/net/ethernet/stmicro/stmmac/Makefile | 2 +-
drivers/net/ethernet/stmicro/stmmac/common.h | 22 ++
drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 4 +
drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 39 ++-
drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c | 6 +
drivers/net/ethernet/stmicro/stmmac/dwmac5.c | 298 +++++++++++++++++++++
drivers/net/ethernet/stmicro/stmmac/dwmac5.h | 52 ++++
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 12 +
.../net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 39 ++-
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 101 ++++++-
10 files changed, 567 insertions(+), 8 deletions(-)
create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac5.c
create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwmac5.h
--
2.9.3
^ permalink raw reply
* [PATCH] net: mvneta: remove duplicate *_coal assignment
From: Jisheng Zhang @ 2018-03-29 9:29 UTC (permalink / raw)
To: Thomas Petazzoni, David Miller; +Cc: netdev, linux-kernel, linux-arm-kernel
The style of the rx/tx queue's *_coal member assignment is:
static void foo_coal_set(...)
{
set the coal in hw;
update queue's foo_coal member; [1]
}
In other place, we call foo_coal_set(pp, queue->foo_coal), so the above [1]
is duplicated and could be removed.
Signed-off-by: Jisheng Zhang <Jisheng.Zhang@synaptics.com>
---
drivers/net/ethernet/marvell/mvneta.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
index eaa4bb80f1c9..30aab9bf77cc 100644
--- a/drivers/net/ethernet/marvell/mvneta.c
+++ b/drivers/net/ethernet/marvell/mvneta.c
@@ -1555,7 +1555,6 @@ static void mvneta_rx_pkts_coal_set(struct mvneta_port *pp,
{
mvreg_write(pp, MVNETA_RXQ_THRESHOLD_REG(rxq->id),
value | MVNETA_RXQ_NON_OCCUPIED(0));
- rxq->pkts_coal = value;
}
/* Set the time delay in usec before RX interrupt will be generated by
@@ -1571,7 +1570,6 @@ static void mvneta_rx_time_coal_set(struct mvneta_port *pp,
val = (clk_rate / 1000000) * value;
mvreg_write(pp, MVNETA_RXQ_TIME_COAL_REG(rxq->id), val);
- rxq->time_coal = value;
}
/* Set threshold for TX_DONE pkts coalescing */
@@ -1586,8 +1584,6 @@ static void mvneta_tx_done_pkts_coal_set(struct mvneta_port *pp,
val |= MVNETA_TXQ_SENT_THRESH_MASK(value);
mvreg_write(pp, MVNETA_TXQ_SIZE_REG(txq->id), val);
-
- txq->done_pkts_coal = value;
}
/* Handle rx descriptor fill by setting buf_cookie and buf_phys_addr */
--
2.16.3
^ permalink raw reply related
* Re: RFC on writel and writel_relaxed
From: Will Deacon @ 2018-03-29 9:20 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Nicholas Piggin, David Miller, paulmck, arnd, linux-rdma,
linuxppc-dev, linus971, alexander.duyck, okaya, jgg, David.Laight,
oohall, netdev, alexander.h.duyck, torvalds
In-Reply-To: <1522272692.21446.42.camel@kernel.crashing.org>
On Thu, Mar 29, 2018 at 08:31:32AM +1100, Benjamin Herrenschmidt wrote:
> On Thu, 2018-03-29 at 02:23 +1000, Nicholas Piggin wrote:
> > This is a variation on the mandatory write barrier that causes writes to weakly
> > ordered I/O regions to be partially ordered. Its effects may go beyond the
> > CPU->Hardware interface and actually affect the hardware at some level.
> >
> > How can a driver writer possibly get that right?
> >
> > IIRC it was added for some big ia64 system that was really expensive
> > to implement the proper wmb() semantics on. So wmb() semantics were
> > quietly downgraded, then the subsequently broken drivers they cared
> > about were fixed by adding the stronger mmiowb().
> >
> > What should have happened was wmb and writel remained correct, sane, and
> > expensive, and they add an mmio_wmb() to order MMIO stores made by the
> > writel_relaxed accessors, then use that to speed up the few drivers they
> > care about.
> >
> > Now that ia64 doesn't matter too much, can we deprecate mmiowb and just
> > make wmb ordering talk about stores to the device, not to some
> > intermediate stage of the interconnect where it can be subsequently
> > reordered wrt the device? Drivers can be converted back to using wmb
> > or writel gradually.
>
> I was under the impression that mmiowb was specifically about ordering
> writel's with a subsequent spin_unlock, without it, MMIOs from
> different CPUs (within the same lock) would still arrive OO.
>
> If that's indeed the case, I would suggest ia64 switches to a similar
> per-cpu flag trick powerpc uses.
... or we could remove ia64.
/me runs for cover
Will
^ permalink raw reply
* RE: [PATCH v7 3/7] bnx2x: Replace doorbell barrier() with wmb()
From: Elior, Ariel @ 2018-03-29 9:17 UTC (permalink / raw)
To: Sinan Kaya, netdev@vger.kernel.org, timur@codeaurora.org,
sulrich@codeaurora.org
Cc: linux-arm-msm@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, Dept-Eng Everest Linux L2,
linux-kernel@vger.kernel.org
In-Reply-To: <1521988761-30344-4-git-send-email-okaya@codeaurora.org>
> Subject: [PATCH v7 3/7] bnx2x: Replace doorbell barrier() with wmb()
>
> barrier() doesn't guarantee memory writes to be observed by the hardware on
> all architectures. barrier() only tells compiler not to move this code
> with respect to other read/writes.
>
> If memory write needs to be observed by the HW, wmb() is the right choice.
The wmb() is there (a couple of lines above). Your modification adds an
unnecessary fence which would hurt high pps scenarios. The memory
writes which the HW needs to observe are the buffer descriptors, not the
producer update message. The producer is written to the HW, and exists
on the stack. The barrier() is there to prevent the compiler from mixing the
order of the prod update message preparation and writing it to the host.
A possible alternative would be to move the existing wmb() to where
the barrier() is, achieving both goals, although in the existing design each
barrier has a distinct purpose. The comment location is misleading, though.
Thanks,
Ariel
^ permalink raw reply
* Re: ath: Remove unnecessary ath_bcast_mac and use eth_broadcast_addr
From: Kalle Valo @ 2018-03-29 9:11 UTC (permalink / raw)
To: Joe Perches
Cc: Luis R. Rodriguez, Jiri Slaby, Nick Kossifidis,
QCA ath9k Development, linux-wireless, netdev, linux-kernel
In-Reply-To: <3ed8112986ba6f538cb45df6ea67e0c027a3dc12.1521628278.git.joe@perches.com>
Joe Perches <joe@perches.com> wrote:
> Remove the static array and use the generic routine to set the
> Ethernet broadcast address.
>
> Signed-off-by: Joe Perches <joe@perches.com>
> Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Patch applied to ath-next branch of ath.git, thanks.
a72c92629108 ath: Remove unnecessary ath_bcast_mac and use eth_broadcast_addr
--
https://patchwork.kernel.org/patch/10299129/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* [PATCH v2 net-next 2/2] Documentation: ip-sysctl.txt: clarify disable_ipv6
From: Lorenzo Bianconi @ 2018-03-29 9:02 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <cover.1522312507.git.lorenzo.bianconi@redhat.com>
Clarify that when disable_ipv6 is enabled even the ipv6 routes
are deleted for the selected interface and from now it will not
be possible to add addresses/routes to that interface
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
---
Documentation/networking/ip-sysctl.txt | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 1d1120753ae8..33f35f049ad5 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -1703,7 +1703,9 @@ disable_ipv6 - BOOLEAN
interface and start Duplicate Address Detection, if necessary.
When this value is changed from 0 to 1 (IPv6 is being disabled),
- it will dynamically delete all address on the given interface.
+ it will dynamically delete all addresses and routes on the given
+ interface. From now on it will not possible to add addresses/routes
+ to the selected interface.
accept_dad - INTEGER
Whether to accept DAD (Duplicate Address Detection).
--
2.14.3
^ permalink raw reply related
* [PATCH v2 net-next 1/2] ipv6: do not set routes if disable_ipv6 has been enabled
From: Lorenzo Bianconi @ 2018-03-29 9:02 UTC (permalink / raw)
To: davem; +Cc: netdev
In-Reply-To: <cover.1522312507.git.lorenzo.bianconi@redhat.com>
Do not allow setting ipv6 routes from userspace if disable_ipv6 has been
enabled. The issue can be triggered using the following reproducer:
- sysctl net.ipv6.conf.all.disable_ipv6=1
- ip -6 route add a:b:c:d::/64 dev em1
- ip -6 route show
a:b:c:d::/64 dev em1 metric 1024 pref medium
Fix it checking disable_ipv6 value in ip6_route_info_create routine
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
---
net/ipv6/route.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index ba8d5df50ebe..e461ef1158b6 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -2917,6 +2917,12 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg,
if (!dev)
goto out;
+ if (idev->cnf.disable_ipv6) {
+ NL_SET_ERR_MSG(extack, "IPv6 is disabled on nexthop device");
+ err = -EACCES;
+ goto out;
+ }
+
if (!(dev->flags & IFF_UP)) {
NL_SET_ERR_MSG(extack, "Nexthop device is not up");
err = -ENETDOWN;
--
2.14.3
^ permalink raw reply related
* [PATCH v2 net-next 0/2] do not allow adding routes if disable_ipv6 is enabled
From: Lorenzo Bianconi @ 2018-03-29 9:02 UTC (permalink / raw)
To: davem; +Cc: netdev
Do not allow userspace to add static ipv6 routes if disable_ipv6 is enabled.
Update disable_ipv6 documentation according to that change
Changes since v1:
- added an extack message telling the user that IPv6 is disabled on the nexthop
device
- rebased on-top of net-next
Lorenzo Bianconi (2):
ipv6: do not set routes if disable_ipv6 has been enabled
Documentation: ip-sysctl.txt: clarify disable_ipv6
Documentation/networking/ip-sysctl.txt | 4 +++-
net/ipv6/route.c | 6 ++++++
2 files changed, 9 insertions(+), 1 deletion(-)
--
2.14.3
^ permalink raw reply
* Re: [RFC PATCH ghak32 V2 01/13] audit: add container id
From: Richard Guy Briggs @ 2018-03-29 9:01 UTC (permalink / raw)
To: Jonathan Corbet
Cc: ebiederm-aS9lmoZGLiVWk0Htik3J/w, simo-H+wXaHxf7aLQT0dZR+AlfA,
jlayton-H+wXaHxf7aLQT0dZR+AlfA, carlos-H+wXaHxf7aLQT0dZR+AlfA,
linux-api-u79uwXL29TY76Z2rM5mHXA,
containers-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA, LKML,
eparis-FjpueFixGhCM4zKIHC2jIg, dhowells-H+wXaHxf7aLQT0dZR+AlfA,
madzcar-Re5JQEeQqe8AvxtiuMwx3w, Linux-Audit Mailing List,
viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
luto-DgEjT+Ai2ygdnm+yROfE0A, netdev-u79uwXL29TY76Z2rM5mHXA,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
cgroups-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20180328123912.49b11c98-T1hC0tSOHrs@public.gmane.org>
On 2018-03-28 12:39, Jonathan Corbet wrote:
> On Fri, 16 Mar 2018 05:00:28 -0400
> Richard Guy Briggs <rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> > Implement the proc fs write to set the audit container ID of a process,
> > emitting an AUDIT_CONTAINER record to document the event.
>
> A little detail, but still...
I am understanding that you would prefer more context (as opposed to
operational detail) in the description, laying out the use case for this
patch(set)?
> > +static int audit_set_containerid_perm(struct task_struct *task, u64 containerid)
> > +{
> > + struct task_struct *parent;
> > + u64 pcontainerid, ccontainerid;
> > +
> > + /* Don't allow to set our own containerid */
> > + if (current == task)
> > + return -EPERM;
> > + /* Don't allow the containerid to be unset */
> > + if (!cid_valid(containerid))
> > + return -EINVAL;
>
> I went looking for cid_valid(), but it turns out you don't add it until
> patch 5. That, I expect, will not be good for bisectability (or patch
> review).
Nice catch, thanks Jon. That is very likely another victim of a git
rebase to re-order afterthoughts in the right place. I'll need to be
more careful of that class of bug, rethink my workflow, or script builds
to verify each commit is compilable.
> Thanks,
>
> jon
- RGB
--
Richard Guy Briggs <rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Sr. S/W Engineer, Kernel Security, Base Operating Systems
Remote, Ottawa, Red Hat Canada
IRC: rgb, SunRaycer
Voice: +1.647.777.2635, Internal: (81) 32635
^ permalink raw reply
* Re: [PATCH 07/30] aio: add delayed cancel support
From: Christoph Hellwig @ 2018-03-29 8:53 UTC (permalink / raw)
To: Al Viro
Cc: Christoph Hellwig, Avi Kivity, linux-aio, linux-fsdevel, netdev,
linux-api, linux-kernel
In-Reply-To: <20180328163526.GV30522@ZenIV.linux.org.uk>
On Wed, Mar 28, 2018 at 05:35:26PM +0100, Al Viro wrote:
> > ret = vfs_fsync(req->file, req->datasync);
> > - fput(req->file);
> > - aio_complete(container_of(req, struct aio_kiocb, fsync), ret, 0);
> > + if (aio_complete(iocb, ret, 0, 0))
> > + fput(file);
>
> IDGI.
> 1) can aio_complete() ever return false here?
It won't. But sometimes checking the return value and sometimes not
seems like a bad pattern.
> 2) do we ever have aio_kiocb that would not have an associated
> struct file * that needs to be dropped on successful aio_complete()? AFAICS,
> rw, fsync and poll variants all have one, and I'm not sure what kind of
> async IO *could* be done without an opened file.
All have a file assoiated at least right now. As mentioned last time
finding a struct to pass that file would be rather annoying, so we'd either
have to pass it explicitly, or do something nasty like duplicating the
pointer in the aio_kiocb in addition to struct kiocb. Which might not
be that bad after all, as it would only bloat the aio_kiocb and not
struct kiocb used on stack all over.
--
To unsubscribe, send a message with 'unsubscribe linux-aio' in
the body to majordomo@kvack.org. For more info on Linux AIO,
see: http://www.kvack.org/aio/
Don't email: <a href=mailto:"aart@kvack.org">aart@kvack.org</a>
^ permalink raw reply
* Re: [PATCH net-next 0/6] net: Allow FIB notifiers to fail add and replace
From: Ido Schimmel @ 2018-03-29 8:29 UTC (permalink / raw)
To: David Ahern
Cc: netdev, davem, roopa, shm, jiri, idosch, jakub.kicinski,
andy.roulin
In-Reply-To: <20180328012200.15175-1-dsa@cumulusnetworks.com>
On Tue, Mar 27, 2018 at 06:21:54PM -0700, David Ahern wrote:
> I wanted to revisit how resource overload is handled for hardware offload
> of FIB entries and rules. At the moment, the in-kernel fib notifier can
> tell a driver about a route or rule add, replace, and delete, but the
> notifier can not affect the action. Specifically, in the case of mlxsw
> if a route or rule add is going to overflow the ASIC resources the only
> recourse is to abort hardware offload. Aborting offload is akin to taking
> down the switch as the path from data plane to the control plane simply
> can not support the traffic bandwidth of the front panel ports. Further,
> the current state of FIB notifiers is inconsistent with other resources
> where a driver can affect a user request - e.g., enslavement of a port
> into a bridge or a VRF.
>
> As a result of the work done over the past 3+ years, I believe we are
> at a point where we can bring consistency to the stack and offloads,
> and reliably allow the FIB notifiers to fail a request, pushing an error
> along with a suitable error message back to the user. Rather than
> aborting offload when the switch is out of resources, userspace is simply
> prevented from adding more routes and has a clear indication of why.
Nice work, David. Ran various tests and didn't see any regressions.
I know you already know this, but for the record, we plan to add
accounting to KVD hash resources which will eventually allow us to
return errors when resources are exceeded.
^ permalink raw reply
* Re: [PATCH net-next 5/6] net/ipv6: Move call_fib6_entry_notifiers up for route adds
From: Ido Schimmel @ 2018-03-29 8:23 UTC (permalink / raw)
To: David Ahern
Cc: netdev, davem, roopa, shm, jiri, idosch, jakub.kicinski,
andy.roulin
In-Reply-To: <20180328012200.15175-6-dsa@cumulusnetworks.com>
On Tue, Mar 27, 2018 at 06:21:59PM -0700, David Ahern wrote:
> Move call to call_fib6_entry_notifiers for new IPv6 routes to right
> before the insertion into the FIB. At this point notifier handlers can
> decide the fate of the new route with a clean path to delete the
> potential new entry if the notifier returns non-0.
>
> Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
^ permalink raw reply
* Re: [PATCH net-next 4/6] net/ipv4: Allow notifier to fail route replace
From: Ido Schimmel @ 2018-03-29 8:23 UTC (permalink / raw)
To: David Ahern
Cc: netdev, davem, roopa, shm, jiri, idosch, jakub.kicinski,
andy.roulin
In-Reply-To: <20180328012200.15175-5-dsa@cumulusnetworks.com>
On Tue, Mar 27, 2018 at 06:21:58PM -0700, David Ahern wrote:
> Add checking to call to call_fib_entry_notifiers for IPv4 route replace.
> Allows a notifier handler to fail the replace.
>
> Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
^ permalink raw reply
* Re: [PATCH net-next 3/6] net/ipv4: Move call_fib_entry_notifiers up for new routes
From: Ido Schimmel @ 2018-03-29 8:22 UTC (permalink / raw)
To: David Ahern
Cc: netdev, davem, roopa, shm, jiri, idosch, jakub.kicinski,
andy.roulin
In-Reply-To: <20180328012200.15175-4-dsa@cumulusnetworks.com>
On Tue, Mar 27, 2018 at 06:21:57PM -0700, David Ahern wrote:
> Move call to call_fib_entry_notifiers for new IPv4 routes to right
> before the call to fib_insert_alias. At this point the only remaining
> failure path is memory allocations in fib_insert_node. Handle that
> very unlikely failure with a call to call_fib_entry_notifiers to
> tell drivers about it.
>
> At this point notifier handlers can decide the fate of the new route
> with a clean path to delete the potential new entry if the notifier
> returns non-0.
>
> Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
^ permalink raw reply
* Re: [PATCH net-next 2/6] net: Move call_fib_rule_notifiers up in fib_nl_newrule
From: Ido Schimmel @ 2018-03-29 8:22 UTC (permalink / raw)
To: David Ahern
Cc: netdev, davem, roopa, shm, jiri, idosch, jakub.kicinski,
andy.roulin
In-Reply-To: <20180328012200.15175-3-dsa@cumulusnetworks.com>
On Tue, Mar 27, 2018 at 06:21:56PM -0700, David Ahern wrote:
> Move call_fib_rule_notifiers up in fib_nl_newrule to the point right
> before the rule is inserted into the list. At this point there are no
> more failure paths within the core rule code, so if the notifier
> does not fail then the rule will be inserted into the list.
>
> Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
BTW, this means we can now return an error from mlxsw instead of only
emitting an extack warning when an unsupported FIB rule is configured.
Will add that.
^ permalink raw reply
* Re: [PATCH net-next 2/6] net: Move call_fib_rule_notifiers up in fib_nl_newrule
From: Ido Schimmel @ 2018-03-29 8:20 UTC (permalink / raw)
To: David Ahern
Cc: netdev, davem, roopa, shm, jiri, idosch, jakub.kicinski,
andy.roulin
In-Reply-To: <20180328012200.15175-3-dsa@cumulusnetworks.com>
On Tue, Mar 27, 2018 at 06:21:56PM -0700, David Ahern wrote:
> Move call_fib_rule_notifiers up in fib_nl_newrule to the point right
> before the rule is inserted into the list. At this point there are no
> more failure paths within the core rule code, so if the notifier
> does not fail then the rule will be inserted into the list.
>
> Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
^ permalink raw reply
* Re: [PATCH net-next 1/6] net: Fix fib notifer to return errno
From: Ido Schimmel @ 2018-03-29 8:19 UTC (permalink / raw)
To: David Ahern
Cc: netdev, davem, roopa, shm, jiri, idosch, jakub.kicinski,
andy.roulin
In-Reply-To: <20180328012200.15175-2-dsa@cumulusnetworks.com>
On Tue, Mar 27, 2018 at 06:21:55PM -0700, David Ahern wrote:
> Notifier handlers use notifier_from_errno to convert any potential error
> to an encoded format. As a consequence the other side, call_fib_notifier{s}
> in this case, needs to use notifier_to_errno to return the error from
> the handler back to its caller.
>
> Signed-off-by: David Ahern <dsa@cumulusnetworks.com>
Reviewed-by: Ido Schimmel <idosch@mellanox.com>
^ permalink raw reply
* Re: [PATCH net-next 1/2] ipv6: do not set routes if disable_ipv6 has been enabled
From: Lorenzo Bianconi @ 2018-03-29 8:19 UTC (permalink / raw)
To: David Ahern; +Cc: davem, netdev
In-Reply-To: <d7815ad8-c1a2-9444-deb9-b3a9c8fb3b50@gmail.com>
> On 3/27/18 11:11 AM, Lorenzo Bianconi wrote:
> > Do not allow to set ipv6 routes from userspace if disable_ipv6 has been
> > enabled. The issue can be triggered using the following reproducer:
> >
> > - sysctl net.ipv6.conf.all.disable_ipv6=1
> > - ip -6 route add a:b:c:d::/64 dev em1
> > - ip -6 route show
> > a:b:c:d::/64 dev em1 metric 1024 pref medium
> >
> > Fix it checking disable_ipv6 value in ip6_route_info_create routine
> >
> > Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
> > ---
> > net/ipv6/route.c | 5 +++++
> > 1 file changed, 5 insertions(+)
> >
> > diff --git a/net/ipv6/route.c b/net/ipv6/route.c
> > index 1d0eaa69874d..672fd7fdb037 100644
> > --- a/net/ipv6/route.c
> > +++ b/net/ipv6/route.c
> > @@ -2917,6 +2917,11 @@ static struct rt6_info *ip6_route_info_create(struct fib6_config *cfg,
> > if (!dev)
> > goto out;
> >
> > + if (idev->cnf.disable_ipv6) {
> > + err = -EACCES;
>
> you need an extack message telling the user that IPv6 is disabled on the
> nexthop device.
>
Ack, will do in v2.
Regards,
Lorenzo
> > + goto out;
> > + }
> > +
> > if (!(dev->flags & IFF_UP)) {
> > NL_SET_ERR_MSG(extack, "Nexthop device is not up");
> > err = -ENETDOWN;
> >
>
^ permalink raw reply
* Re: [PATCH net V2] vhost: correctly remove wait queue during poll failure
From: Jason Wang @ 2018-03-29 8:01 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: kvm, virtualization, netdev, linux-kernel, Darren Kenny
In-Reply-To: <20180329071801-mutt-send-email-mst@kernel.org>
On 2018年03月29日 12:20, Michael S. Tsirkin wrote:
> 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)
>
>
>
Thanks for the reminder.
I post a patch to avoid this.
^ permalink raw reply
* [PATCH net] vhost: validate log when IOTLB is enabled
From: Jason Wang @ 2018-03-29 8:00 UTC (permalink / raw)
To: mst, jasowang; +Cc: netdev, linux-kernel, kvm, virtualization
Vq log_base is the userspace address of bitmap which has nothing to do
with IOTLB. So it needs to be validated unconditionally otherwise we
may try use 0 as log_base which may lead to pin pages that will lead
unexpected result (e.g trigger BUG_ON() in set_bit_to_user()).
Fixes: 6b1e6cc7855b0 ("vhost: new device IOTLB API")
Reported-by: syzbot+6304bf97ef436580fede@syzkaller.appspotmail.com
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
drivers/vhost/vhost.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 5d5a9d9..5320039 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -1244,14 +1244,12 @@ static int vq_log_access_ok(struct vhost_virtqueue *vq,
/* Caller should have vq mutex and device mutex */
int vhost_vq_access_ok(struct vhost_virtqueue *vq)
{
- if (vq->iotlb) {
- /* When device IOTLB was used, the access validation
- * will be validated during prefetching.
- */
- return 1;
- }
- return vq_access_ok(vq, vq->num, vq->desc, vq->avail, vq->used) &&
- vq_log_access_ok(vq, vq->log_base);
+ int ret = vq_log_access_ok(vq, vq->log_base);
+
+ if (ret || vq->iotlb)
+ return ret;
+
+ return vq_access_ok(vq, vq->num, vq->desc, vq->avail, vq->used);
}
EXPORT_SYMBOL_GPL(vhost_vq_access_ok);
--
2.7.4
^ permalink raw reply related
* Re: [PATCH v2] wcn36xx: Disable 5GHz for wcn3610
From: Kalle Valo @ 2018-03-29 7:45 UTC (permalink / raw)
To: Ramon Fried
Cc: loic.poulain, wcn36xx, linux-wireless, netdev, linux-kernel,
devicetree, bjorn.andersson
In-Reply-To: <2d978343-2057-8424-a249-83a0394da5a7@codeaurora.org>
(really adding Bjorn)
Ramon Fried <rfried@codeaurora.org> writes:
> (adding Bjorn Andersson)
>
>
> On 3/29/2018 10:15 AM, Kalle Valo wrote:
>> (adding devicetree list)
>>
>> Ramon Fried <rfried@codeaurora.org> writes:
>>
>>> 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>
>>> ---
>>> v2: fixed wrong assignment, which is logically introduces the
>>> same behaviour, but for correctness.
>>>
>>> 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_WCN3610;
>>> of_node_put(iris_node);
>>> }
>> Should we document qcom,wcn3610 just like wcn3620 is:
>>
>> Documentation/devicetree/bindings/remoteproc/qcom,wcnss-pil.txt:
>> "qcom,wcn3620",
>
> IMHO the mentioned bindings is related to the PIL (peripheral image
> loaded) which is just the firmware part and has
> nothing to do with wifi frontend(IRIS).
Should we then have a bindings document for wcn36xx or is it ok to use
compatible strings like this without any docs? I'm not very familiar
with the devicetree stuff.
--
Kalle Valo
^ permalink raw reply
* Re: [EXT] [PATCH net-next v2 0/2] phylink: API changes
From: Russell King - ARM Linux @ 2018-03-29 7:44 UTC (permalink / raw)
To: Yan Markman
Cc: Florian Fainelli, netdev@vger.kernel.org, Thomas Petazzoni,
Andrew Lunn, David S. Miller, open list, Antoine Tenart,
Stefan Chulski, Maxime Chevallier, Miquel Raynal, Marcin Wojtas,
Yelena Krivosheev
In-Reply-To: <98b31575864f474fa7177c39ff06f81b@IL-EXCH01.marvell.com>
On Thu, Mar 29, 2018 at 05:58:43AM +0000, Yan Markman wrote:
> Hi Florian
> Please keep CC Yelena Krivosheev <yelena@marvell.com>
> for changes with drivers/net/ethernet/marvell/mvneta.c
> Thanks
We have a way to ensure such things happen - it's the MAINTAINERS
file. Please use the established community methods rather than
sending emails asking for people to remember such quirks. 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
>
--
RMK's Patch system: http://www.armlinux.org.uk/developer/patches/
FTTC broadband for 0.8mile line in suburbia: sync at 8.8Mbps down 630kbps up
According to speedtest.net: 8.21Mbps down 510kbps up
^ permalink raw reply
* Re: [PATCH net-next v2 2/3] net: systemport: Fix coalescing settings handling
From: Tal Gilboa @ 2018-03-29 7:42 UTC (permalink / raw)
To: Florian Fainelli, netdev
Cc: davem, jaedon.shin, pgynther, opendmb, Michael Chan, gospo,
saeedm
In-Reply-To: <20180328221538.29290-3-f.fainelli@gmail.com>
On 3/29/2018 1:15 AM, Florian Fainelli wrote:
> There were a number of issues with setting the RX coalescing parameters:
>
> - we would not be preserving values that would have been configured
> across close/open calls, instead we would always reset to no timeout
> and 1 interrupt per packet, this would also prevent DIM from setting its
> default usec/pkts values
>
> - when adaptive RX would be turned on, we woud not be fetching the
> default parameters, we would stay with no timeout/1 packet per
> interrupt until the estimator kicks in and changes that
>
> - finally disabling adaptive RX coalescing while providing parameters
> would not be honored, and we would stay with whatever DIM had
> previously determined instead of the user requested parameters
>
> Fixes: b6e0e875421e ("net: systemport: Implement adaptive interrupt coalescing")
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---
> drivers/net/ethernet/broadcom/bcmsysport.c | 62 +++++++++++++++++++++---------
> drivers/net/ethernet/broadcom/bcmsysport.h | 4 +-
> 2 files changed, 46 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
> index 1e52bb7d822e..4a75b1de22e0 100644
> --- a/drivers/net/ethernet/broadcom/bcmsysport.c
> +++ b/drivers/net/ethernet/broadcom/bcmsysport.c
> @@ -574,16 +574,16 @@ static int bcm_sysport_set_wol(struct net_device *dev,
> return 0;
> }
>
> -static void bcm_sysport_set_rx_coalesce(struct bcm_sysport_priv *priv)
> +static void bcm_sysport_set_rx_coalesce(struct bcm_sysport_priv *priv,
> + u32 usecs, u32 pkts)
> {
> u32 reg;
>
> reg = rdma_readl(priv, RDMA_MBDONE_INTR);
> reg &= ~(RDMA_INTR_THRESH_MASK |
> RDMA_TIMEOUT_MASK << RDMA_TIMEOUT_SHIFT);
> - reg |= priv->dim.coal_pkts;
> - reg |= DIV_ROUND_UP(priv->dim.coal_usecs * 1000, 8192) <<
> - RDMA_TIMEOUT_SHIFT;
> + reg |= pkts;
> + reg |= DIV_ROUND_UP(usecs * 1000, 8192) << RDMA_TIMEOUT_SHIFT;
> rdma_writel(priv, reg, RDMA_MBDONE_INTR);
> }
>
> @@ -626,6 +626,8 @@ static int bcm_sysport_set_coalesce(struct net_device *dev,
> struct ethtool_coalesce *ec)
> {
> struct bcm_sysport_priv *priv = netdev_priv(dev);
> + struct net_dim_cq_moder moder;
> + u32 usecs, pkts;
> unsigned int i;
>
> /* Base system clock is 125Mhz, DMA timeout is this reference clock
> @@ -646,15 +648,21 @@ static int bcm_sysport_set_coalesce(struct net_device *dev,
> for (i = 0; i < dev->num_tx_queues; i++)
> bcm_sysport_set_tx_coalesce(&priv->tx_rings[i], ec);
>
> - priv->dim.coal_usecs = ec->rx_coalesce_usecs;
> - priv->dim.coal_pkts = ec->rx_max_coalesced_frames;
> + priv->rx_coalesce_usecs = ec->rx_coalesce_usecs;
> + priv->rx_max_coalesced_frames = ec->rx_max_coalesced_frames;
> + usecs = priv->rx_coalesce_usecs;
> + pkts = priv->rx_max_coalesced_frames;
>
> - if (!ec->use_adaptive_rx_coalesce && priv->dim.use_dim) {
> - priv->dim.coal_pkts = 1;
> - priv->dim.coal_usecs = 0;
> + if (ec->use_adaptive_rx_coalesce && !priv->dim.use_dim) {
> + moder = net_dim_get_def_profile(priv->dim.dim.mode);
> + usecs = moder.usec;
> + pkts = moder.pkts;
> }
> +
> priv->dim.use_dim = ec->use_adaptive_rx_coalesce;
> - bcm_sysport_set_rx_coalesce(priv);
> +
> + /* Apply desired coalescing parameters */
> + bcm_sysport_set_rx_coalesce(priv, usecs, pkts);
>
> return 0;
> }
> @@ -1058,10 +1066,7 @@ static void bcm_sysport_dim_work(struct work_struct *work)
> struct net_dim_cq_moder cur_profile =
> net_dim_get_profile(dim->mode, dim->profile_ix);
>
> - priv->dim.coal_usecs = cur_profile.usec;
> - priv->dim.coal_pkts = cur_profile.pkts;
> -
> - bcm_sysport_set_rx_coalesce(priv);
> + bcm_sysport_set_rx_coalesce(priv, cur_profile.usec, cur_profile.pkts);
> dim->state = NET_DIM_START_MEASURE;
> }
>
> @@ -1408,9 +1413,11 @@ static void bcm_sysport_adj_link(struct net_device *dev)
> phy_print_status(phydev);
> }
>
> -static void bcm_sysport_init_dim(struct bcm_sysport_net_dim *dim,
> +static void bcm_sysport_init_dim(struct bcm_sysport_priv *priv,
> void (*cb)(struct work_struct *work))
> {
> + struct bcm_sysport_net_dim *dim = &priv->dim;
> +
> INIT_WORK(&dim->dim.work, cb);
> dim->dim.mode = NET_DIM_CQ_PERIOD_MODE_START_FROM_EQE;
> dim->event_ctr = 0;
> @@ -1418,6 +1425,25 @@ static void bcm_sysport_init_dim(struct bcm_sysport_net_dim *dim,
> dim->bytes = 0;
> }
>
> +static void bcm_sysport_init_rx_coalesce(struct bcm_sysport_priv *priv)
> +{
> + struct bcm_sysport_net_dim *dim = &priv->dim;
> + struct net_dim_cq_moder moder;
> + u32 usecs, pkts;
> +
> + usecs = priv->rx_coalesce_usecs;
> + pkts = priv->rx_max_coalesced_frames;
> +
> + /* If DIM was enabled, re-apply default parameters */
> + if (dim->use_dim) {
> + moder = net_dim_get_def_profile(dim->dim.mode);
> + usecs = moder.usec;
> + pkts = moder.pkts;
> + }
> +
> + bcm_sysport_set_rx_coalesce(priv, usecs, pkts);
> +}
> +
> static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv,
> unsigned int index)
> {
> @@ -1658,8 +1684,6 @@ static int bcm_sysport_init_rx_ring(struct bcm_sysport_priv *priv)
> rdma_writel(priv, 0, RDMA_END_ADDR_HI);
> rdma_writel(priv, priv->num_rx_desc_words - 1, RDMA_END_ADDR_LO);
>
> - rdma_writel(priv, 1, RDMA_MBDONE_INTR);
> -
> netif_dbg(priv, hw, priv->netdev,
> "RDMA cfg, num_rx_bds=%d, rx_bds=%p\n",
> priv->num_rx_bds, priv->rx_bds);
> @@ -1827,7 +1851,8 @@ static void bcm_sysport_netif_start(struct net_device *dev)
> struct bcm_sysport_priv *priv = netdev_priv(dev);
>
> /* Enable NAPI */
> - bcm_sysport_init_dim(&priv->dim, bcm_sysport_dim_work);
> + bcm_sysport_init_dim(priv, bcm_sysport_dim_work);
> + bcm_sysport_init_rx_coalesce(priv);
> napi_enable(&priv->napi);
>
> /* Enable RX interrupt and TX ring full interrupt */
> @@ -2333,6 +2358,7 @@ static int bcm_sysport_probe(struct platform_device *pdev)
> /* libphy will adjust the link state accordingly */
> netif_carrier_off(dev);
>
> + priv->rx_max_coalesced_frames = 1;
Do you still want to keep {usecs,frames}={0,1} as default static
configuration? Is the latency so important for the static case? I'm
assuming RT latency is at least 10us so you can somewhat increase the
timer and counter without causing an increase in latency. This should be
properly tested of course so maybe in a future patch.
> u64_stats_init(&priv->syncp);
>
> priv->dsa_notifier.notifier_call = bcm_sysport_dsa_notifier;
> diff --git a/drivers/net/ethernet/broadcom/bcmsysport.h b/drivers/net/ethernet/broadcom/bcmsysport.h
> index 57e18ef8f206..d6e5d0cbf3a3 100644
> --- a/drivers/net/ethernet/broadcom/bcmsysport.h
> +++ b/drivers/net/ethernet/broadcom/bcmsysport.h
> @@ -701,8 +701,6 @@ struct bcm_sysport_net_dim {
> u16 event_ctr;
> unsigned long packets;
> unsigned long bytes;
> - u32 coal_usecs;
> - u32 coal_pkts;
> struct net_dim dim;
> };
>
> @@ -755,6 +753,8 @@ struct bcm_sysport_priv {
> unsigned int rx_c_index;
>
> struct bcm_sysport_net_dim dim;
> + u32 rx_max_coalesced_frames;
> + u32 rx_coalesce_usecs;
>
> /* PHY device */
> struct device_node *phy_dn;
>
Reviewed-by: Tal Gilboa <talgi@mellanox.com>
^ 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