Commit e0632940 authored by Vladimir Oltean's avatar Vladimir Oltean Committed by David S. Miller

net: mscc: ocelot: don't rely on preprocessor for vcap key/action packing

The IGR_PORT_MASK key width is different between the 11-port VSC7514 and
the 6-port VSC9959 switches. And since IGR_PORT_MASK is one of the first
fields of a VCAP key entry, it means that all further field
offset/length pairs are shifted between the 2.

The ocelot driver performs packing of VCAP half keys with the help of
some preprocessor macros:

- A set of macros for defining the HKO (Half Key Offset) and HKL (Half
  Key Length) of each possible key field. The offset of each field is
  defined as the sum between the offset and the sum of the previous
  field.

- A set of accessors on top of vcap_key_set for shorter (aka less
  typing) access to the HKO and HKL of each key field.

Since the field offsets and lengths are different between switches,
defining them through the preprocessor isn't going to fly. So introduce
a structure holding (offset, length) pairs and instantiate it in
ocelot_board.c for VSC7514. In a future patch, a similar structure will
be instantiated in felix_vsc9959.c for NXP LS1028A.

The accessors also need to go. They are based on macro name
concatenation, which is horrible to understand and follow.
Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: default avatarHoratiu Vultur <horatiu.vultur@microchip.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ed13233d
This diff is collapsed.
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <net/switchdev.h> #include <net/switchdev.h>
#include <soc/mscc/ocelot_vcap.h>
#include "ocelot.h" #include "ocelot.h"
#define IFH_EXTRACT_BITFIELD64(x, o, w) (((x) >> (o)) & GENMASK_ULL((w) - 1, 0)) #define IFH_EXTRACT_BITFIELD64(x, o, w) (((x) >> (o)) & GENMASK_ULL((w) - 1, 0))
...@@ -262,6 +263,104 @@ static const struct ocelot_ops ocelot_ops = { ...@@ -262,6 +263,104 @@ static const struct ocelot_ops ocelot_ops = {
.reset = ocelot_reset, .reset = ocelot_reset,
}; };
static const struct vcap_field vsc7514_vcap_is2_keys[] = {
/* Common: 46 bits */
[VCAP_IS2_TYPE] = { 0, 4},
[VCAP_IS2_HK_FIRST] = { 4, 1},
[VCAP_IS2_HK_PAG] = { 5, 8},
[VCAP_IS2_HK_IGR_PORT_MASK] = { 13, 12},
[VCAP_IS2_HK_RSV2] = { 25, 1},
[VCAP_IS2_HK_HOST_MATCH] = { 26, 1},
[VCAP_IS2_HK_L2_MC] = { 27, 1},
[VCAP_IS2_HK_L2_BC] = { 28, 1},
[VCAP_IS2_HK_VLAN_TAGGED] = { 29, 1},
[VCAP_IS2_HK_VID] = { 30, 12},
[VCAP_IS2_HK_DEI] = { 42, 1},
[VCAP_IS2_HK_PCP] = { 43, 3},
/* MAC_ETYPE / MAC_LLC / MAC_SNAP / OAM common */
[VCAP_IS2_HK_L2_DMAC] = { 46, 48},
[VCAP_IS2_HK_L2_SMAC] = { 94, 48},
/* MAC_ETYPE (TYPE=000) */
[VCAP_IS2_HK_MAC_ETYPE_ETYPE] = {142, 16},
[VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0] = {158, 16},
[VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1] = {174, 8},
[VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2] = {182, 3},
/* MAC_LLC (TYPE=001) */
[VCAP_IS2_HK_MAC_LLC_L2_LLC] = {142, 40},
/* MAC_SNAP (TYPE=010) */
[VCAP_IS2_HK_MAC_SNAP_L2_SNAP] = {142, 40},
/* MAC_ARP (TYPE=011) */
[VCAP_IS2_HK_MAC_ARP_SMAC] = { 46, 48},
[VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK] = { 94, 1},
[VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK] = { 95, 1},
[VCAP_IS2_HK_MAC_ARP_LEN_OK] = { 96, 1},
[VCAP_IS2_HK_MAC_ARP_TARGET_MATCH] = { 97, 1},
[VCAP_IS2_HK_MAC_ARP_SENDER_MATCH] = { 98, 1},
[VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN] = { 99, 1},
[VCAP_IS2_HK_MAC_ARP_OPCODE] = {100, 2},
[VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP] = {102, 32},
[VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP] = {134, 32},
[VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP] = {166, 1},
/* IP4_TCP_UDP / IP4_OTHER common */
[VCAP_IS2_HK_IP4] = { 46, 1},
[VCAP_IS2_HK_L3_FRAGMENT] = { 47, 1},
[VCAP_IS2_HK_L3_FRAG_OFS_GT0] = { 48, 1},
[VCAP_IS2_HK_L3_OPTIONS] = { 49, 1},
[VCAP_IS2_HK_IP4_L3_TTL_GT0] = { 50, 1},
[VCAP_IS2_HK_L3_TOS] = { 51, 8},
[VCAP_IS2_HK_L3_IP4_DIP] = { 59, 32},
[VCAP_IS2_HK_L3_IP4_SIP] = { 91, 32},
[VCAP_IS2_HK_DIP_EQ_SIP] = {123, 1},
/* IP4_TCP_UDP (TYPE=100) */
[VCAP_IS2_HK_TCP] = {124, 1},
[VCAP_IS2_HK_L4_SPORT] = {125, 16},
[VCAP_IS2_HK_L4_DPORT] = {141, 16},
[VCAP_IS2_HK_L4_RNG] = {157, 8},
[VCAP_IS2_HK_L4_SPORT_EQ_DPORT] = {165, 1},
[VCAP_IS2_HK_L4_SEQUENCE_EQ0] = {166, 1},
[VCAP_IS2_HK_L4_URG] = {167, 1},
[VCAP_IS2_HK_L4_ACK] = {168, 1},
[VCAP_IS2_HK_L4_PSH] = {169, 1},
[VCAP_IS2_HK_L4_RST] = {170, 1},
[VCAP_IS2_HK_L4_SYN] = {171, 1},
[VCAP_IS2_HK_L4_FIN] = {172, 1},
[VCAP_IS2_HK_L4_1588_DOM] = {173, 8},
[VCAP_IS2_HK_L4_1588_VER] = {181, 4},
/* IP4_OTHER (TYPE=101) */
[VCAP_IS2_HK_IP4_L3_PROTO] = {124, 8},
[VCAP_IS2_HK_L3_PAYLOAD] = {132, 56},
/* IP6_STD (TYPE=110) */
[VCAP_IS2_HK_IP6_L3_TTL_GT0] = { 46, 1},
[VCAP_IS2_HK_L3_IP6_SIP] = { 47, 128},
[VCAP_IS2_HK_IP6_L3_PROTO] = {175, 8},
/* OAM (TYPE=111) */
[VCAP_IS2_HK_OAM_MEL_FLAGS] = {142, 7},
[VCAP_IS2_HK_OAM_VER] = {149, 5},
[VCAP_IS2_HK_OAM_OPCODE] = {154, 8},
[VCAP_IS2_HK_OAM_FLAGS] = {162, 8},
[VCAP_IS2_HK_OAM_MEPID] = {170, 16},
[VCAP_IS2_HK_OAM_CCM_CNTS_EQ0] = {186, 1},
[VCAP_IS2_HK_OAM_IS_Y1731] = {187, 1},
};
static const struct vcap_field vsc7514_vcap_is2_actions[] = {
[VCAP_IS2_ACT_HIT_ME_ONCE] = { 0, 1},
[VCAP_IS2_ACT_CPU_COPY_ENA] = { 1, 1},
[VCAP_IS2_ACT_CPU_QU_NUM] = { 2, 3},
[VCAP_IS2_ACT_MASK_MODE] = { 5, 2},
[VCAP_IS2_ACT_MIRROR_ENA] = { 7, 1},
[VCAP_IS2_ACT_LRN_DIS] = { 8, 1},
[VCAP_IS2_ACT_POLICE_ENA] = { 9, 1},
[VCAP_IS2_ACT_POLICE_IDX] = { 10, 9},
[VCAP_IS2_ACT_POLICE_VCAP_ONLY] = { 19, 1},
[VCAP_IS2_ACT_PORT_MASK] = { 20, 11},
[VCAP_IS2_ACT_REW_OP] = { 31, 9},
[VCAP_IS2_ACT_SMAC_REPLACE_ENA] = { 40, 1},
[VCAP_IS2_ACT_RSV] = { 41, 2},
[VCAP_IS2_ACT_ACL_ID] = { 43, 6},
[VCAP_IS2_ACT_HIT_CNT] = { 49, 32},
};
static int mscc_ocelot_probe(struct platform_device *pdev) static int mscc_ocelot_probe(struct platform_device *pdev)
{ {
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
...@@ -362,6 +461,9 @@ static int mscc_ocelot_probe(struct platform_device *pdev) ...@@ -362,6 +461,9 @@ static int mscc_ocelot_probe(struct platform_device *pdev)
ocelot->ports = devm_kcalloc(&pdev->dev, ocelot->num_phys_ports, ocelot->ports = devm_kcalloc(&pdev->dev, ocelot->num_phys_ports,
sizeof(struct ocelot_port *), GFP_KERNEL); sizeof(struct ocelot_port *), GFP_KERNEL);
ocelot->vcap_is2_keys = vsc7514_vcap_is2_keys;
ocelot->vcap_is2_actions = vsc7514_vcap_is2_actions;
ocelot_init(ocelot); ocelot_init(ocelot);
ocelot_set_cpu_port(ocelot, ocelot->num_phys_ports, ocelot_set_cpu_port(ocelot, ocelot->num_phys_ports,
OCELOT_TAG_PREFIX_NONE, OCELOT_TAG_PREFIX_NONE); OCELOT_TAG_PREFIX_NONE, OCELOT_TAG_PREFIX_NONE);
......
This diff is collapsed.
...@@ -462,6 +462,9 @@ struct ocelot { ...@@ -462,6 +462,9 @@ struct ocelot {
struct ocelot_acl_block acl_block; struct ocelot_acl_block acl_block;
const struct vcap_field *vcap_is2_keys;
const struct vcap_field *vcap_is2_actions;
/* Workqueue to check statistics for overflow with its lock */ /* Workqueue to check statistics for overflow with its lock */
struct mutex stats_lock; struct mutex stats_lock;
u64 *stats; u64 *stats;
......
/* SPDX-License-Identifier: (GPL-2.0 OR MIT)
* Microsemi Ocelot Switch driver
* Copyright (c) 2019 Microsemi Corporation
*/
#ifndef _OCELOT_VCAP_H_
#define _OCELOT_VCAP_H_
/* =================================================================
* VCAP Common
* =================================================================
*/
/* VCAP Type-Group values */
#define VCAP_TG_NONE 0 /* Entry is invalid */
#define VCAP_TG_FULL 1 /* Full entry */
#define VCAP_TG_HALF 2 /* Half entry */
#define VCAP_TG_QUARTER 3 /* Quarter entry */
/* =================================================================
* VCAP IS2
* =================================================================
*/
#define VCAP_IS2_CNT 64
#define VCAP_IS2_ENTRY_WIDTH 376
#define VCAP_IS2_ACTION_WIDTH 99
#define VCAP_PORT_CNT 11
/* IS2 half key types */
#define IS2_TYPE_ETYPE 0
#define IS2_TYPE_LLC 1
#define IS2_TYPE_SNAP 2
#define IS2_TYPE_ARP 3
#define IS2_TYPE_IP_UDP_TCP 4
#define IS2_TYPE_IP_OTHER 5
#define IS2_TYPE_IPV6 6
#define IS2_TYPE_OAM 7
#define IS2_TYPE_SMAC_SIP6 8
#define IS2_TYPE_ANY 100 /* Pseudo type */
/* IS2 half key type mask for matching any IP */
#define IS2_TYPE_MASK_IP_ANY 0xe
/* IS2 action types */
#define IS2_ACTION_TYPE_NORMAL 0
#define IS2_ACTION_TYPE_SMAC_SIP 1
/* IS2 MASK_MODE values */
#define IS2_ACT_MASK_MODE_NONE 0
#define IS2_ACT_MASK_MODE_FILTER 1
#define IS2_ACT_MASK_MODE_POLICY 2
#define IS2_ACT_MASK_MODE_REDIR 3
/* IS2 REW_OP values */
#define IS2_ACT_REW_OP_NONE 0
#define IS2_ACT_REW_OP_PTP_ONE 2
#define IS2_ACT_REW_OP_PTP_TWO 3
#define IS2_ACT_REW_OP_SPECIAL 8
#define IS2_ACT_REW_OP_PTP_ORG 9
#define IS2_ACT_REW_OP_PTP_ONE_SUB_DELAY_1 (IS2_ACT_REW_OP_PTP_ONE | (1 << 3))
#define IS2_ACT_REW_OP_PTP_ONE_SUB_DELAY_2 (IS2_ACT_REW_OP_PTP_ONE | (2 << 3))
#define IS2_ACT_REW_OP_PTP_ONE_ADD_DELAY (IS2_ACT_REW_OP_PTP_ONE | (1 << 5))
#define IS2_ACT_REW_OP_PTP_ONE_ADD_SUB BIT(7)
#define VCAP_PORT_WIDTH 4
/* IS2 quarter key - SMAC_SIP4 */
#define IS2_QKO_IGR_PORT 0
#define IS2_QKL_IGR_PORT VCAP_PORT_WIDTH
#define IS2_QKO_L2_SMAC (IS2_QKO_IGR_PORT + IS2_QKL_IGR_PORT)
#define IS2_QKL_L2_SMAC 48
#define IS2_QKO_L3_IP4_SIP (IS2_QKO_L2_SMAC + IS2_QKL_L2_SMAC)
#define IS2_QKL_L3_IP4_SIP 32
enum vcap_is2_half_key_field {
/* Common */
VCAP_IS2_TYPE,
VCAP_IS2_HK_FIRST,
VCAP_IS2_HK_PAG,
VCAP_IS2_HK_RSV1,
VCAP_IS2_HK_IGR_PORT_MASK,
VCAP_IS2_HK_RSV2,
VCAP_IS2_HK_HOST_MATCH,
VCAP_IS2_HK_L2_MC,
VCAP_IS2_HK_L2_BC,
VCAP_IS2_HK_VLAN_TAGGED,
VCAP_IS2_HK_VID,
VCAP_IS2_HK_DEI,
VCAP_IS2_HK_PCP,
/* MAC_ETYPE / MAC_LLC / MAC_SNAP / OAM common */
VCAP_IS2_HK_L2_DMAC,
VCAP_IS2_HK_L2_SMAC,
/* MAC_ETYPE (TYPE=000) */
VCAP_IS2_HK_MAC_ETYPE_ETYPE,
VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0,
VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1,
VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2,
/* MAC_LLC (TYPE=001) */
VCAP_IS2_HK_MAC_LLC_DMAC,
VCAP_IS2_HK_MAC_LLC_SMAC,
VCAP_IS2_HK_MAC_LLC_L2_LLC,
/* MAC_SNAP (TYPE=010) */
VCAP_IS2_HK_MAC_SNAP_SMAC,
VCAP_IS2_HK_MAC_SNAP_DMAC,
VCAP_IS2_HK_MAC_SNAP_L2_SNAP,
/* MAC_ARP (TYPE=011) */
VCAP_IS2_HK_MAC_ARP_SMAC,
VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK,
VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK,
VCAP_IS2_HK_MAC_ARP_LEN_OK,
VCAP_IS2_HK_MAC_ARP_TARGET_MATCH,
VCAP_IS2_HK_MAC_ARP_SENDER_MATCH,
VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN,
VCAP_IS2_HK_MAC_ARP_OPCODE,
VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP,
VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP,
VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP,
/* IP4_TCP_UDP / IP4_OTHER common */
VCAP_IS2_HK_IP4,
VCAP_IS2_HK_L3_FRAGMENT,
VCAP_IS2_HK_L3_FRAG_OFS_GT0,
VCAP_IS2_HK_L3_OPTIONS,
VCAP_IS2_HK_IP4_L3_TTL_GT0,
VCAP_IS2_HK_L3_TOS,
VCAP_IS2_HK_L3_IP4_DIP,
VCAP_IS2_HK_L3_IP4_SIP,
VCAP_IS2_HK_DIP_EQ_SIP,
/* IP4_TCP_UDP (TYPE=100) */
VCAP_IS2_HK_TCP,
VCAP_IS2_HK_L4_SPORT,
VCAP_IS2_HK_L4_DPORT,
VCAP_IS2_HK_L4_RNG,
VCAP_IS2_HK_L4_SPORT_EQ_DPORT,
VCAP_IS2_HK_L4_SEQUENCE_EQ0,
VCAP_IS2_HK_L4_URG,
VCAP_IS2_HK_L4_ACK,
VCAP_IS2_HK_L4_PSH,
VCAP_IS2_HK_L4_RST,
VCAP_IS2_HK_L4_SYN,
VCAP_IS2_HK_L4_FIN,
VCAP_IS2_HK_L4_1588_DOM,
VCAP_IS2_HK_L4_1588_VER,
/* IP4_OTHER (TYPE=101) */
VCAP_IS2_HK_IP4_L3_PROTO,
VCAP_IS2_HK_L3_PAYLOAD,
/* IP6_STD (TYPE=110) */
VCAP_IS2_HK_IP6_L3_TTL_GT0,
VCAP_IS2_HK_IP6_L3_PROTO,
VCAP_IS2_HK_L3_IP6_SIP,
/* OAM (TYPE=111) */
VCAP_IS2_HK_OAM_MEL_FLAGS,
VCAP_IS2_HK_OAM_VER,
VCAP_IS2_HK_OAM_OPCODE,
VCAP_IS2_HK_OAM_FLAGS,
VCAP_IS2_HK_OAM_MEPID,
VCAP_IS2_HK_OAM_CCM_CNTS_EQ0,
VCAP_IS2_HK_OAM_IS_Y1731,
};
struct vcap_field {
int offset;
int length;
};
enum vcap_is2_action_field {
VCAP_IS2_ACT_HIT_ME_ONCE,
VCAP_IS2_ACT_CPU_COPY_ENA,
VCAP_IS2_ACT_CPU_QU_NUM,
VCAP_IS2_ACT_MASK_MODE,
VCAP_IS2_ACT_MIRROR_ENA,
VCAP_IS2_ACT_LRN_DIS,
VCAP_IS2_ACT_POLICE_ENA,
VCAP_IS2_ACT_POLICE_IDX,
VCAP_IS2_ACT_POLICE_VCAP_ONLY,
VCAP_IS2_ACT_PORT_MASK,
VCAP_IS2_ACT_REW_OP,
VCAP_IS2_ACT_SMAC_REPLACE_ENA,
VCAP_IS2_ACT_RSV,
VCAP_IS2_ACT_ACL_ID,
VCAP_IS2_ACT_HIT_CNT,
};
#endif /* _OCELOT_VCAP_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment