Netdev List
 help / color / mirror / Atom feed
* [PATCH v2 02/17] octeontx2-af: NIX Tx scheduler queue config support
From: sunil.kovvuri @ 2018-10-22 17:55 UTC (permalink / raw)
  To: netdev, davem; +Cc: arnd, linux-soc, Sunil Goutham
In-Reply-To: <1540230964-5506-1-git-send-email-sunil.kovvuri@gmail.com>

From: Sunil Goutham <sgoutham@marvell.com>

This patch adds support for a PF/VF driver to configure
NIX transmit scheduler queues via mbox. Since PF/VF doesn't
know the absolute HW index of the NIXLF attached to it, AF
traps the register config and overwrites with the correct
NIXLF index.

HW supports shaping, colouring and policing of packets with
these multilevel traffic scheduler queues. Instead of
introducing different mbox message formats for different
configurations and making both AF & PF/VF driver implementation
cumbersome, access to the scheduler queue's CSRs is provided
via mbox. AF checks whether the sender PF/VF has the
corresponding queue allocated or not and dumps the config
to HW. With a single mbox msg 20 registers can be configured.

Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
---
 drivers/net/ethernet/marvell/octeontx2/af/Makefile |   3 +-
 drivers/net/ethernet/marvell/octeontx2/af/mbox.h   |  15 ++-
 drivers/net/ethernet/marvell/octeontx2/af/rvu.h    |  11 +++
 .../net/ethernet/marvell/octeontx2/af/rvu_nix.c    | 104 ++++++++++++++++++++-
 .../net/ethernet/marvell/octeontx2/af/rvu_reg.c    |  71 ++++++++++++++
 5 files changed, 199 insertions(+), 5 deletions(-)
 create mode 100644 drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.c

diff --git a/drivers/net/ethernet/marvell/octeontx2/af/Makefile b/drivers/net/ethernet/marvell/octeontx2/af/Makefile
index 45b108f..264cbd7 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/Makefile
+++ b/drivers/net/ethernet/marvell/octeontx2/af/Makefile
@@ -7,4 +7,5 @@ obj-$(CONFIG_OCTEONTX2_MBOX) += octeontx2_mbox.o
 obj-$(CONFIG_OCTEONTX2_AF) += octeontx2_af.o
 
 octeontx2_mbox-y := mbox.o
-octeontx2_af-y := cgx.o rvu.o rvu_cgx.o rvu_npa.o rvu_nix.o
+octeontx2_af-y := cgx.o rvu.o rvu_cgx.o rvu_npa.o rvu_nix.o \
+		  rvu_reg.o
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
index 282e556..f2e0743 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
@@ -154,7 +154,8 @@ M(NIX_LF_FREE,		0x8001, msg_req, msg_rsp)			\
 M(NIX_AQ_ENQ,		0x8002, nix_aq_enq_req, nix_aq_enq_rsp)		\
 M(NIX_HWCTX_DISABLE,	0x8003, hwctx_disable_req, msg_rsp)		\
 M(NIX_TXSCH_ALLOC,	0x8004, nix_txsch_alloc_req, nix_txsch_alloc_rsp) \
-M(NIX_TXSCH_FREE,	0x8005, nix_txsch_free_req, msg_rsp)
+M(NIX_TXSCH_FREE,	0x8005, nix_txsch_free_req, msg_rsp)		\
+M(NIX_TXSCHQ_CFG,	0x8006, nix_txschq_config, msg_rsp)
 
 /* Messages initiated by AF (range 0xC00 - 0xDFF) */
 #define MBOX_UP_CGX_MESSAGES						\
@@ -448,4 +449,16 @@ struct nix_txsch_free_req {
 	u16 schq;
 };
 
+struct nix_txschq_config {
+	struct mbox_msghdr hdr;
+	u8 lvl;	/* SMQ/MDQ/TL4/TL3/TL2/TL1 */
+#define TXSCHQ_IDX_SHIFT	16
+#define TXSCHQ_IDX_MASK		(BIT_ULL(10) - 1)
+#define TXSCHQ_IDX(reg, shift)	(((reg) >> (shift)) & TXSCHQ_IDX_MASK)
+	u8 num_regs;
+#define MAX_REGS_PER_MBOX_MSG	20
+	u64 reg[MAX_REGS_PER_MBOX_MSG];
+	u64 regval[MAX_REGS_PER_MBOX_MSG];
+};
+
 #endif /* MBOX_H */
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
index c402eba..4b15552 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
@@ -195,6 +195,14 @@ int rvu_lf_reset(struct rvu *rvu, struct rvu_block *block, int lf);
 int rvu_get_blkaddr(struct rvu *rvu, int blktype, u16 pcifunc);
 int rvu_poll_reg(struct rvu *rvu, u64 block, u64 offset, u64 mask, bool zero);
 
+/* RVU HW reg validation */
+enum regmap_block {
+	TXSCHQ_HWREGMAP = 0,
+	MAX_HWREGMAP,
+};
+
+bool rvu_check_valid_reg(int regmap, int regblk, u64 reg);
+
 /* NPA/NIX AQ APIs */
 int rvu_aq_alloc(struct rvu *rvu, struct admin_queue **ad_queue,
 		 int qsize, int inst_size, int res_size);
@@ -277,4 +285,7 @@ int rvu_mbox_handler_NIX_TXSCH_ALLOC(struct rvu *rvu,
 int rvu_mbox_handler_NIX_TXSCH_FREE(struct rvu *rvu,
 				    struct nix_txsch_free_req *req,
 				    struct msg_rsp *rsp);
+int rvu_mbox_handler_NIX_TXSCHQ_CFG(struct rvu *rvu,
+				    struct nix_txschq_config *req,
+				    struct msg_rsp *rsp);
 #endif /* RVU_H */
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
index e8374d9..56f242d 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
@@ -738,10 +738,10 @@ static void nix_reset_tx_linkcfg(struct rvu *rvu, int blkaddr,
 	if (lvl == NIX_TXSCH_LVL_TL4)
 		rvu_write64(rvu, blkaddr, NIX_AF_TL4X_SDP_LINK_CFG(schq), 0x00);
 
-	if (lvl != NIX_TXSCH_LVL_TL3)
+	if (lvl != NIX_TXSCH_LVL_TL2)
 		return;
 
-	/* Reset TL3's CGX or LBK link config */
+	/* Reset TL2's CGX or LBK link config */
 	for (link = 0; link < (hw->cgx_links + hw->lbk_links); link++)
 		rvu_write64(rvu, blkaddr,
 			    NIX_AF_TL3_TL2X_LINKX_CFG(schq, link), 0x00);
@@ -851,7 +851,7 @@ static int nix_txschq_free(struct rvu *rvu, u16 pcifunc)
 	/* Disable TL2/3 queue links before SMQ flush*/
 	spin_lock(&rvu->rsrc_lock);
 	for (lvl = NIX_TXSCH_LVL_TL4; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
-		if (lvl != NIX_TXSCH_LVL_TL3 && lvl != NIX_TXSCH_LVL_TL4)
+		if (lvl != NIX_TXSCH_LVL_TL2 && lvl != NIX_TXSCH_LVL_TL4)
 			continue;
 
 		txsch = &nix_hw->txsch[lvl];
@@ -909,6 +909,104 @@ int rvu_mbox_handler_NIX_TXSCH_FREE(struct rvu *rvu,
 	return nix_txschq_free(rvu, req->hdr.pcifunc);
 }
 
+static bool is_txschq_config_valid(struct rvu *rvu, u16 pcifunc, int blkaddr,
+				   int lvl, u64 reg, u64 regval)
+{
+	u64 regbase = reg & 0xFFFF;
+	u16 schq, parent;
+
+	if (!rvu_check_valid_reg(TXSCHQ_HWREGMAP, lvl, reg))
+		return false;
+
+	schq = TXSCHQ_IDX(reg, TXSCHQ_IDX_SHIFT);
+	/* Check if this schq belongs to this PF/VF or not */
+	if (!is_valid_txschq(rvu, blkaddr, lvl, pcifunc, schq))
+		return false;
+
+	parent = (regval >> 16) & 0x1FF;
+	/* Validate MDQ's TL4 parent */
+	if (regbase == NIX_AF_MDQX_PARENT(0) &&
+	    !is_valid_txschq(rvu, blkaddr, NIX_TXSCH_LVL_TL4, pcifunc, parent))
+		return false;
+
+	/* Validate TL4's TL3 parent */
+	if (regbase == NIX_AF_TL4X_PARENT(0) &&
+	    !is_valid_txschq(rvu, blkaddr, NIX_TXSCH_LVL_TL3, pcifunc, parent))
+		return false;
+
+	/* Validate TL3's TL2 parent */
+	if (regbase == NIX_AF_TL3X_PARENT(0) &&
+	    !is_valid_txschq(rvu, blkaddr, NIX_TXSCH_LVL_TL2, pcifunc, parent))
+		return false;
+
+	/* Validate TL2's TL1 parent */
+	if (regbase == NIX_AF_TL2X_PARENT(0) &&
+	    !is_valid_txschq(rvu, blkaddr, NIX_TXSCH_LVL_TL1, pcifunc, parent))
+		return false;
+
+	return true;
+}
+
+int rvu_mbox_handler_NIX_TXSCHQ_CFG(struct rvu *rvu,
+				    struct nix_txschq_config *req,
+				    struct msg_rsp *rsp)
+{
+	struct rvu_hwinfo *hw = rvu->hw;
+	u16 pcifunc = req->hdr.pcifunc;
+	u64 reg, regval, schq_regbase;
+	struct nix_txsch *txsch;
+	struct nix_hw *nix_hw;
+	int blkaddr, idx, err;
+	int nixlf;
+
+	if (req->lvl >= NIX_TXSCH_LVL_CNT ||
+	    req->num_regs > MAX_REGS_PER_MBOX_MSG)
+		return NIX_AF_INVAL_TXSCHQ_CFG;
+
+	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
+	if (blkaddr < 0)
+		return NIX_AF_ERR_AF_LF_INVALID;
+
+	nix_hw = get_nix_hw(rvu->hw, blkaddr);
+	if (!nix_hw)
+		return -EINVAL;
+
+	nixlf = rvu_get_lf(rvu, &hw->block[blkaddr], pcifunc, 0);
+	if (nixlf < 0)
+		return NIX_AF_ERR_AF_LF_INVALID;
+
+	txsch = &nix_hw->txsch[req->lvl];
+	for (idx = 0; idx < req->num_regs; idx++) {
+		reg = req->reg[idx];
+		regval = req->regval[idx];
+		schq_regbase = reg & 0xFFFF;
+
+		if (!is_txschq_config_valid(rvu, pcifunc, blkaddr,
+					    txsch->lvl, reg, regval))
+			return NIX_AF_INVAL_TXSCHQ_CFG;
+
+		/* Replace PF/VF visible NIXLF slot with HW NIXLF id */
+		if (schq_regbase == NIX_AF_SMQX_CFG(0)) {
+			nixlf = rvu_get_lf(rvu, &hw->block[blkaddr],
+					   pcifunc, 0);
+			regval &= ~(0x7FULL << 24);
+			regval |= ((u64)nixlf << 24);
+		}
+
+		rvu_write64(rvu, blkaddr, reg, regval);
+
+		/* Check for SMQ flush, if so, poll for its completion */
+		if (schq_regbase == NIX_AF_SMQX_CFG(0) &&
+		    (regval & BIT_ULL(49))) {
+			err = rvu_poll_reg(rvu, blkaddr,
+					   reg, BIT_ULL(49), true);
+			if (err)
+				return NIX_AF_SMQ_FLUSH_FAILED;
+		}
+	}
+	return 0;
+}
+
 static int nix_setup_txschq(struct rvu *rvu, struct nix_hw *nix_hw, int blkaddr)
 {
 	struct nix_txsch *txsch;
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.c
new file mode 100644
index 0000000..9d7c135
--- /dev/null
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.c
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Marvell OcteonTx2 RVU Admin Function driver
+ *
+ * Copyright (C) 2018 Marvell International Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/pci.h>
+
+#include "rvu_struct.h"
+#include "common.h"
+#include "mbox.h"
+#include "rvu.h"
+
+struct reg_range {
+	u64  start;
+	u64  end;
+};
+
+struct hw_reg_map {
+	u8	regblk;
+	u8	num_ranges;
+	u64	mask;
+#define	 MAX_REG_RANGES	8
+	struct reg_range range[MAX_REG_RANGES];
+};
+
+static struct hw_reg_map txsch_reg_map[NIX_TXSCH_LVL_CNT] = {
+	{NIX_TXSCH_LVL_SMQ, 2, 0xFFFF, {{0x0700, 0x0708}, {0x1400, 0x14C8} } },
+	{NIX_TXSCH_LVL_TL4, 3, 0xFFFF, {{0x0B00, 0x0B08}, {0x0B10, 0x0B18},
+			      {0x1200, 0x12E0} } },
+	{NIX_TXSCH_LVL_TL3, 3, 0xFFFF, {{0x1000, 0x10E0}, {0x1600, 0x1608},
+			      {0x1610, 0x1618} } },
+	{NIX_TXSCH_LVL_TL2, 2, 0xFFFF, {{0x0E00, 0x0EE0}, {0x1700, 0x1768} } },
+	{NIX_TXSCH_LVL_TL1, 1, 0xFFFF, {{0x0C00, 0x0D98} } },
+};
+
+bool rvu_check_valid_reg(int regmap, int regblk, u64 reg)
+{
+	int idx;
+	struct hw_reg_map *map;
+
+	/* Only 64bit offsets */
+	if (reg & 0x07)
+		return false;
+
+	if (regmap == TXSCHQ_HWREGMAP) {
+		if (regblk >= NIX_TXSCH_LVL_CNT)
+			return false;
+		map = &txsch_reg_map[regblk];
+	} else {
+		return false;
+	}
+
+	/* Should never happen */
+	if (map->regblk != regblk)
+		return false;
+
+	reg &= map->mask;
+
+	for (idx = 0; idx < map->num_ranges; idx++) {
+		if (reg >= map->range[idx].start &&
+		    reg < map->range[idx].end)
+			return true;
+	}
+	return false;
+}
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 01/17] octeontx2-af: NIX Tx scheduler queues alloc/free
From: sunil.kovvuri @ 2018-10-22 17:55 UTC (permalink / raw)
  To: netdev, davem; +Cc: arnd, linux-soc, Sunil Goutham, Nithin Dabilpuram
In-Reply-To: <1540230964-5506-1-git-send-email-sunil.kovvuri@gmail.com>

From: Sunil Goutham <sgoutham@marvell.com>

Added support for a PF/VF to allocate or free NIX transmit
scheduler queues via mbox. For setting up pkt transmission
priorities between queues, the scheduler queues have to be
contiguous w.r.t their HW indices. So both contiguous and
non-contiguous allocations are supported.

Upon receiving NIX_TXSCH_FREE mbox msg all scheduler queues
allocated to sending PFFUNC (PF/VF) will be freed. Selective
free is not supported.

Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
Signed-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
---
 drivers/net/ethernet/marvell/octeontx2/af/mbox.h   |  36 +++-
 drivers/net/ethernet/marvell/octeontx2/af/rvu.c    |   4 +-
 drivers/net/ethernet/marvell/octeontx2/af/rvu.h    |   9 +-
 .../net/ethernet/marvell/octeontx2/af/rvu_nix.c    | 220 +++++++++++++++++++++
 4 files changed, 265 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
index c339024..282e556 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/mbox.h
@@ -15,6 +15,7 @@
 #include <linux/sizes.h>
 
 #include "rvu_struct.h"
+#include "common.h"
 
 #define MBOX_SIZE		SZ_64K
 
@@ -151,7 +152,9 @@ M(NPA_HWCTX_DISABLE,	0x403, hwctx_disable_req, msg_rsp)		\
 M(NIX_LF_ALLOC,		0x8000, nix_lf_alloc_req, nix_lf_alloc_rsp)	\
 M(NIX_LF_FREE,		0x8001, msg_req, msg_rsp)			\
 M(NIX_AQ_ENQ,		0x8002, nix_aq_enq_req, nix_aq_enq_rsp)		\
-M(NIX_HWCTX_DISABLE,	0x8003, hwctx_disable_req, msg_rsp)
+M(NIX_HWCTX_DISABLE,	0x8003, hwctx_disable_req, msg_rsp)		\
+M(NIX_TXSCH_ALLOC,	0x8004, nix_txsch_alloc_req, nix_txsch_alloc_rsp) \
+M(NIX_TXSCH_FREE,	0x8005, nix_txsch_free_req, msg_rsp)
 
 /* Messages initiated by AF (range 0xC00 - 0xDFF) */
 #define MBOX_UP_CGX_MESSAGES						\
@@ -414,4 +417,35 @@ struct nix_aq_enq_rsp {
 	};
 };
 
+/* Tx scheduler/shaper mailbox messages */
+
+#define MAX_TXSCHQ_PER_FUNC		128
+
+struct nix_txsch_alloc_req {
+	struct mbox_msghdr hdr;
+	/* Scheduler queue count request at each level */
+	u16 schq_contig[NIX_TXSCH_LVL_CNT]; /* No of contiguous queues */
+	u16 schq[NIX_TXSCH_LVL_CNT]; /* No of non-contiguous queues */
+};
+
+struct nix_txsch_alloc_rsp {
+	struct mbox_msghdr hdr;
+	/* Scheduler queue count allocated at each level */
+	u16 schq_contig[NIX_TXSCH_LVL_CNT];
+	u16 schq[NIX_TXSCH_LVL_CNT];
+	/* Scheduler queue list allocated at each level */
+	u16 schq_contig_list[NIX_TXSCH_LVL_CNT][MAX_TXSCHQ_PER_FUNC];
+	u16 schq_list[NIX_TXSCH_LVL_CNT][MAX_TXSCHQ_PER_FUNC];
+};
+
+struct nix_txsch_free_req {
+	struct mbox_msghdr hdr;
+#define TXSCHQ_FREE_ALL BIT_ULL(0)
+	u16 flags;
+	/* Scheduler queue level to be freed */
+	u16 schq_lvl;
+	/* List of scheduler queues to be freed */
+	u16 schq;
+};
+
 #endif /* MBOX_H */
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
index c06cca9..9594432 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
@@ -80,7 +80,7 @@ int rvu_alloc_rsrc(struct rsrc_bmap *rsrc)
 	return id;
 }
 
-static int rvu_alloc_rsrc_contig(struct rsrc_bmap *rsrc, int nrsrc)
+int rvu_alloc_rsrc_contig(struct rsrc_bmap *rsrc, int nrsrc)
 {
 	int start;
 
@@ -105,7 +105,7 @@ static void rvu_free_rsrc_contig(struct rsrc_bmap *rsrc, int nrsrc, int start)
 	bitmap_clear(rsrc->bmap, start, nrsrc);
 }
 
-static bool rvu_rsrc_check_contig(struct rsrc_bmap *rsrc, int nrsrc)
+bool rvu_rsrc_check_contig(struct rsrc_bmap *rsrc, int nrsrc)
 {
 	int start;
 
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
index b48b5af..c402eba 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.h
@@ -180,11 +180,12 @@ static inline u64 rvupf_read64(struct rvu *rvu, u64 offset)
 /* Function Prototypes
  * RVU
  */
-
 int rvu_alloc_bitmap(struct rsrc_bmap *rsrc);
 int rvu_alloc_rsrc(struct rsrc_bmap *rsrc);
 void rvu_free_rsrc(struct rsrc_bmap *rsrc, int id);
 int rvu_rsrc_free_count(struct rsrc_bmap *rsrc);
+int rvu_alloc_rsrc_contig(struct rsrc_bmap *rsrc, int nrsrc);
+bool rvu_rsrc_check_contig(struct rsrc_bmap *rsrc, int nrsrc);
 int rvu_get_pf(u16 pcifunc);
 struct rvu_pfvf *rvu_get_pfvf(struct rvu *rvu, int pcifunc);
 void rvu_get_pf_numvfs(struct rvu *rvu, int pf, int *numvfs, int *hwvf);
@@ -270,4 +271,10 @@ int rvu_mbox_handler_NIX_AQ_ENQ(struct rvu *rvu,
 int rvu_mbox_handler_NIX_HWCTX_DISABLE(struct rvu *rvu,
 				       struct hwctx_disable_req *req,
 				       struct msg_rsp *rsp);
+int rvu_mbox_handler_NIX_TXSCH_ALLOC(struct rvu *rvu,
+				     struct nix_txsch_alloc_req *req,
+				     struct nix_txsch_alloc_rsp *rsp);
+int rvu_mbox_handler_NIX_TXSCH_FREE(struct rvu *rvu,
+				    struct nix_txsch_free_req *req,
+				    struct msg_rsp *rsp);
 #endif /* RVU_H */
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
index 214ca2c..e8374d9 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c
@@ -689,6 +689,226 @@ int rvu_mbox_handler_NIX_LF_FREE(struct rvu *rvu, struct msg_req *req,
 	return 0;
 }
 
+/* Disable shaping of pkts by a scheduler queue
+ * at a given scheduler level.
+ */
+static void nix_reset_tx_shaping(struct rvu *rvu, int blkaddr,
+				 int lvl, int schq)
+{
+	u64  cir_reg = 0, pir_reg = 0;
+	u64  cfg;
+
+	switch (lvl) {
+	case NIX_TXSCH_LVL_TL1:
+		cir_reg = NIX_AF_TL1X_CIR(schq);
+		pir_reg = 0; /* PIR not available at TL1 */
+		break;
+	case NIX_TXSCH_LVL_TL2:
+		cir_reg = NIX_AF_TL2X_CIR(schq);
+		pir_reg = NIX_AF_TL2X_PIR(schq);
+		break;
+	case NIX_TXSCH_LVL_TL3:
+		cir_reg = NIX_AF_TL3X_CIR(schq);
+		pir_reg = NIX_AF_TL3X_PIR(schq);
+		break;
+	case NIX_TXSCH_LVL_TL4:
+		cir_reg = NIX_AF_TL4X_CIR(schq);
+		pir_reg = NIX_AF_TL4X_PIR(schq);
+		break;
+	}
+
+	if (!cir_reg)
+		return;
+	cfg = rvu_read64(rvu, blkaddr, cir_reg);
+	rvu_write64(rvu, blkaddr, cir_reg, cfg & ~BIT_ULL(0));
+
+	if (!pir_reg)
+		return;
+	cfg = rvu_read64(rvu, blkaddr, pir_reg);
+	rvu_write64(rvu, blkaddr, pir_reg, cfg & ~BIT_ULL(0));
+}
+
+static void nix_reset_tx_linkcfg(struct rvu *rvu, int blkaddr,
+				 int lvl, int schq)
+{
+	struct rvu_hwinfo *hw = rvu->hw;
+	int link;
+
+	/* Reset TL4's SDP link config */
+	if (lvl == NIX_TXSCH_LVL_TL4)
+		rvu_write64(rvu, blkaddr, NIX_AF_TL4X_SDP_LINK_CFG(schq), 0x00);
+
+	if (lvl != NIX_TXSCH_LVL_TL3)
+		return;
+
+	/* Reset TL3's CGX or LBK link config */
+	for (link = 0; link < (hw->cgx_links + hw->lbk_links); link++)
+		rvu_write64(rvu, blkaddr,
+			    NIX_AF_TL3_TL2X_LINKX_CFG(schq, link), 0x00);
+}
+
+int rvu_mbox_handler_NIX_TXSCH_ALLOC(struct rvu *rvu,
+				     struct nix_txsch_alloc_req *req,
+				     struct nix_txsch_alloc_rsp *rsp)
+{
+	u16 pcifunc = req->hdr.pcifunc;
+	struct nix_txsch *txsch;
+	int lvl, idx, req_schq;
+	struct rvu_pfvf *pfvf;
+	struct nix_hw *nix_hw;
+	int blkaddr, rc = 0;
+	u16 schq;
+
+	pfvf = rvu_get_pfvf(rvu, pcifunc);
+	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
+	if (!pfvf->nixlf || blkaddr < 0)
+		return NIX_AF_ERR_AF_LF_INVALID;
+
+	nix_hw = get_nix_hw(rvu->hw, blkaddr);
+	if (!nix_hw)
+		return -EINVAL;
+
+	spin_lock(&rvu->rsrc_lock);
+	for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
+		txsch = &nix_hw->txsch[lvl];
+		req_schq = req->schq_contig[lvl] + req->schq[lvl];
+
+		/* There are only 28 TL1s */
+		if (lvl == NIX_TXSCH_LVL_TL1 && req_schq > txsch->schq.max)
+			goto err;
+
+		/* Check if request is valid */
+		if (!req_schq || req_schq > MAX_TXSCHQ_PER_FUNC)
+			goto err;
+
+		/* If contiguous queues are needed, check for availability */
+		if (req->schq_contig[lvl] &&
+		    !rvu_rsrc_check_contig(&txsch->schq, req->schq_contig[lvl]))
+			goto err;
+
+		/* Check if full request can be accommodated */
+		if (req_schq >= rvu_rsrc_free_count(&txsch->schq))
+			goto err;
+	}
+
+	for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
+		txsch = &nix_hw->txsch[lvl];
+		rsp->schq_contig[lvl] = req->schq_contig[lvl];
+		rsp->schq[lvl] = req->schq[lvl];
+
+		schq = 0;
+		/* Alloc contiguous queues first */
+		if (req->schq_contig[lvl]) {
+			schq = rvu_alloc_rsrc_contig(&txsch->schq,
+						     req->schq_contig[lvl]);
+
+			for (idx = 0; idx < req->schq_contig[lvl]; idx++) {
+				txsch->pfvf_map[schq] = pcifunc;
+				nix_reset_tx_linkcfg(rvu, blkaddr, lvl, schq);
+				nix_reset_tx_shaping(rvu, blkaddr, lvl, schq);
+				rsp->schq_contig_list[lvl][idx] = schq;
+				schq++;
+			}
+		}
+
+		/* Alloc non-contiguous queues */
+		for (idx = 0; idx < req->schq[lvl]; idx++) {
+			schq = rvu_alloc_rsrc(&txsch->schq);
+			txsch->pfvf_map[schq] = pcifunc;
+			nix_reset_tx_linkcfg(rvu, blkaddr, lvl, schq);
+			nix_reset_tx_shaping(rvu, blkaddr, lvl, schq);
+			rsp->schq_list[lvl][idx] = schq;
+		}
+	}
+	goto exit;
+err:
+	rc = NIX_AF_ERR_TLX_ALLOC_FAIL;
+exit:
+	spin_unlock(&rvu->rsrc_lock);
+	return rc;
+}
+
+static int nix_txschq_free(struct rvu *rvu, u16 pcifunc)
+{
+	int blkaddr, nixlf, lvl, schq, err;
+	struct rvu_hwinfo *hw = rvu->hw;
+	struct nix_txsch *txsch;
+	struct nix_hw *nix_hw;
+	u64 cfg;
+
+	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, pcifunc);
+	if (blkaddr < 0)
+		return NIX_AF_ERR_AF_LF_INVALID;
+
+	nix_hw = get_nix_hw(rvu->hw, blkaddr);
+	if (!nix_hw)
+		return -EINVAL;
+
+	nixlf = rvu_get_lf(rvu, &hw->block[blkaddr], pcifunc, 0);
+	if (nixlf < 0)
+		return NIX_AF_ERR_AF_LF_INVALID;
+
+	/* Disable TL2/3 queue links before SMQ flush*/
+	spin_lock(&rvu->rsrc_lock);
+	for (lvl = NIX_TXSCH_LVL_TL4; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
+		if (lvl != NIX_TXSCH_LVL_TL3 && lvl != NIX_TXSCH_LVL_TL4)
+			continue;
+
+		txsch = &nix_hw->txsch[lvl];
+		for (schq = 0; schq < txsch->schq.max; schq++) {
+			if (txsch->pfvf_map[schq] != pcifunc)
+				continue;
+			nix_reset_tx_linkcfg(rvu, blkaddr, lvl, schq);
+		}
+	}
+
+	/* Flush SMQs */
+	txsch = &nix_hw->txsch[NIX_TXSCH_LVL_SMQ];
+	for (schq = 0; schq < txsch->schq.max; schq++) {
+		if (txsch->pfvf_map[schq] != pcifunc)
+			continue;
+		cfg = rvu_read64(rvu, blkaddr, NIX_AF_SMQX_CFG(schq));
+		/* Do SMQ flush and set enqueue xoff */
+		cfg |= BIT_ULL(50) | BIT_ULL(49);
+		rvu_write64(rvu, blkaddr, NIX_AF_SMQX_CFG(schq), cfg);
+
+		/* Wait for flush to complete */
+		err = rvu_poll_reg(rvu, blkaddr,
+				   NIX_AF_SMQX_CFG(schq), BIT_ULL(49), true);
+		if (err) {
+			dev_err(rvu->dev,
+				"NIXLF%d: SMQ%d flush failed\n", nixlf, schq);
+		}
+	}
+
+	/* Now free scheduler queues to free pool */
+	for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
+		txsch = &nix_hw->txsch[lvl];
+		for (schq = 0; schq < txsch->schq.max; schq++) {
+			if (txsch->pfvf_map[schq] != pcifunc)
+				continue;
+			rvu_free_rsrc(&txsch->schq, schq);
+			txsch->pfvf_map[schq] = 0;
+		}
+	}
+	spin_unlock(&rvu->rsrc_lock);
+
+	/* Sync cached info for this LF in NDC-TX to LLC/DRAM */
+	rvu_write64(rvu, blkaddr, NIX_AF_NDC_TX_SYNC, BIT_ULL(12) | nixlf);
+	err = rvu_poll_reg(rvu, blkaddr, NIX_AF_NDC_TX_SYNC, BIT_ULL(12), true);
+	if (err)
+		dev_err(rvu->dev, "NDC-TX sync failed for NIXLF %d\n", nixlf);
+
+	return 0;
+}
+
+int rvu_mbox_handler_NIX_TXSCH_FREE(struct rvu *rvu,
+				    struct nix_txsch_free_req *req,
+				    struct msg_rsp *rsp)
+{
+	return nix_txschq_free(rvu, req->hdr.pcifunc);
+}
+
 static int nix_setup_txschq(struct rvu *rvu, struct nix_hw *nix_hw, int blkaddr)
 {
 	struct nix_txsch *txsch;
-- 
2.7.4

^ permalink raw reply related

* [PATCH v2 00/17] octeontx2-af: NPC parser and NIX blocks initialization
From: sunil.kovvuri @ 2018-10-22 17:55 UTC (permalink / raw)
  To: netdev, davem; +Cc: arnd, linux-soc, Sunil Goutham

From: Sunil Goutham <sgoutham@marvell.com>

This patchset is a continuation to earlier submitted two patch
series to add a new driver for Marvell's OcteonTX2 SOC's 
Resource virtualization unit (RVU) admin function driver.

1. octeontx2-af: Add RVU Admin Function driver
   https://www.spinics.net/lists/netdev/msg528272.html
2. octeontx2-af: NPA and NIX blocks initialization 
   https://www.spinics.net/lists/netdev/msg529163.html

This patch series adds more NIX block configuration logic
and additionally adds NPC block parser profile configuration.
In brief below is what this series adds.
NIX block:
- Support for PF/VF to allocate/free transmit scheduler queues,
  maintenance and their configuration.
- Adds support for packet replication lists, only broadcast
  packets is covered for now.
- Defines few RSS flow algorithms for HW to distribute packets.
  This is not the hash algorithsm (i.e toeplitz or crc32), here SW
  defines what fields in packet should HW take and calculate the hash.
- Support for PF/VF to configure VTAG strip and capture capabilities.
- Reset NIXLF statastics.

NPC block:
This block has multiple parser engines which support packet parsing
at multiple layers and generates a parse result which is further used
to generate a key. Based on packet field offsets in the key, SW can 
install packet forwarding rules.
This patch series adds
- Initial parser profile to be programmed into parser engines.
- Default forwarding rules to forward packets to different logical
  interfaces having a NIXLF attached.
- Support for promiscuous and multicast modes.

Changes from v1:
 1 Fixed kernel build failure when compiled with BIG_ENDIAN enabled.
   - Reported by Kbuild test robot
 2 Fixed a warning observed when kernel is built with -Wunused-but-set-variable

Geetha sowjanya (1):
  octeontx2-af: Config pkind for CGX mapped PFs

Hao Zheng (1):
  octeontx2-af: Add NPC KPU profile

Stanislaw Kardach (1):
  octeontx2-af: Add LMAC channel info to NIXLF_ALLOC response

Sunil Goutham (12):
  octeontx2-af: NIX Tx scheduler queues alloc/free
  octeontx2-af: NIX Tx scheduler queue config support
  octeontx2-af: Config NPC KPU engines with parser profile
  octeontx2-af: Broadcast packet replication support
  octeontx2-af: Update bcast list upon NIXLF alloc/free
  octeontx2-af: Enable packet length and csum validation
  octeontx2-af: NPC MCAM and LDATA extract minimal configuration
  octeontx2-af: Install ucast and bcast pkt forwarding rules
  octeontx2-af: NIX Rx flowkey configuration for RSS
  octeontx2-af: Support for changing RSS algorithm
  octeontx2-af: Support for setting MAC address
  octeontx2-af: Support for NIXLF's UCAST/PROMISC/ALLMULTI modes

Vamsi Attunuru (2):
  octeontx2-af: Reset NIXLF's Rx/Tx stats
  octeontx2-af: Support for VTAG strip and capture

 drivers/net/ethernet/marvell/octeontx2/af/Makefile |    3 +-
 drivers/net/ethernet/marvell/octeontx2/af/cgx.c    |   12 +
 drivers/net/ethernet/marvell/octeontx2/af/cgx.h    |    1 +
 drivers/net/ethernet/marvell/octeontx2/af/common.h |   50 +
 drivers/net/ethernet/marvell/octeontx2/af/mbox.h   |  110 +-
 drivers/net/ethernet/marvell/octeontx2/af/npc.h    |  262 +
 .../ethernet/marvell/octeontx2/af/npc_profile.h    | 5709 ++++++++++++++++++++
 drivers/net/ethernet/marvell/octeontx2/af/rvu.c    |   12 +-
 drivers/net/ethernet/marvell/octeontx2/af/rvu.h    |   97 +-
 .../net/ethernet/marvell/octeontx2/af/rvu_cgx.c    |    7 +-
 .../net/ethernet/marvell/octeontx2/af/rvu_nix.c    | 1067 ++++
 .../net/ethernet/marvell/octeontx2/af/rvu_npc.c    |  816 +++
 .../net/ethernet/marvell/octeontx2/af/rvu_reg.c    |   71 +
 .../net/ethernet/marvell/octeontx2/af/rvu_reg.h    |   61 +
 .../net/ethernet/marvell/octeontx2/af/rvu_struct.h |   35 +
 15 files changed, 8306 insertions(+), 7 deletions(-)
 create mode 100644 drivers/net/ethernet/marvell/octeontx2/af/npc.h
 create mode 100644 drivers/net/ethernet/marvell/octeontx2/af/npc_profile.h
 create mode 100644 drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
 create mode 100644 drivers/net/ethernet/marvell/octeontx2/af/rvu_reg.c

-- 
2.7.4

^ permalink raw reply

* Re: [iproute PATCH] tc: htb: Print default value in hex
From: Phil Sutter @ 2018-10-22 17:28 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Jiri Pirko, netdev
In-Reply-To: <20181022095623.6ffabb31@xeon-e3>

On Mon, Oct 22, 2018 at 09:56:23AM -0700, Stephen Hemminger wrote:
> On Fri, 19 Oct 2018 17:42:55 +0200
> Phil Sutter <phil@nwl.cc> wrote:
> 
> > Value of 'default' is assumed to be hexadecimal when parsing, so
> > consequently it should be printed in hex as well. This is a regression
> > introduced when adding JSON output.
> > 
> > Fixes: f354fa6aa5ff0 ("tc: jsonify htb qdisc")
> > Signed-off-by: Phil Sutter <phil@nwl.cc>
> > ---
> >  tc/q_htb.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/tc/q_htb.c b/tc/q_htb.c
> > index c8b2941d945b7..c69485db8ef7d 100644
> > --- a/tc/q_htb.c
> > +++ b/tc/q_htb.c
> > @@ -332,7 +332,7 @@ static int htb_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
> >  		if (RTA_PAYLOAD(tb[TCA_HTB_INIT])  < sizeof(*gopt)) return -1;
> >  
> >  		print_int(PRINT_ANY, "r2q", "r2q %d", gopt->rate2quantum);
> > -		print_uint(PRINT_ANY, "default", " default %u", gopt->defcls);
> > +		print_uint(PRINT_ANY, "default", " default %x", gopt->defcls);
> >  		print_uint(PRINT_ANY, "direct_packets_stat",
> >  			   " direct_packets_stat %u", gopt->direct_pkts);
> >  		if (show_details) {
> 
> The output should be in hex. Because you used print_uint it will still be in decimal
> in the JSON output.  The correct fix here is to use print_0xhex instead.
> 
> Please fix that, test it, and resubmit.

I did test, but not JSON output. It is not a regression in the latter
because it has been like this since JSON output was added to HTB.
Assuming the output is programmatically parsed, it shouldn't matter too
much as well.

Grepping through the code I found three more cases where print_uint()
was used for data printed in %x. Should I fix those as well?

Thanks, Phil

^ permalink raw reply

* Re: [PATCH net-next 3/4] net: phy-c45: Implement reset/suspend/resume callbacks
From: Florian Fainelli @ 2018-10-22 17:13 UTC (permalink / raw)
  To: Russell King - ARM Linux, Jose Abreu
  Cc: Andrew Lunn, netdev, David S. Miller, Joao Pinto
In-Reply-To: <20181022154851.GA1492@n2100.armlinux.org.uk>

On 10/22/18 8:48 AM, Russell King - ARM Linux wrote:
> On Mon, Oct 22, 2018 at 01:47:48PM +0100, Jose Abreu wrote:
>> Hello,
>>
>> On 22-10-2018 13:28, Andrew Lunn wrote:
>>>>  EXPORT_SYMBOL_GPL(gen10g_resume);
>>>> @@ -327,7 +381,7 @@ struct phy_driver genphy_10g_driver = {
>>>>  	.phy_id         = 0xffffffff,
>>>>  	.phy_id_mask    = 0xffffffff,
>>>>  	.name           = "Generic 10G PHY",
>>>> -	.soft_reset	= gen10g_no_soft_reset,
>>>> +	.soft_reset	= gen10g_soft_reset,
>>>>  	.config_init    = gen10g_config_init,
>>>>  	.features       = 0,
>>>>  	.aneg_done	= genphy_c45_aneg_done,
>>> Hi Jose
>>>
>>> You need to be careful here. There is a reason this is called
>>> gen10g_no_soft_reset, rather than having an empty
>>> gen10g_soft_reset. Some PHYs break when you do a reset.  So adding a
>>> gen10g_soft_reset is fine, but don't change this here, without first
>>> understanding the history, and talking to Russell King.
>>
>> Hmm, the reset function only interacts with standard PCS
>> registers, which should always be available ...
>>
>> >From my tests I need to do at least 1 reset during power-up so in
>> ultimate case I can add a feature quirk or similar.
>>
>> Russell, can you please comment ?
> 
> Setting the reset bit on 88x3310 causes the entire device to become
> completely inaccessible until hardware reset.  Therefore, this bit
> must _never_ be set for these devices.  That said, we have a separate
> driver for these PHYs, but that will only be used for them if it's
> present in the kernel.  If we accidentally fall back to the generic
> driver, then we'll screw the 88x3310 until a full hardware reset.
> 
> We also have a bunch of net devices that make use of this crippled
> "generic" 10G support - we don't know whether resetting the PHY
> for those systems will cause a regression - maybe board firmware
> already configured the PHY?  I can't say either way on that, except
> that we've had crippled 10G support in PHYLIB for a number of years
> now _with_ users, and adding reset support drastically changes the
> subsystem's behaviour for these users.
> 
> I would recommend not touching the generic 10G driver, but instead
> implement your own driver for your PHY to avoid causing regressions.
> 

Agreed.
-- 
Florian

^ permalink raw reply

* Re: [PATCH net-next 1/4] net: phy: Use C45 Helpers when forcing PHY
From: Florian Fainelli @ 2018-10-22 17:11 UTC (permalink / raw)
  To: Jose Abreu, netdev; +Cc: Andrew Lunn, David S. Miller, Joao Pinto
In-Reply-To: <b600cb7c389ba737d2d41b20f6376a8c32bb0039.1540204183.git.joabreu@synopsys.com>

On 10/22/18 3:32 AM, Jose Abreu wrote:
> If PHY is in force state and we have a C45 phy we need to use the
> standard C45 helpers and not the C22 ones.
> 
> Signed-off-by: Jose Abreu <joabreu@synopsys.com>
> Cc: Andrew Lunn <andrew@lunn.ch>
> Cc: Florian Fainelli <f.fainelli@gmail.com>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: Joao Pinto <joao.pinto@synopsys.com>
> ---
>  drivers/net/phy/phy.c | 2 +-
>  include/linux/phy.h   | 8 ++++++++
>  2 files changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
> index 1d73ac3309ce..0ff4946e208e 100644
> --- a/drivers/net/phy/phy.c
> +++ b/drivers/net/phy/phy.c
> @@ -995,7 +995,7 @@ void phy_state_machine(struct work_struct *work)
>  		}
>  		break;
>  	case PHY_FORCING:
> -		err = genphy_update_link(phydev);
> +		err = phy_update_link(phydev);
>  		if (err)
>  			break;
>  
> diff --git a/include/linux/phy.h b/include/linux/phy.h
> index 3ea87f774a76..02c2ee8bc05b 100644
> --- a/include/linux/phy.h
> +++ b/include/linux/phy.h
> @@ -1044,6 +1044,14 @@ static inline int phy_read_status(struct phy_device *phydev)
>  		return genphy_read_status(phydev);
>  }
>  
> +static inline int phy_update_link(struct phy_device *phydev)
> +{
> +	if (phydev->is_c45)
> +		return gen10g_read_status(phydev);

Should not this be genphy_c45_read_link() for symmetry with
genphy_update_link() which only updates phydev->link?
-- 
Florian

^ permalink raw reply

* Re: [PATCH iproute2 1/1] DEBUG: Fix make check when need build generate_nlmsg
From: Stephen Hemminger @ 2018-10-22 17:09 UTC (permalink / raw)
  To: Petr Vorel; +Cc: netdev
In-Reply-To: <20181022170341.GA13678@dell5510>

On Mon, 22 Oct 2018 19:03:41 +0200
Petr Vorel <pvorel@suse.cz> wrote:

> Hi Stephen,
> 
> > Applied, it seem to have gotten lost somewhere between my laptop and the repo.  
> Thanks a lot for merging :).
> 
> There is a patchset "Minor shell code cleanup", which has state Accepted, but
> not in git
> https://patchwork.ozlabs.org/project/netdev/list/?series=67063&state=*
> Did they got lost as well, or you don't agree with it?
> 
> 
> Kind regards,
> Petr

Let me go hunting.

^ permalink raw reply

* Re: [PATCH bpf-next] selftests/bpf: enable (uncomment) all tests in test_libbpf.sh
From: Jesper Dangaard Brouer @ 2018-10-22 17:08 UTC (permalink / raw)
  To: Quentin Monnet
  Cc: Alexei Starovoitov, Daniel Borkmann, netdev, oss-drivers, brouer
In-Reply-To: <ca443d9a-3809-5c05-dac4-99f8ba313cb5@netronome.com>

On Mon, 22 Oct 2018 11:00:27 +0100
Quentin Monnet <quentin.monnet@netronome.com> wrote:

> 2018-10-21 23:04 UTC+0200 ~ Jesper Dangaard Brouer <brouer@redhat.com>
> > On Sun, 21 Oct 2018 16:37:08 +0100
> > Quentin Monnet <quentin.monnet@netronome.com> wrote:
> >   
> >> 2018-10-21 11:57 UTC+0200 ~ Jesper Dangaard Brouer <brouer@redhat.com>  
> >>> On Sat, 20 Oct 2018 23:00:24 +0100
> >>> Quentin Monnet <quentin.monnet@netronome.com> wrote:
> >>>     
> >>
> >> [...]
> >>  
> >>>> --- a/tools/testing/selftests/bpf/test_libbpf.sh
> >>>> +++ b/tools/testing/selftests/bpf/test_libbpf.sh
> >>>> @@ -33,17 +33,11 @@ trap exit_handler 0 2 3 6 9
> >>>>   
> >>>>   libbpf_open_file test_l4lb.o
> >>>>   
> >>>> -# TODO: fix libbpf to load noinline functions
> >>>> -# [warning] libbpf: incorrect bpf_call opcode
> >>>> -#libbpf_open_file test_l4lb_noinline.o
> >>>> +libbpf_open_file test_l4lb_noinline.o
> >>>>   
> >>>> -# TODO: fix test_xdp_meta.c to load with libbpf
> >>>> -# [warning] libbpf: test_xdp_meta.o doesn't provide kernel version
> >>>> -#libbpf_open_file test_xdp_meta.o
> >>>> +libbpf_open_file test_xdp_meta.o
> >>>>   
> >>>> -# TODO: fix libbpf to handle .eh_frame
> >>>> -# [warning] libbpf: relocation failed: no section(10)
> >>>> -#libbpf_open_file ../../../../samples/bpf/tracex3_kern.o
> >>>> +libbpf_open_file ../../../../samples/bpf/tracex3_kern.o    
> >>>
> >>> I don't like the ../../../../samples/bpf/ reference (even-through I
> >>> added this TODO), as the kselftests AFAIK support installing the
> >>> selftests and then this tests will fail.
> >>> Maybe we can find another example kern.o file?
> >>> (which isn't compiled with -target bpf)    
> >>
> >> Hi Jesper, yeah maybe making the test rely on something from samples/bpf
> >> instead of just the selftests/bpf directory is not a good idea. But
> >> there is no program compiled without the "-target-bpf" in that
> >> directory. What we could do is explicitly compile one without the flag
> >> in the Makefile, as in the patch below, but I am not sure that doing so
> >> is acceptable?  
> > 
> > I think it makes sense to have a test program compiled without the
> > "-target-bpf", as that will happen for users.  And I guess we can add
> > some more specific test that are related to "-target-bpf".  
> 
> Alright, I can repost my second version that takes a test out of the
> default target for building BPF programs, after the merge window.
> 

Okay, guess there is no rush in getting this in now, and we can wait
for after the merge window.


> >> Or should tests for libbpf have a directory of their own,
> >> with another Makefile?  
> > 
> > Hmm, I'm not sure about that idea.
> > 
> > I did plan by naming the test "libbpf_open_file", what we add more
> > libbpf_ prefixed tests to the test_libbpf.sh script, which should
> > cover more aspects of the _base_ libbpf functionality.
> >   
> >> Another question regarding the test with test_xdp_meta.o: does the fix I
> >> suggested (setting a version in the .C file) makes sense, or did you
> >> leave this test for testing someday that libbpf would be able to open
> >> even programs that do not set a version (in which case this is still not
> >> the case if program type is not provided, and in fact my fix ruins
> >> everything? :s).  
> > 
> > Well, yes.  I was hinting if we should relax the version requirement
> > for e.g. XDP BPF progs.  
> 
> This is already the case. What happens for this test is that we never
> tell libbpf that this program is XDP, we just ask it to open the ELF
> file and the whole time libbpf treats it as a program of type
> BPF_PROG_TYPE_UNSPEC. So we can fix the BPF source (by adding a version)
> or we can fix test_libbpf_open.c (to tell libbpf this is XDP), but I
> don't believe there is anything to add to libbpf in that regard. I think
> we could simply remove the test on test_xdp_meta.o from test_libbpf.h,
> actually. What is you opinion?

Yes, we should likely just drop the test then.

-- 
Best regards,
  Jesper Dangaard Brouer
  MSc.CS, Principal Kernel Engineer at Red Hat
  LinkedIn: http://www.linkedin.com/in/brouer

^ permalink raw reply

* Re: [iproute PATCH] tc: Remove pointless assignments in batch()
From: Stephen Hemminger @ 2018-10-22 17:08 UTC (permalink / raw)
  To: Phil Sutter; +Cc: Chris Mi, netdev
In-Reply-To: <20181018134848.1298-1-phil@nwl.cc>

On Thu, 18 Oct 2018 15:48:48 +0200
Phil Sutter <phil@nwl.cc> wrote:

> All these assignments are later overwritten without reading in between,
> so just drop them.
> 
> Fixes: 485d0c6001c4a ("tc: Add batchsize feature for filter and actions")
> Signed-off-by: Phil Sutter <phil@nwl.cc>

Applied

^ permalink raw reply

* Re: [iproute PATCH] tipc: Drop unused variable 'genl'
From: Stephen Hemminger @ 2018-10-22 17:08 UTC (permalink / raw)
  To: Phil Sutter; +Cc: Richard Alpe, netdev
In-Reply-To: <20181018134809.843-1-phil@nwl.cc>

On Thu, 18 Oct 2018 15:48:09 +0200
Phil Sutter <phil@nwl.cc> wrote:

> Although initialized by call to libmnl, the variable is used only in a
> call to sizeof(). Drop it and call sizeof with its type instead.
> 
> Fixes: f043759dd4928 ("tipc: add new TIPC configuration tool")
> Signed-off-by: Phil Sutter <phil@nwl.cc>

Applied

^ permalink raw reply

* Re: [PATCH v2 1/2] dt-bindings: net: add MDIO bus multiplexer driven by a regmap device
From: Florian Fainelli @ 2018-10-22 17:08 UTC (permalink / raw)
  To: Pankaj Bansal, Andrew Lunn; +Cc: netdev@vger.kernel.org
In-Reply-To: <HE1PR0402MB332335E7185C83A3B560BAB6F1F40@HE1PR0402MB3323.eurprd04.prod.outlook.com>

On 10/21/18 9:22 PM, Pankaj Bansal wrote:
> 
>> -----Original Message-----
>> From: Pankaj Bansal
>> Sent: Thursday, October 18, 2018 10:00 AM
>> To: Florian Fainelli <f.fainelli@gmail.com>; Andrew Lunn <andrew@lunn.ch>
>> Cc: netdev@vger.kernel.org
>> Subject: RE: [PATCH v2 1/2] dt-bindings: net: add MDIO bus multiplexer driven by
>> a regmap device
>>
>> Hi Florian
>>
>>> -----Original Message-----
>>> From: Florian Fainelli [mailto:f.fainelli@gmail.com]
>>> Sent: Sunday, October 7, 2018 11:32 PM
>>> To: Pankaj Bansal <pankaj.bansal@nxp.com>; Andrew Lunn
>>> <andrew@lunn.ch>
>>> Cc: netdev@vger.kernel.org
>>> Subject: Re: [PATCH v2 1/2] dt-bindings: net: add MDIO bus multiplexer
>>> driven by a regmap device
>>>
>>>
>>>
>>> On 10/07/18 11:24, Pankaj Bansal wrote:
>>>> Add support for an MDIO bus multiplexer controlled by a regmap
>>>> device, like an FPGA.
>>>>
>>>> Tested on a NXP LX2160AQDS board which uses the "QIXIS" FPGA
>>>> attached to the i2c bus.
>>>>
>>>> Signed-off-by: Pankaj Bansal <pankaj.bansal@nxp.com>
>>>> ---
>>>>
>>>> Notes:
>>>>     V2:
>>>>      - Fixed formatting error caused by using space instead of tab
>>>>      - Add newline between property list and subnode
>>>>      - Add newline between two subnodes
>>>>
>>>>  .../bindings/net/mdio-mux-regmap.txt         | 95 ++++++++++++++++++
>>>>  1 file changed, 95 insertions(+)
>>>>
>>>> diff --git
>>>> a/Documentation/devicetree/bindings/net/mdio-mux-regmap.txt
>>>> b/Documentation/devicetree/bindings/net/mdio-mux-regmap.txt
>>>> new file mode 100644
>>>> index 000000000000..88ebac26c1c5
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/net/mdio-mux-regmap.txt
>>>> @@ -0,0 +1,95 @@
>>>> +Properties for an MDIO bus multiplexer controlled by a regmap
>>>> +
>>>> +This is a special case of a MDIO bus multiplexer.  A regmap device,
>>>> +like an FPGA, is used to control which child bus is connected.  The
>>>> +mdio-mux node must be a child of the device that is controlled by a
>> regmap.
>>>> +The driver currently only supports devices with upto 32-bit registers.
>>>
>>> I would omit any sort of details about Linux constructs designed to
>>> support specific needs (e.g: regmap) as well as putting driver
>>> limitations into a binding document because it really ought to be restricted to
>> describing hardware.
>>>
>>
>> Actually the platform driver mdio-mux-regmap.c, is generalization of mdio-mux-
>> mmioreg.c As such, it doesn't describe any new hardware, so no new properties
>> are described by it.
>> The only new property is compatible field.
>> I don't know how to describe this driver otherwise.  Can you please help?
> 
> I further thought about it. mdio-mux-regmap.c is not meant to control a specific device.
> It is meant to control some registers of parent device. Therefore, IMO this should not be a
> Platform driver and there should not be any "compatible" property to which this driver is associated.
> 
> Rather this driver should expose the APIs, which should be called by parent devices' driver.

Which one is "this driver" in that context? If you already have a driver
that FPGA bus/piece of hardware, then that driver itself could be
offering the MDIO muxing capabilities directly. You might still want to
have some Device Tree representation to properly parent the PHY devices
to the branches of the mux.

> 
> What is your thought on this ?
> 
>>
>>>> +
>>>> +Required properties in addition to the generic multiplexer properties:
>>>> +
>>>> +- compatible : string, must contain "mdio-mux-regmap"
>>>> +
>>>> +- reg : integer, contains the offset of the register that controls the bus
>>>> +	multiplexer. it can be 32 bit number.
>>>
>>> Technically it could be any "reg" property size, the only requirement
>>> is that it must be of the appropriate size with respect to what the
>>> parent node of this "mdio-mux-regmap" node has, determined by #address-
>> cells/#size-cells width.
>>
>> We are reading only single cell of this property using "of_propert_read_u32".
>> That is why I put the size in this.
>>
>>>
>>>> +
>>>> +- mux-mask : integer, contains an 32 bit mask that specifies which
>>>> +	bits in the register control the actual bus multiplexer.  The
>>>> +	'reg' property of each child mdio-mux node must be constrained by
>>>> +	this mask.
>>>
>>> Same thing here.
>>
>> We are reading only single cell of this property using "of_propert_read_u32".
>> That is why I put the size in this.
>>
>>>
>>> Since this is a MDIO mux, I would invite you to specify what the
>>> correct #address-cells/#size-cells values should be (1, and 0
>>> respectively as your example correctly shows).
>>>
>>
>> I will mention #address-cells/#size-cells values
>>
>>>> +
>>>> +Example:
>>>> +
>>>> +The FPGA node defines a i2c connected FPGA with a register space of
>>>> +0x30
>>> bytes.
>>>> +For the "EMI2" MDIO bus, register 0x54 (BRDCFG4) controls the mux
>>>> +on that
>>> bus.
>>>> +A bitmask of 0x07 means that bits 0, 1 and 2 (bit 0 is lsb) are the
>>>> +bits on
>>>> +BRDCFG4 that control the actual mux.
>>>> +
>>>> +i2c@2000000 {
>>>> +	compatible = "fsl,vf610-i2c";
>>>> +	#address-cells = <1>;
>>>> +	#size-cells = <0>;
>>>> +	reg = <0x0 0x2000000 0x0 0x10000>;
>>>> +	interrupts = <0 34 0x4>; // Level high type
>>>> +	clock-names = "i2c";
>>>> +	clocks = <&clockgen 4 7>;
>>>> +	fsl-scl-gpio = <&gpio2 15 0>;
>>>> +	status = "okay";
>>>> +
>>>> +	/* The FPGA node */
>>>> +	fpga@66 {
>>>> +		compatible = "fsl,lx2160aqds-fpga", "fsl,fpga-qixis-i2c";
>>>> +		reg = <0x66>;
>>>> +		#address-cells = <1>;
>>>> +		#size-cells = <0>;
>>>> +
>>>> +		mdio1_mux@54 {
>>>> +			compatible = "mdio-mux-regmap", "mdio-mux";
>>>> +			mdio-parent-bus = <&emdio2>; /* MDIO bus */
>>>> +			reg = <0x54>;		 /* BRDCFG4 */
>>>> +			mux-mask = <0x07>;      /* EMI2_MDIO */
>>>> +			#address-cells=<1>;
>>>> +			#size-cells = <0>;
>>>> +
>>>> +			mdio1_ioslot1@0 {   // Slot 1
>>>> +				reg = <0x00>;
>>>> +				#address-cells = <1>;
>>>> +				#size-cells = <0>;
>>>> +
>>>> +				phy1@1 {
>>>> +					reg = <1>;
>>>> +					compatible = "ethernet-phy-
>>> id0210.7441";
>>>> +				};
>>>> +
>>>> +				phy1@0 {
>>>> +					reg = <0>;
>>>> +					compatible = "ethernet-phy-
>>> id0210.7441";
>>>> +				};
>>>> +			};
>>>> +
>>>> +			mdio1_ioslot2@1 {   // Slot 2
>>>> +				reg = <0x01>;
>>>> +				#address-cells = <1>;
>>>> +				#size-cells = <0>;
>>>> +
>>>> +			};
>>>> +
>>>> +			mdio1_ioslot3@2 {   // Slot 3
>>>> +				reg = <0x02>;
>>>> +				#address-cells = <1>;
>>>> +				#size-cells = <0>;
>>>> +
>>>> +			};
>>>> +		};
>>>> +	};
>>>> +};
>>>> +
>>>> +	/* The parent MDIO bus. */
>>>> +	emdio2: mdio@0x8B97000 {
>>>> +		compatible = "fsl,fman-memac-mdio";
>>>> +		reg = <0x0 0x8B97000 0x0 0x1000>;
>>>> +		device_type = "mdio";
>>>> +		little-endian;
>>>> +
>>>> +		#address-cells = <1>;
>>>> +		#size-cells = <0>;
>>>> +	};
>>>>
>>>
>>> --
>>> Florian


-- 
Florian

^ permalink raw reply

* Re: [iproute PATCH] ip-route: Fix parse_encap_seg6() srh parsing
From: Stephen Hemminger @ 2018-10-22 17:08 UTC (permalink / raw)
  To: Phil Sutter; +Cc: David Lebrun, netdev
In-Reply-To: <20181018134414.32474-1-phil@nwl.cc>

On Thu, 18 Oct 2018 15:44:14 +0200
Phil Sutter <phil@nwl.cc> wrote:

> In case caller did not specify 'segs' parameter, parse_srh() would read
> garbage while iterating over 'segbuf'. Avoid this by initializing
> 'segbuf' to an empty string.
> 
> Fixes: e8493916a8ede ("iproute: add support for SR-IPv6 lwtunnel encapsulation")
> Signed-off-by: Phil Sutter <phil@nwl.cc>

Applied

^ permalink raw reply

* Re: [iproute PATCH] rdma: Don't pass garbage to rd_check_is_filtered()
From: Stephen Hemminger @ 2018-10-22 17:07 UTC (permalink / raw)
  To: Phil Sutter; +Cc: netdev
In-Reply-To: <20181018123550.20817-1-phil@nwl.cc>

On Thu, 18 Oct 2018 14:35:50 +0200
Phil Sutter <phil@nwl.cc> wrote:

> Variables 'src_port' and 'dst_port' are initialized only if attributes
> RDMA_NLDEV_ATTR_RES_SRC_ADDR or RDMA_NLDEV_ATTR_RES_DST_ADDR are
> present. Make sure to pass them over to rd_check_is_filtered() only if
> that is the case.
> 
> Fixes: 9a362cc71a455 ("rdma: Add CM_ID resource tracking information")
> Signed-off-by: Phil Sutter <phil@nwl.cc>

Applied, thanks.

^ permalink raw reply

* Re: [iproute PATCH] ip-route: Fix for memleak in error path
From: Stephen Hemminger @ 2018-10-22 17:06 UTC (permalink / raw)
  To: Phil Sutter; +Cc: netdev
In-Reply-To: <20181018123031.19854-1-phil@nwl.cc>

On Thu, 18 Oct 2018 14:30:31 +0200
Phil Sutter <phil@nwl.cc> wrote:

> If call to rta_addattr_l() failed, parse_encap_seg6() would leak memory.
> Fix this by making sure calls to free() are not skipped.
> 
> Fixes: bd59e5b1517b0 ("ip-route: Fix segfault with many nexthops")
> Signed-off-by: Phil Sutter <phil@nwl.cc>

Applied, thanks.

^ permalink raw reply

