From: Vladimir Oltean <olteanv@gmail.com>
To: andrew@lunn.ch, f.fainelli@gmail.com, vivien.didelot@gmail.com,
davem@davemloft.net
Cc: jiri@resnulli.us, idosch@idosch.org, kuba@kernel.org,
netdev@vger.kernel.org, xiaoliang.yang_1@nxp.com,
linux-kernel@vger.kernel.org, horatiu.vultur@microchip.com,
alexandre.belloni@bootlin.com, allan.nielsen@microchip.com,
joergen.andreasen@microchip.com, UNGLinuxDriver@microchip.com,
yangbo.lu@nxp.com, alexandru.marginean@nxp.com, po.liu@nxp.com,
claudiu.manoil@nxp.com, leoyang.li@nxp.com
Subject: [PATCH net-next 1/6] net: mscc: ocelot: add action of police on vcap_is2
Date: Sun, 29 Mar 2020 02:51:57 +0200 [thread overview]
Message-ID: <20200329005202.17926-2-olteanv@gmail.com> (raw)
In-Reply-To: <20200329005202.17926-1-olteanv@gmail.com>
From: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Ocelot has 384 policers that can be allocated to ingress ports,
QoS classes per port, and VCAP IS2 entries. ocelot_police.c
supports to set policers which can be allocated to police action
of VCAP IS2. We allocate policers from maximum pol_id, and
decrease the pol_id when add a new vcap_is2 entry which is
police action.
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Patch taken from Xiaoliang's submission here:
https://patchwork.ozlabs.org/patch/1263213/
with the compilation error fixed.
drivers/net/ethernet/mscc/ocelot_ace.c | 64 ++++++++++++++++++++---
drivers/net/ethernet/mscc/ocelot_ace.h | 4 ++
drivers/net/ethernet/mscc/ocelot_flower.c | 9 ++++
drivers/net/ethernet/mscc/ocelot_police.c | 24 +++++++++
drivers/net/ethernet/mscc/ocelot_police.h | 5 ++
include/soc/mscc/ocelot.h | 1 +
6 files changed, 100 insertions(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c b/drivers/net/ethernet/mscc/ocelot_ace.c
index 906b54025b17..3bd286044480 100644
--- a/drivers/net/ethernet/mscc/ocelot_ace.c
+++ b/drivers/net/ethernet/mscc/ocelot_ace.c
@@ -7,6 +7,7 @@
#include <linux/proc_fs.h>
#include <soc/mscc/ocelot_vcap.h>
+#include "ocelot_police.h"
#include "ocelot_ace.h"
#include "ocelot_s2.h"
@@ -299,9 +300,9 @@ static void vcap_action_set(struct ocelot *ocelot, struct vcap_data *data,
}
static void is2_action_set(struct ocelot *ocelot, struct vcap_data *data,
- enum ocelot_ace_action action)
+ struct ocelot_ace_rule *ace)
{
- switch (action) {
+ switch (ace->action) {
case OCELOT_ACL_ACTION_DROP:
vcap_action_set(ocelot, data, VCAP_IS2_ACT_PORT_MASK, 0);
vcap_action_set(ocelot, data, VCAP_IS2_ACT_MASK_MODE, 1);
@@ -319,6 +320,15 @@ static void is2_action_set(struct ocelot *ocelot, struct vcap_data *data,
vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_QU_NUM, 0);
vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_COPY_ENA, 1);
break;
+ case OCELOT_ACL_ACTION_POLICE:
+ vcap_action_set(ocelot, data, VCAP_IS2_ACT_PORT_MASK, 0);
+ vcap_action_set(ocelot, data, VCAP_IS2_ACT_MASK_MODE, 0);
+ vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_ENA, 1);
+ vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_IDX,
+ ace->pol_ix);
+ vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_QU_NUM, 0);
+ vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_COPY_ENA, 0);
+ break;
}
}
@@ -611,7 +621,7 @@ static void is2_entry_set(struct ocelot *ocelot, int ix,
}
vcap_key_set(ocelot, &data, VCAP_IS2_TYPE, type, type_mask);
- is2_action_set(ocelot, &data, ace->action);
+ is2_action_set(ocelot, &data, ace);
vcap_data_set(data.counter, data.counter_offset,
vcap_is2->counter_width, ace->stats.pkts);
@@ -639,12 +649,19 @@ static void is2_entry_get(struct ocelot *ocelot, struct ocelot_ace_rule *rule,
rule->stats.pkts = cnt;
}
-static void ocelot_ace_rule_add(struct ocelot_acl_block *block,
+static void ocelot_ace_rule_add(struct ocelot *ocelot,
+ struct ocelot_acl_block *block,
struct ocelot_ace_rule *rule)
{
struct ocelot_ace_rule *tmp;
struct list_head *pos, *n;
+ if (rule->action == OCELOT_ACL_ACTION_POLICE) {
+ block->pol_lpr--;
+ rule->pol_ix = block->pol_lpr;
+ ocelot_ace_policer_add(ocelot, rule->pol_ix, &rule->pol);
+ }
+
block->count++;
if (list_empty(&block->rules)) {
@@ -697,7 +714,7 @@ int ocelot_ace_rule_offload_add(struct ocelot *ocelot,
int i, index;
/* Add rule to the linked list */
- ocelot_ace_rule_add(block, rule);
+ ocelot_ace_rule_add(ocelot, block, rule);
/* Get the index of the inserted rule */
index = ocelot_ace_rule_get_index_id(block, rule);
@@ -713,7 +730,33 @@ int ocelot_ace_rule_offload_add(struct ocelot *ocelot,
return 0;
}
-static void ocelot_ace_rule_del(struct ocelot_acl_block *block,
+static void ocelot_ace_police_del(struct ocelot *ocelot,
+ struct ocelot_acl_block *block,
+ u32 ix)
+{
+ struct ocelot_ace_rule *ace;
+ int index = -1;
+
+ if (ix < block->pol_lpr)
+ return;
+
+ list_for_each_entry(ace, &block->rules, list) {
+ index++;
+ if (ace->action == OCELOT_ACL_ACTION_POLICE &&
+ ace->pol_ix < ix) {
+ ace->pol_ix += 1;
+ ocelot_ace_policer_add(ocelot, ace->pol_ix,
+ &ace->pol);
+ is2_entry_set(ocelot, index, ace);
+ }
+ }
+
+ ocelot_ace_policer_del(ocelot, block->pol_lpr);
+ block->pol_lpr++;
+}
+
+static void ocelot_ace_rule_del(struct ocelot *ocelot,
+ struct ocelot_acl_block *block,
struct ocelot_ace_rule *rule)
{
struct ocelot_ace_rule *tmp;
@@ -722,6 +765,10 @@ static void ocelot_ace_rule_del(struct ocelot_acl_block *block,
list_for_each_safe(pos, q, &block->rules) {
tmp = list_entry(pos, struct ocelot_ace_rule, list);
if (tmp->id == rule->id) {
+ if (tmp->action == OCELOT_ACL_ACTION_POLICE)
+ ocelot_ace_police_del(ocelot, block,
+ tmp->pol_ix);
+
list_del(pos);
kfree(tmp);
}
@@ -744,7 +791,7 @@ int ocelot_ace_rule_offload_del(struct ocelot *ocelot,
index = ocelot_ace_rule_get_index_id(block, rule);
/* Delete rule */
- ocelot_ace_rule_del(block, rule);
+ ocelot_ace_rule_del(ocelot, block, rule);
/* Move up all the blocks over the deleted rule */
for (i = index; i < block->count; i++) {
@@ -779,6 +826,7 @@ int ocelot_ace_rule_stats_update(struct ocelot *ocelot,
int ocelot_ace_init(struct ocelot *ocelot)
{
const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2];
+ struct ocelot_acl_block *block = &ocelot->acl_block;
struct vcap_data data;
memset(&data, 0, sizeof(data));
@@ -807,6 +855,8 @@ int ocelot_ace_init(struct ocelot *ocelot)
ocelot_write_gix(ocelot, 0x3fffff, ANA_POL_CIR_STATE,
OCELOT_POLICER_DISCARD);
+ block->pol_lpr = OCELOT_POLICER_DISCARD - 1;
+
INIT_LIST_HEAD(&ocelot->acl_block.rules);
return 0;
diff --git a/drivers/net/ethernet/mscc/ocelot_ace.h b/drivers/net/ethernet/mscc/ocelot_ace.h
index b9a5868e3f15..29d22c566786 100644
--- a/drivers/net/ethernet/mscc/ocelot_ace.h
+++ b/drivers/net/ethernet/mscc/ocelot_ace.h
@@ -7,6 +7,7 @@
#define _MSCC_OCELOT_ACE_H_
#include "ocelot.h"
+#include "ocelot_police.h"
#include <net/sch_generic.h>
#include <net/pkt_cls.h>
@@ -176,6 +177,7 @@ struct ocelot_ace_frame_ipv6 {
enum ocelot_ace_action {
OCELOT_ACL_ACTION_DROP,
OCELOT_ACL_ACTION_TRAP,
+ OCELOT_ACL_ACTION_POLICE,
};
struct ocelot_ace_stats {
@@ -208,6 +210,8 @@ struct ocelot_ace_rule {
struct ocelot_ace_frame_ipv4 ipv4;
struct ocelot_ace_frame_ipv6 ipv6;
} frame;
+ struct ocelot_policer pol;
+ u32 pol_ix;
};
int ocelot_ace_rule_offload_add(struct ocelot *ocelot,
diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c b/drivers/net/ethernet/mscc/ocelot_flower.c
index 6cbca9b05520..bf0b04775dda 100644
--- a/drivers/net/ethernet/mscc/ocelot_flower.c
+++ b/drivers/net/ethernet/mscc/ocelot_flower.c
@@ -12,6 +12,8 @@ static int ocelot_flower_parse_action(struct flow_cls_offload *f,
struct ocelot_ace_rule *ace)
{
const struct flow_action_entry *a;
+ s64 burst;
+ u64 rate;
int i;
if (!flow_offload_has_one_action(&f->rule->action))
@@ -29,6 +31,13 @@ static int ocelot_flower_parse_action(struct flow_cls_offload *f,
case FLOW_ACTION_TRAP:
ace->action = OCELOT_ACL_ACTION_TRAP;
break;
+ case FLOW_ACTION_POLICE:
+ ace->action = OCELOT_ACL_ACTION_POLICE;
+ rate = a->police.rate_bytes_ps;
+ ace->pol.rate = div_u64(rate, 1000) * 8;
+ burst = rate * PSCHED_NS2TICKS(a->police.burst);
+ ace->pol.burst = div_u64(burst, PSCHED_TICKS_PER_SEC);
+ break;
default:
return -EOPNOTSUPP;
}
diff --git a/drivers/net/ethernet/mscc/ocelot_police.c b/drivers/net/ethernet/mscc/ocelot_police.c
index faddce43f2e3..8d25b2706ff0 100644
--- a/drivers/net/ethernet/mscc/ocelot_police.c
+++ b/drivers/net/ethernet/mscc/ocelot_police.c
@@ -225,3 +225,27 @@ int ocelot_port_policer_del(struct ocelot *ocelot, int port)
return 0;
}
+
+int ocelot_ace_policer_add(struct ocelot *ocelot, u32 pol_ix,
+ struct ocelot_policer *pol)
+{
+ struct qos_policer_conf pp = { 0 };
+
+ if (!pol)
+ return -EINVAL;
+
+ pp.mode = MSCC_QOS_RATE_MODE_DATA;
+ pp.pir = pol->rate;
+ pp.pbs = pol->burst;
+
+ return qos_policer_conf_set(ocelot, 0, pol_ix, &pp);
+}
+
+int ocelot_ace_policer_del(struct ocelot *ocelot, u32 pol_ix)
+{
+ struct qos_policer_conf pp = { 0 };
+
+ pp.mode = MSCC_QOS_RATE_MODE_DISABLED;
+
+ return qos_policer_conf_set(ocelot, 0, pol_ix, &pp);
+}
diff --git a/drivers/net/ethernet/mscc/ocelot_police.h b/drivers/net/ethernet/mscc/ocelot_police.h
index ae9509229463..22025cce0a6a 100644
--- a/drivers/net/ethernet/mscc/ocelot_police.h
+++ b/drivers/net/ethernet/mscc/ocelot_police.h
@@ -19,4 +19,9 @@ int ocelot_port_policer_add(struct ocelot *ocelot, int port,
int ocelot_port_policer_del(struct ocelot *ocelot, int port);
+int ocelot_ace_policer_add(struct ocelot *ocelot, u32 pol_ix,
+ struct ocelot_policer *pol);
+
+int ocelot_ace_policer_del(struct ocelot *ocelot, u32 pol_ix);
+
#endif /* _MSCC_OCELOT_POLICE_H_ */
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index 23a78d927838..3db66638a3b2 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -473,6 +473,7 @@ struct ocelot_ops {
struct ocelot_acl_block {
struct list_head rules;
int count;
+ int pol_lpr;
};
struct ocelot_port {
--
2.17.1
next prev parent reply other threads:[~2020-03-29 0:53 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-03-29 0:51 [PATCH net-next 0/6] Port and flow policers for DSA (SJA1105, Felix/Ocelot) Vladimir Oltean
2020-03-29 0:51 ` Vladimir Oltean [this message]
2020-03-29 0:51 ` [PATCH net-next 2/6] net: dsa: refactor matchall mirred action to separate function Vladimir Oltean
2020-03-29 0:51 ` [PATCH net-next 3/6] net: dsa: add port policers Vladimir Oltean
2020-03-29 0:52 ` [PATCH net-next 4/6] net: dsa: felix: " Vladimir Oltean
2020-03-29 11:10 ` Vladimir Oltean
2020-03-29 0:52 ` [PATCH net-next 5/6] net: dsa: sja1105: add configuration of " Vladimir Oltean
2020-03-29 0:52 ` [PATCH net-next 6/6] net: dsa: sja1105: add broadcast and per-traffic class policers Vladimir Oltean
2020-03-29 9:57 ` Ido Schimmel
2020-03-29 11:37 ` Vladimir Oltean
2020-03-29 11:46 ` Vladimir Oltean
2020-03-29 12:02 ` Nikolay Aleksandrov
2020-03-29 12:49 ` Nikolay Aleksandrov
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=20200329005202.17926-2-olteanv@gmail.com \
--to=olteanv@gmail.com \
--cc=UNGLinuxDriver@microchip.com \
--cc=alexandre.belloni@bootlin.com \
--cc=alexandru.marginean@nxp.com \
--cc=allan.nielsen@microchip.com \
--cc=andrew@lunn.ch \
--cc=claudiu.manoil@nxp.com \
--cc=davem@davemloft.net \
--cc=f.fainelli@gmail.com \
--cc=horatiu.vultur@microchip.com \
--cc=idosch@idosch.org \
--cc=jiri@resnulli.us \
--cc=joergen.andreasen@microchip.com \
--cc=kuba@kernel.org \
--cc=leoyang.li@nxp.com \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=po.liu@nxp.com \
--cc=vivien.didelot@gmail.com \
--cc=xiaoliang.yang_1@nxp.com \
--cc=yangbo.lu@nxp.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.