From patchwork Tue Jun 2 05:18:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaoliang Yang X-Patchwork-Id: 218061 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8C8DFC433E1 for ; Tue, 2 Jun 2020 05:24:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 54F95206A2 for ; Tue, 2 Jun 2020 05:24:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728207AbgFBFYl (ORCPT ); Tue, 2 Jun 2020 01:24:41 -0400 Received: from inva020.nxp.com ([92.121.34.13]:44328 "EHLO inva020.nxp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726604AbgFBFYO (ORCPT ); Tue, 2 Jun 2020 01:24:14 -0400 Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 43A9B1A0B8A; Tue, 2 Jun 2020 07:24:02 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 0EE541A0B79; Tue, 2 Jun 2020 07:23:52 +0200 (CEST) Received: from localhost.localdomain (mega.ap.freescale.net [10.192.208.232]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id EF0D3402DF; Tue, 2 Jun 2020 13:23:39 +0800 (SGT) From: Xiaoliang Yang To: xiaoliang.yang_1@nxp.com, po.liu@nxp.com, claudiu.manoil@nxp.com, alexandru.marginean@nxp.com, vladimir.oltean@nxp.com, leoyang.li@nxp.com, mingkai.hu@nxp.com, andrew@lunn.ch, f.fainelli@gmail.com, vivien.didelot@gmail.com, davem@davemloft.net, jiri@resnulli.us, idosch@idosch.org, kuba@kernel.org, vinicius.gomes@intel.com, nikolay@cumulusnetworks.com, roopa@cumulusnetworks.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, horatiu.vultur@microchip.com, alexandre.belloni@bootlin.com, allan.nielsen@microchip.com, joergen.andreasen@microchip.com, UNGLinuxDriver@microchip.com, linux-devel@linux.nxdi.nxp.com Subject: [PATCH v2 net-next 02/10] net: mscc: ocelot: generalize existing code for VCAP Date: Tue, 2 Jun 2020 13:18:20 +0800 Message-Id: <20200602051828.5734-3-xiaoliang.yang_1@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200602051828.5734-1-xiaoliang.yang_1@nxp.com> References: <20200602051828.5734-1-xiaoliang.yang_1@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vladimir Oltean The Ocelot driver only supports VCAP IS2, the security enforcement block which implements Access Control List actions (trap, drop, police). In preparation of VCAP IS1 support, generalize the existing code to work with any VCAP. In that direction, move all VCAP instantiation-specific data to struct vcap_props, and pass that as an argument to each function that does the key and action packing. Only the high-level functions need to have access to ocelot->vcap[VCAP_IS2]. Signed-off-by: Vladimir Oltean Signed-off-by: Xiaoliang Yang --- drivers/net/dsa/ocelot/felix.c | 2 - drivers/net/dsa/ocelot/felix.h | 2 - drivers/net/dsa/ocelot/felix_vsc9959.c | 25 +- drivers/net/ethernet/mscc/ocelot_ace.c | 400 ++++++++++++---------- drivers/net/ethernet/mscc/ocelot_board.c | 5 +- drivers/net/ethernet/mscc/ocelot_flower.c | 1 + drivers/net/ethernet/mscc/ocelot_regs.c | 20 +- drivers/net/ethernet/mscc/ocelot_s2.h | 64 ---- include/soc/mscc/ocelot.h | 21 +- include/soc/mscc/ocelot_vcap.h | 62 ++++ 10 files changed, 313 insertions(+), 289 deletions(-) delete mode 100644 drivers/net/ethernet/mscc/ocelot_s2.h diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c index 66648986e6e3..4508d6063fd9 100644 --- a/drivers/net/dsa/ocelot/felix.c +++ b/drivers/net/dsa/ocelot/felix.c @@ -432,8 +432,6 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports) ocelot->num_stats = felix->info->num_stats; ocelot->shared_queue_sz = felix->info->shared_queue_sz; ocelot->num_mact_rows = felix->info->num_mact_rows; - ocelot->vcap_is2_keys = felix->info->vcap_is2_keys; - ocelot->vcap_is2_actions= felix->info->vcap_is2_actions; ocelot->vcap = felix->info->vcap; ocelot->ops = felix->info->ops; diff --git a/drivers/net/dsa/ocelot/felix.h b/drivers/net/dsa/ocelot/felix.h index a891736ca006..b1b6ecfa5a55 100644 --- a/drivers/net/dsa/ocelot/felix.h +++ b/drivers/net/dsa/ocelot/felix.h @@ -21,8 +21,6 @@ struct felix_info { unsigned int num_stats; int num_ports; int num_tx_queues; - struct vcap_field *vcap_is2_keys; - struct vcap_field *vcap_is2_actions; const struct vcap_props *vcap; int switch_pci_bar; int imdio_pci_bar; diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c index 1dd9e348152d..ef3bf875e64c 100644 --- a/drivers/net/dsa/ocelot/felix_vsc9959.c +++ b/drivers/net/dsa/ocelot/felix_vsc9959.c @@ -156,14 +156,16 @@ static const u32 vsc9959_qs_regmap[] = { REG_RESERVED(QS_INH_DBG), }; -static const u32 vsc9959_s2_regmap[] = { - REG(S2_CORE_UPDATE_CTRL, 0x000000), - REG(S2_CORE_MV_CFG, 0x000004), - REG(S2_CACHE_ENTRY_DAT, 0x000008), - REG(S2_CACHE_MASK_DAT, 0x000108), - REG(S2_CACHE_ACTION_DAT, 0x000208), - REG(S2_CACHE_CNT_DAT, 0x000308), - REG(S2_CACHE_TG_DAT, 0x000388), +static const u32 vsc9959_vcap_regmap[] = { + /* VCAP_CORE_CFG */ + REG(VCAP_CORE_UPDATE_CTRL, 0x000000), + REG(VCAP_CORE_MV_CFG, 0x000004), + /* VCAP_CORE_CACHE */ + REG(VCAP_CACHE_ENTRY_DAT, 0x000008), + REG(VCAP_CACHE_MASK_DAT, 0x000108), + REG(VCAP_CACHE_ACTION_DAT, 0x000208), + REG(VCAP_CACHE_CNT_DAT, 0x000308), + REG(VCAP_CACHE_TG_DAT, 0x000388), }; static const u32 vsc9959_qsys_regmap[] = { @@ -335,7 +337,7 @@ static const u32 *vsc9959_regmap[] = { [QSYS] = vsc9959_qsys_regmap, [REW] = vsc9959_rew_regmap, [SYS] = vsc9959_sys_regmap, - [S2] = vsc9959_s2_regmap, + [S2] = vsc9959_vcap_regmap, [PTP] = vsc9959_ptp_regmap, [GCB] = vsc9959_gcb_regmap, }; @@ -677,6 +679,9 @@ static const struct vcap_props vsc9959_vcap_props[] = { }, .counter_words = 4, .counter_width = 32, + .target = S2, + .keys = vsc9959_vcap_is2_keys, + .actions = vsc9959_vcap_is2_actions, }, }; @@ -1401,8 +1406,6 @@ struct felix_info felix_info_vsc9959 = { .ops = &vsc9959_ops, .stats_layout = vsc9959_stats_layout, .num_stats = ARRAY_SIZE(vsc9959_stats_layout), - .vcap_is2_keys = vsc9959_vcap_is2_keys, - .vcap_is2_actions = vsc9959_vcap_is2_actions, .vcap = vsc9959_vcap_props, .shared_queue_sz = 128 * 1024, .num_mact_rows = 2048, diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c b/drivers/net/ethernet/mscc/ocelot_ace.c index dfd82a3baab2..748c618db7d8 100644 --- a/drivers/net/ethernet/mscc/ocelot_ace.c +++ b/drivers/net/ethernet/mscc/ocelot_ace.c @@ -9,7 +9,6 @@ #include #include "ocelot_police.h" #include "ocelot_ace.h" -#include "ocelot_s2.h" #define OCELOT_POLICER_DISCARD 0x17f #define ENTRY_WIDTH 32 @@ -48,126 +47,138 @@ struct vcap_data { u32 tg_mask; /* Current type-group mask */ }; -static u32 vcap_s2_read_update_ctrl(struct ocelot *ocelot) +static u32 vcap_read_update_ctrl(struct ocelot *ocelot, + const struct vcap_props *vcap) { - return ocelot_read(ocelot, S2_CORE_UPDATE_CTRL); + return ocelot_target_read(ocelot, vcap->target, VCAP_CORE_UPDATE_CTRL); } -static void vcap_cmd(struct ocelot *ocelot, u16 ix, int cmd, int sel) +static void vcap_cmd(struct ocelot *ocelot, const struct vcap_props *vcap, + u16 ix, int cmd, int sel) { - const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2]; + u32 value = (VCAP_CORE_UPDATE_CTRL_UPDATE_CMD(cmd) | + VCAP_CORE_UPDATE_CTRL_UPDATE_ADDR(ix) | + VCAP_CORE_UPDATE_CTRL_UPDATE_SHOT); - u32 value = (S2_CORE_UPDATE_CTRL_UPDATE_CMD(cmd) | - S2_CORE_UPDATE_CTRL_UPDATE_ADDR(ix) | - S2_CORE_UPDATE_CTRL_UPDATE_SHOT); - - if ((sel & VCAP_SEL_ENTRY) && ix >= vcap_is2->entry_count) + if ((sel & VCAP_SEL_ENTRY) && ix >= vcap->entry_count) return; if (!(sel & VCAP_SEL_ENTRY)) - value |= S2_CORE_UPDATE_CTRL_UPDATE_ENTRY_DIS; + value |= VCAP_CORE_UPDATE_CTRL_UPDATE_ENTRY_DIS; if (!(sel & VCAP_SEL_ACTION)) - value |= S2_CORE_UPDATE_CTRL_UPDATE_ACTION_DIS; + value |= VCAP_CORE_UPDATE_CTRL_UPDATE_ACTION_DIS; if (!(sel & VCAP_SEL_COUNTER)) - value |= S2_CORE_UPDATE_CTRL_UPDATE_CNT_DIS; + value |= VCAP_CORE_UPDATE_CTRL_UPDATE_CNT_DIS; + + ocelot_target_write(ocelot, vcap->target, value, VCAP_CORE_UPDATE_CTRL); - ocelot_write(ocelot, value, S2_CORE_UPDATE_CTRL); - readx_poll_timeout(vcap_s2_read_update_ctrl, ocelot, value, - (value & S2_CORE_UPDATE_CTRL_UPDATE_SHOT) == 0, - 10, 100000); + read_poll_timeout(vcap_read_update_ctrl, value, + (value & VCAP_CORE_UPDATE_CTRL_UPDATE_SHOT) == 0, + 10, 100000, false, ocelot, vcap); } /* Convert from 0-based row to VCAP entry row and run command */ -static void vcap_row_cmd(struct ocelot *ocelot, u32 row, int cmd, int sel) +static void vcap_row_cmd(struct ocelot *ocelot, const struct vcap_props *vcap, + u32 row, int cmd, int sel) { - const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2]; - - vcap_cmd(ocelot, vcap_is2->entry_count - row - 1, cmd, sel); + vcap_cmd(ocelot, vcap, vcap->entry_count - row - 1, cmd, sel); } -static void vcap_entry2cache(struct ocelot *ocelot, struct vcap_data *data) +static void vcap_entry2cache(struct ocelot *ocelot, + const struct vcap_props *vcap, + struct vcap_data *data) { - const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2]; u32 entry_words, i; - entry_words = DIV_ROUND_UP(vcap_is2->entry_width, ENTRY_WIDTH); + entry_words = DIV_ROUND_UP(vcap->entry_width, ENTRY_WIDTH); for (i = 0; i < entry_words; i++) { - ocelot_write_rix(ocelot, data->entry[i], S2_CACHE_ENTRY_DAT, i); - ocelot_write_rix(ocelot, ~data->mask[i], S2_CACHE_MASK_DAT, i); + ocelot_target_write_rix(ocelot, vcap->target, data->entry[i], + VCAP_CACHE_ENTRY_DAT, i); + ocelot_target_write_rix(ocelot, vcap->target, ~data->mask[i], + VCAP_CACHE_MASK_DAT, i); } - ocelot_write(ocelot, data->tg, S2_CACHE_TG_DAT); + ocelot_target_write(ocelot, vcap->target, data->tg, VCAP_CACHE_TG_DAT); } -static void vcap_cache2entry(struct ocelot *ocelot, struct vcap_data *data) +static void vcap_cache2entry(struct ocelot *ocelot, + const struct vcap_props *vcap, + struct vcap_data *data) { - const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2]; u32 entry_words, i; - entry_words = DIV_ROUND_UP(vcap_is2->entry_width, ENTRY_WIDTH); + entry_words = DIV_ROUND_UP(vcap->entry_width, ENTRY_WIDTH); for (i = 0; i < entry_words; i++) { - data->entry[i] = ocelot_read_rix(ocelot, S2_CACHE_ENTRY_DAT, i); + data->entry[i] = ocelot_target_read_rix(ocelot, vcap->target, + VCAP_CACHE_ENTRY_DAT, i); // Invert mask - data->mask[i] = ~ocelot_read_rix(ocelot, S2_CACHE_MASK_DAT, i); + data->mask[i] = ~ocelot_target_read_rix(ocelot, vcap->target, + VCAP_CACHE_MASK_DAT, i); } - data->tg = ocelot_read(ocelot, S2_CACHE_TG_DAT); + data->tg = ocelot_target_read(ocelot, vcap->target, VCAP_CACHE_TG_DAT); } -static void vcap_action2cache(struct ocelot *ocelot, struct vcap_data *data) +static void vcap_action2cache(struct ocelot *ocelot, + const struct vcap_props *vcap, + struct vcap_data *data) { - const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2]; u32 action_words, i, width, mask; /* Encode action type */ - width = vcap_is2->action_type_width; + width = vcap->action_type_width; if (width) { mask = GENMASK(width, 0); data->action[0] = ((data->action[0] & ~mask) | data->type); } - action_words = DIV_ROUND_UP(vcap_is2->action_width, ENTRY_WIDTH); + action_words = DIV_ROUND_UP(vcap->action_width, ENTRY_WIDTH); for (i = 0; i < action_words; i++) - ocelot_write_rix(ocelot, data->action[i], S2_CACHE_ACTION_DAT, - i); + ocelot_target_write_rix(ocelot, vcap->target, data->action[i], + VCAP_CACHE_ACTION_DAT, i); - for (i = 0; i < vcap_is2->counter_words; i++) - ocelot_write_rix(ocelot, data->counter[i], S2_CACHE_CNT_DAT, i); + for (i = 0; i < vcap->counter_words; i++) + ocelot_target_write_rix(ocelot, vcap->target, data->counter[i], + VCAP_CACHE_CNT_DAT, i); } -static void vcap_cache2action(struct ocelot *ocelot, struct vcap_data *data) +static void vcap_cache2action(struct ocelot *ocelot, + const struct vcap_props *vcap, + struct vcap_data *data) { - const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2]; u32 action_words, i, width; - action_words = DIV_ROUND_UP(vcap_is2->action_width, ENTRY_WIDTH); + action_words = DIV_ROUND_UP(vcap->action_width, ENTRY_WIDTH); for (i = 0; i < action_words; i++) - data->action[i] = ocelot_read_rix(ocelot, S2_CACHE_ACTION_DAT, - i); + data->action[i] = ocelot_target_read_rix(ocelot, vcap->target, + VCAP_CACHE_ACTION_DAT, + i); - for (i = 0; i < vcap_is2->counter_words; i++) - data->counter[i] = ocelot_read_rix(ocelot, S2_CACHE_CNT_DAT, i); + for (i = 0; i < vcap->counter_words; i++) + data->counter[i] = ocelot_target_read_rix(ocelot, vcap->target, + VCAP_CACHE_CNT_DAT, + i); /* Extract action type */ - width = vcap_is2->action_type_width; + width = vcap->action_type_width; data->type = (width ? (data->action[0] & GENMASK(width, 0)) : 0); } /* Calculate offsets for entry */ -static void is2_data_get(struct ocelot *ocelot, struct vcap_data *data, int ix) +static void vcap_data_offset_get(const struct vcap_props *vcap, + struct vcap_data *data, int ix) { - const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2]; u32 i, col, offset, count, cnt, base; - u32 width = vcap_is2->tg_width; + u32 width = vcap->tg_width; count = (data->tg_sw == VCAP_TG_HALF ? 2 : 4); col = (ix % 2); - cnt = (vcap_is2->sw_count / count); - base = (vcap_is2->sw_count - col * cnt - cnt); + cnt = (vcap->sw_count / count); + base = (vcap->sw_count - col * cnt - cnt); data->tg_value = 0; data->tg_mask = 0; for (i = 0; i < cnt; i++) { @@ -178,13 +189,13 @@ static void is2_data_get(struct ocelot *ocelot, struct vcap_data *data, int ix) /* Calculate key/action/counter offsets */ col = (count - col - 1); - data->key_offset = (base * vcap_is2->entry_width) / vcap_is2->sw_count; - data->counter_offset = (cnt * col * vcap_is2->counter_width); + data->key_offset = (base * vcap->entry_width) / vcap->sw_count; + data->counter_offset = (cnt * col * vcap->counter_width); i = data->type; - width = vcap_is2->action_table[i].width; - cnt = vcap_is2->action_table[i].count; - data->action_offset = - (((cnt * col * width) / count) + vcap_is2->action_type_width); + width = vcap->action_table[i].width; + cnt = vcap->action_table[i].count; + data->action_offset = (((cnt * col * width) / count) + + vcap->action_type_width); } static void vcap_data_set(u32 *data, u32 offset, u32 len, u32 value) @@ -222,22 +233,21 @@ static void vcap_key_field_set(struct vcap_data *data, u32 offset, u32 width, vcap_data_set(data->mask, offset + data->key_offset, width, mask); } -static void vcap_key_set(struct ocelot *ocelot, struct vcap_data *data, - enum vcap_is2_half_key_field field, - u32 value, u32 mask) +static void vcap_key_set(const struct vcap_props *vcap, struct vcap_data *data, + int field, u32 value, u32 mask) { - u32 offset = ocelot->vcap_is2_keys[field].offset; - u32 length = ocelot->vcap_is2_keys[field].length; + u32 offset = vcap->keys[field].offset; + u32 length = vcap->keys[field].length; vcap_key_field_set(data, offset, length, value, mask); } -static void vcap_key_bytes_set(struct ocelot *ocelot, struct vcap_data *data, - enum vcap_is2_half_key_field field, +static void vcap_key_bytes_set(const struct vcap_props *vcap, + struct vcap_data *data, int field, u8 *val, u8 *msk) { - u32 offset = ocelot->vcap_is2_keys[field].offset; - u32 count = ocelot->vcap_is2_keys[field].length; + u32 offset = vcap->keys[field].offset; + u32 count = vcap->keys[field].length; u32 i, j, n = 0, value = 0, mask = 0; WARN_ON(count % 8); @@ -263,37 +273,37 @@ static void vcap_key_bytes_set(struct ocelot *ocelot, struct vcap_data *data, } } -static void vcap_key_l4_port_set(struct ocelot *ocelot, struct vcap_data *data, - enum vcap_is2_half_key_field field, +static void vcap_key_l4_port_set(const struct vcap_props *vcap, + struct vcap_data *data, int field, struct ocelot_vcap_udp_tcp *port) { - u32 offset = ocelot->vcap_is2_keys[field].offset; - u32 length = ocelot->vcap_is2_keys[field].length; + u32 offset = vcap->keys[field].offset; + u32 length = vcap->keys[field].length; WARN_ON(length != 16); vcap_key_field_set(data, offset, length, port->value, port->mask); } -static void vcap_key_bit_set(struct ocelot *ocelot, struct vcap_data *data, - enum vcap_is2_half_key_field field, +static void vcap_key_bit_set(const struct vcap_props *vcap, + struct vcap_data *data, int field, enum ocelot_vcap_bit val) { - u32 offset = ocelot->vcap_is2_keys[field].offset; - u32 length = ocelot->vcap_is2_keys[field].length; u32 value = (val == OCELOT_VCAP_BIT_1 ? 1 : 0); u32 msk = (val == OCELOT_VCAP_BIT_ANY ? 0 : 1); + u32 offset = vcap->keys[field].offset; + u32 length = vcap->keys[field].length; WARN_ON(length != 1); vcap_key_field_set(data, offset, length, value, msk); } -static void vcap_action_set(struct ocelot *ocelot, struct vcap_data *data, - enum vcap_is2_action_field field, u32 value) +static void vcap_action_set(const struct vcap_props *vcap, + struct vcap_data *data, int field, u32 value) { - int offset = ocelot->vcap_is2_actions[field].offset; - int length = ocelot->vcap_is2_actions[field].length; + int offset = vcap->actions[field].offset; + int length = vcap->actions[field].length; vcap_data_set(data->action, offset + data->action_offset, length, value); @@ -302,32 +312,34 @@ static void vcap_action_set(struct ocelot *ocelot, struct vcap_data *data, static void is2_action_set(struct ocelot *ocelot, struct vcap_data *data, struct ocelot_ace_rule *ace) { + const struct vcap_props *vcap = &ocelot->vcap[VCAP_IS2]; + 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); - vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_ENA, 1); - vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_IDX, + vcap_action_set(vcap, data, VCAP_IS2_ACT_PORT_MASK, 0); + vcap_action_set(vcap, data, VCAP_IS2_ACT_MASK_MODE, 1); + vcap_action_set(vcap, data, VCAP_IS2_ACT_POLICE_ENA, 1); + vcap_action_set(vcap, data, VCAP_IS2_ACT_POLICE_IDX, OCELOT_POLICER_DISCARD); - vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_QU_NUM, 0); - vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_COPY_ENA, 0); + vcap_action_set(vcap, data, VCAP_IS2_ACT_CPU_QU_NUM, 0); + vcap_action_set(vcap, data, VCAP_IS2_ACT_CPU_COPY_ENA, 0); break; case OCELOT_ACL_ACTION_TRAP: - vcap_action_set(ocelot, data, VCAP_IS2_ACT_PORT_MASK, 0); - vcap_action_set(ocelot, data, VCAP_IS2_ACT_MASK_MODE, 1); - vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_ENA, 0); - vcap_action_set(ocelot, data, VCAP_IS2_ACT_POLICE_IDX, 0); - vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_QU_NUM, 0); - vcap_action_set(ocelot, data, VCAP_IS2_ACT_CPU_COPY_ENA, 1); + vcap_action_set(vcap, data, VCAP_IS2_ACT_PORT_MASK, 0); + vcap_action_set(vcap, data, VCAP_IS2_ACT_MASK_MODE, 1); + vcap_action_set(vcap, data, VCAP_IS2_ACT_POLICE_ENA, 0); + vcap_action_set(vcap, data, VCAP_IS2_ACT_POLICE_IDX, 0); + vcap_action_set(vcap, data, VCAP_IS2_ACT_CPU_QU_NUM, 0); + vcap_action_set(vcap, 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, + vcap_action_set(vcap, data, VCAP_IS2_ACT_PORT_MASK, 0); + vcap_action_set(vcap, data, VCAP_IS2_ACT_MASK_MODE, 0); + vcap_action_set(vcap, data, VCAP_IS2_ACT_POLICE_ENA, 1); + vcap_action_set(vcap, 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); + vcap_action_set(vcap, data, VCAP_IS2_ACT_CPU_QU_NUM, 0); + vcap_action_set(vcap, data, VCAP_IS2_ACT_CPU_COPY_ENA, 0); break; } } @@ -335,7 +347,7 @@ static void is2_action_set(struct ocelot *ocelot, struct vcap_data *data, static void is2_entry_set(struct ocelot *ocelot, int ix, struct ocelot_ace_rule *ace) { - const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2]; + const struct vcap_props *vcap = &ocelot->vcap[VCAP_IS2]; u32 val, msk, type, type_mask = 0xf, i, count; struct ocelot_ace_vlan *tag = &ace->vlan; struct ocelot_vcap_u64 payload; @@ -346,52 +358,52 @@ static void is2_entry_set(struct ocelot *ocelot, int ix, memset(&data, 0, sizeof(data)); /* Read row */ - vcap_row_cmd(ocelot, row, VCAP_CMD_READ, VCAP_SEL_ALL); - vcap_cache2entry(ocelot, &data); - vcap_cache2action(ocelot, &data); + vcap_row_cmd(ocelot, vcap, row, VCAP_CMD_READ, VCAP_SEL_ALL); + vcap_cache2entry(ocelot, vcap, &data); + vcap_cache2action(ocelot, vcap, &data); data.tg_sw = VCAP_TG_HALF; - is2_data_get(ocelot, &data, ix); + vcap_data_offset_get(vcap, &data, ix); data.tg = (data.tg & ~data.tg_mask); if (ace->prio != 0) data.tg |= data.tg_value; data.type = IS2_ACTION_TYPE_NORMAL; - vcap_key_set(ocelot, &data, VCAP_IS2_HK_PAG, 0, 0); - vcap_key_set(ocelot, &data, VCAP_IS2_HK_IGR_PORT_MASK, 0, + vcap_key_set(vcap, &data, VCAP_IS2_HK_PAG, 0, 0); + vcap_key_set(vcap, &data, VCAP_IS2_HK_IGR_PORT_MASK, 0, ~ace->ingress_port_mask); - vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_FIRST, OCELOT_VCAP_BIT_1); - vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_HOST_MATCH, + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_FIRST, OCELOT_VCAP_BIT_ANY); + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_HOST_MATCH, OCELOT_VCAP_BIT_ANY); - vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L2_MC, ace->dmac_mc); - vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L2_BC, ace->dmac_bc); - vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_VLAN_TAGGED, tag->tagged); - vcap_key_set(ocelot, &data, VCAP_IS2_HK_VID, + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L2_MC, ace->dmac_mc); + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L2_BC, ace->dmac_bc); + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_VLAN_TAGGED, tag->tagged); + vcap_key_set(vcap, &data, VCAP_IS2_HK_VID, tag->vid.value, tag->vid.mask); - vcap_key_set(ocelot, &data, VCAP_IS2_HK_PCP, + vcap_key_set(vcap, &data, VCAP_IS2_HK_PCP, tag->pcp.value[0], tag->pcp.mask[0]); - vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_DEI, tag->dei); + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_DEI, tag->dei); switch (ace->type) { case OCELOT_ACE_TYPE_ETYPE: { struct ocelot_ace_frame_etype *etype = &ace->frame.etype; type = IS2_TYPE_ETYPE; - vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_DMAC, + vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L2_DMAC, etype->dmac.value, etype->dmac.mask); - vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_SMAC, + vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L2_SMAC, etype->smac.value, etype->smac.mask); - vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_MAC_ETYPE_ETYPE, + vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_MAC_ETYPE_ETYPE, etype->etype.value, etype->etype.mask); /* Clear unused bits */ - vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0, + vcap_key_set(vcap, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0, 0, 0); - vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1, + vcap_key_set(vcap, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1, 0, 0); - vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2, + vcap_key_set(vcap, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2, 0, 0); - vcap_key_bytes_set(ocelot, &data, + vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0, etype->data.value, etype->data.mask); break; @@ -400,15 +412,15 @@ static void is2_entry_set(struct ocelot *ocelot, int ix, struct ocelot_ace_frame_llc *llc = &ace->frame.llc; type = IS2_TYPE_LLC; - vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_DMAC, + vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L2_DMAC, llc->dmac.value, llc->dmac.mask); - vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_SMAC, + vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L2_SMAC, llc->smac.value, llc->smac.mask); for (i = 0; i < 4; i++) { payload.value[i] = llc->llc.value[i]; payload.mask[i] = llc->llc.mask[i]; } - vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_MAC_LLC_L2_LLC, + vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_MAC_LLC_L2_LLC, payload.value, payload.mask); break; } @@ -416,11 +428,11 @@ static void is2_entry_set(struct ocelot *ocelot, int ix, struct ocelot_ace_frame_snap *snap = &ace->frame.snap; type = IS2_TYPE_SNAP; - vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_DMAC, + vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L2_DMAC, snap->dmac.value, snap->dmac.mask); - vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L2_SMAC, + vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L2_SMAC, snap->smac.value, snap->smac.mask); - vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_MAC_SNAP_L2_SNAP, + vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_MAC_SNAP_L2_SNAP, ace->frame.snap.snap.value, ace->frame.snap.snap.mask); break; @@ -429,24 +441,24 @@ static void is2_entry_set(struct ocelot *ocelot, int ix, struct ocelot_ace_frame_arp *arp = &ace->frame.arp; type = IS2_TYPE_ARP; - vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_MAC_ARP_SMAC, + vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_MAC_ARP_SMAC, arp->smac.value, arp->smac.mask); - vcap_key_bit_set(ocelot, &data, + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK, arp->ethernet); - vcap_key_bit_set(ocelot, &data, + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK, arp->ip); - vcap_key_bit_set(ocelot, &data, + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_MAC_ARP_LEN_OK, arp->length); - vcap_key_bit_set(ocelot, &data, + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_MAC_ARP_TARGET_MATCH, arp->dmac_match); - vcap_key_bit_set(ocelot, &data, + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_MAC_ARP_SENDER_MATCH, arp->smac_match); - vcap_key_bit_set(ocelot, &data, + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN, arp->unknown); @@ -455,15 +467,15 @@ static void is2_entry_set(struct ocelot *ocelot, int ix, (arp->arp == OCELOT_VCAP_BIT_0 ? 2 : 0)); msk = ((arp->req == OCELOT_VCAP_BIT_ANY ? 0 : 1) | (arp->arp == OCELOT_VCAP_BIT_ANY ? 0 : 2)); - vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ARP_OPCODE, + vcap_key_set(vcap, &data, VCAP_IS2_HK_MAC_ARP_OPCODE, val, msk); - vcap_key_bytes_set(ocelot, &data, + vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP, arp->dip.value.addr, arp->dip.mask.addr); - vcap_key_bytes_set(ocelot, &data, + vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP, arp->sip.value.addr, arp->sip.mask.addr); - vcap_key_set(ocelot, &data, VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP, + vcap_key_set(vcap, &data, VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP, 0, 0); break; } @@ -532,22 +544,22 @@ static void is2_entry_set(struct ocelot *ocelot, int ix, seq_zero = ipv6->seq_zero; } - vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_IP4, + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_IP4, ipv4 ? OCELOT_VCAP_BIT_1 : OCELOT_VCAP_BIT_0); - vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L3_FRAGMENT, + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L3_FRAGMENT, fragment); - vcap_key_set(ocelot, &data, VCAP_IS2_HK_L3_FRAG_OFS_GT0, 0, 0); - vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L3_OPTIONS, + vcap_key_set(vcap, &data, VCAP_IS2_HK_L3_FRAG_OFS_GT0, 0, 0); + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L3_OPTIONS, options); - vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_IP4_L3_TTL_GT0, + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_IP4_L3_TTL_GT0, ttl); - vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L3_TOS, + vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L3_TOS, ds.value, ds.mask); - vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L3_IP4_DIP, + vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L3_IP4_DIP, dip.value.addr, dip.mask.addr); - vcap_key_bytes_set(ocelot, &data, VCAP_IS2_HK_L3_IP4_SIP, + vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L3_IP4_SIP, sip.value.addr, sip.mask.addr); - vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_DIP_EQ_SIP, + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_DIP_EQ_SIP, sip_eq_dip); val = proto.value[0]; msk = proto.mask[0]; @@ -556,33 +568,33 @@ static void is2_entry_set(struct ocelot *ocelot, int ix, /* UDP/TCP protocol match */ tcp = (val == 6 ? OCELOT_VCAP_BIT_1 : OCELOT_VCAP_BIT_0); - vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_TCP, tcp); - vcap_key_l4_port_set(ocelot, &data, + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_TCP, tcp); + vcap_key_l4_port_set(vcap, &data, VCAP_IS2_HK_L4_DPORT, dport); - vcap_key_l4_port_set(ocelot, &data, + vcap_key_l4_port_set(vcap, &data, VCAP_IS2_HK_L4_SPORT, sport); - vcap_key_set(ocelot, &data, VCAP_IS2_HK_L4_RNG, 0, 0); - vcap_key_bit_set(ocelot, &data, + vcap_key_set(vcap, &data, VCAP_IS2_HK_L4_RNG, 0, 0); + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_SPORT_EQ_DPORT, sport_eq_dport); - vcap_key_bit_set(ocelot, &data, + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_SEQUENCE_EQ0, seq_zero); - vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_FIN, + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_FIN, tcp_fin); - vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_SYN, + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_SYN, tcp_syn); - vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_RST, + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_RST, tcp_rst); - vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_PSH, + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_PSH, tcp_psh); - vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_ACK, + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_ACK, tcp_ack); - vcap_key_bit_set(ocelot, &data, VCAP_IS2_HK_L4_URG, + vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_URG, tcp_urg); - vcap_key_set(ocelot, &data, VCAP_IS2_HK_L4_1588_DOM, + vcap_key_set(vcap, &data, VCAP_IS2_HK_L4_1588_DOM, 0, 0); - vcap_key_set(ocelot, &data, VCAP_IS2_HK_L4_1588_VER, + vcap_key_set(vcap, &data, VCAP_IS2_HK_L4_1588_VER, 0, 0); } else { if (msk == 0) { @@ -596,10 +608,10 @@ static void is2_entry_set(struct ocelot *ocelot, int ix, payload.mask[i] = ip_data->mask[i]; } } - vcap_key_bytes_set(ocelot, &data, + vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_IP4_L3_PROTO, proto.value, proto.mask); - vcap_key_bytes_set(ocelot, &data, + vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L3_PAYLOAD, payload.value, payload.mask); } @@ -609,42 +621,44 @@ static void is2_entry_set(struct ocelot *ocelot, int ix, default: type = 0; type_mask = 0; - count = vcap_is2->entry_width / 2; + count = vcap->entry_width / 2; /* Iterate over the non-common part of the key and * clear entry data */ - for (i = ocelot->vcap_is2_keys[VCAP_IS2_HK_L2_DMAC].offset; + for (i = vcap->keys[VCAP_IS2_HK_L2_DMAC].offset; i < count; i += ENTRY_WIDTH) { vcap_key_field_set(&data, i, min(32u, count - i), 0, 0); } break; } - vcap_key_set(ocelot, &data, VCAP_IS2_TYPE, type, type_mask); + vcap_key_set(vcap, &data, VCAP_IS2_TYPE, type, type_mask); is2_action_set(ocelot, &data, ace); vcap_data_set(data.counter, data.counter_offset, - vcap_is2->counter_width, ace->stats.pkts); + vcap->counter_width, ace->stats.pkts); /* Write row */ - vcap_entry2cache(ocelot, &data); - vcap_action2cache(ocelot, &data); - vcap_row_cmd(ocelot, row, VCAP_CMD_WRITE, VCAP_SEL_ALL); + vcap_entry2cache(ocelot, vcap, &data); + vcap_action2cache(ocelot, vcap, &data); + vcap_row_cmd(ocelot, vcap, row, VCAP_CMD_WRITE, VCAP_SEL_ALL); } -static void is2_entry_get(struct ocelot *ocelot, struct ocelot_ace_rule *rule, - int ix) +static void vcap_entry_get(struct ocelot *ocelot, struct ocelot_ace_rule *rule, + int ix) { - const struct vcap_props *vcap_is2 = &ocelot->vcap[VCAP_IS2]; + const struct vcap_props *vcap = &ocelot->vcap[VCAP_IS2]; struct vcap_data data; - int row = (ix / 2); + int row, count; u32 cnt; - vcap_row_cmd(ocelot, row, VCAP_CMD_READ, VCAP_SEL_COUNTER); - vcap_cache2action(ocelot, &data); data.tg_sw = VCAP_TG_HALF; - is2_data_get(ocelot, &data, ix); + count = (1 << (data.tg_sw - 1)); + row = (ix / count); + vcap_row_cmd(ocelot, vcap, row, VCAP_CMD_READ, VCAP_SEL_COUNTER); + vcap_cache2action(ocelot, vcap, &data); + vcap_data_offset_get(vcap, &data, ix); cnt = vcap_data_get(data.counter, data.counter_offset, - vcap_is2->counter_width); + vcap->counter_width); rule->stats.pkts = cnt; } @@ -924,7 +938,7 @@ int ocelot_ace_rule_stats_update(struct ocelot *ocelot, int index; index = ocelot_ace_rule_get_index_id(block, rule); - is2_entry_get(ocelot, rule, index); + vcap_entry_get(ocelot, rule, index); /* After we get the result we need to clear the counters */ tmp = ocelot_ace_rule_get_rule_index(block, index); @@ -934,22 +948,29 @@ int ocelot_ace_rule_stats_update(struct ocelot *ocelot, return 0; } -int ocelot_ace_init(struct ocelot *ocelot) +static void vcap_init(struct ocelot *ocelot, const struct vcap_props *vcap) { - 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)); - vcap_entry2cache(ocelot, &data); - ocelot_write(ocelot, vcap_is2->entry_count, S2_CORE_MV_CFG); - vcap_cmd(ocelot, 0, VCAP_CMD_INITIALIZE, VCAP_SEL_ENTRY); + vcap_entry2cache(ocelot, vcap, &data); + ocelot_target_write(ocelot, vcap->target, vcap->entry_count, + VCAP_CORE_MV_CFG); + vcap_cmd(ocelot, vcap, 0, VCAP_CMD_INITIALIZE, VCAP_SEL_ENTRY); - vcap_action2cache(ocelot, &data); - ocelot_write(ocelot, vcap_is2->action_count, S2_CORE_MV_CFG); - vcap_cmd(ocelot, 0, VCAP_CMD_INITIALIZE, + vcap_action2cache(ocelot, vcap, &data); + ocelot_target_write(ocelot, vcap->target, vcap->action_count, + VCAP_CORE_MV_CFG); + vcap_cmd(ocelot, vcap, 0, VCAP_CMD_INITIALIZE, VCAP_SEL_ACTION | VCAP_SEL_COUNTER); +} + +int ocelot_ace_init(struct ocelot *ocelot) +{ + struct ocelot_acl_block *block = &ocelot->acl_block; + + vcap_init(ocelot, &ocelot->vcap[VCAP_IS2]); /* Create a policer that will drop the frames for the cpu. * This policer will be used as action in the acl rules to drop @@ -967,8 +988,7 @@ int ocelot_ace_init(struct ocelot *ocelot) OCELOT_POLICER_DISCARD); block->pol_lpr = OCELOT_POLICER_DISCARD - 1; - - INIT_LIST_HEAD(&ocelot->acl_block.rules); + INIT_LIST_HEAD(&block->rules); return 0; } diff --git a/drivers/net/ethernet/mscc/ocelot_board.c b/drivers/net/ethernet/mscc/ocelot_board.c index 4a15d2ff8b70..db1b4935c48b 100644 --- a/drivers/net/ethernet/mscc/ocelot_board.c +++ b/drivers/net/ethernet/mscc/ocelot_board.c @@ -364,6 +364,9 @@ static const struct vcap_props vsc7514_vcap_props[] = { }, .counter_words = 4, .counter_width = 32, + .target = S2, + .keys = vsc7514_vcap_is2_keys, + .actions = vsc7514_vcap_is2_actions, }, }; @@ -482,8 +485,6 @@ static int mscc_ocelot_probe(struct platform_device *pdev) ocelot->ports = devm_kcalloc(&pdev->dev, ocelot->num_phys_ports, sizeof(struct ocelot_port *), GFP_KERNEL); - ocelot->vcap_is2_keys = vsc7514_vcap_is2_keys; - ocelot->vcap_is2_actions = vsc7514_vcap_is2_actions; ocelot->vcap = vsc7514_vcap_props; ocelot_init(ocelot); diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c b/drivers/net/ethernet/mscc/ocelot_flower.c index 5ce172e22b43..891925f73cbc 100644 --- a/drivers/net/ethernet/mscc/ocelot_flower.c +++ b/drivers/net/ethernet/mscc/ocelot_flower.c @@ -5,6 +5,7 @@ #include #include +#include #include "ocelot_ace.h" diff --git a/drivers/net/ethernet/mscc/ocelot_regs.c b/drivers/net/ethernet/mscc/ocelot_regs.c index 81d81ff75646..18ce99730406 100644 --- a/drivers/net/ethernet/mscc/ocelot_regs.c +++ b/drivers/net/ethernet/mscc/ocelot_regs.c @@ -224,14 +224,16 @@ static const u32 ocelot_sys_regmap[] = { REG(SYS_PTP_CFG, 0x0006c4), }; -static const u32 ocelot_s2_regmap[] = { - REG(S2_CORE_UPDATE_CTRL, 0x000000), - REG(S2_CORE_MV_CFG, 0x000004), - REG(S2_CACHE_ENTRY_DAT, 0x000008), - REG(S2_CACHE_MASK_DAT, 0x000108), - REG(S2_CACHE_ACTION_DAT, 0x000208), - REG(S2_CACHE_CNT_DAT, 0x000308), - REG(S2_CACHE_TG_DAT, 0x000388), +static const u32 ocelot_vcap_regmap[] = { + /* VCAP_CORE_CFG */ + REG(VCAP_CORE_UPDATE_CTRL, 0x000000), + REG(VCAP_CORE_MV_CFG, 0x000004), + /* VCAP_CORE_CACHE */ + REG(VCAP_CACHE_ENTRY_DAT, 0x000008), + REG(VCAP_CACHE_MASK_DAT, 0x000108), + REG(VCAP_CACHE_ACTION_DAT, 0x000208), + REG(VCAP_CACHE_CNT_DAT, 0x000308), + REG(VCAP_CACHE_TG_DAT, 0x000388), }; static const u32 ocelot_ptp_regmap[] = { @@ -252,7 +254,7 @@ static const u32 *ocelot_regmap[] = { [QSYS] = ocelot_qsys_regmap, [REW] = ocelot_rew_regmap, [SYS] = ocelot_sys_regmap, - [S2] = ocelot_s2_regmap, + [S2] = ocelot_vcap_regmap, [PTP] = ocelot_ptp_regmap, }; diff --git a/drivers/net/ethernet/mscc/ocelot_s2.h b/drivers/net/ethernet/mscc/ocelot_s2.h deleted file mode 100644 index 80107bec2e45..000000000000 --- a/drivers/net/ethernet/mscc/ocelot_s2.h +++ /dev/null @@ -1,64 +0,0 @@ -/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ -/* Microsemi Ocelot Switch driver - * Copyright (c) 2018 Microsemi Corporation - */ - -#ifndef _OCELOT_S2_CORE_H_ -#define _OCELOT_S2_CORE_H_ - -#define S2_CORE_UPDATE_CTRL_UPDATE_CMD(x) (((x) << 22) & GENMASK(24, 22)) -#define S2_CORE_UPDATE_CTRL_UPDATE_CMD_M GENMASK(24, 22) -#define S2_CORE_UPDATE_CTRL_UPDATE_CMD_X(x) (((x) & GENMASK(24, 22)) >> 22) -#define S2_CORE_UPDATE_CTRL_UPDATE_ENTRY_DIS BIT(21) -#define S2_CORE_UPDATE_CTRL_UPDATE_ACTION_DIS BIT(20) -#define S2_CORE_UPDATE_CTRL_UPDATE_CNT_DIS BIT(19) -#define S2_CORE_UPDATE_CTRL_UPDATE_ADDR(x) (((x) << 3) & GENMASK(18, 3)) -#define S2_CORE_UPDATE_CTRL_UPDATE_ADDR_M GENMASK(18, 3) -#define S2_CORE_UPDATE_CTRL_UPDATE_ADDR_X(x) (((x) & GENMASK(18, 3)) >> 3) -#define S2_CORE_UPDATE_CTRL_UPDATE_SHOT BIT(2) -#define S2_CORE_UPDATE_CTRL_CLEAR_CACHE BIT(1) -#define S2_CORE_UPDATE_CTRL_MV_TRAFFIC_IGN BIT(0) - -#define S2_CORE_MV_CFG_MV_NUM_POS(x) (((x) << 16) & GENMASK(31, 16)) -#define S2_CORE_MV_CFG_MV_NUM_POS_M GENMASK(31, 16) -#define S2_CORE_MV_CFG_MV_NUM_POS_X(x) (((x) & GENMASK(31, 16)) >> 16) -#define S2_CORE_MV_CFG_MV_SIZE(x) ((x) & GENMASK(15, 0)) -#define S2_CORE_MV_CFG_MV_SIZE_M GENMASK(15, 0) - -#define S2_CACHE_ENTRY_DAT_RSZ 0x4 - -#define S2_CACHE_MASK_DAT_RSZ 0x4 - -#define S2_CACHE_ACTION_DAT_RSZ 0x4 - -#define S2_CACHE_CNT_DAT_RSZ 0x4 - -#define S2_STICKY_VCAP_ROW_DELETED_STICKY BIT(0) - -#define S2_BIST_CTRL_TCAM_BIST BIT(1) -#define S2_BIST_CTRL_TCAM_INIT BIT(0) - -#define S2_BIST_CFG_TCAM_BIST_SOE_ENA BIT(8) -#define S2_BIST_CFG_TCAM_HCG_DIS BIT(7) -#define S2_BIST_CFG_TCAM_CG_DIS BIT(6) -#define S2_BIST_CFG_TCAM_BIAS(x) ((x) & GENMASK(5, 0)) -#define S2_BIST_CFG_TCAM_BIAS_M GENMASK(5, 0) - -#define S2_BIST_STAT_BIST_RT_ERR BIT(15) -#define S2_BIST_STAT_BIST_PENC_ERR BIT(14) -#define S2_BIST_STAT_BIST_COMP_ERR BIT(13) -#define S2_BIST_STAT_BIST_ADDR_ERR BIT(12) -#define S2_BIST_STAT_BIST_BL1E_ERR BIT(11) -#define S2_BIST_STAT_BIST_BL1_ERR BIT(10) -#define S2_BIST_STAT_BIST_BL0E_ERR BIT(9) -#define S2_BIST_STAT_BIST_BL0_ERR BIT(8) -#define S2_BIST_STAT_BIST_PH1_ERR BIT(7) -#define S2_BIST_STAT_BIST_PH0_ERR BIT(6) -#define S2_BIST_STAT_BIST_PV1_ERR BIT(5) -#define S2_BIST_STAT_BIST_PV0_ERR BIT(4) -#define S2_BIST_STAT_BIST_RUN BIT(3) -#define S2_BIST_STAT_BIST_ERR BIT(2) -#define S2_BIST_STAT_BIST_BUSY BIT(1) -#define S2_BIST_STAT_TCAM_RDY BIT(0) - -#endif /* _OCELOT_S2_CORE_H_ */ diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h index 2ac08f3b8f68..91357b1c8f31 100644 --- a/include/soc/mscc/ocelot.h +++ b/include/soc/mscc/ocelot.h @@ -376,13 +376,6 @@ enum ocelot_reg { SYS_CM_DATA_RD, SYS_CM_OP, SYS_CM_DATA, - S2_CORE_UPDATE_CTRL = S2 << TARGET_OFFSET, - S2_CORE_MV_CFG, - S2_CACHE_ENTRY_DAT, - S2_CACHE_MASK_DAT, - S2_CACHE_ACTION_DAT, - S2_CACHE_CNT_DAT, - S2_CACHE_TG_DAT, PTP_PIN_CFG = PTP << TARGET_OFFSET, PTP_PIN_TOD_SEC_MSB, PTP_PIN_TOD_SEC_LSB, @@ -395,6 +388,18 @@ enum ocelot_reg { GCB_SOFT_RST = GCB << TARGET_OFFSET, }; +enum { + /* VCAP_CORE_CFG */ + VCAP_CORE_UPDATE_CTRL, + VCAP_CORE_MV_CFG, + /* VCAP_CORE_CACHE */ + VCAP_CACHE_ENTRY_DAT, + VCAP_CACHE_MASK_DAT, + VCAP_CACHE_ACTION_DAT, + VCAP_CACHE_CNT_DAT, + VCAP_CACHE_TG_DAT, +}; + enum ocelot_regfield { ANA_ADVLEARN_VLAN_CHK, ANA_ADVLEARN_LEARN_MIRROR, @@ -537,8 +542,6 @@ struct ocelot { struct ocelot_acl_block acl_block; - const struct vcap_field *vcap_is2_keys; - const struct vcap_field *vcap_is2_actions; const struct vcap_props *vcap; /* Workqueue to check statistics for overflow with its lock */ diff --git a/include/soc/mscc/ocelot_vcap.h b/include/soc/mscc/ocelot_vcap.h index 5748373ab4d3..26d9384b3657 100644 --- a/include/soc/mscc/ocelot_vcap.h +++ b/include/soc/mscc/ocelot_vcap.h @@ -6,6 +6,8 @@ #ifndef _OCELOT_VCAP_H_ #define _OCELOT_VCAP_H_ +#include "ocelot.h" + /* ================================================================= * VCAP Common * ================================================================= @@ -33,6 +35,11 @@ struct vcap_props { } action_table[2]; u16 counter_words; /* Number of counter words */ u16 counter_width; /* Counter width (in bits) */ + + enum ocelot_target target; + + const struct vcap_field *keys; + const struct vcap_field *actions; }; /* VCAP Type-Group values */ @@ -41,6 +48,61 @@ struct vcap_props { #define VCAP_TG_HALF 2 /* Half entry */ #define VCAP_TG_QUARTER 3 /* Quarter entry */ +#define VCAP_CORE_UPDATE_CTRL_UPDATE_CMD(x) (((x) << 22) & GENMASK(24, 22)) +#define VCAP_CORE_UPDATE_CTRL_UPDATE_CMD_M GENMASK(24, 22) +#define VCAP_CORE_UPDATE_CTRL_UPDATE_CMD_X(x) (((x) & GENMASK(24, 22)) >> 22) +#define VCAP_CORE_UPDATE_CTRL_UPDATE_ENTRY_DIS BIT(21) +#define VCAP_CORE_UPDATE_CTRL_UPDATE_ACTION_DIS BIT(20) +#define VCAP_CORE_UPDATE_CTRL_UPDATE_CNT_DIS BIT(19) +#define VCAP_CORE_UPDATE_CTRL_UPDATE_ADDR(x) (((x) << 3) & GENMASK(18, 3)) +#define VCAP_CORE_UPDATE_CTRL_UPDATE_ADDR_M GENMASK(18, 3) +#define VCAP_CORE_UPDATE_CTRL_UPDATE_ADDR_X(x) (((x) & GENMASK(18, 3)) >> 3) +#define VCAP_CORE_UPDATE_CTRL_UPDATE_SHOT BIT(2) +#define VCAP_CORE_UPDATE_CTRL_CLEAR_CACHE BIT(1) +#define VCAP_CORE_UPDATE_CTRL_MV_TRAFFIC_IGN BIT(0) + +#define VCAP_CORE_MV_CFG_MV_NUM_POS(x) (((x) << 16) & GENMASK(31, 16)) +#define VCAP_CORE_MV_CFG_MV_NUM_POS_M GENMASK(31, 16) +#define VCAP_CORE_MV_CFG_MV_NUM_POS_X(x) (((x) & GENMASK(31, 16)) >> 16) +#define VCAP_CORE_MV_CFG_MV_SIZE(x) ((x) & GENMASK(15, 0)) +#define VCAP_CORE_MV_CFG_MV_SIZE_M GENMASK(15, 0) + +#define VCAP_CACHE_ENTRY_DAT_RSZ 0x4 + +#define VCAP_CACHE_MASK_DAT_RSZ 0x4 + +#define VCAP_CACHE_ACTION_DAT_RSZ 0x4 + +#define VCAP_CACHE_CNT_DAT_RSZ 0x4 + +#define VCAP_STICKY_VCAP_ROW_DELETED_STICKY BIT(0) + +#define TCAM_BIST_CTRL_TCAM_BIST BIT(1) +#define TCAM_BIST_CTRL_TCAM_INIT BIT(0) + +#define TCAM_BIST_CFG_TCAM_BIST_SOE_ENA BIT(8) +#define TCAM_BIST_CFG_TCAM_HCG_DIS BIT(7) +#define TCAM_BIST_CFG_TCAM_CG_DIS BIT(6) +#define TCAM_BIST_CFG_TCAM_BIAS(x) ((x) & GENMASK(5, 0)) +#define TCAM_BIST_CFG_TCAM_BIAS_M GENMASK(5, 0) + +#define TCAM_BIST_STAT_BIST_RT_ERR BIT(15) +#define TCAM_BIST_STAT_BIST_PENC_ERR BIT(14) +#define TCAM_BIST_STAT_BIST_COMP_ERR BIT(13) +#define TCAM_BIST_STAT_BIST_ADDR_ERR BIT(12) +#define TCAM_BIST_STAT_BIST_BL1E_ERR BIT(11) +#define TCAM_BIST_STAT_BIST_BL1_ERR BIT(10) +#define TCAM_BIST_STAT_BIST_BL0E_ERR BIT(9) +#define TCAM_BIST_STAT_BIST_BL0_ERR BIT(8) +#define TCAM_BIST_STAT_BIST_PH1_ERR BIT(7) +#define TCAM_BIST_STAT_BIST_PH0_ERR BIT(6) +#define TCAM_BIST_STAT_BIST_PV1_ERR BIT(5) +#define TCAM_BIST_STAT_BIST_PV0_ERR BIT(4) +#define TCAM_BIST_STAT_BIST_RUN BIT(3) +#define TCAM_BIST_STAT_BIST_ERR BIT(2) +#define TCAM_BIST_STAT_BIST_BUSY BIT(1) +#define TCAM_BIST_STAT_TCAM_RDY BIT(0) + /* ================================================================= * VCAP IS2 * ================================================================= From patchwork Tue Jun 2 05:18:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaoliang Yang X-Patchwork-Id: 218060 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 13DEFC433E1 for ; Tue, 2 Jun 2020 05:25:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DC435206A2 for ; Tue, 2 Jun 2020 05:25:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726678AbgFBFYI (ORCPT ); Tue, 2 Jun 2020 01:24:08 -0400 Received: from inva020.nxp.com ([92.121.34.13]:44394 "EHLO inva020.nxp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726012AbgFBFYG (ORCPT ); Tue, 2 Jun 2020 01:24:06 -0400 Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id F10931A0B82; Tue, 2 Jun 2020 07:24:03 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 360021A00EC; Tue, 2 Jun 2020 07:23:54 +0200 (CEST) Received: from localhost.localdomain (mega.ap.freescale.net [10.192.208.232]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 4721740285; Tue, 2 Jun 2020 13:23:42 +0800 (SGT) From: Xiaoliang Yang To: xiaoliang.yang_1@nxp.com, po.liu@nxp.com, claudiu.manoil@nxp.com, alexandru.marginean@nxp.com, vladimir.oltean@nxp.com, leoyang.li@nxp.com, mingkai.hu@nxp.com, andrew@lunn.ch, f.fainelli@gmail.com, vivien.didelot@gmail.com, davem@davemloft.net, jiri@resnulli.us, idosch@idosch.org, kuba@kernel.org, vinicius.gomes@intel.com, nikolay@cumulusnetworks.com, roopa@cumulusnetworks.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, horatiu.vultur@microchip.com, alexandre.belloni@bootlin.com, allan.nielsen@microchip.com, joergen.andreasen@microchip.com, UNGLinuxDriver@microchip.com, linux-devel@linux.nxdi.nxp.com Subject: [PATCH v2 net-next 03/10] net: mscc: ocelot: allocated rules to different hardware VCAP TCAMs by chain index Date: Tue, 2 Jun 2020 13:18:21 +0800 Message-Id: <20200602051828.5734-4-xiaoliang.yang_1@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200602051828.5734-1-xiaoliang.yang_1@nxp.com> References: <20200602051828.5734-1-xiaoliang.yang_1@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org There are three hardware TCAMs for ocelot chips: IS1, IS2 and ES0. Each one supports different actions. The hardware flow order is: IS1->IS2->ES0. This patch add three blocks to store rules according to chain index. chain 0 is offloaded to IS1, chain 1 is offloaded to IS2, and egress chain 0 is offloaded to ES0. Using action goto chain to express flow order as follows: tc filter add dev swp0 chain 0 parent ffff: flower skip_sw \ action goto chain 1 Signed-off-by: Xiaoliang Yang --- drivers/net/ethernet/mscc/ocelot_ace.c | 51 +++++++++++++++-------- drivers/net/ethernet/mscc/ocelot_ace.h | 7 ++-- drivers/net/ethernet/mscc/ocelot_flower.c | 46 +++++++++++++++++--- include/soc/mscc/ocelot.h | 2 +- include/soc/mscc/ocelot_vcap.h | 4 +- 5 files changed, 81 insertions(+), 29 deletions(-) diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c b/drivers/net/ethernet/mscc/ocelot_ace.c index 748c618db7d8..b76593b40097 100644 --- a/drivers/net/ethernet/mscc/ocelot_ace.c +++ b/drivers/net/ethernet/mscc/ocelot_ace.c @@ -341,6 +341,8 @@ static void is2_action_set(struct ocelot *ocelot, struct vcap_data *data, vcap_action_set(vcap, data, VCAP_IS2_ACT_CPU_QU_NUM, 0); vcap_action_set(vcap, data, VCAP_IS2_ACT_CPU_COPY_ENA, 0); break; + default: + break; } } @@ -644,9 +646,9 @@ static void is2_entry_set(struct ocelot *ocelot, int ix, } static void vcap_entry_get(struct ocelot *ocelot, struct ocelot_ace_rule *rule, - int ix) + int ix, int block_id) { - const struct vcap_props *vcap = &ocelot->vcap[VCAP_IS2]; + const struct vcap_props *vcap = &ocelot->vcap[block_id]; struct vcap_data data; int row, count; u32 cnt; @@ -663,6 +665,19 @@ static void vcap_entry_get(struct ocelot *ocelot, struct ocelot_ace_rule *rule, rule->stats.pkts = cnt; } +static void vcap_entry_set(struct ocelot *ocelot, int ix, + struct ocelot_ace_rule *ace, + int block_id) +{ + switch (block_id) { + case VCAP_IS2: + is2_entry_set(ocelot, ix, ace); + break; + default: + break; + } +} + static void ocelot_ace_rule_add(struct ocelot *ocelot, struct ocelot_acl_block *block, struct ocelot_ace_rule *rule) @@ -790,7 +805,7 @@ static bool ocelot_ace_is_problematic_non_mac_etype(struct ocelot_ace_rule *ace) static bool ocelot_exclusive_mac_etype_ace_rules(struct ocelot *ocelot, struct ocelot_ace_rule *ace) { - struct ocelot_acl_block *block = &ocelot->acl_block; + struct ocelot_acl_block *block = &ocelot->acl_block[VCAP_IS2]; struct ocelot_ace_rule *tmp; unsigned long port; int i; @@ -824,15 +839,16 @@ static bool ocelot_exclusive_mac_etype_ace_rules(struct ocelot *ocelot, return true; } -int ocelot_ace_rule_offload_add(struct ocelot *ocelot, +int ocelot_ace_rule_offload_add(struct ocelot *ocelot, int block_id, struct ocelot_ace_rule *rule, struct netlink_ext_ack *extack) { - struct ocelot_acl_block *block = &ocelot->acl_block; + struct ocelot_acl_block *block = &ocelot->acl_block[block_id]; struct ocelot_ace_rule *ace; int i, index; - if (!ocelot_exclusive_mac_etype_ace_rules(ocelot, rule)) { + if (block_id == VCAP_IS2 && + !ocelot_exclusive_mac_etype_ace_rules(ocelot, rule)) { NL_SET_ERR_MSG_MOD(extack, "Cannot mix MAC_ETYPE with non-MAC_ETYPE rules"); return -EBUSY; @@ -847,11 +863,11 @@ int ocelot_ace_rule_offload_add(struct ocelot *ocelot, /* Move down the rules to make place for the new rule */ for (i = block->count - 1; i > index; i--) { ace = ocelot_ace_rule_get_rule_index(block, i); - is2_entry_set(ocelot, i, ace); + vcap_entry_set(ocelot, i, ace, block_id); } /* Now insert the new rule */ - is2_entry_set(ocelot, index, rule); + vcap_entry_set(ocelot, index, rule, block_id); return 0; } @@ -902,10 +918,10 @@ static void ocelot_ace_rule_del(struct ocelot *ocelot, block->count--; } -int ocelot_ace_rule_offload_del(struct ocelot *ocelot, +int ocelot_ace_rule_offload_del(struct ocelot *ocelot, int block_id, struct ocelot_ace_rule *rule) { - struct ocelot_acl_block *block = &ocelot->acl_block; + struct ocelot_acl_block *block = &ocelot->acl_block[block_id]; struct ocelot_ace_rule del_ace; struct ocelot_ace_rule *ace; int i, index; @@ -921,29 +937,29 @@ int ocelot_ace_rule_offload_del(struct ocelot *ocelot, /* Move up all the blocks over the deleted rule */ for (i = index; i < block->count; i++) { ace = ocelot_ace_rule_get_rule_index(block, i); - is2_entry_set(ocelot, i, ace); + vcap_entry_set(ocelot, i, ace, block_id); } /* Now delete the last rule, because it is duplicated */ - is2_entry_set(ocelot, block->count, &del_ace); + vcap_entry_set(ocelot, block->count, &del_ace, block_id); return 0; } -int ocelot_ace_rule_stats_update(struct ocelot *ocelot, +int ocelot_ace_rule_stats_update(struct ocelot *ocelot, int block_id, struct ocelot_ace_rule *rule) { - struct ocelot_acl_block *block = &ocelot->acl_block; + struct ocelot_acl_block *block = &ocelot->acl_block[block_id]; struct ocelot_ace_rule *tmp; int index; index = ocelot_ace_rule_get_index_id(block, rule); - vcap_entry_get(ocelot, rule, index); + vcap_entry_get(ocelot, rule, index, block_id); /* After we get the result we need to clear the counters */ tmp = ocelot_ace_rule_get_rule_index(block, index); tmp->stats.pkts = 0; - is2_entry_set(ocelot, index, tmp); + vcap_entry_set(ocelot, index, tmp, block_id); return 0; } @@ -968,7 +984,7 @@ static void vcap_init(struct ocelot *ocelot, const struct vcap_props *vcap) int ocelot_ace_init(struct ocelot *ocelot) { - struct ocelot_acl_block *block = &ocelot->acl_block; + struct ocelot_acl_block *block; vcap_init(ocelot, &ocelot->vcap[VCAP_IS2]); @@ -987,6 +1003,7 @@ int ocelot_ace_init(struct ocelot *ocelot) ocelot_write_gix(ocelot, 0x3fffff, ANA_POL_CIR_STATE, OCELOT_POLICER_DISCARD); + block = &ocelot->acl_block[VCAP_IS2]; block->pol_lpr = OCELOT_POLICER_DISCARD - 1; INIT_LIST_HEAD(&block->rules); diff --git a/drivers/net/ethernet/mscc/ocelot_ace.h b/drivers/net/ethernet/mscc/ocelot_ace.h index 099e177f2617..a9fd99401a65 100644 --- a/drivers/net/ethernet/mscc/ocelot_ace.h +++ b/drivers/net/ethernet/mscc/ocelot_ace.h @@ -175,6 +175,7 @@ struct ocelot_ace_frame_ipv6 { }; enum ocelot_ace_action { + OCELOT_ACL_ACTION_NULL, OCELOT_ACL_ACTION_DROP, OCELOT_ACL_ACTION_TRAP, OCELOT_ACL_ACTION_POLICE, @@ -214,12 +215,12 @@ struct ocelot_ace_rule { u32 pol_ix; }; -int ocelot_ace_rule_offload_add(struct ocelot *ocelot, +int ocelot_ace_rule_offload_add(struct ocelot *ocelot, int block_id, struct ocelot_ace_rule *rule, struct netlink_ext_ack *extack); -int ocelot_ace_rule_offload_del(struct ocelot *ocelot, +int ocelot_ace_rule_offload_del(struct ocelot *ocelot, int block_id, struct ocelot_ace_rule *rule); -int ocelot_ace_rule_stats_update(struct ocelot *ocelot, +int ocelot_ace_rule_stats_update(struct ocelot *ocelot, int block_id, struct ocelot_ace_rule *rule); int ocelot_ace_init(struct ocelot *ocelot); diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c b/drivers/net/ethernet/mscc/ocelot_flower.c index 891925f73cbc..a1f7b6b28170 100644 --- a/drivers/net/ethernet/mscc/ocelot_flower.c +++ b/drivers/net/ethernet/mscc/ocelot_flower.c @@ -9,13 +9,26 @@ #include "ocelot_ace.h" +static int ocelot_block_id_get(int chain, bool ingress) +{ + /* Select TCAM blocks by using chain index. Rules in chain 0 are + * implemented on IS1, chain 1 are implemented on IS2, and egress + * chain corresponds to ES0 block. + */ + if (ingress) + return chain ? VCAP_IS2 : VCAP_IS1; + else + return VCAP_ES0; +} + static int ocelot_flower_parse_action(struct flow_cls_offload *f, struct ocelot_ace_rule *ace) { + struct netlink_ext_ack *extack = f->common.extack; const struct flow_action_entry *a; + int i, allowed_chain = 0; s64 burst; u64 rate; - int i; if (!flow_offload_has_one_action(&f->rule->action)) return -EOPNOTSUPP; @@ -28,9 +41,11 @@ static int ocelot_flower_parse_action(struct flow_cls_offload *f, switch (a->id) { case FLOW_ACTION_DROP: ace->action = OCELOT_ACL_ACTION_DROP; + allowed_chain = 1; break; case FLOW_ACTION_TRAP: ace->action = OCELOT_ACL_ACTION_TRAP; + allowed_chain = 1; break; case FLOW_ACTION_POLICE: ace->action = OCELOT_ACL_ACTION_POLICE; @@ -38,10 +53,23 @@ static int ocelot_flower_parse_action(struct flow_cls_offload *f, 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); + allowed_chain = 1; + break; + case FLOW_ACTION_GOTO: + if (a->chain_index != f->common.chain_index + 1) { + NL_SET_ERR_MSG_MOD(extack, "HW only support goto next chain\n"); + return -EOPNOTSUPP; + } + ace->action = OCELOT_ACL_ACTION_NULL; + allowed_chain = f->common.chain_index; break; default: return -EOPNOTSUPP; } + if (f->common.chain_index != allowed_chain) { + NL_SET_ERR_MSG_MOD(extack, "Action is not supported on this chain\n"); + return -EOPNOTSUPP; + } } return 0; @@ -205,7 +233,7 @@ int ocelot_cls_flower_replace(struct ocelot *ocelot, int port, struct flow_cls_offload *f, bool ingress) { struct ocelot_ace_rule *ace; - int ret; + int ret, block_id; ace = ocelot_ace_rule_create(ocelot, port, f); if (!ace) @@ -216,8 +244,10 @@ int ocelot_cls_flower_replace(struct ocelot *ocelot, int port, kfree(ace); return ret; } + block_id = ocelot_block_id_get(f->common.chain_index, ingress); - return ocelot_ace_rule_offload_add(ocelot, ace, f->common.extack); + return ocelot_ace_rule_offload_add(ocelot, block_id, ace, + f->common.extack); } EXPORT_SYMBOL_GPL(ocelot_cls_flower_replace); @@ -225,11 +255,13 @@ int ocelot_cls_flower_destroy(struct ocelot *ocelot, int port, struct flow_cls_offload *f, bool ingress) { struct ocelot_ace_rule ace; + int block_id; ace.prio = f->common.prio; ace.id = f->cookie; + block_id = ocelot_block_id_get(f->common.chain_index, ingress); - return ocelot_ace_rule_offload_del(ocelot, &ace); + return ocelot_ace_rule_offload_del(ocelot, block_id, &ace); } EXPORT_SYMBOL_GPL(ocelot_cls_flower_destroy); @@ -237,11 +269,13 @@ int ocelot_cls_flower_stats(struct ocelot *ocelot, int port, struct flow_cls_offload *f, bool ingress) { struct ocelot_ace_rule ace; - int ret; + int ret, block_id; ace.prio = f->common.prio; ace.id = f->cookie; - ret = ocelot_ace_rule_stats_update(ocelot, &ace); + block_id = ocelot_block_id_get(f->common.chain_index, ingress); + + ret = ocelot_ace_rule_stats_update(ocelot, block_id, &ace); if (ret) return ret; diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h index 91357b1c8f31..4b2320bdc036 100644 --- a/include/soc/mscc/ocelot.h +++ b/include/soc/mscc/ocelot.h @@ -540,7 +540,7 @@ struct ocelot { struct list_head multicast; - struct ocelot_acl_block acl_block; + struct ocelot_acl_block acl_block[3]; const struct vcap_props *vcap; diff --git a/include/soc/mscc/ocelot_vcap.h b/include/soc/mscc/ocelot_vcap.h index 26d9384b3657..495847a40490 100644 --- a/include/soc/mscc/ocelot_vcap.h +++ b/include/soc/mscc/ocelot_vcap.h @@ -14,9 +14,9 @@ */ enum { - /* VCAP_IS1, */ + VCAP_IS1, VCAP_IS2, - /* VCAP_ES0, */ + VCAP_ES0, }; struct vcap_props { From patchwork Tue Jun 2 05:18:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaoliang Yang X-Patchwork-Id: 218064 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1C3F7C433DF for ; Tue, 2 Jun 2020 05:24:11 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F153E20772 for ; Tue, 2 Jun 2020 05:24:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726755AbgFBFYK (ORCPT ); Tue, 2 Jun 2020 01:24:10 -0400 Received: from inva020.nxp.com ([92.121.34.13]:44434 "EHLO inva020.nxp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726205AbgFBFYH (ORCPT ); Tue, 2 Jun 2020 01:24:07 -0400 Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 05BB31A00EC; Tue, 2 Jun 2020 07:24:06 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 778A21A0B71; Tue, 2 Jun 2020 07:23:56 +0200 (CEST) Received: from localhost.localdomain (mega.ap.freescale.net [10.192.208.232]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 6FA7D402E8; Tue, 2 Jun 2020 13:23:44 +0800 (SGT) From: Xiaoliang Yang To: xiaoliang.yang_1@nxp.com, po.liu@nxp.com, claudiu.manoil@nxp.com, alexandru.marginean@nxp.com, vladimir.oltean@nxp.com, leoyang.li@nxp.com, mingkai.hu@nxp.com, andrew@lunn.ch, f.fainelli@gmail.com, vivien.didelot@gmail.com, davem@davemloft.net, jiri@resnulli.us, idosch@idosch.org, kuba@kernel.org, vinicius.gomes@intel.com, nikolay@cumulusnetworks.com, roopa@cumulusnetworks.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, horatiu.vultur@microchip.com, alexandre.belloni@bootlin.com, allan.nielsen@microchip.com, joergen.andreasen@microchip.com, UNGLinuxDriver@microchip.com, linux-devel@linux.nxdi.nxp.com Subject: [PATCH v2 net-next 04/10] net: mscc: ocelot: change vcap to be compatible with full and quad entry Date: Tue, 2 Jun 2020 13:18:22 +0800 Message-Id: <20200602051828.5734-5-xiaoliang.yang_1@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200602051828.5734-1-xiaoliang.yang_1@nxp.com> References: <20200602051828.5734-1-xiaoliang.yang_1@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org When calculating vcap data offset, the function only supports half key entry. This patch modify vcap_data_offset_get function to calculate a correct data offset when setting VCAP Type-Group to VCAP_TG_FULL or VCAP_TG_QUARTER. Signed-off-by: Xiaoliang Yang --- drivers/net/ethernet/mscc/ocelot_ace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c b/drivers/net/ethernet/mscc/ocelot_ace.c index b76593b40097..8c384b0771bb 100644 --- a/drivers/net/ethernet/mscc/ocelot_ace.c +++ b/drivers/net/ethernet/mscc/ocelot_ace.c @@ -175,8 +175,8 @@ static void vcap_data_offset_get(const struct vcap_props *vcap, u32 i, col, offset, count, cnt, base; u32 width = vcap->tg_width; - count = (data->tg_sw == VCAP_TG_HALF ? 2 : 4); - col = (ix % 2); + count = (1 << (data->tg_sw - 1)); + col = (ix % count); cnt = (vcap->sw_count / count); base = (vcap->sw_count - col * cnt - cnt); data->tg_value = 0; From patchwork Tue Jun 2 05:18:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaoliang Yang X-Patchwork-Id: 218062 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 00D1BC433DF for ; Tue, 2 Jun 2020 05:24:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CCA65206A2 for ; Tue, 2 Jun 2020 05:24:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727116AbgFBFYQ (ORCPT ); Tue, 2 Jun 2020 01:24:16 -0400 Received: from inva020.nxp.com ([92.121.34.13]:44542 "EHLO inva020.nxp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726683AbgFBFYN (ORCPT ); Tue, 2 Jun 2020 01:24:13 -0400 Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 4D57B1A0B71; Tue, 2 Jun 2020 07:24:08 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id 3B5771A0A5A; Tue, 2 Jun 2020 07:23:58 +0200 (CEST) Received: from localhost.localdomain (mega.ap.freescale.net [10.192.208.232]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 9F9DC4031F; Tue, 2 Jun 2020 13:23:46 +0800 (SGT) From: Xiaoliang Yang To: xiaoliang.yang_1@nxp.com, po.liu@nxp.com, claudiu.manoil@nxp.com, alexandru.marginean@nxp.com, vladimir.oltean@nxp.com, leoyang.li@nxp.com, mingkai.hu@nxp.com, andrew@lunn.ch, f.fainelli@gmail.com, vivien.didelot@gmail.com, davem@davemloft.net, jiri@resnulli.us, idosch@idosch.org, kuba@kernel.org, vinicius.gomes@intel.com, nikolay@cumulusnetworks.com, roopa@cumulusnetworks.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, horatiu.vultur@microchip.com, alexandre.belloni@bootlin.com, allan.nielsen@microchip.com, joergen.andreasen@microchip.com, UNGLinuxDriver@microchip.com, linux-devel@linux.nxdi.nxp.com Subject: [PATCH v2 net-next 05/10] net: mscc: ocelot: VCAP IS1 support Date: Tue, 2 Jun 2020 13:18:23 +0800 Message-Id: <20200602051828.5734-6-xiaoliang.yang_1@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200602051828.5734-1-xiaoliang.yang_1@nxp.com> References: <20200602051828.5734-1-xiaoliang.yang_1@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org VCAP IS1 is a VCAP module which can filter MAC, IP, VLAN, protocol, and TCP/UDP ports keys, and do Qos classified and VLAN retag actions. This patch added VCAP IS1 support in ocelot ace driver, which can supports vlan modify and skbedit priority action of tc filter. Usage: tc qdisc add dev swp0 ingress tc filter add dev swp0 protocol 802.1Q parent ffff: flower \ skip_sw vlan_id 1 vlan_prio 1 action vlan modify id 2 priority 2 Signed-off-by: Xiaoliang Yang --- drivers/net/dsa/ocelot/felix_vsc9959.c | 102 +++++++++++ drivers/net/ethernet/mscc/ocelot.c | 7 + drivers/net/ethernet/mscc/ocelot_ace.c | 198 +++++++++++++++++++++- drivers/net/ethernet/mscc/ocelot_ace.h | 11 ++ drivers/net/ethernet/mscc/ocelot_flower.c | 11 ++ drivers/net/ethernet/mscc/ocelot_regs.c | 1 + include/soc/mscc/ocelot.h | 1 + include/soc/mscc/ocelot_vcap.h | 91 ++++++++++ 8 files changed, 421 insertions(+), 1 deletion(-) diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c index ef3bf875e64c..f08a5f1c61a5 100644 --- a/drivers/net/dsa/ocelot/felix_vsc9959.c +++ b/drivers/net/dsa/ocelot/felix_vsc9959.c @@ -16,6 +16,8 @@ #define VSC9959_VCAP_IS2_CNT 1024 #define VSC9959_VCAP_IS2_ENTRY_WIDTH 376 #define VSC9959_VCAP_PORT_CNT 6 +#define VSC9959_VCAP_IS1_CNT 256 +#define VSC9959_VCAP_IS1_ENTRY_WIDTH 376 /* TODO: should find a better place for these */ #define USXGMII_BMCR_RESET BIT(15) @@ -337,6 +339,7 @@ static const u32 *vsc9959_regmap[] = { [QSYS] = vsc9959_qsys_regmap, [REW] = vsc9959_rew_regmap, [SYS] = vsc9959_sys_regmap, + [S1] = vsc9959_vcap_regmap, [S2] = vsc9959_vcap_regmap, [PTP] = vsc9959_ptp_regmap, [GCB] = vsc9959_gcb_regmap, @@ -369,6 +372,11 @@ static const struct resource vsc9959_target_io_res[] = { .end = 0x001ffff, .name = "sys", }, + [S1] = { + .start = 0x0050000, + .end = 0x00503ff, + .name = "s1", + }, [S2] = { .start = 0x0060000, .end = 0x00603ff, @@ -559,6 +567,80 @@ static const struct ocelot_stat_layout vsc9959_stats_layout[] = { { .offset = 0x111, .name = "drop_green_prio_7", }, }; +struct vcap_field vsc9959_vcap_is1_keys[] = { + [VCAP_IS1_HK_TYPE] = { 0, 1}, + [VCAP_IS1_HK_LOOKUP] = { 1, 2}, + [VCAP_IS1_HK_IGR_PORT_MASK] = { 3, 7}, + [VCAP_IS1_HK_RSV] = { 10, 9}, + [VCAP_IS1_HK_OAM_Y1731] = { 19, 1}, + [VCAP_IS1_HK_L2_MC] = { 20, 1}, + [VCAP_IS1_HK_L2_BC] = { 21, 1}, + [VCAP_IS1_HK_IP_MC] = { 22, 1}, + [VCAP_IS1_HK_VLAN_TAGGED] = { 23, 1}, + [VCAP_IS1_HK_VLAN_DBL_TAGGED] = { 24, 1}, + [VCAP_IS1_HK_TPID] = { 25, 1}, + [VCAP_IS1_HK_VID] = { 26, 12}, + [VCAP_IS1_HK_DEI] = { 38, 1}, + [VCAP_IS1_HK_PCP] = { 39, 3}, + /* Specific Fields for IS1 Half Key S1_NORMAL */ + [VCAP_IS1_HK_L2_SMAC] = { 42, 48}, + [VCAP_IS1_HK_ETYPE_LEN] = { 90, 1}, + [VCAP_IS1_HK_ETYPE] = { 91, 16}, + [VCAP_IS1_HK_IP_SNAP] = {107, 1}, + [VCAP_IS1_HK_IP4] = {108, 1}, + /* Layer-3 Information */ + [VCAP_IS1_HK_L3_FRAGMENT] = {109, 1}, + [VCAP_IS1_HK_L3_FRAG_OFS_GT0] = {110, 1}, + [VCAP_IS1_HK_L3_OPTIONS] = {111, 1}, + [VCAP_IS1_HK_L3_DSCP] = {112, 6}, + [VCAP_IS1_HK_L3_IP4_SIP] = {118, 32}, + /* Layer-4 Information */ + [VCAP_IS1_HK_TCP_UDP] = {150, 1}, + [VCAP_IS1_HK_TCP] = {151, 1}, + [VCAP_IS1_HK_L4_SPORT] = {152, 16}, + [VCAP_IS1_HK_L4_RNG] = {168, 8}, + /* Specific Fields for IS1 Half Key S1_5TUPLE_IP4 */ + [VCAP_IS1_HK_IP4_INNER_TPID] = { 42, 1}, + [VCAP_IS1_HK_IP4_INNER_VID] = { 43, 12}, + [VCAP_IS1_HK_IP4_INNER_DEI] = { 55, 1}, + [VCAP_IS1_HK_IP4_INNER_PCP] = { 56, 3}, + [VCAP_IS1_HK_IP4_IP4] = { 59, 1}, + [VCAP_IS1_HK_IP4_L3_FRAGMENT] = { 60, 1}, + [VCAP_IS1_HK_IP4_L3_FRAG_OFS_GT0] = { 61, 1}, + [VCAP_IS1_HK_IP4_L3_OPTIONS] = { 62, 1}, + [VCAP_IS1_HK_IP4_L3_DSCP] = { 63, 6}, + [VCAP_IS1_HK_IP4_L3_IP4_DIP] = { 69, 32}, + [VCAP_IS1_HK_IP4_L3_IP4_SIP] = {101, 32}, + [VCAP_IS1_HK_IP4_L3_PROTO] = {133, 8}, + [VCAP_IS1_HK_IP4_TCP_UDP] = {141, 1}, + [VCAP_IS1_HK_IP4_TCP] = {142, 1}, + [VCAP_IS1_HK_IP4_L4_RNG] = {143, 8}, + [VCAP_IS1_HK_IP4_IP_PAYLOAD_S1_5TUPLE] = {151, 32}, +}; + +struct vcap_field vsc9959_vcap_is1_actions[] = { + [VCAP_IS1_ACT_DSCP_ENA] = { 0, 1}, + [VCAP_IS1_ACT_DSCP_VAL] = { 1, 6}, + [VCAP_IS1_ACT_QOS_ENA] = { 7, 1}, + [VCAP_IS1_ACT_QOS_VAL] = { 8, 3}, + [VCAP_IS1_ACT_DP_ENA] = { 11, 1}, + [VCAP_IS1_ACT_DP_VAL] = { 12, 1}, + [VCAP_IS1_ACT_PAG_OVERRIDE_MASK] = { 13, 8}, + [VCAP_IS1_ACT_PAG_VAL] = { 21, 8}, + [VCAP_IS1_ACT_RSV] = { 29, 9}, + [VCAP_IS1_ACT_VID_REPLACE_ENA] = { 38, 1}, + [VCAP_IS1_ACT_VID_ADD_VAL] = { 39, 12}, + [VCAP_IS1_ACT_FID_SEL] = { 51, 2}, + [VCAP_IS1_ACT_FID_VAL] = { 53, 13}, + [VCAP_IS1_ACT_PCP_DEI_ENA] = { 66, 1}, + [VCAP_IS1_ACT_PCP_VAL] = { 67, 3}, + [VCAP_IS1_ACT_DEI_VAL] = { 70, 1}, + [VCAP_IS1_ACT_VLAN_POP_CNT_ENA] = { 71, 1}, + [VCAP_IS1_ACT_VLAN_POP_CNT] = { 72, 2}, + [VCAP_IS1_ACT_CUSTOM_ACE_TYPE_ENA] = { 74, 4}, + [VCAP_IS1_ACT_HIT_STICKY] = { 78, 1}, +}; + struct vcap_field vsc9959_vcap_is2_keys[] = { /* Common: 41 bits */ [VCAP_IS2_TYPE] = { 0, 4}, @@ -658,6 +740,26 @@ struct vcap_field vsc9959_vcap_is2_actions[] = { }; static const struct vcap_props vsc9959_vcap_props[] = { + [VCAP_IS1] = { + .tg_width = 2, + .sw_count = 4, + .entry_count = VSC9959_VCAP_IS1_CNT, + .entry_width = VSC9959_VCAP_IS1_ENTRY_WIDTH, + .action_count = VSC9959_VCAP_IS1_CNT + 1, + .action_width = 312, + .action_type_width = 0, + .action_table = { + [IS1_ACTION_TYPE_NORMAL] = { + .width = 78, + .count = 4 + }, + }, + .counter_words = 1, + .counter_width = 4, + .target = S1, + .keys = vsc9959_vcap_is1_keys, + .actions = vsc9959_vcap_is1_actions, + }, [VCAP_IS2] = { .tg_width = 2, .sw_count = 4, diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c index 9cfe1fd98c30..533e907af0e9 100644 --- a/drivers/net/ethernet/mscc/ocelot.c +++ b/drivers/net/ethernet/mscc/ocelot.c @@ -136,6 +136,13 @@ static void ocelot_vcap_enable(struct ocelot *ocelot, int port) ocelot_write_gix(ocelot, ANA_PORT_VCAP_S2_CFG_S2_ENA | ANA_PORT_VCAP_S2_CFG_S2_IP6_CFG(0xa), ANA_PORT_VCAP_S2_CFG, port); + + ocelot_write_gix(ocelot, ANA_PORT_VCAP_CFG_S1_ENA, + ANA_PORT_VCAP_CFG, port); + ocelot_write_gix(ocelot, + ANA_PORT_VCAP_S1_KEY_CFG_S1_KEY_IP6_CFG(2) | + ANA_PORT_VCAP_S1_KEY_CFG_S1_KEY_IP4_CFG(2), + ANA_PORT_VCAP_S1_KEY_CFG, port); } static inline u32 ocelot_vlant_read_vlanaccess(struct ocelot *ocelot) diff --git a/drivers/net/ethernet/mscc/ocelot_ace.c b/drivers/net/ethernet/mscc/ocelot_ace.c index 8c384b0771bb..bf21e4c5a9db 100644 --- a/drivers/net/ethernet/mscc/ocelot_ace.c +++ b/drivers/net/ethernet/mscc/ocelot_ace.c @@ -645,6 +645,197 @@ static void is2_entry_set(struct ocelot *ocelot, int ix, vcap_row_cmd(ocelot, vcap, row, VCAP_CMD_WRITE, VCAP_SEL_ALL); } +static void is1_action_set(struct ocelot *ocelot, struct vcap_data *data, + struct ocelot_ace_rule *ace) +{ + const struct vcap_props *vcap = &ocelot->vcap[VCAP_IS1]; + + switch (ace->action) { + case OCELOT_ACL_ACTION_VLAN_MODIFY: + vcap_action_set(vcap, data, VCAP_IS1_ACT_VID_REPLACE_ENA, 1); + vcap_action_set(vcap, data, VCAP_IS1_ACT_VID_ADD_VAL, + ace->vlan_modify.vid); + vcap_action_set(vcap, data, VCAP_IS1_ACT_PCP_DEI_ENA, 1); + vcap_action_set(vcap, data, VCAP_IS1_ACT_PCP_VAL, + ace->vlan_modify.pcp); + vcap_action_set(vcap, data, VCAP_IS1_ACT_DEI_VAL, + ace->vlan_modify.dei); + break; + case OCELOT_ACL_ACTION_PRIORITY: + vcap_action_set(vcap, data, VCAP_IS1_ACT_QOS_ENA, 1); + vcap_action_set(vcap, data, VCAP_IS1_ACT_QOS_VAL, + ace->qos_val); + break; + default: + break; + } +} + +static void is1_entry_set(struct ocelot *ocelot, int ix, + struct ocelot_ace_rule *ace) +{ + const struct vcap_props *vcap = &ocelot->vcap[VCAP_IS1]; + u32 val, msk, type, i; + struct ocelot_ace_vlan *tag = &ace->vlan; + struct ocelot_vcap_u64 payload; + struct vcap_data data; + int row = ix / 2; + + memset(&payload, 0, sizeof(payload)); + memset(&data, 0, sizeof(data)); + + /* Read row */ + vcap_row_cmd(ocelot, vcap, row, VCAP_CMD_READ, VCAP_SEL_ALL); + vcap_cache2entry(ocelot, vcap, &data); + vcap_cache2action(ocelot, vcap, &data); + + data.tg_sw = VCAP_TG_HALF; + data.type = IS1_ACTION_TYPE_NORMAL; + vcap_data_offset_get(vcap, &data, ix); + data.tg = (data.tg & ~data.tg_mask); + if (ace->prio != 0) + data.tg |= data.tg_value; + + vcap_key_set(vcap, &data, VCAP_IS1_HK_IGR_PORT_MASK, 0, + ~ace->ingress_port_mask); + vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_L2_MC, ace->dmac_mc); + vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_L2_BC, ace->dmac_bc); + vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_VLAN_TAGGED, tag->tagged); + vcap_key_set(vcap, &data, VCAP_IS1_HK_VID, + tag->vid.value, tag->vid.mask); + vcap_key_set(vcap, &data, VCAP_IS1_HK_PCP, + tag->pcp.value[0], tag->pcp.mask[0]); + type = IS1_TYPE_S1_NORMAL; + + switch (ace->type) { + case OCELOT_ACE_TYPE_ETYPE: { + struct ocelot_ace_frame_etype *etype = &ace->frame.etype; + + type = IS1_TYPE_S1_NORMAL; + vcap_key_bytes_set(vcap, &data, VCAP_IS1_HK_L2_SMAC, + etype->smac.value, etype->smac.mask); + vcap_key_bytes_set(vcap, &data, VCAP_IS1_HK_ETYPE, + etype->etype.value, etype->etype.mask); + break; + } + case OCELOT_ACE_TYPE_IPV4: + case OCELOT_ACE_TYPE_IPV6: { + enum ocelot_vcap_bit sip_eq_dip, sport_eq_dport; + enum ocelot_vcap_bit seq_zero, tcp; + enum ocelot_vcap_bit ttl, fragment, options; + enum ocelot_vcap_bit tcp_ack, tcp_urg; + enum ocelot_vcap_bit tcp_fin, tcp_syn, tcp_rst, tcp_psh; + struct ocelot_ace_frame_ipv4 *ipv4 = NULL; + struct ocelot_ace_frame_ipv6 *ipv6 = NULL; + struct ocelot_vcap_udp_tcp *sport, *dport; + struct ocelot_vcap_ipv4 sip, dip; + struct ocelot_vcap_u8 proto, ds; + struct ocelot_vcap_u48 *ip_data; + struct ocelot_vcap_u32 port; + + type = IS1_TYPE_S1_5TUPLE_IP4; + if (ace->type == OCELOT_ACE_TYPE_IPV4) { + ipv4 = &ace->frame.ipv4; + ttl = ipv4->ttl; + fragment = ipv4->fragment; + options = ipv4->options; + proto = ipv4->proto; + ds = ipv4->ds; + ip_data = &ipv4->data; + sip = ipv4->sip; + dip = ipv4->dip; + sport = &ipv4->sport; + dport = &ipv4->dport; + tcp_fin = ipv4->tcp_fin; + tcp_syn = ipv4->tcp_syn; + tcp_rst = ipv4->tcp_rst; + tcp_psh = ipv4->tcp_psh; + tcp_ack = ipv4->tcp_ack; + tcp_urg = ipv4->tcp_urg; + sip_eq_dip = ipv4->sip_eq_dip; + sport_eq_dport = ipv4->sport_eq_dport; + seq_zero = ipv4->seq_zero; + } else { + ipv6 = &ace->frame.ipv6; + ttl = ipv6->ttl; + fragment = OCELOT_VCAP_BIT_ANY; + options = OCELOT_VCAP_BIT_ANY; + proto = ipv6->proto; + ds = ipv6->ds; + ip_data = &ipv6->data; + for (i = 0; i < 4; i++) { + dip.value.addr[i] = ipv6->dip.value[i]; + dip.mask.addr[i] = ipv6->dip.mask[i]; + sip.value.addr[i] = ipv6->sip.value[i]; + sip.mask.addr[i] = ipv6->sip.mask[i]; + } + sport = &ipv6->sport; + dport = &ipv6->dport; + tcp_fin = ipv6->tcp_fin; + tcp_syn = ipv6->tcp_syn; + tcp_rst = ipv6->tcp_rst; + tcp_psh = ipv6->tcp_psh; + tcp_ack = ipv6->tcp_ack; + tcp_urg = ipv6->tcp_urg; + sip_eq_dip = ipv6->sip_eq_dip; + sport_eq_dport = ipv6->sport_eq_dport; + seq_zero = ipv6->seq_zero; + } + + vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_IP4_IP4, + ipv4 ? OCELOT_VCAP_BIT_1 : OCELOT_VCAP_BIT_0); + vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_IP4_L3_FRAGMENT, + fragment); + vcap_key_set(vcap, &data, VCAP_IS1_HK_IP4_L3_FRAG_OFS_GT0, + 0, 0); + vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_IP4_L3_OPTIONS, + options); + vcap_key_bytes_set(vcap, &data, VCAP_IS1_HK_IP4_L3_IP4_DIP, + dip.value.addr, dip.mask.addr); + vcap_key_bytes_set(vcap, &data, VCAP_IS1_HK_IP4_L3_IP4_SIP, + sip.value.addr, sip.mask.addr); + val = proto.value[0]; + msk = proto.mask[0]; + if (msk == 0xff && (val == 6 || val == 17)) { + /* UDP/TCP protocol match */ + tcp = (val == 6 ? + OCELOT_VCAP_BIT_1 : OCELOT_VCAP_BIT_0); + vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_IP4_TCP, + tcp); + vcap_key_l4_port_set(vcap, &data, + VCAP_IS1_HK_L4_SPORT, sport); + vcap_key_set(vcap, &data, VCAP_IS1_HK_IP4_L4_RNG, + 0, 0); + port.value[0] = sport->value & 0xFF; + port.value[1] = sport->value >> 8; + port.value[2] = dport->value & 0xFF; + port.value[3] = dport->value >> 8; + port.mask[0] = sport->mask & 0xFF; + port.mask[1] = sport->mask >> 8; + port.mask[2] = dport->mask & 0xFF; + port.mask[3] = dport->mask >> 8; + vcap_key_bytes_set(vcap, &data, + VCAP_IS1_HK_IP4_IP_PAYLOAD_S1_5TUPLE, + port.value, port.mask); + } + break; + } + default: + break; + } + vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_TYPE, + type ? OCELOT_VCAP_BIT_1 : OCELOT_VCAP_BIT_0); + + is1_action_set(ocelot, &data, ace); + vcap_data_set(data.counter, data.counter_offset, + vcap->counter_width, ace->stats.pkts); + + /* Write row */ + vcap_entry2cache(ocelot, vcap, &data); + vcap_action2cache(ocelot, vcap, &data); + vcap_row_cmd(ocelot, vcap, row, VCAP_CMD_WRITE, VCAP_SEL_ALL); +} + static void vcap_entry_get(struct ocelot *ocelot, struct ocelot_ace_rule *rule, int ix, int block_id) { @@ -670,6 +861,9 @@ static void vcap_entry_set(struct ocelot *ocelot, int ix, int block_id) { switch (block_id) { + case VCAP_IS1: + is1_entry_set(ocelot, ix, ace); + break; case VCAP_IS2: is2_entry_set(ocelot, ix, ace); break; @@ -986,6 +1180,7 @@ int ocelot_ace_init(struct ocelot *ocelot) { struct ocelot_acl_block *block; + vcap_init(ocelot, &ocelot->vcap[VCAP_IS1]); vcap_init(ocelot, &ocelot->vcap[VCAP_IS2]); /* Create a policer that will drop the frames for the cpu. @@ -1005,7 +1200,8 @@ int ocelot_ace_init(struct ocelot *ocelot) block = &ocelot->acl_block[VCAP_IS2]; block->pol_lpr = OCELOT_POLICER_DISCARD - 1; - INIT_LIST_HEAD(&block->rules); + INIT_LIST_HEAD(&ocelot->acl_block[VCAP_IS1].rules); + INIT_LIST_HEAD(&ocelot->acl_block[VCAP_IS2].rules); return 0; } diff --git a/drivers/net/ethernet/mscc/ocelot_ace.h b/drivers/net/ethernet/mscc/ocelot_ace.h index a9fd99401a65..bb2df6adaefd 100644 --- a/drivers/net/ethernet/mscc/ocelot_ace.h +++ b/drivers/net/ethernet/mscc/ocelot_ace.h @@ -93,6 +93,12 @@ struct ocelot_ace_vlan { enum ocelot_vcap_bit tagged; /* Tagged/untagged frame */ }; +struct ocelot_ace_action_vlan { + u16 vid; + u8 pcp; + u8 dei; +}; + struct ocelot_ace_frame_etype { struct ocelot_vcap_u48 dmac; struct ocelot_vcap_u48 smac; @@ -158,6 +164,7 @@ struct ocelot_ace_frame_ipv4 { struct ocelot_ace_frame_ipv6 { struct ocelot_vcap_u8 proto; /* IPv6 protocol */ struct ocelot_vcap_u128 sip; /* IPv6 source (byte 0-7 ignored) */ + struct ocelot_vcap_u128 dip; /* IPv6 destination (byte 0-7 ignored) */ enum ocelot_vcap_bit ttl; /* TTL zero */ struct ocelot_vcap_u8 ds; struct ocelot_vcap_u48 data; /* Not UDP/TCP: IP data */ @@ -179,6 +186,8 @@ enum ocelot_ace_action { OCELOT_ACL_ACTION_DROP, OCELOT_ACL_ACTION_TRAP, OCELOT_ACL_ACTION_POLICE, + OCELOT_ACL_ACTION_VLAN_MODIFY, + OCELOT_ACL_ACTION_PRIORITY, }; struct ocelot_ace_stats { @@ -200,6 +209,7 @@ struct ocelot_ace_rule { enum ocelot_vcap_bit dmac_mc; enum ocelot_vcap_bit dmac_bc; struct ocelot_ace_vlan vlan; + struct ocelot_ace_action_vlan vlan_modify; enum ocelot_ace_type type; union { @@ -213,6 +223,7 @@ struct ocelot_ace_rule { } frame; struct ocelot_policer pol; u32 pol_ix; + u8 qos_val; }; int ocelot_ace_rule_offload_add(struct ocelot *ocelot, int block_id, diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c b/drivers/net/ethernet/mscc/ocelot_flower.c index a1f7b6b28170..7f1a40ede652 100644 --- a/drivers/net/ethernet/mscc/ocelot_flower.c +++ b/drivers/net/ethernet/mscc/ocelot_flower.c @@ -63,6 +63,17 @@ static int ocelot_flower_parse_action(struct flow_cls_offload *f, ace->action = OCELOT_ACL_ACTION_NULL; allowed_chain = f->common.chain_index; break; + case FLOW_ACTION_VLAN_MANGLE: + ace->action = OCELOT_ACL_ACTION_VLAN_MODIFY; + ace->vlan_modify.vid = a->vlan.vid; + ace->vlan_modify.pcp = a->vlan.prio; + allowed_chain = 0; + break; + case FLOW_ACTION_PRIORITY: + ace->action = OCELOT_ACL_ACTION_PRIORITY; + ace->qos_val = a->priority; + allowed_chain = 0; + break; default: return -EOPNOTSUPP; } diff --git a/drivers/net/ethernet/mscc/ocelot_regs.c b/drivers/net/ethernet/mscc/ocelot_regs.c index 18ce99730406..2be74b275685 100644 --- a/drivers/net/ethernet/mscc/ocelot_regs.c +++ b/drivers/net/ethernet/mscc/ocelot_regs.c @@ -254,6 +254,7 @@ static const u32 *ocelot_regmap[] = { [QSYS] = ocelot_qsys_regmap, [REW] = ocelot_rew_regmap, [SYS] = ocelot_sys_regmap, + [S1] = ocelot_vcap_regmap, [S2] = ocelot_vcap_regmap, [PTP] = ocelot_ptp_regmap, }; diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h index 4b2320bdc036..1768ad1ca4e6 100644 --- a/include/soc/mscc/ocelot.h +++ b/include/soc/mscc/ocelot.h @@ -107,6 +107,7 @@ enum ocelot_target { QSYS, REW, SYS, + S1, S2, HSIO, PTP, diff --git a/include/soc/mscc/ocelot_vcap.h b/include/soc/mscc/ocelot_vcap.h index 495847a40490..9e83757f9b02 100644 --- a/include/soc/mscc/ocelot_vcap.h +++ b/include/soc/mscc/ocelot_vcap.h @@ -264,4 +264,95 @@ enum vcap_is2_action_field { VCAP_IS2_ACT_HIT_CNT, }; +/* ================================================================= + * VCAP IS1 + * ================================================================= + */ + +/* IS1 half key types */ +#define IS1_TYPE_S1_NORMAL 0 +#define IS1_TYPE_S1_5TUPLE_IP4 1 + +/* IS1 full key types */ +#define IS1_TYPE_S1_NORMAL_IP6 0 +#define IS1_TYPE_S1_7TUPLE 1 +#define IS2_TYPE_S1_5TUPLE_IP6 2 + +enum { + IS1_ACTION_TYPE_NORMAL, + IS1_ACTION_TYPE_MAX, +}; + +enum vcap_is1_half_key_field { + VCAP_IS1_HK_TYPE, + VCAP_IS1_HK_LOOKUP, + VCAP_IS1_HK_IGR_PORT_MASK, + VCAP_IS1_HK_RSV, + VCAP_IS1_HK_OAM_Y1731, + VCAP_IS1_HK_L2_MC, + VCAP_IS1_HK_L2_BC, + VCAP_IS1_HK_IP_MC, + VCAP_IS1_HK_VLAN_TAGGED, + VCAP_IS1_HK_VLAN_DBL_TAGGED, + VCAP_IS1_HK_TPID, + VCAP_IS1_HK_VID, + VCAP_IS1_HK_DEI, + VCAP_IS1_HK_PCP, + /* Specific Fields for IS1 Half Key S1_NORMAL */ + VCAP_IS1_HK_L2_SMAC, + VCAP_IS1_HK_ETYPE_LEN, + VCAP_IS1_HK_ETYPE, + VCAP_IS1_HK_IP_SNAP, + VCAP_IS1_HK_IP4, + VCAP_IS1_HK_L3_FRAGMENT, + VCAP_IS1_HK_L3_FRAG_OFS_GT0, + VCAP_IS1_HK_L3_OPTIONS, + VCAP_IS1_HK_L3_DSCP, + VCAP_IS1_HK_L3_IP4_SIP, + VCAP_IS1_HK_TCP_UDP, + VCAP_IS1_HK_TCP, + VCAP_IS1_HK_L4_SPORT, + VCAP_IS1_HK_L4_RNG, + /* Specific Fields for IS1 Half Key S1_5TUPLE_IP4 */ + VCAP_IS1_HK_IP4_INNER_TPID, + VCAP_IS1_HK_IP4_INNER_VID, + VCAP_IS1_HK_IP4_INNER_DEI, + VCAP_IS1_HK_IP4_INNER_PCP, + VCAP_IS1_HK_IP4_IP4, + VCAP_IS1_HK_IP4_L3_FRAGMENT, + VCAP_IS1_HK_IP4_L3_FRAG_OFS_GT0, + VCAP_IS1_HK_IP4_L3_OPTIONS, + VCAP_IS1_HK_IP4_L3_DSCP, + VCAP_IS1_HK_IP4_L3_IP4_DIP, + VCAP_IS1_HK_IP4_L3_IP4_SIP, + VCAP_IS1_HK_IP4_L3_PROTO, + VCAP_IS1_HK_IP4_TCP_UDP, + VCAP_IS1_HK_IP4_TCP, + VCAP_IS1_HK_IP4_L4_RNG, + VCAP_IS1_HK_IP4_IP_PAYLOAD_S1_5TUPLE, +}; + +enum vcap_is1_action_field { + VCAP_IS1_ACT_DSCP_ENA, + VCAP_IS1_ACT_DSCP_VAL, + VCAP_IS1_ACT_QOS_ENA, + VCAP_IS1_ACT_QOS_VAL, + VCAP_IS1_ACT_DP_ENA, + VCAP_IS1_ACT_DP_VAL, + VCAP_IS1_ACT_PAG_OVERRIDE_MASK, + VCAP_IS1_ACT_PAG_VAL, + VCAP_IS1_ACT_RSV, + VCAP_IS1_ACT_VID_REPLACE_ENA, + VCAP_IS1_ACT_VID_ADD_VAL, + VCAP_IS1_ACT_FID_SEL, + VCAP_IS1_ACT_FID_VAL, + VCAP_IS1_ACT_PCP_DEI_ENA, + VCAP_IS1_ACT_PCP_VAL, + VCAP_IS1_ACT_DEI_VAL, + VCAP_IS1_ACT_VLAN_POP_CNT_ENA, + VCAP_IS1_ACT_VLAN_POP_CNT, + VCAP_IS1_ACT_CUSTOM_ACE_TYPE_ENA, + VCAP_IS1_ACT_HIT_STICKY, +}; + #endif /* _OCELOT_VCAP_H_ */ From patchwork Tue Jun 2 05:18:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaoliang Yang X-Patchwork-Id: 218063 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2D042C433E0 for ; Tue, 2 Jun 2020 05:24:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1571B206A2 for ; Tue, 2 Jun 2020 05:24:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728047AbgFBFYW (ORCPT ); Tue, 2 Jun 2020 01:24:22 -0400 Received: from inva020.nxp.com ([92.121.34.13]:44676 "EHLO inva020.nxp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727788AbgFBFYT (ORCPT ); Tue, 2 Jun 2020 01:24:19 -0400 Received: from inva020.nxp.com (localhost [127.0.0.1]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id B28AF1A00EC; Tue, 2 Jun 2020 07:24:16 +0200 (CEST) Received: from invc005.ap-rdc01.nxp.com (invc005.ap-rdc01.nxp.com [165.114.16.14]) by inva020.eu-rdc02.nxp.com (Postfix) with ESMTP id EF7891A0B6E; Tue, 2 Jun 2020 07:24:06 +0200 (CEST) Received: from localhost.localdomain (mega.ap.freescale.net [10.192.208.232]) by invc005.ap-rdc01.nxp.com (Postfix) with ESMTP id 4F55B40327; Tue, 2 Jun 2020 13:23:55 +0800 (SGT) From: Xiaoliang Yang To: xiaoliang.yang_1@nxp.com, po.liu@nxp.com, claudiu.manoil@nxp.com, alexandru.marginean@nxp.com, vladimir.oltean@nxp.com, leoyang.li@nxp.com, mingkai.hu@nxp.com, andrew@lunn.ch, f.fainelli@gmail.com, vivien.didelot@gmail.com, davem@davemloft.net, jiri@resnulli.us, idosch@idosch.org, kuba@kernel.org, vinicius.gomes@intel.com, nikolay@cumulusnetworks.com, roopa@cumulusnetworks.com, netdev@vger.kernel.org, linux-kernel@vger.kernel.org, horatiu.vultur@microchip.com, alexandre.belloni@bootlin.com, allan.nielsen@microchip.com, joergen.andreasen@microchip.com, UNGLinuxDriver@microchip.com, linux-devel@linux.nxdi.nxp.com Subject: [PATCH v2 net-next 09/10] net: dsa: felix: correct VCAP IS2 keys offset Date: Tue, 2 Jun 2020 13:18:27 +0800 Message-Id: <20200602051828.5734-10-xiaoliang.yang_1@nxp.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200602051828.5734-1-xiaoliang.yang_1@nxp.com> References: <20200602051828.5734-1-xiaoliang.yang_1@nxp.com> X-Virus-Scanned: ClamAV using ClamSMTP Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Some of IS2 IP4_TCP_UDP keys are not correct, like L4_DPORT, L4_SPORT and other L4 keys. It causes the issue that VCAP IS2 could not filter a right dst/src port for TCP/UDP packages. Signed-off-by: Xiaoliang Yang --- drivers/net/dsa/ocelot/felix_vsc9959.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/net/dsa/ocelot/felix_vsc9959.c b/drivers/net/dsa/ocelot/felix_vsc9959.c index fceba87509ba..539f3c062b50 100644 --- a/drivers/net/dsa/ocelot/felix_vsc9959.c +++ b/drivers/net/dsa/ocelot/felix_vsc9959.c @@ -730,17 +730,17 @@ struct vcap_field vsc9959_vcap_is2_keys[] = { [VCAP_IS2_HK_DIP_EQ_SIP] = {118, 1}, /* IP4_TCP_UDP (TYPE=100) */ [VCAP_IS2_HK_TCP] = {119, 1}, - [VCAP_IS2_HK_L4_SPORT] = {120, 16}, - [VCAP_IS2_HK_L4_DPORT] = {136, 16}, + [VCAP_IS2_HK_L4_DPORT] = {120, 16}, + [VCAP_IS2_HK_L4_SPORT] = {136, 16}, [VCAP_IS2_HK_L4_RNG] = {152, 8}, [VCAP_IS2_HK_L4_SPORT_EQ_DPORT] = {160, 1}, [VCAP_IS2_HK_L4_SEQUENCE_EQ0] = {161, 1}, - [VCAP_IS2_HK_L4_URG] = {162, 1}, - [VCAP_IS2_HK_L4_ACK] = {163, 1}, - [VCAP_IS2_HK_L4_PSH] = {164, 1}, - [VCAP_IS2_HK_L4_RST] = {165, 1}, - [VCAP_IS2_HK_L4_SYN] = {166, 1}, - [VCAP_IS2_HK_L4_FIN] = {167, 1}, + [VCAP_IS2_HK_L4_FIN] = {162, 1}, + [VCAP_IS2_HK_L4_SYN] = {163, 1}, + [VCAP_IS2_HK_L4_RST] = {164, 1}, + [VCAP_IS2_HK_L4_PSH] = {165, 1}, + [VCAP_IS2_HK_L4_ACK] = {166, 1}, + [VCAP_IS2_HK_L4_URG] = {167, 1}, [VCAP_IS2_HK_L4_1588_DOM] = {168, 8}, [VCAP_IS2_HK_L4_1588_VER] = {176, 4}, /* IP4_OTHER (TYPE=101) */