* Re: [iproute PATCH] rdma: Fix for ineffective check in add_filter()
From: Stephen Hemminger @ 2018-10-22 17:06 UTC (permalink / raw)
  To: Phil Sutter; +Cc: netdev, Arkadi Sharshevsky
In-Reply-To: <20181018114154.8886-1-phil@nwl.cc>

On Thu, 18 Oct 2018 13:41:54 +0200
Phil Sutter <phil@nwl.cc> wrote:

> With 'name' field defined as array in struct filters, it will always
> contain a value irrespective of whether a name was assigned or not.
> 
> Fix this by turning the field into a const char pointer.
> 
> Fixes: 8cd644095842a ("devlink: Add support for devlink resource abstraction")
> Signed-off-by: Phil Sutter <phil@nwl.cc>

Applied, and fixed fixes

^ permalink raw reply

* Re: [PATCH 19/20] rtlwifi: rtl8821ae: phy: Mark expected switch fall-through
From: Pkshih @ 2018-10-23  1:24 UTC (permalink / raw)
  To: gustavo@embeddedor.com
  Cc: linux-wireless@vger.kernel.org, kvalo@codeaurora.org,
	davem@davemloft.net, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <0a15ff0a1f238f2868ceefc6440ba9ac03e98a22.1540239684.git.gustavo@embeddedor.com>

On Mon, 2018-10-22 at 22:47 +0200, Gustavo A. R. Silva wrote:
> In preparation to enabling -Wimplicit-fallthrough, mark switch cases
> where we are expecting to fall through.
> 
> Signed-off-by: Gustavo A. R. Silva <gustavo@embeddedor.com>
> ---
>  drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
> b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
> index 176deb2..a75451c 100644
> --- a/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
> +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8821ae/phy.c
> @@ -394,6 +394,7 @@ static void _rtl8812ae_phy_set_rfe_reg_24g(struct
> ieee80211_hw *hw)
>  			rtl_set_bbreg(hw, RB_RFE_INV, BMASKRFEINV, 0x000);
>  			break;
>  		}
> +		/* fall through */
>  	case 0:
>  	case 2:
>  	default:

If BT isn't coexisting in the case 1, the settings will be the same as case 0/2.

Acked-by: Ping-Ke Shih <pkshih@realtek.com>



^ permalink raw reply

* Re: [PATCH iproute2 1/1] DEBUG: Fix make check when need build generate_nlmsg
From: Petr Vorel @ 2018-10-22 17:03 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20181022095106.5fb7a690@xeon-e3>

Hi Stephen,

> Applied, it seem to have gotten lost somewhere between my laptop and the repo.
Thanks a lot for merging :).

There is a patchset "Minor shell code cleanup", which has state Accepted, but
not in git
https://patchwork.ozlabs.org/project/netdev/list/?series=67063&state=*
Did they got lost as well, or you don't agree with it?


Kind regards,
Petr

^ permalink raw reply

* Re: [PATCH 1/9] net: dsa: bcm_sf2: simplify getting .driver_data
From: Florian Fainelli @ 2018-10-22 17:01 UTC (permalink / raw)
  To: Wolfram Sang, linux-kernel
  Cc: linux-renesas-soc, Andrew Lunn, Vivien Didelot, David S. Miller,
	netdev
In-Reply-To: <20181021200021.1693-2-wsa+renesas@sang-engineering.com>

On 10/21/18 1:00 PM, Wolfram Sang wrote:
> We should get 'driver_data' from 'struct device' directly. Going via
> platform_device is an unneeded step back and forth.
> 
> Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com>

Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
-- 
Florian

^ permalink raw reply

* Re: [iproute2 PATCH] bridge: fix vlan show stats formatting
From: Stephen Hemminger @ 2018-10-22 17:00 UTC (permalink / raw)
  To: Tobias Jungel; +Cc: netdev
In-Reply-To: <09b37bb3d091567c1f8958994e69e1221a61c0dc.camel@gmail.com>

On Sat, 20 Oct 2018 15:42:33 +0200
Tobias Jungel <tobias.jungel@gmail.com> wrote:

> The output of -statistics vlan show was broken previous change for json
> output. This aligns the format to vlan show.
> 
> Signed-off-by: Tobias Jungel <tobias.jungel@gmail.com>

This patch causes new warning:
    CC       vlan.o
vlan.c: In function ‘print_vlan_stats_attr’:
vlan.c:492:2: warning: ‘ifname’ may be used uninitialized in this function [-Wmaybe-uninitialized]
  print_color_string(PRINT_FP, COLOR_IFNAME,
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       NULL, "%-16s", ifname);
       ~~~~~~~~~~~~~~~~~~~~~~


Reverting the patch, please fix and resubmit.

^ permalink raw reply

* Re: [iproute PATCH] tc: htb: Print default value in hex
From: Stephen Hemminger @ 2018-10-22 16:56 UTC (permalink / raw)
  To: Phil Sutter; +Cc: Jiri Pirko, netdev
In-Reply-To: <20181019154255.25749-1-phil@nwl.cc>

On Fri, 19 Oct 2018 17:42:55 +0200
Phil Sutter <phil@nwl.cc> wrote:

> Value of 'default' is assumed to be hexadecimal when parsing, so
> consequently it should be printed in hex as well. This is a regression
> introduced when adding JSON output.
> 
> Fixes: f354fa6aa5ff0 ("tc: jsonify htb qdisc")
> Signed-off-by: Phil Sutter <phil@nwl.cc>
> ---
>  tc/q_htb.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tc/q_htb.c b/tc/q_htb.c
> index c8b2941d945b7..c69485db8ef7d 100644
> --- a/tc/q_htb.c
> +++ b/tc/q_htb.c
> @@ -332,7 +332,7 @@ static int htb_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
>  		if (RTA_PAYLOAD(tb[TCA_HTB_INIT])  < sizeof(*gopt)) return -1;
>  
>  		print_int(PRINT_ANY, "r2q", "r2q %d", gopt->rate2quantum);
> -		print_uint(PRINT_ANY, "default", " default %u", gopt->defcls);
> +		print_uint(PRINT_ANY, "default", " default %x", gopt->defcls);
>  		print_uint(PRINT_ANY, "direct_packets_stat",
>  			   " direct_packets_stat %u", gopt->direct_pkts);
>  		if (show_details) {

The output should be in hex. Because you used print_uint it will still be in decimal
in the JSON output.  The correct fix here is to use print_0xhex instead.

Please fix that, test it, and resubmit.

^ permalink raw reply

* Re: [PATCH iproute2 1/1] DEBUG: Fix make check when need build generate_nlmsg
From: Stephen Hemminger @ 2018-10-22 16:51 UTC (permalink / raw)
  To: Petr Vorel; +Cc: netdev
In-Reply-To: <20180925124956.10565-1-pvorel@suse.cz>

On Tue, 25 Sep 2018 14:49:56 +0200
Petr Vorel <pvorel@suse.cz> wrote:

> make check from top level Makefile defines several flags which break
> building generate_nlmsg:
> 
> $ make check
> make -C tools
> gcc  -Wall -Wstrict-prototypes  -Wmissing-prototypes -Wmissing-declarations -Wold-style-definition -Wformat=2 -O2 -I../include -I../include/uapi -DRESOLVE_HOSTNAMES -DLIBDIR=\"/usr/lib\" -DCONFDIR=\"/etc/iproute2\" -DNETNS_RUN_DIR=\"/var/run/netns\" -DNETNS_ETC_DIR=\"/etc/netns\" -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE  -DHAVE_SETNS -DHAVE_SELINUX -DHAVE_ELF -DHAVE_LIBMNL -I/usr/include/libmnl -DNEED_STRLCPY -DHAVE_LIBCAP ../lib/libutil.a ../lib/libnetlink.a -lselinux -lelf -lmnl -lcap  -I../../include -include../../include/uapi/linux/netlink.h -o generate_nlmsg generate_nlmsg.c ../../lib/libnetlink.c -lmnl
> gcc: error: ../lib/libutil.a: No such file or directory
> gcc: error: ../lib/libnetlink.a: No such file or directory
> make[2]: *** [Makefile:5: generate_nlmsg] Error 1
> make[1]: *** [Makefile:40: generate_nlmsg] Error 2
> 
> To fix it reset CFLAGS in sub Makefile and remove LDLIBS entirely (as
> required -lmnl flag was specified in 5dc2204c ("testsuite: add libmnl").
> 
> Fixes: 8804a8c0 ("Makefile: Add check target")
> 
> Signed-off-by: Petr Vorel <pvorel@suse.cz>
> ---
> Hi Stephen,
> 
> I'm sorry for this regression.
> 
> Kind regards,
> Petr

Applied, it seem to have gotten lost somewhere between my laptop and the repo.

^ permalink raw reply

* Re: [iproute2 PATCH] bridge: fix vlan show stats formatting
From: Stephen Hemminger @ 2018-10-22 16:47 UTC (permalink / raw)
  To: Tobias Jungel; +Cc: netdev
In-Reply-To: <09b37bb3d091567c1f8958994e69e1221a61c0dc.camel@gmail.com>

On Sat, 20 Oct 2018 15:42:33 +0200
Tobias Jungel <tobias.jungel@gmail.com> wrote:

> The output of -statistics vlan show was broken previous change for json
> output. This aligns the format to vlan show.
> 
> Signed-off-by: Tobias Jungel <tobias.jungel@gmail.com>

Applied, thanks

^ permalink raw reply

* [PATCH net-next v2 1/6] qed: Add doorbell overflow recovery mechanism
From: Ariel Elior @ 2018-10-22 16:40 UTC (permalink / raw)
  To: davem; +Cc: netdev, Ariel Elior, Michal Kalderon, Tomer Tayar
In-Reply-To: <20181022164045.25393-1-Ariel.Elior@cavium.com>

Add the database used to register doorbelling entities, and APIs for adding
and deleting entries, and logic for traversing the database and doorbelling
once on behalf of all entities.

Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com>
Signed-off-by: Tomer Tayar <Tomer.Tayar@cavium.com>
---
 drivers/net/ethernet/qlogic/qed/qed.h         |  17 ++
 drivers/net/ethernet/qlogic/qed/qed_dev.c     | 320 ++++++++++++++++++++++++++
 drivers/net/ethernet/qlogic/qed/qed_dev_api.h |  28 +++
 include/linux/qed/qed_if.h                    |  22 ++
 4 files changed, 387 insertions(+)

diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h
index 5f0962d..882279e 100644
--- a/drivers/net/ethernet/qlogic/qed/qed.h
+++ b/drivers/net/ethernet/qlogic/qed/qed.h
@@ -296,6 +296,12 @@ enum qed_wol_support {
 	QED_WOL_SUPPORT_PME,
 };
 
+enum qed_db_rec_exec {
+	DB_REC_DRY_RUN,
+	DB_REC_REAL_DEAL,
+	DB_REC_ONCE,
+};
+
 struct qed_hw_info {
 	/* PCI personality */
 	enum qed_pci_personality personality;
@@ -425,6 +431,14 @@ struct qed_qm_info {
 	u8 num_pf_rls;
 };
 
+struct qed_db_recovery_info {
+	struct list_head list;
+
+	/* Lock to protect the doorbell recovery mechanism list */
+	spinlock_t lock;
+	u32 db_recovery_counter;
+};
+
 struct storm_stats {
 	u32     address;
 	u32     len;
@@ -640,6 +654,9 @@ struct qed_hwfn {
 	/* L2-related */
 	struct qed_l2_info *p_l2_info;
 
+	/* Mechanism for recovering from doorbell drop */
+	struct qed_db_recovery_info db_recovery_info;
+
 	/* Nvm images number and attributes */
 	struct qed_nvm_image_info nvm_info;
 
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c
index 7ceb2b9..a63f87f 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dev.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c
@@ -66,6 +66,318 @@
 
 static DEFINE_SPINLOCK(qm_lock);
 
+/******************** Doorbell Recovery *******************/
+/* The doorbell recovery mechanism consists of a list of entries which represent
+ * doorbelling entities (l2 queues, roce sq/rq/cqs, the slowpath spq, etc). Each
+ * entity needs to register with the mechanism and provide the parameters
+ * describing it's doorbell, including a location where last used doorbell data
+ * can be found. The doorbell execute function will traverse the list and
+ * doorbell all of the registered entries.
+ */
+struct qed_db_recovery_entry {
+	struct list_head list_entry;
+	void __iomem *db_addr;
+	void *db_data;
+	enum qed_db_rec_width db_width;
+	enum qed_db_rec_space db_space;
+	u8 hwfn_idx;
+};
+
+/* Display a single doorbell recovery entry */
+static void qed_db_recovery_dp_entry(struct qed_hwfn *p_hwfn,
+				     struct qed_db_recovery_entry *db_entry,
+				     char *action)
+{
+	DP_VERBOSE(p_hwfn,
+		   QED_MSG_SPQ,
+		   "(%s: db_entry %p, addr %p, data %p, width %s, %s space, hwfn %d)\n",
+		   action,
+		   db_entry,
+		   db_entry->db_addr,
+		   db_entry->db_data,
+		   db_entry->db_width == DB_REC_WIDTH_32B ? "32b" : "64b",
+		   db_entry->db_space == DB_REC_USER ? "user" : "kernel",
+		   db_entry->hwfn_idx);
+}
+
+/* Doorbell address sanity (address within doorbell bar range) */
+static bool qed_db_rec_sanity(struct qed_dev *cdev,
+			      void __iomem *db_addr, void *db_data)
+{
+	/* Make sure doorbell address is within the doorbell bar */
+	if (db_addr < cdev->doorbells ||
+	    (u8 __iomem *)db_addr >
+	    (u8 __iomem *)cdev->doorbells + cdev->db_size) {
+		WARN(true,
+		     "Illegal doorbell address: %p. Legal range for doorbell addresses is [%p..%p]\n",
+		     db_addr,
+		     cdev->doorbells,
+		     (u8 __iomem *)cdev->doorbells + cdev->db_size);
+		return false;
+	}
+
+	/* ake sure doorbell data pointer is not null */
+	if (!db_data) {
+		WARN(true, "Illegal doorbell data pointer: %p", db_data);
+		return false;
+	}
+
+	return true;
+}
+
+/* Find hwfn according to the doorbell address */
+static struct qed_hwfn *qed_db_rec_find_hwfn(struct qed_dev *cdev,
+					     void __iomem *db_addr)
+{
+	struct qed_hwfn *p_hwfn;
+
+	/* In CMT doorbell bar is split down the middle between engine 0 and enigne 1 */
+	if (cdev->num_hwfns > 1)
+		p_hwfn = db_addr < cdev->hwfns[1].doorbells ?
+		    &cdev->hwfns[0] : &cdev->hwfns[1];
+	else
+		p_hwfn = QED_LEADING_HWFN(cdev);
+
+	return p_hwfn;
+}
+
+/* Add a new entry to the doorbell recovery mechanism */
+int qed_db_recovery_add(struct qed_dev *cdev,
+			void __iomem *db_addr,
+			void *db_data,
+			enum qed_db_rec_width db_width,
+			enum qed_db_rec_space db_space)
+{
+	struct qed_db_recovery_entry *db_entry;
+	struct qed_hwfn *p_hwfn;
+
+	/* Shortcircuit VFs, for now */
+	if (IS_VF(cdev)) {
+		DP_VERBOSE(cdev,
+			   QED_MSG_IOV, "db recovery - skipping VF doorbell\n");
+		return 0;
+	}
+
+	/* Sanitize doorbell address */
+	if (!qed_db_rec_sanity(cdev, db_addr, db_data))
+		return -EINVAL;
+
+	/* Obtain hwfn from doorbell address */
+	p_hwfn = qed_db_rec_find_hwfn(cdev, db_addr);
+
+	/* Create entry */
+	db_entry = kzalloc(sizeof(*db_entry), GFP_KERNEL);
+	if (!db_entry) {
+		DP_NOTICE(cdev, "Failed to allocate a db recovery entry\n");
+		return -ENOMEM;
+	}
+
+	/* Populate entry */
+	db_entry->db_addr = db_addr;
+	db_entry->db_data = db_data;
+	db_entry->db_width = db_width;
+	db_entry->db_space = db_space;
+	db_entry->hwfn_idx = p_hwfn->my_id;
+
+	/* Display */
+	qed_db_recovery_dp_entry(p_hwfn, db_entry, "Adding");
+
+	/* Protect the list */
+	spin_lock_bh(&p_hwfn->db_recovery_info.lock);
+	list_add_tail(&db_entry->list_entry, &p_hwfn->db_recovery_info.list);
+	spin_unlock_bh(&p_hwfn->db_recovery_info.lock);
+
+	return 0;
+}
+
+/* Remove an entry from the doorbell recovery mechanism */
+int qed_db_recovery_del(struct qed_dev *cdev,
+			void __iomem *db_addr, void *db_data)
+{
+	struct qed_db_recovery_entry *db_entry = NULL;
+	struct qed_hwfn *p_hwfn;
+	int rc = -EINVAL;
+
+	/* Shortcircuit VFs, for now */
+	if (IS_VF(cdev)) {
+		DP_VERBOSE(cdev,
+			   QED_MSG_IOV, "db recovery - skipping VF doorbell\n");
+		return 0;
+	}
+
+	/* Sanitize doorbell address */
+	if (!qed_db_rec_sanity(cdev, db_addr, db_data))
+		return -EINVAL;
+
+	/* Obtain hwfn from doorbell address */
+	p_hwfn = qed_db_rec_find_hwfn(cdev, db_addr);
+
+	/* Protect the list */
+	spin_lock_bh(&p_hwfn->db_recovery_info.lock);
+	list_for_each_entry(db_entry,
+			    &p_hwfn->db_recovery_info.list, list_entry) {
+		/* search according to db_data addr since db_addr is not unique (roce) */
+		if (db_entry->db_data == db_data) {
+			qed_db_recovery_dp_entry(p_hwfn, db_entry, "Deleting");
+			list_del(&db_entry->list_entry);
+			rc = 0;
+			break;
+		}
+	}
+
+	spin_unlock_bh(&p_hwfn->db_recovery_info.lock);
+
+	if (rc == -EINVAL)
+
+		DP_NOTICE(p_hwfn,
+			  "Failed to find element in list. Key (db_data addr) was %p. db_addr was %p\n",
+			  db_data, db_addr);
+	else
+		kfree(db_entry);
+
+	return rc;
+}
+
+/* Initialize the doorbell recovery mechanism */
+static int qed_db_recovery_setup(struct qed_hwfn *p_hwfn)
+{
+	DP_VERBOSE(p_hwfn, QED_MSG_SPQ, "Setting up db recovery\n");
+
+	/* Make sure db_size was set in cdev */
+	if (!p_hwfn->cdev->db_size) {
+		DP_ERR(p_hwfn->cdev, "db_size not set\n");
+		return -EINVAL;
+	}
+
+	INIT_LIST_HEAD(&p_hwfn->db_recovery_info.list);
+	spin_lock_init(&p_hwfn->db_recovery_info.lock);
+	p_hwfn->db_recovery_info.db_recovery_counter = 0;
+
+	return 0;
+}
+
+/* Destroy the doorbell recovery mechanism */
+static void qed_db_recovery_teardown(struct qed_hwfn *p_hwfn)
+{
+	struct qed_db_recovery_entry *db_entry = NULL;
+
+	DP_VERBOSE(p_hwfn, QED_MSG_SPQ, "Tearing down db recovery\n");
+	if (!list_empty(&p_hwfn->db_recovery_info.list)) {
+		DP_VERBOSE(p_hwfn,
+			   QED_MSG_SPQ,
+			   "Doorbell Recovery teardown found the doorbell recovery list was not empty (Expected in disorderly driver unload (e.g. recovery) otherwise this probably means some flow forgot to db_recovery_del). Prepare to purge doorbell recovery list...\n");
+		while (!list_empty(&p_hwfn->db_recovery_info.list)) {
+			db_entry =
+			    list_first_entry(&p_hwfn->db_recovery_info.list,
+					     struct qed_db_recovery_entry,
+					     list_entry);
+			qed_db_recovery_dp_entry(p_hwfn, db_entry, "Purging");
+			list_del(&db_entry->list_entry);
+			kfree(db_entry);
+		}
+	}
+	p_hwfn->db_recovery_info.db_recovery_counter = 0;
+}
+
+/* Print the content of the doorbell recovery mechanism */
+void qed_db_recovery_dp(struct qed_hwfn *p_hwfn)
+{
+	struct qed_db_recovery_entry *db_entry = NULL;
+
+	DP_NOTICE(p_hwfn,
+		  "Dispalying doorbell recovery database. Counter was %d\n",
+		  p_hwfn->db_recovery_info.db_recovery_counter);
+
+	/* Protect the list */
+	spin_lock_bh(&p_hwfn->db_recovery_info.lock);
+	list_for_each_entry(db_entry,
+			    &p_hwfn->db_recovery_info.list, list_entry) {
+		qed_db_recovery_dp_entry(p_hwfn, db_entry, "Printing");
+	}
+
+	spin_unlock_bh(&p_hwfn->db_recovery_info.lock);
+}
+
+/* Ring the doorbell of a single doorbell recovery entry */
+static void qed_db_recovery_ring(struct qed_hwfn *p_hwfn,
+				 struct qed_db_recovery_entry *db_entry,
+				 enum qed_db_rec_exec db_exec)
+{
+	if (db_exec != DB_REC_ONCE) {
+		/* Print according to width */
+		if (db_entry->db_width == DB_REC_WIDTH_32B) {
+			DP_VERBOSE(p_hwfn, QED_MSG_SPQ,
+				   "%s doorbell address %p data %x\n",
+				   db_exec == DB_REC_DRY_RUN ?
+				   "would have rung" : "ringing",
+				   db_entry->db_addr,
+				   *(u32 *)db_entry->db_data);
+		} else {
+			DP_VERBOSE(p_hwfn, QED_MSG_SPQ,
+				   "%s doorbell address %p data %llx\n",
+				   db_exec == DB_REC_DRY_RUN ?
+				   "would have rung" : "ringing",
+				   db_entry->db_addr,
+				   *(u64 *)(db_entry->db_data));
+		}
+	}
+
+	/* Sanity */
+	if (!qed_db_rec_sanity(p_hwfn->cdev, db_entry->db_addr,
+			       db_entry->db_data))
+		return;
+
+	/* Flush the write combined buffer. Since there are multiple doorbelling
+	 * entities using the same address, if we don't flush, a transaction
+	 * could be lost.
+	 */
+	wmb();
+
+	/* Ring the doorbell */
+	if (db_exec == DB_REC_REAL_DEAL || db_exec == DB_REC_ONCE) {
+		if (db_entry->db_width == DB_REC_WIDTH_32B)
+			DIRECT_REG_WR(db_entry->db_addr,
+				      *(u32 *)(db_entry->db_data));
+		else
+			DIRECT_REG_WR64(db_entry->db_addr,
+					*(u64 *)(db_entry->db_data));
+	}
+
+	/* Flush the write combined buffer. Next doorbell may come from a
+	 * different entity to the same address...
+	 */
+	wmb();
+}
+
+/* Traverse the doorbell recovery entry list and ring all the doorbells */
+void qed_db_recovery_execute(struct qed_hwfn *p_hwfn,
+			     enum qed_db_rec_exec db_exec)
+{
+	struct qed_db_recovery_entry *db_entry = NULL;
+
+	if (db_exec != DB_REC_ONCE) {
+		DP_NOTICE(p_hwfn,
+			  "Executing doorbell recovery. Counter was %d\n",
+			  p_hwfn->db_recovery_info.db_recovery_counter);
+
+		/* Track amount of times recovery was executed */
+		p_hwfn->db_recovery_info.db_recovery_counter++;
+	}
+
+	/* Protect the list */
+	spin_lock_bh(&p_hwfn->db_recovery_info.lock);
+	list_for_each_entry(db_entry,
+			    &p_hwfn->db_recovery_info.list, list_entry) {
+		qed_db_recovery_ring(p_hwfn, db_entry, db_exec);
+		if (db_exec == DB_REC_ONCE)
+			break;
+	}
+
+	spin_unlock_bh(&p_hwfn->db_recovery_info.lock);
+}
+
+/******************** Doorbell Recovery end ****************/
+
 #define QED_MIN_DPIS            (4)
 #define QED_MIN_PWM_REGION      (QED_WID_SIZE * QED_MIN_DPIS)
 
@@ -190,6 +502,9 @@ void qed_resc_free(struct qed_dev *cdev)
 		qed_dmae_info_free(p_hwfn);
 		qed_dcbx_info_free(p_hwfn);
 		qed_dbg_user_data_free(p_hwfn);
+
+		/* Destroy doorbell recovery mechanism */
+		qed_db_recovery_teardown(p_hwfn);
 	}
 }
 
@@ -946,6 +1261,11 @@ int qed_resc_alloc(struct qed_dev *cdev)
 		struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
 		u32 n_eqes, num_cons;
 
+		/* Initialize the doorbell recovery mechanism */
+		rc = qed_db_recovery_setup(p_hwfn);
+		if (rc)
+			goto alloc_err;
+
 		/* First allocate the context manager structure */
 		rc = qed_cxt_mngr_alloc(p_hwfn);
 		if (rc)
diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev_api.h b/drivers/net/ethernet/qlogic/qed/qed_dev_api.h
index defdda1..acccd85 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_dev_api.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_dev_api.h
@@ -472,6 +472,34 @@ int qed_final_cleanup(struct qed_hwfn *p_hwfn,
 int
 qed_set_queue_coalesce(u16 rx_coal, u16 tx_coal, void *p_handle);
 
+/**
+ * @brief db_recovery_add - add doorbell information to the doorbell
+ * recovery mechanism.
+ *
+ * @param cdev
+ * @param db_addr - doorbell address
+ * @param db_data - address of where db_data is stored
+ * @param db_width - doorbell is 32b pr 64b
+ * @param db_space - doorbell recovery addresses are user or kernel space
+ */
+int qed_db_recovery_add(struct qed_dev *cdev,
+			void __iomem *db_addr,
+			void *db_data,
+			enum qed_db_rec_width db_width,
+			enum qed_db_rec_space db_space);
+
+/**
+ * @brief db_recovery_del - remove doorbell information from the doorbell
+ * recovery mechanism. db_data serves as key (db_addr is not unique).
+ *
+ * @param cdev
+ * @param db_addr - doorbell address
+ * @param db_data - address where db_data is stored. Serves as key for the
+ *                  entry to delete.
+ */
+int qed_db_recovery_del(struct qed_dev *cdev,
+			void __iomem *db_addr, void *db_data);
+
 
 const char *qed_hw_get_resc_name(enum qed_resources res_id);
 #endif
diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h
index dee3c9c..afb2e4c 100644
--- a/include/linux/qed/qed_if.h
+++ b/include/linux/qed/qed_if.h
@@ -448,11 +448,33 @@ struct qed_mfw_tlv_iscsi {
 	bool tx_bytes_set;
 };
 
+enum qed_db_rec_width {
+	DB_REC_WIDTH_32B,
+	DB_REC_WIDTH_64B,
+};
+
+enum qed_db_rec_space {
+	DB_REC_KERNEL,
+	DB_REC_USER,
+};
+
 #define DIRECT_REG_WR(reg_addr, val) writel((u32)val, \
 					    (void __iomem *)(reg_addr))
 
 #define DIRECT_REG_RD(reg_addr) readl((void __iomem *)(reg_addr))
 
+#ifndef writeq
+#define writeq writeq
+static inline void writeq(u64 val, void __iomem *reg)
+{
+	writel(val & 0xffffffff, reg);
+	writel(val >> 32, reg + 0x4UL);
+}
+#endif
+
+#define DIRECT_REG_WR64(reg_addr, val) writeq((u32)val,	\
+					      (void __iomem *)(reg_addr))
+
 #define QED_COALESCE_MAX 0x1FF
 #define QED_DEFAULT_RX_USECS 12
 #define QED_DEFAULT_TX_USECS 48
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next v2 4/6] qed: Register light L2 queues with doorbell overflow recovery mechanism
From: Ariel Elior @ 2018-10-22 16:40 UTC (permalink / raw)
  To: davem; +Cc: netdev, Ariel Elior, Michal Kalderon, Tomer Tayar
In-Reply-To: <20181022164045.25393-1-Ariel.Elior@cavium.com>

Light L2 queues are doorbelling entities. Modify the implementation
to keep the doorbell data necessary for doorbelling in well known
location instead of recomputing every time. Register the LL2 queue
with doorbell recovery mechanism.

Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com>
Signed-off-by: Tomer Tayar <Tomer.Tayar@cavium.com>
---
 drivers/net/ethernet/qlogic/qed/qed_ll2.c | 30 ++++++++++++++++++++----------
 drivers/net/ethernet/qlogic/qed/qed_ll2.h |  1 +
 2 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.c b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
index aa63338..504c8f7 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ll2.c
+++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.c
@@ -1085,7 +1085,14 @@ static int qed_sp_ll2_tx_queue_start(struct qed_hwfn *p_hwfn,
 
 	p_ramrod->gsi_offload_flag = p_ll2_conn->input.gsi_enable;
 
-	return qed_spq_post(p_hwfn, p_ent, NULL);
+	rc = qed_spq_post(p_hwfn, p_ent, NULL);
+	if (rc)
+		return rc;
+
+	rc = qed_db_recovery_add(p_hwfn->cdev, p_tx->doorbell_addr,
+				 &p_tx->db_msg, DB_REC_WIDTH_32B,
+				 DB_REC_KERNEL);
+	return rc;
 }
 
 static int qed_sp_ll2_rx_queue_stop(struct qed_hwfn *p_hwfn,
@@ -1119,9 +1126,11 @@ static int qed_sp_ll2_rx_queue_stop(struct qed_hwfn *p_hwfn,
 static int qed_sp_ll2_tx_queue_stop(struct qed_hwfn *p_hwfn,
 				    struct qed_ll2_info *p_ll2_conn)
 {
+	struct qed_ll2_tx_queue *p_tx = &p_ll2_conn->tx_queue;
 	struct qed_spq_entry *p_ent = NULL;
 	struct qed_sp_init_data init_data;
 	int rc = -EINVAL;
+	qed_db_recovery_del(p_hwfn->cdev, p_tx->doorbell_addr, &p_tx->db_msg);
 
 	/* Get SPQ entry */
 	memset(&init_data, 0, sizeof(init_data));
@@ -1542,6 +1551,13 @@ int qed_ll2_establish_connection(void *cxt, u8 connection_handle)
 	p_tx->doorbell_addr = (u8 __iomem *)p_hwfn->doorbells +
 					    qed_db_addr(p_ll2_conn->cid,
 							DQ_DEMS_LEGACY);
+	/* prepare db data */
+	SET_FIELD(p_tx->db_msg.params, CORE_DB_DATA_DEST, DB_DEST_XCM);
+	SET_FIELD(p_tx->db_msg.params, CORE_DB_DATA_AGG_CMD, DB_AGG_CMD_SET);
+	SET_FIELD(p_tx->db_msg.params, CORE_DB_DATA_AGG_VAL_SEL,
+		  DQ_XCM_CORE_TX_BD_PROD_CMD);
+	p_tx->db_msg.agg_flags = DQ_XCM_CORE_DQ_CF_CMD;
+
 
 	rc = qed_ll2_establish_connection_rx(p_hwfn, p_ll2_conn);
 	if (rc)
@@ -1780,7 +1796,6 @@ static void qed_ll2_tx_packet_notify(struct qed_hwfn *p_hwfn,
 	bool b_notify = p_ll2_conn->tx_queue.cur_send_packet->notify_fw;
 	struct qed_ll2_tx_queue *p_tx = &p_ll2_conn->tx_queue;
 	struct qed_ll2_tx_packet *p_pkt = NULL;
-	struct core_db_data db_msg = { 0, 0, 0 };
 	u16 bd_prod;
 
 	/* If there are missing BDs, don't do anything now */
@@ -1809,24 +1824,19 @@ static void qed_ll2_tx_packet_notify(struct qed_hwfn *p_hwfn,
 		list_move_tail(&p_pkt->list_entry, &p_tx->active_descq);
 	}
 
-	SET_FIELD(db_msg.params, CORE_DB_DATA_DEST, DB_DEST_XCM);
-	SET_FIELD(db_msg.params, CORE_DB_DATA_AGG_CMD, DB_AGG_CMD_SET);
-	SET_FIELD(db_msg.params, CORE_DB_DATA_AGG_VAL_SEL,
-		  DQ_XCM_CORE_TX_BD_PROD_CMD);
-	db_msg.agg_flags = DQ_XCM_CORE_DQ_CF_CMD;
-	db_msg.spq_prod = cpu_to_le16(bd_prod);
+	p_tx->db_msg.spq_prod = cpu_to_le16(bd_prod);
 
 	/* Make sure the BDs data is updated before ringing the doorbell */
 	wmb();
 
-	DIRECT_REG_WR(p_tx->doorbell_addr, *((u32 *)&db_msg));
+	DIRECT_REG_WR(p_tx->doorbell_addr, *((u32 *)&p_tx->db_msg));
 
 	DP_VERBOSE(p_hwfn,
 		   (NETIF_MSG_TX_QUEUED | QED_MSG_LL2),
 		   "LL2 [q 0x%02x cid 0x%08x type 0x%08x] Doorbelled [producer 0x%04x]\n",
 		   p_ll2_conn->queue_id,
 		   p_ll2_conn->cid,
-		   p_ll2_conn->input.conn_type, db_msg.spq_prod);
+		   p_ll2_conn->input.conn_type, p_tx->db_msg.spq_prod);
 }
 
 int qed_ll2_prepare_tx_packet(void *cxt,
diff --git a/drivers/net/ethernet/qlogic/qed/qed_ll2.h b/drivers/net/ethernet/qlogic/qed/qed_ll2.h
index 1a5c1ae..5f01fbd 100644
--- a/drivers/net/ethernet/qlogic/qed/qed_ll2.h
+++ b/drivers/net/ethernet/qlogic/qed/qed_ll2.h
@@ -103,6 +103,7 @@ struct qed_ll2_tx_queue {
 	struct qed_ll2_tx_packet cur_completing_packet;
 	u16 cur_completing_bd_idx;
 	void __iomem *doorbell_addr;
+	struct core_db_data db_msg;
 	u16 bds_idx;
 	u16 cur_send_frag_num;
 	u16 cur_completing_frag_num;
-- 
1.8.3.1

^ permalink raw reply related

* [PATCH net-next v2 6/6] qede: Register l2 queues with doorbell overflow recovery mechanism
From: Ariel Elior @ 2018-10-22 16:40 UTC (permalink / raw)
  To: davem; +Cc: netdev, Ariel Elior, Michal Kalderon, Tomer Tayar
In-Reply-To: <20181022164045.25393-1-Ariel.Elior@cavium.com>

All L2 queues funnel through this flow, so this would cover the
regular RSS queues, as well queues created for VFs, mqos queues,
xdp queues, etc.

Signed-off-by: Ariel Elior <Ariel.Elior@cavium.com>
Signed-off-by: Michal Kalderon <Michal.Kalderon@cavium.com>
Signed-off-by: Tomer Tayar <Tomer.Tayar@cavium.com>
---
 drivers/net/ethernet/qlogic/qede/qede_main.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/ethernet/qlogic/qede/qede_main.c b/drivers/net/ethernet/qlogic/qede/qede_main.c
index 46d0f2e..1c4cea8 100644
--- a/drivers/net/ethernet/qlogic/qede/qede_main.c
+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c
@@ -1774,6 +1774,10 @@ static int qede_drain_txq(struct qede_dev *edev,
 static int qede_stop_txq(struct qede_dev *edev,
 			 struct qede_tx_queue *txq, int rss_id)
 {
+	/* delete doorbell from doorbell recovery mechanism */
+	edev->ops->common->db_recovery_del(edev->cdev, txq->doorbell_addr,
+					   &txq->tx_db);
+
 	return edev->ops->q_tx_stop(edev->cdev, rss_id, txq->handle);
 }
 
@@ -1910,6 +1914,11 @@ static int qede_start_txq(struct qede_dev *edev,
 		  DQ_XCM_ETH_TX_BD_PROD_CMD);
 	txq->tx_db.data.agg_flags = DQ_XCM_ETH_DQ_CF_CMD;
 
+	/* register doorbell with doorbell recovery mechanism */
+	rc = edev->ops->common->db_recovery_add(edev->cdev, txq->doorbell_addr,
+						&txq->tx_db, DB_REC_WIDTH_32B,
+						DB_REC_KERNEL);
+
 	return rc;
 }
 
-- 
1.8.3.1

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox