public inbox for netdev@vger.kernel.org 
 help / color / mirror / Atom feed
From: Jiri Pirko <jiri@resnulli•us>
To: netdev@vger•kernel.org
Cc: davem@davemloft•net, arkadis@mellanox•com, idosch@mellanox•com,
	mlxsw@mellanox•com, jhs@mojatatu•com, ivecera@redhat•com,
	roopa@cumulusnetworks•com, f.fainelli@gmail•com,
	vivien.didelot@savoirfairelinux•com, john.fastabend@gmail•com,
	andrew@lunn•ch
Subject: [patch net-next RFC 7/8] mlxsw: spectrum: Support for counters on router interfaces
Date: Thu, 16 Feb 2017 16:22:43 +0100	[thread overview]
Message-ID: <1487258564-3775-8-git-send-email-jiri@resnulli.us> (raw)
In-Reply-To: <1487258564-3775-1-git-send-email-jiri@resnulli.us>

From: Arkadi Sharshevsky <arkadis@mellanox•com>

Add support for counter allocation on router interfaces. The allocation
depends on the counter state of relevant table. In case the counting is
disabled or no counters left the counter index will be set as invalid.

Also a counter pool for router allocation is added.

Signed-off-by: Arakdi Sharshevsky <arkadis@mellanox•com>
Signed-off-by: Jiri Pirko <jiri@mellanox•com>
---
 drivers/net/ethernet/mellanox/mlxsw/spectrum.c     | 143 +++++++++++++++++++++
 drivers/net/ethernet/mellanox/mlxsw/spectrum.h     |  19 +++
 drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.c |   7 +-
 drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.h |   9 +-
 4 files changed, 176 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index cb66416..9a8c563 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -3318,6 +3318,138 @@ static struct mlxsw_config_profile mlxsw_sp_config_profile = {
 	.resource_query_enable		= 1,
 };
 
+static void mlxsw_sp_rif_counter_set(struct mlxsw_sp_rif *r,
+				     int counter_index, bool valid,
+				     enum mlxsw_sp_rif_counter_dir dir)
+{
+	switch (dir) {
+	case MLXSW_SP_RIF_COUNTER_EGRESS:
+		r->counter_egress = counter_index;
+		r->counter_egress_valid = valid;
+		break;
+	case MLXSW_SP_RIF_COUNTER_INGRESS:
+		r->counter_ingress = counter_index;
+		r->counter_ingress_valid = valid;
+		break;
+	}
+}
+
+static int mlxsw_sp_rif_counter_get(struct mlxsw_sp_rif *r,
+				    enum mlxsw_sp_rif_counter_dir dir)
+{
+	switch (dir) {
+	case MLXSW_SP_RIF_COUNTER_EGRESS:
+		if (r->counter_egress_valid)
+			return r->counter_egress;
+		break;
+	case MLXSW_SP_RIF_COUNTER_INGRESS:
+		if (r->counter_ingress_valid)
+			return r->counter_ingress;
+		break;
+	}
+	return -EINVAL;
+}
+
+static int mlxsw_sp_rif_counter_edit(struct mlxsw_sp *mlxsw_sp, u16 rif,
+				     int counter_index, bool enable,
+				     enum mlxsw_sp_rif_counter_dir dir)
+{
+	char ritr_pl[MLXSW_REG_RITR_LEN];
+	bool is_egress = false;
+	int err;
+
+	if (dir == MLXSW_SP_RIF_COUNTER_EGRESS)
+		is_egress = true;
+	mlxsw_reg_ritr_rif_pack(ritr_pl, rif);
+	err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
+	if (err)
+		return err;
+
+	mlxsw_reg_ritr_counter_pack(ritr_pl, counter_index, enable,
+				    is_egress);
+	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ritr), ritr_pl);
+}
+
+int mlxsw_sp_rif_counter_value_get(struct mlxsw_sp *mlxsw_sp,
+				   struct mlxsw_sp_rif *r,
+				   enum mlxsw_sp_rif_counter_dir dir, u64 *cnt)
+{
+	char ricnt_pl[MLXSW_REG_RICNT_LEN];
+	int counter_index;
+	int err;
+
+	counter_index = mlxsw_sp_rif_counter_get(r, dir);
+	if (counter_index < 0)
+		return -EINVAL;
+	mlxsw_reg_ricnt_pack(ricnt_pl, counter_index,
+			     MLXSW_REG_RICNT_OPCODE_NOP);
+	err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ricnt), ricnt_pl);
+	if (err)
+		return err;
+	*cnt = mlxsw_reg_ricnt_good_unicast_packets_get(ricnt_pl);
+	return 0;
+}
+
+static int mlxsw_sp_rif_counter_clear(struct mlxsw_sp *mlxsw_sp,
+				      int counter_index)
+{
+	char ricnt_pl[MLXSW_REG_RICNT_LEN];
+
+	mlxsw_reg_ricnt_pack(ricnt_pl, counter_index,
+			     MLXSW_REG_RICNT_OPCODE_CLEAR);
+	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ricnt), ricnt_pl);
+}
+
+int mlxsw_sp_rif_counter_alloc(struct mlxsw_sp *mlxsw_sp,
+			       struct mlxsw_sp_rif *r,
+			       enum mlxsw_sp_rif_counter_dir dir)
+{
+	int counter_index;
+	int err;
+
+	counter_index = mlxsw_sp_counter_alloc(mlxsw_sp,
+					       MLXSW_SP_COUNTER_SUB_POOL_RIF,
+					       MLXSW_SP_COUNTER_SIZE_RIF_BASIC);
+	if (counter_index < 0) {
+		err = counter_index;
+		return err;
+	}
+
+	err = mlxsw_sp_rif_counter_clear(mlxsw_sp, counter_index);
+	if (err)
+		goto err_counter_clear;
+
+	err = mlxsw_sp_rif_counter_edit(mlxsw_sp, r->rif, counter_index,
+					true, dir);
+	if (err)
+		goto err_counter_edit;
+
+	mlxsw_sp_rif_counter_set(r, counter_index, true, dir);
+	return 0;
+
+err_counter_edit:
+err_counter_clear:
+	mlxsw_sp_counter_free(mlxsw_sp, MLXSW_SP_COUNTER_SUB_POOL_RIF,
+			      counter_index);
+	return err;
+}
+
+void mlxsw_sp_rif_counter_free(struct mlxsw_sp *mlxsw_sp,
+			       struct mlxsw_sp_rif *r,
+			       enum mlxsw_sp_rif_counter_dir dir)
+{
+	int counter_index;
+
+	counter_index = mlxsw_sp_rif_counter_get(r, dir);
+	if (counter_index < 0)
+		return;
+	mlxsw_sp_rif_counter_edit(mlxsw_sp, r->rif,
+				  counter_index, false, dir);
+	mlxsw_sp_counter_free(mlxsw_sp, MLXSW_SP_COUNTER_SUB_POOL_RIF,
+			      counter_index);
+	mlxsw_sp_rif_counter_set(r, 0, false, dir);
+}
+
 static struct mlxsw_driver mlxsw_sp_driver = {
 	.kind				= mlxsw_sp_driver_name,
 	.priv_size			= sizeof(struct mlxsw_sp),
@@ -3549,6 +3681,15 @@ mlxsw_sp_vport_rif_sp_create(struct mlxsw_sp_port *mlxsw_sp_vport,
 	f->r = r;
 	mlxsw_sp->rifs[rif] = r;
 
+	if (devlink_dpipe_table_counter_enabled(priv_to_devlink(mlxsw_sp->core),
+						MLXSW_SP_DPIPE_TABLE_NAME_ERIF)){
+		err = mlxsw_sp_rif_counter_alloc(mlxsw_sp, r,
+						 MLXSW_SP_RIF_COUNTER_EGRESS);
+		if (err)
+			netdev_dbg(mlxsw_sp_vport->dev,
+				   "Counter alloc Failed err=%d\n", err);
+	}
+
 	return r;
 
 err_rif_alloc:
@@ -3570,6 +3711,8 @@ static void mlxsw_sp_vport_rif_sp_destroy(struct mlxsw_sp_port *mlxsw_sp_vport,
 	u16 rif = r->rif;
 
 	mlxsw_sp_router_rif_gone_sync(mlxsw_sp, r);
+	mlxsw_sp_rif_counter_free(mlxsw_sp, r, MLXSW_SP_RIF_COUNTER_EGRESS);
+	mlxsw_sp_rif_counter_free(mlxsw_sp, r, MLXSW_SP_RIF_COUNTER_INGRESS);
 
 	mlxsw_sp->rifs[rif] = NULL;
 	f->r = NULL;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
index 1aec58a..1fb2a43 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
@@ -85,6 +85,11 @@
 
 #define MLXSW_SP_CELL_FACTOR 2	/* 2 * cell_size / (IPG + cell_size + 1) */
 
+enum mlxsw_sp_rif_counter_dir {
+	MLXSW_SP_RIF_COUNTER_INGRESS,
+	MLXSW_SP_RIF_COUNTER_EGRESS,
+};
+
 static inline u16 mlxsw_sp_pfc_delay_get(int mtu, u16 delay)
 {
 	delay = MLXSW_SP_BYTES_TO_CELLS(DIV_ROUND_UP(delay, BITS_PER_BYTE));
@@ -116,6 +121,10 @@ struct mlxsw_sp_rif {
 	unsigned char addr[ETH_ALEN];
 	int mtu;
 	u16 rif;
+	unsigned int counter_ingress;
+	bool counter_ingress_valid;
+	unsigned int counter_egress;
+	bool counter_egress_valid;
 };
 
 struct mlxsw_sp_mid {
@@ -711,4 +720,14 @@ int mlxsw_sp_flower_replace(struct mlxsw_sp_port *mlxsw_sp_port, bool ingress,
 void mlxsw_sp_flower_destroy(struct mlxsw_sp_port *mlxsw_sp_port, bool ingress,
 			     struct tc_cls_flower_offload *f);
 
+int mlxsw_sp_rif_counter_value_get(struct mlxsw_sp *mlxsw_sp,
+				   struct mlxsw_sp_rif *r,
+				   enum mlxsw_sp_rif_counter_dir dir,
+				   u64 *cnt);
+void mlxsw_sp_rif_counter_free(struct mlxsw_sp *mlxsw_sp,
+			       struct mlxsw_sp_rif *r,
+			       enum mlxsw_sp_rif_counter_dir dir);
+int mlxsw_sp_rif_counter_alloc(struct mlxsw_sp *mlxsw_sp,
+			       struct mlxsw_sp_rif *r,
+			       enum mlxsw_sp_rif_counter_dir dir);
 #endif
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.c
index a0344c6..3e3ca6b 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.c
@@ -53,7 +53,12 @@ struct mlxsw_sp_counter_pool {
 	unsigned int sub_pools_count;
 };
 
-static struct mlxsw_sp_counter_sub_pool mlxsw_sp_counter_sub_pools[] = {};
+static struct mlxsw_sp_counter_sub_pool mlxsw_sp_counter_sub_pools[] = {
+	[MLXSW_SP_COUNTER_SUB_POOL_RIF] = {
+		.bank_count = 2,
+		.entry_size = MLXSW_SP_COUNTER_SIZE_RIF_BASIC,
+	},
+};
 
 int mlxsw_sp_counter_pool_init(struct mlxsw_sp *mlxsw_sp)
 {
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.h
index d300b89..aaf4c90 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_cnt.h
@@ -37,7 +37,14 @@
 
 #include "spectrum.h"
 
-enum mlxsw_sp_counter_sub_pool_id;
+enum mlxsw_sp_counter_sub_pool_id {
+	MLXSW_SP_COUNTER_SUB_POOL_RIF,
+};
+
+/* Counter indexes number needed for different resources */
+enum mlxsw_sp_counter_sizes {
+	MLXSW_SP_COUNTER_SIZE_RIF_BASIC = 10,
+};
 
 int mlxsw_sp_counter_alloc(struct mlxsw_sp *mlxsw_sp, unsigned int sub_pool_id,
 			   unsigned int entry_size);
-- 
2.7.4

  parent reply	other threads:[~2017-02-16 15:22 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-16 15:22 [patch net-next RFC 0/8] Add support for pipeline debug (dpipe) Jiri Pirko
2017-02-16 15:22 ` [patch net-next RFC 1/8] devlink: Support " Jiri Pirko
2017-02-16 15:57   ` John Fastabend
2017-02-17  8:49   ` Simon Horman
2017-02-18  7:38     ` Jiri Pirko
2017-02-20  8:27       ` Simon Horman
2017-02-16 15:22 ` [patch net-next RFC 2/8] mlxsw: spectrum: Add support for flow counter allocator Jiri Pirko
2017-02-16 15:22 ` [patch net-next RFC 3/8] mlxsw: reg: Add counter fields to RITR register Jiri Pirko
2017-02-16 15:22 ` [patch net-next RFC 4/8] mlxsw: spectrum: Add placeholder for dpipe Jiri Pirko
2017-02-16 15:22 ` [patch net-next RFC 5/8] mlxsw: spectrum: Add definition for egress rif table Jiri Pirko
2017-02-16 15:22 ` [patch net-next RFC 6/8] mlxsw: reg: Add Router Interface Counter Register Jiri Pirko
2017-02-16 15:22 ` Jiri Pirko [this message]
2017-02-16 15:22 ` [patch net-next RFC 8/8] mlxsw: spectrum: Add Support for erif table entries access Jiri Pirko
2017-02-16 15:51 ` [patch net-next RFC 0/8] Add support for pipeline debug (dpipe) John Fastabend
2017-02-16 16:26   ` Jiri Pirko
2017-02-16 16:11 ` Andrew Lunn
2017-02-16 16:20   ` Jiri Pirko
2017-02-16 16:40     ` Andrew Lunn
2017-02-16 16:48       ` Jiri Pirko
2017-02-16 21:20         ` arkadis
2017-02-16 17:04 ` Andrew Lunn
2017-02-16 18:40   ` Jiri Pirko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1487258564-3775-8-git-send-email-jiri@resnulli.us \
    --to=jiri@resnulli$(echo .)us \
    --cc=andrew@lunn$(echo .)ch \
    --cc=arkadis@mellanox$(echo .)com \
    --cc=davem@davemloft$(echo .)net \
    --cc=f.fainelli@gmail$(echo .)com \
    --cc=idosch@mellanox$(echo .)com \
    --cc=ivecera@redhat$(echo .)com \
    --cc=jhs@mojatatu$(echo .)com \
    --cc=john.fastabend@gmail$(echo .)com \
    --cc=mlxsw@mellanox$(echo .)com \
    --cc=netdev@vger$(echo .)kernel.org \
    --cc=roopa@cumulusnetworks$(echo .)com \
    --cc=vivien.didelot@savoirfairelinux$(echo .)com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox