2019-05-31 15:16:56 +08:00
|
|
|
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
|
|
|
/* Microsemi Ocelot Switch driver
|
|
|
|
* Copyright (c) 2019 Microsemi Corporation
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <linux/iopoll.h>
|
|
|
|
#include <linux/proc_fs.h>
|
|
|
|
|
2020-02-29 22:31:10 +08:00
|
|
|
#include <soc/mscc/ocelot_vcap.h>
|
2020-03-29 19:51:57 +08:00
|
|
|
#include "ocelot_police.h"
|
2020-06-20 23:43:45 +08:00
|
|
|
#include "ocelot_vcap.h"
|
2019-05-31 15:16:56 +08:00
|
|
|
|
|
|
|
#define ENTRY_WIDTH 32
|
|
|
|
|
|
|
|
enum vcap_sel {
|
|
|
|
VCAP_SEL_ENTRY = 0x1,
|
|
|
|
VCAP_SEL_ACTION = 0x2,
|
|
|
|
VCAP_SEL_COUNTER = 0x4,
|
|
|
|
VCAP_SEL_ALL = 0x7,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum vcap_cmd {
|
|
|
|
VCAP_CMD_WRITE = 0, /* Copy from Cache to TCAM */
|
|
|
|
VCAP_CMD_READ = 1, /* Copy from TCAM to Cache */
|
|
|
|
VCAP_CMD_MOVE_UP = 2, /* Move <count> up */
|
|
|
|
VCAP_CMD_MOVE_DOWN = 3, /* Move <count> down */
|
|
|
|
VCAP_CMD_INITIALIZE = 4, /* Write all (from cache) */
|
|
|
|
};
|
|
|
|
|
|
|
|
#define VCAP_ENTRY_WIDTH 12 /* Max entry width (32bit words) */
|
|
|
|
#define VCAP_COUNTER_WIDTH 4 /* Max counter width (32bit words) */
|
|
|
|
|
|
|
|
struct vcap_data {
|
|
|
|
u32 entry[VCAP_ENTRY_WIDTH]; /* ENTRY_DAT */
|
|
|
|
u32 mask[VCAP_ENTRY_WIDTH]; /* MASK_DAT */
|
|
|
|
u32 action[VCAP_ENTRY_WIDTH]; /* ACTION_DAT */
|
|
|
|
u32 counter[VCAP_COUNTER_WIDTH]; /* CNT_DAT */
|
|
|
|
u32 tg; /* TG_DAT */
|
|
|
|
u32 type; /* Action type */
|
|
|
|
u32 tg_sw; /* Current type-group */
|
|
|
|
u32 cnt; /* Current counter */
|
|
|
|
u32 key_offset; /* Current entry offset */
|
|
|
|
u32 action_offset; /* Current action offset */
|
|
|
|
u32 counter_offset; /* Current counter offset */
|
|
|
|
u32 tg_value; /* Current type-group value */
|
|
|
|
u32 tg_mask; /* Current type-group mask */
|
2019-06-06 22:46:49 +08:00
|
|
|
};
|
2019-05-31 15:16:56 +08:00
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
static u32 vcap_read_update_ctrl(struct ocelot *ocelot,
|
|
|
|
const struct vcap_props *vcap)
|
2019-05-31 15:16:56 +08:00
|
|
|
{
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
return ocelot_target_read(ocelot, vcap->target, VCAP_CORE_UPDATE_CTRL);
|
2019-05-31 15:16:56 +08:00
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
static void vcap_cmd(struct ocelot *ocelot, const struct vcap_props *vcap,
|
|
|
|
u16 ix, int cmd, int sel)
|
2019-05-31 15:16:56 +08:00
|
|
|
{
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
u32 value = (VCAP_CORE_UPDATE_CTRL_UPDATE_CMD(cmd) |
|
|
|
|
VCAP_CORE_UPDATE_CTRL_UPDATE_ADDR(ix) |
|
|
|
|
VCAP_CORE_UPDATE_CTRL_UPDATE_SHOT);
|
2020-02-29 22:31:12 +08:00
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
if ((sel & VCAP_SEL_ENTRY) && ix >= vcap->entry_count)
|
2019-05-31 15:16:56 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (!(sel & VCAP_SEL_ENTRY))
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
value |= VCAP_CORE_UPDATE_CTRL_UPDATE_ENTRY_DIS;
|
2019-05-31 15:16:56 +08:00
|
|
|
|
|
|
|
if (!(sel & VCAP_SEL_ACTION))
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
value |= VCAP_CORE_UPDATE_CTRL_UPDATE_ACTION_DIS;
|
2019-05-31 15:16:56 +08:00
|
|
|
|
|
|
|
if (!(sel & VCAP_SEL_COUNTER))
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
value |= VCAP_CORE_UPDATE_CTRL_UPDATE_CNT_DIS;
|
|
|
|
|
|
|
|
ocelot_target_write(ocelot, vcap->target, value, VCAP_CORE_UPDATE_CTRL);
|
2019-05-31 15:16:56 +08:00
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
read_poll_timeout(vcap_read_update_ctrl, value,
|
|
|
|
(value & VCAP_CORE_UPDATE_CTRL_UPDATE_SHOT) == 0,
|
|
|
|
10, 100000, false, ocelot, vcap);
|
2019-05-31 15:16:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Convert from 0-based row to VCAP entry row and run command */
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
static void vcap_row_cmd(struct ocelot *ocelot, const struct vcap_props *vcap,
|
|
|
|
u32 row, int cmd, int sel)
|
2019-05-31 15:16:56 +08:00
|
|
|
{
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_cmd(ocelot, vcap, vcap->entry_count - row - 1, cmd, sel);
|
2019-05-31 15:16:56 +08:00
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
static void vcap_entry2cache(struct ocelot *ocelot,
|
|
|
|
const struct vcap_props *vcap,
|
|
|
|
struct vcap_data *data)
|
2019-05-31 15:16:56 +08:00
|
|
|
{
|
2020-02-29 22:31:12 +08:00
|
|
|
u32 entry_words, i;
|
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
entry_words = DIV_ROUND_UP(vcap->entry_width, ENTRY_WIDTH);
|
2019-05-31 15:16:56 +08:00
|
|
|
|
2020-02-29 22:31:12 +08:00
|
|
|
for (i = 0; i < entry_words; i++) {
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
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);
|
2019-05-31 15:16:56 +08:00
|
|
|
}
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
ocelot_target_write(ocelot, vcap->target, data->tg, VCAP_CACHE_TG_DAT);
|
2019-05-31 15:16:56 +08:00
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
static void vcap_cache2entry(struct ocelot *ocelot,
|
|
|
|
const struct vcap_props *vcap,
|
|
|
|
struct vcap_data *data)
|
2019-05-31 15:16:56 +08:00
|
|
|
{
|
2020-02-29 22:31:12 +08:00
|
|
|
u32 entry_words, i;
|
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
entry_words = DIV_ROUND_UP(vcap->entry_width, ENTRY_WIDTH);
|
2019-05-31 15:16:56 +08:00
|
|
|
|
2020-02-29 22:31:12 +08:00
|
|
|
for (i = 0; i < entry_words; i++) {
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
data->entry[i] = ocelot_target_read_rix(ocelot, vcap->target,
|
|
|
|
VCAP_CACHE_ENTRY_DAT, i);
|
2019-05-31 15:16:56 +08:00
|
|
|
// Invert mask
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
data->mask[i] = ~ocelot_target_read_rix(ocelot, vcap->target,
|
|
|
|
VCAP_CACHE_MASK_DAT, i);
|
2019-05-31 15:16:56 +08:00
|
|
|
}
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
data->tg = ocelot_target_read(ocelot, vcap->target, VCAP_CACHE_TG_DAT);
|
2019-05-31 15:16:56 +08:00
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
static void vcap_action2cache(struct ocelot *ocelot,
|
|
|
|
const struct vcap_props *vcap,
|
|
|
|
struct vcap_data *data)
|
2019-05-31 15:16:56 +08:00
|
|
|
{
|
2020-06-20 23:43:37 +08:00
|
|
|
u32 action_words, mask;
|
|
|
|
int i, width;
|
2019-05-31 15:16:56 +08:00
|
|
|
|
|
|
|
/* Encode action type */
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
width = vcap->action_type_width;
|
2019-05-31 15:16:56 +08:00
|
|
|
if (width) {
|
|
|
|
mask = GENMASK(width, 0);
|
|
|
|
data->action[0] = ((data->action[0] & ~mask) | data->type);
|
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
action_words = DIV_ROUND_UP(vcap->action_width, ENTRY_WIDTH);
|
2019-05-31 15:16:56 +08:00
|
|
|
|
2020-02-29 22:31:12 +08:00
|
|
|
for (i = 0; i < action_words; i++)
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
ocelot_target_write_rix(ocelot, vcap->target, data->action[i],
|
|
|
|
VCAP_CACHE_ACTION_DAT, i);
|
2020-02-29 22:31:12 +08:00
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
for (i = 0; i < vcap->counter_words; i++)
|
|
|
|
ocelot_target_write_rix(ocelot, vcap->target, data->counter[i],
|
|
|
|
VCAP_CACHE_CNT_DAT, i);
|
2019-05-31 15:16:56 +08:00
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
static void vcap_cache2action(struct ocelot *ocelot,
|
|
|
|
const struct vcap_props *vcap,
|
|
|
|
struct vcap_data *data)
|
2019-05-31 15:16:56 +08:00
|
|
|
{
|
2020-06-20 23:43:37 +08:00
|
|
|
u32 action_words;
|
|
|
|
int i, width;
|
2020-02-29 22:31:12 +08:00
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
action_words = DIV_ROUND_UP(vcap->action_width, ENTRY_WIDTH);
|
2019-05-31 15:16:56 +08:00
|
|
|
|
2020-02-29 22:31:12 +08:00
|
|
|
for (i = 0; i < action_words; i++)
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
data->action[i] = ocelot_target_read_rix(ocelot, vcap->target,
|
|
|
|
VCAP_CACHE_ACTION_DAT,
|
|
|
|
i);
|
2019-05-31 15:16:56 +08:00
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
for (i = 0; i < vcap->counter_words; i++)
|
|
|
|
data->counter[i] = ocelot_target_read_rix(ocelot, vcap->target,
|
|
|
|
VCAP_CACHE_CNT_DAT,
|
|
|
|
i);
|
2019-05-31 15:16:56 +08:00
|
|
|
|
|
|
|
/* Extract action type */
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
width = vcap->action_type_width;
|
2019-05-31 15:16:56 +08:00
|
|
|
data->type = (width ? (data->action[0] & GENMASK(width, 0)) : 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Calculate offsets for entry */
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
static void vcap_data_offset_get(const struct vcap_props *vcap,
|
|
|
|
struct vcap_data *data, int ix)
|
2019-05-31 15:16:56 +08:00
|
|
|
{
|
2020-09-30 06:27:31 +08:00
|
|
|
int num_subwords_per_entry, num_subwords_per_action;
|
|
|
|
int i, col, offset, num_entries_per_row, base;
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
u32 width = vcap->tg_width;
|
2019-05-31 15:16:56 +08:00
|
|
|
|
2020-09-30 06:27:29 +08:00
|
|
|
switch (data->tg_sw) {
|
|
|
|
case VCAP_TG_FULL:
|
2020-09-30 06:27:30 +08:00
|
|
|
num_entries_per_row = 1;
|
2020-09-30 06:27:29 +08:00
|
|
|
break;
|
|
|
|
case VCAP_TG_HALF:
|
2020-09-30 06:27:30 +08:00
|
|
|
num_entries_per_row = 2;
|
2020-09-30 06:27:29 +08:00
|
|
|
break;
|
|
|
|
case VCAP_TG_QUARTER:
|
2020-09-30 06:27:30 +08:00
|
|
|
num_entries_per_row = 4;
|
2020-09-30 06:27:29 +08:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-09-30 06:27:30 +08:00
|
|
|
col = (ix % num_entries_per_row);
|
2020-09-30 06:27:31 +08:00
|
|
|
num_subwords_per_entry = (vcap->sw_count / num_entries_per_row);
|
|
|
|
base = (vcap->sw_count - col * num_subwords_per_entry -
|
|
|
|
num_subwords_per_entry);
|
2019-05-31 15:16:56 +08:00
|
|
|
data->tg_value = 0;
|
|
|
|
data->tg_mask = 0;
|
2020-09-30 06:27:31 +08:00
|
|
|
for (i = 0; i < num_subwords_per_entry; i++) {
|
2019-05-31 15:16:56 +08:00
|
|
|
offset = ((base + i) * width);
|
|
|
|
data->tg_value |= (data->tg_sw << offset);
|
|
|
|
data->tg_mask |= GENMASK(offset + width - 1, offset);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Calculate key/action/counter offsets */
|
2020-09-30 06:27:30 +08:00
|
|
|
col = (num_entries_per_row - col - 1);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
data->key_offset = (base * vcap->entry_width) / vcap->sw_count;
|
2020-09-30 06:27:31 +08:00
|
|
|
data->counter_offset = (num_subwords_per_entry * col *
|
|
|
|
vcap->counter_width);
|
2019-05-31 15:16:56 +08:00
|
|
|
i = data->type;
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
width = vcap->action_table[i].width;
|
2020-09-30 06:27:31 +08:00
|
|
|
num_subwords_per_action = vcap->action_table[i].count;
|
|
|
|
data->action_offset = ((num_subwords_per_action * col * width) /
|
|
|
|
num_entries_per_row);
|
|
|
|
data->action_offset += vcap->action_type_width;
|
2019-05-31 15:16:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void vcap_data_set(u32 *data, u32 offset, u32 len, u32 value)
|
|
|
|
{
|
|
|
|
u32 i, v, m;
|
|
|
|
|
|
|
|
for (i = 0; i < len; i++, offset++) {
|
|
|
|
v = data[offset / ENTRY_WIDTH];
|
|
|
|
m = (1 << (offset % ENTRY_WIDTH));
|
|
|
|
if (value & (1 << i))
|
|
|
|
v |= m;
|
|
|
|
else
|
|
|
|
v &= ~m;
|
|
|
|
data[offset / ENTRY_WIDTH] = v;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static u32 vcap_data_get(u32 *data, u32 offset, u32 len)
|
|
|
|
{
|
|
|
|
u32 i, v, m, value = 0;
|
|
|
|
|
|
|
|
for (i = 0; i < len; i++, offset++) {
|
|
|
|
v = data[offset / ENTRY_WIDTH];
|
|
|
|
m = (1 << (offset % ENTRY_WIDTH));
|
|
|
|
if (v & m)
|
|
|
|
value |= (1 << i);
|
|
|
|
}
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
|
2020-02-29 22:31:10 +08:00
|
|
|
static void vcap_key_field_set(struct vcap_data *data, u32 offset, u32 width,
|
|
|
|
u32 value, u32 mask)
|
2019-05-31 15:16:56 +08:00
|
|
|
{
|
|
|
|
vcap_data_set(data->entry, offset + data->key_offset, width, value);
|
|
|
|
vcap_data_set(data->mask, offset + data->key_offset, width, mask);
|
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
static void vcap_key_set(const struct vcap_props *vcap, struct vcap_data *data,
|
|
|
|
int field, u32 value, u32 mask)
|
2020-02-29 22:31:10 +08:00
|
|
|
{
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
u32 offset = vcap->keys[field].offset;
|
|
|
|
u32 length = vcap->keys[field].length;
|
2020-02-29 22:31:10 +08:00
|
|
|
|
|
|
|
vcap_key_field_set(data, offset, length, value, mask);
|
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
static void vcap_key_bytes_set(const struct vcap_props *vcap,
|
|
|
|
struct vcap_data *data, int field,
|
2020-02-29 22:31:10 +08:00
|
|
|
u8 *val, u8 *msk)
|
2019-05-31 15:16:56 +08:00
|
|
|
{
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
u32 offset = vcap->keys[field].offset;
|
|
|
|
u32 count = vcap->keys[field].length;
|
2019-05-31 15:16:56 +08:00
|
|
|
u32 i, j, n = 0, value = 0, mask = 0;
|
|
|
|
|
2020-02-29 22:31:10 +08:00
|
|
|
WARN_ON(count % 8);
|
|
|
|
|
2019-05-31 15:16:56 +08:00
|
|
|
/* Data wider than 32 bits are split up in chunks of maximum 32 bits.
|
|
|
|
* The 32 LSB of the data are written to the 32 MSB of the TCAM.
|
|
|
|
*/
|
2020-02-29 22:31:10 +08:00
|
|
|
offset += count;
|
|
|
|
count /= 8;
|
|
|
|
|
2019-05-31 15:16:56 +08:00
|
|
|
for (i = 0; i < count; i++) {
|
|
|
|
j = (count - i - 1);
|
|
|
|
value += (val[j] << n);
|
|
|
|
mask += (msk[j] << n);
|
|
|
|
n += 8;
|
|
|
|
if (n == ENTRY_WIDTH || (i + 1) == count) {
|
|
|
|
offset -= n;
|
2020-02-29 22:31:10 +08:00
|
|
|
vcap_key_field_set(data, offset, n, value, mask);
|
2019-05-31 15:16:56 +08:00
|
|
|
n = 0;
|
|
|
|
value = 0;
|
|
|
|
mask = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
static void vcap_key_l4_port_set(const struct vcap_props *vcap,
|
|
|
|
struct vcap_data *data, int field,
|
2019-05-31 15:16:56 +08:00
|
|
|
struct ocelot_vcap_udp_tcp *port)
|
|
|
|
{
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
u32 offset = vcap->keys[field].offset;
|
|
|
|
u32 length = vcap->keys[field].length;
|
2020-02-29 22:31:10 +08:00
|
|
|
|
|
|
|
WARN_ON(length != 16);
|
|
|
|
|
|
|
|
vcap_key_field_set(data, offset, length, port->value, port->mask);
|
2019-05-31 15:16:56 +08:00
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
static void vcap_key_bit_set(const struct vcap_props *vcap,
|
|
|
|
struct vcap_data *data, int field,
|
2019-05-31 15:16:56 +08:00
|
|
|
enum ocelot_vcap_bit val)
|
|
|
|
{
|
2020-02-29 22:31:10 +08:00
|
|
|
u32 value = (val == OCELOT_VCAP_BIT_1 ? 1 : 0);
|
|
|
|
u32 msk = (val == OCELOT_VCAP_BIT_ANY ? 0 : 1);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
u32 offset = vcap->keys[field].offset;
|
|
|
|
u32 length = vcap->keys[field].length;
|
2019-05-31 15:16:56 +08:00
|
|
|
|
2020-02-29 22:31:10 +08:00
|
|
|
WARN_ON(length != 1);
|
2019-05-31 15:16:56 +08:00
|
|
|
|
2020-02-29 22:31:10 +08:00
|
|
|
vcap_key_field_set(data, offset, length, value, msk);
|
2019-05-31 15:16:56 +08:00
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
static void vcap_action_set(const struct vcap_props *vcap,
|
|
|
|
struct vcap_data *data, int field, u32 value)
|
2020-02-29 22:31:10 +08:00
|
|
|
{
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
int offset = vcap->actions[field].offset;
|
|
|
|
int length = vcap->actions[field].length;
|
2020-02-29 22:31:10 +08:00
|
|
|
|
|
|
|
vcap_data_set(data->action, offset + data->action_offset, length,
|
|
|
|
value);
|
|
|
|
}
|
2019-05-31 15:16:56 +08:00
|
|
|
|
2020-02-29 22:31:10 +08:00
|
|
|
static void is2_action_set(struct ocelot *ocelot, struct vcap_data *data,
|
2020-06-20 23:43:46 +08:00
|
|
|
struct ocelot_vcap_filter *filter)
|
2019-05-31 15:16:56 +08:00
|
|
|
{
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
const struct vcap_props *vcap = &ocelot->vcap[VCAP_IS2];
|
2020-10-02 20:02:20 +08:00
|
|
|
struct ocelot_vcap_action *a = &filter->action;
|
|
|
|
|
|
|
|
vcap_action_set(vcap, data, VCAP_IS2_ACT_MASK_MODE, a->mask_mode);
|
|
|
|
vcap_action_set(vcap, data, VCAP_IS2_ACT_PORT_MASK, a->port_mask);
|
2022-03-17 04:41:42 +08:00
|
|
|
vcap_action_set(vcap, data, VCAP_IS2_ACT_MIRROR_ENA, a->mirror_ena);
|
2020-10-02 20:02:20 +08:00
|
|
|
vcap_action_set(vcap, data, VCAP_IS2_ACT_POLICE_ENA, a->police_ena);
|
|
|
|
vcap_action_set(vcap, data, VCAP_IS2_ACT_POLICE_IDX, a->pol_ix);
|
|
|
|
vcap_action_set(vcap, data, VCAP_IS2_ACT_CPU_QU_NUM, a->cpu_qu_num);
|
|
|
|
vcap_action_set(vcap, data, VCAP_IS2_ACT_CPU_COPY_ENA, a->cpu_copy_ena);
|
2019-05-31 15:16:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void is2_entry_set(struct ocelot *ocelot, int ix,
|
2020-06-20 23:43:46 +08:00
|
|
|
struct ocelot_vcap_filter *filter)
|
2019-05-31 15:16:56 +08:00
|
|
|
{
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
const struct vcap_props *vcap = &ocelot->vcap[VCAP_IS2];
|
2020-06-20 23:43:46 +08:00
|
|
|
struct ocelot_vcap_key_vlan *tag = &filter->vlan;
|
2019-05-31 15:16:56 +08:00
|
|
|
u32 val, msk, type, type_mask = 0xf, i, count;
|
2019-06-04 04:49:53 +08:00
|
|
|
struct ocelot_vcap_u64 payload;
|
|
|
|
struct vcap_data data;
|
2019-05-31 15:16:56 +08:00
|
|
|
int row = (ix / 2);
|
|
|
|
|
2019-06-04 04:49:53 +08:00
|
|
|
memset(&payload, 0, sizeof(payload));
|
|
|
|
memset(&data, 0, sizeof(data));
|
|
|
|
|
2019-05-31 15:16:56 +08:00
|
|
|
/* Read row */
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_row_cmd(ocelot, vcap, row, VCAP_CMD_READ, VCAP_SEL_ALL);
|
|
|
|
vcap_cache2entry(ocelot, vcap, &data);
|
|
|
|
vcap_cache2action(ocelot, vcap, &data);
|
2019-05-31 15:16:56 +08:00
|
|
|
|
|
|
|
data.tg_sw = VCAP_TG_HALF;
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_data_offset_get(vcap, &data, ix);
|
2019-05-31 15:16:56 +08:00
|
|
|
data.tg = (data.tg & ~data.tg_mask);
|
2020-06-20 23:43:46 +08:00
|
|
|
if (filter->prio != 0)
|
2019-05-31 15:16:56 +08:00
|
|
|
data.tg |= data.tg_value;
|
|
|
|
|
|
|
|
data.type = IS2_ACTION_TYPE_NORMAL;
|
|
|
|
|
2020-10-02 20:02:25 +08:00
|
|
|
vcap_key_set(vcap, &data, VCAP_IS2_HK_PAG, filter->pag, 0xff);
|
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_FIRST,
|
|
|
|
(filter->lookup == 0) ? OCELOT_VCAP_BIT_1 :
|
|
|
|
OCELOT_VCAP_BIT_0);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_set(vcap, &data, VCAP_IS2_HK_IGR_PORT_MASK, 0,
|
2020-06-20 23:43:46 +08:00
|
|
|
~filter->ingress_port_mask);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_HOST_MATCH,
|
2020-02-29 22:31:10 +08:00
|
|
|
OCELOT_VCAP_BIT_ANY);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L2_MC, filter->dmac_mc);
|
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L2_BC, filter->dmac_bc);
|
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_VLAN_TAGGED, tag->tagged);
|
|
|
|
vcap_key_set(vcap, &data, VCAP_IS2_HK_VID,
|
2020-02-29 22:31:10 +08:00
|
|
|
tag->vid.value, tag->vid.mask);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_set(vcap, &data, VCAP_IS2_HK_PCP,
|
2020-02-29 22:31:10 +08:00
|
|
|
tag->pcp.value[0], tag->pcp.mask[0]);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_DEI, tag->dei);
|
2019-05-31 15:16:56 +08:00
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
switch (filter->key_type) {
|
|
|
|
case OCELOT_VCAP_KEY_ETYPE: {
|
|
|
|
struct ocelot_vcap_key_etype *etype = &filter->key.etype;
|
2019-05-31 15:16:56 +08:00
|
|
|
|
|
|
|
type = IS2_TYPE_ETYPE;
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L2_DMAC,
|
2020-02-29 22:31:10 +08:00
|
|
|
etype->dmac.value, etype->dmac.mask);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L2_SMAC,
|
2020-02-29 22:31:10 +08:00
|
|
|
etype->smac.value, etype->smac.mask);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_MAC_ETYPE_ETYPE,
|
2020-02-29 22:31:10 +08:00
|
|
|
etype->etype.value, etype->etype.mask);
|
|
|
|
/* Clear unused bits */
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_set(vcap, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0,
|
2020-02-29 22:31:10 +08:00
|
|
|
0, 0);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_set(vcap, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1,
|
2020-02-29 22:31:10 +08:00
|
|
|
0, 0);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_set(vcap, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2,
|
2020-02-29 22:31:10 +08:00
|
|
|
0, 0);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bytes_set(vcap, &data,
|
2020-02-29 22:31:10 +08:00
|
|
|
VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0,
|
|
|
|
etype->data.value, etype->data.mask);
|
2019-05-31 15:16:56 +08:00
|
|
|
break;
|
|
|
|
}
|
2020-06-20 23:43:46 +08:00
|
|
|
case OCELOT_VCAP_KEY_LLC: {
|
|
|
|
struct ocelot_vcap_key_llc *llc = &filter->key.llc;
|
2019-05-31 15:16:56 +08:00
|
|
|
|
|
|
|
type = IS2_TYPE_LLC;
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L2_DMAC,
|
2020-02-29 22:31:10 +08:00
|
|
|
llc->dmac.value, llc->dmac.mask);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L2_SMAC,
|
2020-02-29 22:31:10 +08:00
|
|
|
llc->smac.value, llc->smac.mask);
|
2019-05-31 15:16:56 +08:00
|
|
|
for (i = 0; i < 4; i++) {
|
|
|
|
payload.value[i] = llc->llc.value[i];
|
|
|
|
payload.mask[i] = llc->llc.mask[i];
|
|
|
|
}
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_MAC_LLC_L2_LLC,
|
2020-02-29 22:31:10 +08:00
|
|
|
payload.value, payload.mask);
|
2019-05-31 15:16:56 +08:00
|
|
|
break;
|
|
|
|
}
|
2020-06-20 23:43:46 +08:00
|
|
|
case OCELOT_VCAP_KEY_SNAP: {
|
|
|
|
struct ocelot_vcap_key_snap *snap = &filter->key.snap;
|
2019-05-31 15:16:56 +08:00
|
|
|
|
|
|
|
type = IS2_TYPE_SNAP;
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L2_DMAC,
|
2020-02-29 22:31:10 +08:00
|
|
|
snap->dmac.value, snap->dmac.mask);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L2_SMAC,
|
2020-02-29 22:31:10 +08:00
|
|
|
snap->smac.value, snap->smac.mask);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_MAC_SNAP_L2_SNAP,
|
2020-06-20 23:43:46 +08:00
|
|
|
filter->key.snap.snap.value,
|
|
|
|
filter->key.snap.snap.mask);
|
2019-05-31 15:16:56 +08:00
|
|
|
break;
|
|
|
|
}
|
2020-06-20 23:43:46 +08:00
|
|
|
case OCELOT_VCAP_KEY_ARP: {
|
|
|
|
struct ocelot_vcap_key_arp *arp = &filter->key.arp;
|
2019-05-31 15:16:56 +08:00
|
|
|
|
|
|
|
type = IS2_TYPE_ARP;
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_MAC_ARP_SMAC,
|
2020-02-29 22:31:10 +08:00
|
|
|
arp->smac.value, arp->smac.mask);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bit_set(vcap, &data,
|
2020-02-29 22:31:10 +08:00
|
|
|
VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK,
|
|
|
|
arp->ethernet);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bit_set(vcap, &data,
|
2020-02-29 22:31:10 +08:00
|
|
|
VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK,
|
|
|
|
arp->ip);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bit_set(vcap, &data,
|
2020-02-29 22:31:10 +08:00
|
|
|
VCAP_IS2_HK_MAC_ARP_LEN_OK,
|
|
|
|
arp->length);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bit_set(vcap, &data,
|
2020-02-29 22:31:10 +08:00
|
|
|
VCAP_IS2_HK_MAC_ARP_TARGET_MATCH,
|
|
|
|
arp->dmac_match);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bit_set(vcap, &data,
|
2020-02-29 22:31:10 +08:00
|
|
|
VCAP_IS2_HK_MAC_ARP_SENDER_MATCH,
|
|
|
|
arp->smac_match);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bit_set(vcap, &data,
|
2020-02-29 22:31:10 +08:00
|
|
|
VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN,
|
|
|
|
arp->unknown);
|
2019-05-31 15:16:56 +08:00
|
|
|
|
|
|
|
/* OPCODE is inverse, bit 0 is reply flag, bit 1 is RARP flag */
|
|
|
|
val = ((arp->req == OCELOT_VCAP_BIT_0 ? 1 : 0) |
|
|
|
|
(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));
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_set(vcap, &data, VCAP_IS2_HK_MAC_ARP_OPCODE,
|
2020-02-29 22:31:10 +08:00
|
|
|
val, msk);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bytes_set(vcap, &data,
|
2020-02-29 22:31:10 +08:00
|
|
|
VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP,
|
|
|
|
arp->dip.value.addr, arp->dip.mask.addr);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bytes_set(vcap, &data,
|
2020-02-29 22:31:10 +08:00
|
|
|
VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP,
|
|
|
|
arp->sip.value.addr, arp->sip.mask.addr);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_set(vcap, &data, VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP,
|
2020-02-29 22:31:10 +08:00
|
|
|
0, 0);
|
2019-05-31 15:16:56 +08:00
|
|
|
break;
|
|
|
|
}
|
2020-06-20 23:43:46 +08:00
|
|
|
case OCELOT_VCAP_KEY_IPV4:
|
|
|
|
case OCELOT_VCAP_KEY_IPV6: {
|
2019-05-31 15:16:56 +08:00
|
|
|
enum ocelot_vcap_bit sip_eq_dip, sport_eq_dport, seq_zero, tcp;
|
|
|
|
enum ocelot_vcap_bit ttl, fragment, options, tcp_ack, tcp_urg;
|
|
|
|
enum ocelot_vcap_bit tcp_fin, tcp_syn, tcp_rst, tcp_psh;
|
2020-06-20 23:43:46 +08:00
|
|
|
struct ocelot_vcap_key_ipv4 *ipv4 = NULL;
|
|
|
|
struct ocelot_vcap_key_ipv6 *ipv6 = NULL;
|
2019-05-31 15:16:56 +08:00
|
|
|
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;
|
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
if (filter->key_type == OCELOT_VCAP_KEY_IPV4) {
|
|
|
|
ipv4 = &filter->key.ipv4;
|
2019-05-31 15:16:56 +08:00
|
|
|
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 {
|
2020-06-20 23:43:46 +08:00
|
|
|
ipv6 = &filter->key.ipv6;
|
2019-05-31 15:16:56 +08:00
|
|
|
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 < 8; i++) {
|
|
|
|
val = ipv6->sip.value[i + 8];
|
|
|
|
msk = ipv6->sip.mask[i + 8];
|
|
|
|
if (i < 4) {
|
|
|
|
dip.value.addr[i] = val;
|
|
|
|
dip.mask.addr[i] = msk;
|
|
|
|
} else {
|
|
|
|
sip.value.addr[i - 4] = val;
|
|
|
|
sip.mask.addr[i - 4] = msk;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_IP4,
|
2019-05-31 15:16:56 +08:00
|
|
|
ipv4 ? OCELOT_VCAP_BIT_1 : OCELOT_VCAP_BIT_0);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L3_FRAGMENT,
|
2020-02-29 22:31:10 +08:00
|
|
|
fragment);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
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,
|
2020-02-29 22:31:10 +08:00
|
|
|
options);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_IP4_L3_TTL_GT0,
|
2020-02-29 22:31:10 +08:00
|
|
|
ttl);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L3_TOS,
|
2020-02-29 22:31:10 +08:00
|
|
|
ds.value, ds.mask);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L3_IP4_DIP,
|
2020-02-29 22:31:10 +08:00
|
|
|
dip.value.addr, dip.mask.addr);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L3_IP4_SIP,
|
2020-02-29 22:31:10 +08:00
|
|
|
sip.value.addr, sip.mask.addr);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_DIP_EQ_SIP,
|
2020-02-29 22:31:10 +08:00
|
|
|
sip_eq_dip);
|
2019-05-31 15:16:56 +08:00
|
|
|
val = proto.value[0];
|
|
|
|
msk = proto.mask[0];
|
|
|
|
type = IS2_TYPE_IP_UDP_TCP;
|
2022-03-03 22:01:21 +08:00
|
|
|
if (msk == 0xff && (val == IPPROTO_TCP || val == IPPROTO_UDP)) {
|
2019-05-31 15:16:56 +08:00
|
|
|
/* UDP/TCP protocol match */
|
2022-03-03 22:01:21 +08:00
|
|
|
tcp = (val == IPPROTO_TCP ?
|
2019-05-31 15:16:56 +08:00
|
|
|
OCELOT_VCAP_BIT_1 : OCELOT_VCAP_BIT_0);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_TCP, tcp);
|
|
|
|
vcap_key_l4_port_set(vcap, &data,
|
2020-02-29 22:31:10 +08:00
|
|
|
VCAP_IS2_HK_L4_DPORT, dport);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_l4_port_set(vcap, &data,
|
2020-02-29 22:31:10 +08:00
|
|
|
VCAP_IS2_HK_L4_SPORT, sport);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_set(vcap, &data, VCAP_IS2_HK_L4_RNG, 0, 0);
|
|
|
|
vcap_key_bit_set(vcap, &data,
|
2020-02-29 22:31:10 +08:00
|
|
|
VCAP_IS2_HK_L4_SPORT_EQ_DPORT,
|
2019-05-31 15:16:56 +08:00
|
|
|
sport_eq_dport);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bit_set(vcap, &data,
|
2020-02-29 22:31:10 +08:00
|
|
|
VCAP_IS2_HK_L4_SEQUENCE_EQ0,
|
|
|
|
seq_zero);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_FIN,
|
2020-02-29 22:31:10 +08:00
|
|
|
tcp_fin);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_SYN,
|
2020-02-29 22:31:10 +08:00
|
|
|
tcp_syn);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_RST,
|
2020-02-29 22:31:10 +08:00
|
|
|
tcp_rst);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_PSH,
|
2020-02-29 22:31:10 +08:00
|
|
|
tcp_psh);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_ACK,
|
2020-02-29 22:31:10 +08:00
|
|
|
tcp_ack);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_URG,
|
2020-02-29 22:31:10 +08:00
|
|
|
tcp_urg);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_set(vcap, &data, VCAP_IS2_HK_L4_1588_DOM,
|
2020-02-29 22:31:10 +08:00
|
|
|
0, 0);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_set(vcap, &data, VCAP_IS2_HK_L4_1588_VER,
|
2020-02-29 22:31:10 +08:00
|
|
|
0, 0);
|
2019-05-31 15:16:56 +08:00
|
|
|
} else {
|
|
|
|
if (msk == 0) {
|
|
|
|
/* Any IP protocol match */
|
|
|
|
type_mask = IS2_TYPE_MASK_IP_ANY;
|
|
|
|
} else {
|
|
|
|
/* Non-UDP/TCP protocol match */
|
|
|
|
type = IS2_TYPE_IP_OTHER;
|
|
|
|
for (i = 0; i < 6; i++) {
|
|
|
|
payload.value[i] = ip_data->value[i];
|
|
|
|
payload.mask[i] = ip_data->mask[i];
|
|
|
|
}
|
|
|
|
}
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bytes_set(vcap, &data,
|
2020-02-29 22:31:10 +08:00
|
|
|
VCAP_IS2_HK_IP4_L3_PROTO,
|
|
|
|
proto.value, proto.mask);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_bytes_set(vcap, &data,
|
2020-02-29 22:31:10 +08:00
|
|
|
VCAP_IS2_HK_L3_PAYLOAD,
|
|
|
|
payload.value, payload.mask);
|
2019-05-31 15:16:56 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2020-06-20 23:43:46 +08:00
|
|
|
case OCELOT_VCAP_KEY_ANY:
|
2019-05-31 15:16:56 +08:00
|
|
|
default:
|
|
|
|
type = 0;
|
|
|
|
type_mask = 0;
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
count = vcap->entry_width / 2;
|
2020-02-29 22:31:10 +08:00
|
|
|
/* Iterate over the non-common part of the key and
|
|
|
|
* clear entry data
|
|
|
|
*/
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
for (i = vcap->keys[VCAP_IS2_HK_L2_DMAC].offset;
|
2020-02-29 22:31:10 +08:00
|
|
|
i < count; i += ENTRY_WIDTH) {
|
|
|
|
vcap_key_field_set(&data, i, min(32u, count - i), 0, 0);
|
2019-05-31 15:16:56 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_key_set(vcap, &data, VCAP_IS2_TYPE, type, type_mask);
|
2020-06-20 23:43:46 +08:00
|
|
|
is2_action_set(ocelot, &data, filter);
|
2020-02-29 22:31:10 +08:00
|
|
|
vcap_data_set(data.counter, data.counter_offset,
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap->counter_width, filter->stats.pkts);
|
2019-05-31 15:16:56 +08:00
|
|
|
|
|
|
|
/* Write row */
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap_entry2cache(ocelot, vcap, &data);
|
|
|
|
vcap_action2cache(ocelot, vcap, &data);
|
|
|
|
vcap_row_cmd(ocelot, vcap, row, VCAP_CMD_WRITE, VCAP_SEL_ALL);
|
2019-05-31 15:16:56 +08:00
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: offload ingress skbedit and vlan actions to VCAP IS1
VCAP IS1 is a VCAP module which can filter on the most common L2/L3/L4
Ethernet keys, and modify the results of the basic QoS classification
and VLAN classification based on those flow keys.
There are 3 VCAP IS1 lookups, mapped over chains 10000, 11000 and 12000.
Currently the driver is hardcoded to use IS1_ACTION_TYPE_NORMAL half
keys.
Note that the VLAN_MANGLE has been omitted for now. In hardware, the
VCAP_IS1_ACT_VID_REPLACE_ENA field replaces the classified VLAN
(metadata associated with the frame) and not the VLAN from the header
itself. There are currently some issues which need to be addressed when
operating in standalone, or in bridge with vlan_filtering=0 modes,
because in those cases the switch ports have VLAN awareness disabled,
and changing the classified VLAN to anything other than the pvid causes
the packets to be dropped. Another issue is that on egress, we expect
port tagging to push the classified VLAN, but port tagging is disabled
in the modes mentioned above, so although the classified VLAN is
replaced, it is not visible in the packet transmitted by the switch.
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 20:02:23 +08:00
|
|
|
static void is1_action_set(struct ocelot *ocelot, struct vcap_data *data,
|
|
|
|
const struct ocelot_vcap_filter *filter)
|
|
|
|
{
|
|
|
|
const struct vcap_props *vcap = &ocelot->vcap[VCAP_IS1];
|
|
|
|
const struct ocelot_vcap_action *a = &filter->action;
|
|
|
|
|
|
|
|
vcap_action_set(vcap, data, VCAP_IS1_ACT_VID_REPLACE_ENA,
|
|
|
|
a->vid_replace_ena);
|
|
|
|
vcap_action_set(vcap, data, VCAP_IS1_ACT_VID_ADD_VAL, a->vid);
|
|
|
|
vcap_action_set(vcap, data, VCAP_IS1_ACT_VLAN_POP_CNT_ENA,
|
|
|
|
a->vlan_pop_cnt_ena);
|
|
|
|
vcap_action_set(vcap, data, VCAP_IS1_ACT_VLAN_POP_CNT,
|
|
|
|
a->vlan_pop_cnt);
|
|
|
|
vcap_action_set(vcap, data, VCAP_IS1_ACT_PCP_DEI_ENA, a->pcp_dei_ena);
|
|
|
|
vcap_action_set(vcap, data, VCAP_IS1_ACT_PCP_VAL, a->pcp);
|
|
|
|
vcap_action_set(vcap, data, VCAP_IS1_ACT_DEI_VAL, a->dei);
|
|
|
|
vcap_action_set(vcap, data, VCAP_IS1_ACT_QOS_ENA, a->qos_ena);
|
|
|
|
vcap_action_set(vcap, data, VCAP_IS1_ACT_QOS_VAL, a->qos_val);
|
|
|
|
vcap_action_set(vcap, data, VCAP_IS1_ACT_PAG_OVERRIDE_MASK,
|
|
|
|
a->pag_override_mask);
|
|
|
|
vcap_action_set(vcap, data, VCAP_IS1_ACT_PAG_VAL, a->pag_val);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void is1_entry_set(struct ocelot *ocelot, int ix,
|
|
|
|
struct ocelot_vcap_filter *filter)
|
|
|
|
{
|
|
|
|
const struct vcap_props *vcap = &ocelot->vcap[VCAP_IS1];
|
|
|
|
struct ocelot_vcap_key_vlan *tag = &filter->vlan;
|
|
|
|
struct vcap_data data;
|
|
|
|
int row = ix / 2;
|
|
|
|
u32 type;
|
|
|
|
|
|
|
|
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 (filter->prio != 0)
|
|
|
|
data.tg |= data.tg_value;
|
|
|
|
|
2020-10-02 20:02:25 +08:00
|
|
|
vcap_key_set(vcap, &data, VCAP_IS1_HK_LOOKUP, filter->lookup, 0x3);
|
net: mscc: ocelot: offload ingress skbedit and vlan actions to VCAP IS1
VCAP IS1 is a VCAP module which can filter on the most common L2/L3/L4
Ethernet keys, and modify the results of the basic QoS classification
and VLAN classification based on those flow keys.
There are 3 VCAP IS1 lookups, mapped over chains 10000, 11000 and 12000.
Currently the driver is hardcoded to use IS1_ACTION_TYPE_NORMAL half
keys.
Note that the VLAN_MANGLE has been omitted for now. In hardware, the
VCAP_IS1_ACT_VID_REPLACE_ENA field replaces the classified VLAN
(metadata associated with the frame) and not the VLAN from the header
itself. There are currently some issues which need to be addressed when
operating in standalone, or in bridge with vlan_filtering=0 modes,
because in those cases the switch ports have VLAN awareness disabled,
and changing the classified VLAN to anything other than the pvid causes
the packets to be dropped. Another issue is that on egress, we expect
port tagging to push the classified VLAN, but port tagging is disabled
in the modes mentioned above, so although the classified VLAN is
replaced, it is not visible in the packet transmitted by the switch.
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 20:02:23 +08:00
|
|
|
vcap_key_set(vcap, &data, VCAP_IS1_HK_IGR_PORT_MASK, 0,
|
|
|
|
~filter->ingress_port_mask);
|
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_L2_MC, filter->dmac_mc);
|
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_L2_BC, filter->dmac_bc);
|
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_VLAN_TAGGED, tag->tagged);
|
2024-08-15 08:07:07 +08:00
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_TPID, tag->tpid);
|
net: mscc: ocelot: offload ingress skbedit and vlan actions to VCAP IS1
VCAP IS1 is a VCAP module which can filter on the most common L2/L3/L4
Ethernet keys, and modify the results of the basic QoS classification
and VLAN classification based on those flow keys.
There are 3 VCAP IS1 lookups, mapped over chains 10000, 11000 and 12000.
Currently the driver is hardcoded to use IS1_ACTION_TYPE_NORMAL half
keys.
Note that the VLAN_MANGLE has been omitted for now. In hardware, the
VCAP_IS1_ACT_VID_REPLACE_ENA field replaces the classified VLAN
(metadata associated with the frame) and not the VLAN from the header
itself. There are currently some issues which need to be addressed when
operating in standalone, or in bridge with vlan_filtering=0 modes,
because in those cases the switch ports have VLAN awareness disabled,
and changing the classified VLAN to anything other than the pvid causes
the packets to be dropped. Another issue is that on egress, we expect
port tagging to push the classified VLAN, but port tagging is disabled
in the modes mentioned above, so although the classified VLAN is
replaced, it is not visible in the packet transmitted by the switch.
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 20:02:23 +08:00
|
|
|
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 (filter->key_type) {
|
|
|
|
case OCELOT_VCAP_KEY_ETYPE: {
|
|
|
|
struct ocelot_vcap_key_etype *etype = &filter->key.etype;
|
|
|
|
|
|
|
|
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_VCAP_KEY_IPV4: {
|
|
|
|
struct ocelot_vcap_key_ipv4 *ipv4 = &filter->key.ipv4;
|
|
|
|
struct ocelot_vcap_udp_tcp *sport = &ipv4->sport;
|
|
|
|
struct ocelot_vcap_udp_tcp *dport = &ipv4->dport;
|
|
|
|
enum ocelot_vcap_bit tcp_udp = OCELOT_VCAP_BIT_0;
|
|
|
|
struct ocelot_vcap_u8 proto = ipv4->proto;
|
|
|
|
struct ocelot_vcap_ipv4 sip = ipv4->sip;
|
|
|
|
u32 val, msk;
|
|
|
|
|
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_IP_SNAP,
|
|
|
|
OCELOT_VCAP_BIT_1);
|
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_IP4,
|
|
|
|
OCELOT_VCAP_BIT_1);
|
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_ETYPE_LEN,
|
|
|
|
OCELOT_VCAP_BIT_1);
|
|
|
|
vcap_key_bytes_set(vcap, &data, VCAP_IS1_HK_L3_IP4_SIP,
|
|
|
|
sip.value.addr, sip.mask.addr);
|
|
|
|
|
|
|
|
val = proto.value[0];
|
|
|
|
msk = proto.mask[0];
|
|
|
|
|
|
|
|
if ((val == NEXTHDR_TCP || val == NEXTHDR_UDP) && msk == 0xff)
|
|
|
|
tcp_udp = OCELOT_VCAP_BIT_1;
|
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_TCP_UDP, tcp_udp);
|
|
|
|
|
|
|
|
if (tcp_udp) {
|
|
|
|
enum ocelot_vcap_bit tcp = OCELOT_VCAP_BIT_0;
|
|
|
|
|
|
|
|
if (val == NEXTHDR_TCP)
|
|
|
|
tcp = OCELOT_VCAP_BIT_1;
|
|
|
|
|
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_TCP, tcp);
|
|
|
|
vcap_key_l4_port_set(vcap, &data, VCAP_IS1_HK_L4_SPORT,
|
|
|
|
sport);
|
|
|
|
/* Overloaded field */
|
|
|
|
vcap_key_l4_port_set(vcap, &data, VCAP_IS1_HK_ETYPE,
|
|
|
|
dport);
|
|
|
|
} else {
|
|
|
|
/* IPv4 "other" frame */
|
|
|
|
struct ocelot_vcap_u16 etype = {0};
|
|
|
|
|
|
|
|
/* Overloaded field */
|
|
|
|
etype.value[0] = proto.value[0];
|
|
|
|
etype.mask[0] = proto.mask[0];
|
|
|
|
|
|
|
|
vcap_key_bytes_set(vcap, &data, VCAP_IS1_HK_ETYPE,
|
|
|
|
etype.value, etype.mask);
|
|
|
|
}
|
2021-03-10 13:33:16 +08:00
|
|
|
break;
|
net: mscc: ocelot: offload ingress skbedit and vlan actions to VCAP IS1
VCAP IS1 is a VCAP module which can filter on the most common L2/L3/L4
Ethernet keys, and modify the results of the basic QoS classification
and VLAN classification based on those flow keys.
There are 3 VCAP IS1 lookups, mapped over chains 10000, 11000 and 12000.
Currently the driver is hardcoded to use IS1_ACTION_TYPE_NORMAL half
keys.
Note that the VLAN_MANGLE has been omitted for now. In hardware, the
VCAP_IS1_ACT_VID_REPLACE_ENA field replaces the classified VLAN
(metadata associated with the frame) and not the VLAN from the header
itself. There are currently some issues which need to be addressed when
operating in standalone, or in bridge with vlan_filtering=0 modes,
because in those cases the switch ports have VLAN awareness disabled,
and changing the classified VLAN to anything other than the pvid causes
the packets to be dropped. Another issue is that on egress, we expect
port tagging to push the classified VLAN, but port tagging is disabled
in the modes mentioned above, so although the classified VLAN is
replaced, it is not visible in the packet transmitted by the switch.
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 20:02:23 +08:00
|
|
|
}
|
|
|
|
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, filter);
|
|
|
|
vcap_data_set(data.counter, data.counter_offset,
|
|
|
|
vcap->counter_width, filter->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);
|
|
|
|
}
|
|
|
|
|
2020-10-02 20:02:24 +08:00
|
|
|
static void es0_action_set(struct ocelot *ocelot, struct vcap_data *data,
|
|
|
|
const struct ocelot_vcap_filter *filter)
|
|
|
|
{
|
|
|
|
const struct vcap_props *vcap = &ocelot->vcap[VCAP_ES0];
|
|
|
|
const struct ocelot_vcap_action *a = &filter->action;
|
|
|
|
|
|
|
|
vcap_action_set(vcap, data, VCAP_ES0_ACT_PUSH_OUTER_TAG,
|
|
|
|
a->push_outer_tag);
|
|
|
|
vcap_action_set(vcap, data, VCAP_ES0_ACT_PUSH_INNER_TAG,
|
|
|
|
a->push_inner_tag);
|
|
|
|
vcap_action_set(vcap, data, VCAP_ES0_ACT_TAG_A_TPID_SEL,
|
|
|
|
a->tag_a_tpid_sel);
|
|
|
|
vcap_action_set(vcap, data, VCAP_ES0_ACT_TAG_A_VID_SEL,
|
|
|
|
a->tag_a_vid_sel);
|
|
|
|
vcap_action_set(vcap, data, VCAP_ES0_ACT_TAG_A_PCP_SEL,
|
|
|
|
a->tag_a_pcp_sel);
|
|
|
|
vcap_action_set(vcap, data, VCAP_ES0_ACT_VID_A_VAL, a->vid_a_val);
|
|
|
|
vcap_action_set(vcap, data, VCAP_ES0_ACT_PCP_A_VAL, a->pcp_a_val);
|
|
|
|
vcap_action_set(vcap, data, VCAP_ES0_ACT_TAG_B_TPID_SEL,
|
|
|
|
a->tag_b_tpid_sel);
|
|
|
|
vcap_action_set(vcap, data, VCAP_ES0_ACT_TAG_B_VID_SEL,
|
|
|
|
a->tag_b_vid_sel);
|
|
|
|
vcap_action_set(vcap, data, VCAP_ES0_ACT_TAG_B_PCP_SEL,
|
|
|
|
a->tag_b_pcp_sel);
|
|
|
|
vcap_action_set(vcap, data, VCAP_ES0_ACT_VID_B_VAL, a->vid_b_val);
|
|
|
|
vcap_action_set(vcap, data, VCAP_ES0_ACT_PCP_B_VAL, a->pcp_b_val);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void es0_entry_set(struct ocelot *ocelot, int ix,
|
|
|
|
struct ocelot_vcap_filter *filter)
|
|
|
|
{
|
|
|
|
const struct vcap_props *vcap = &ocelot->vcap[VCAP_ES0];
|
|
|
|
struct ocelot_vcap_key_vlan *tag = &filter->vlan;
|
|
|
|
struct vcap_data data;
|
|
|
|
int row = ix;
|
|
|
|
|
|
|
|
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_FULL;
|
|
|
|
data.type = ES0_ACTION_TYPE_NORMAL;
|
|
|
|
vcap_data_offset_get(vcap, &data, ix);
|
|
|
|
data.tg = (data.tg & ~data.tg_mask);
|
|
|
|
if (filter->prio != 0)
|
|
|
|
data.tg |= data.tg_value;
|
|
|
|
|
|
|
|
vcap_key_set(vcap, &data, VCAP_ES0_IGR_PORT, filter->ingress_port.value,
|
|
|
|
filter->ingress_port.mask);
|
|
|
|
vcap_key_set(vcap, &data, VCAP_ES0_EGR_PORT, filter->egress_port.value,
|
|
|
|
filter->egress_port.mask);
|
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_ES0_L2_MC, filter->dmac_mc);
|
|
|
|
vcap_key_bit_set(vcap, &data, VCAP_ES0_L2_BC, filter->dmac_bc);
|
|
|
|
vcap_key_set(vcap, &data, VCAP_ES0_VID,
|
|
|
|
tag->vid.value, tag->vid.mask);
|
|
|
|
vcap_key_set(vcap, &data, VCAP_ES0_PCP,
|
|
|
|
tag->pcp.value[0], tag->pcp.mask[0]);
|
|
|
|
|
|
|
|
es0_action_set(ocelot, &data, filter);
|
|
|
|
vcap_data_set(data.counter, data.counter_offset,
|
|
|
|
vcap->counter_width, filter->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);
|
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 20:02:22 +08:00
|
|
|
static void vcap_entry_get(struct ocelot *ocelot, int ix,
|
|
|
|
struct ocelot_vcap_filter *filter)
|
2019-05-31 15:16:56 +08:00
|
|
|
{
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 20:02:22 +08:00
|
|
|
const struct vcap_props *vcap = &ocelot->vcap[filter->block_id];
|
2019-05-31 15:16:56 +08:00
|
|
|
struct vcap_data data;
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
int row, count;
|
2019-05-31 15:16:56 +08:00
|
|
|
u32 cnt;
|
|
|
|
|
2020-10-02 20:02:24 +08:00
|
|
|
if (filter->block_id == VCAP_ES0)
|
|
|
|
data.tg_sw = VCAP_TG_FULL;
|
|
|
|
else
|
|
|
|
data.tg_sw = VCAP_TG_HALF;
|
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
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);
|
2019-05-31 15:16:56 +08:00
|
|
|
cnt = vcap_data_get(data.counter, data.counter_offset,
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
vcap->counter_width);
|
2019-05-31 15:16:56 +08:00
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
filter->stats.pkts = cnt;
|
2019-05-31 15:16:56 +08:00
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 20:02:22 +08:00
|
|
|
static void vcap_entry_set(struct ocelot *ocelot, int ix,
|
|
|
|
struct ocelot_vcap_filter *filter)
|
|
|
|
{
|
net: mscc: ocelot: offload ingress skbedit and vlan actions to VCAP IS1
VCAP IS1 is a VCAP module which can filter on the most common L2/L3/L4
Ethernet keys, and modify the results of the basic QoS classification
and VLAN classification based on those flow keys.
There are 3 VCAP IS1 lookups, mapped over chains 10000, 11000 and 12000.
Currently the driver is hardcoded to use IS1_ACTION_TYPE_NORMAL half
keys.
Note that the VLAN_MANGLE has been omitted for now. In hardware, the
VCAP_IS1_ACT_VID_REPLACE_ENA field replaces the classified VLAN
(metadata associated with the frame) and not the VLAN from the header
itself. There are currently some issues which need to be addressed when
operating in standalone, or in bridge with vlan_filtering=0 modes,
because in those cases the switch ports have VLAN awareness disabled,
and changing the classified VLAN to anything other than the pvid causes
the packets to be dropped. Another issue is that on egress, we expect
port tagging to push the classified VLAN, but port tagging is disabled
in the modes mentioned above, so although the classified VLAN is
replaced, it is not visible in the packet transmitted by the switch.
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 20:02:23 +08:00
|
|
|
if (filter->block_id == VCAP_IS1)
|
|
|
|
return is1_entry_set(ocelot, ix, filter);
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 20:02:22 +08:00
|
|
|
if (filter->block_id == VCAP_IS2)
|
|
|
|
return is2_entry_set(ocelot, ix, filter);
|
2020-10-02 20:02:24 +08:00
|
|
|
if (filter->block_id == VCAP_ES0)
|
|
|
|
return es0_entry_set(ocelot, ix, filter);
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 20:02:22 +08:00
|
|
|
}
|
|
|
|
|
2021-11-18 18:12:02 +08:00
|
|
|
struct vcap_policer_entry {
|
|
|
|
struct list_head list;
|
|
|
|
refcount_t refcount;
|
|
|
|
u32 pol_ix;
|
|
|
|
};
|
|
|
|
|
|
|
|
int ocelot_vcap_policer_add(struct ocelot *ocelot, u32 pol_ix,
|
|
|
|
struct ocelot_policer *pol)
|
2020-06-20 23:43:47 +08:00
|
|
|
{
|
|
|
|
struct qos_policer_conf pp = { 0 };
|
2021-11-18 18:12:02 +08:00
|
|
|
struct vcap_policer_entry *tmp;
|
|
|
|
int ret;
|
2020-06-20 23:43:47 +08:00
|
|
|
|
|
|
|
if (!pol)
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
pp.mode = MSCC_QOS_RATE_MODE_DATA;
|
|
|
|
pp.pir = pol->rate;
|
|
|
|
pp.pbs = pol->burst;
|
|
|
|
|
2021-11-18 18:12:02 +08:00
|
|
|
list_for_each_entry(tmp, &ocelot->vcap_pol.pol_list, list)
|
|
|
|
if (tmp->pol_ix == pol_ix) {
|
|
|
|
refcount_inc(&tmp->refcount);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
|
|
|
|
if (!tmp)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
2022-05-03 20:01:49 +08:00
|
|
|
ret = qos_policer_conf_set(ocelot, pol_ix, &pp);
|
2021-11-18 18:12:02 +08:00
|
|
|
if (ret) {
|
|
|
|
kfree(tmp);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
tmp->pol_ix = pol_ix;
|
|
|
|
refcount_set(&tmp->refcount, 1);
|
|
|
|
list_add_tail(&tmp->list, &ocelot->vcap_pol.pol_list);
|
|
|
|
|
|
|
|
return 0;
|
2020-06-20 23:43:47 +08:00
|
|
|
}
|
2021-11-18 18:12:02 +08:00
|
|
|
EXPORT_SYMBOL(ocelot_vcap_policer_add);
|
2020-06-20 23:43:47 +08:00
|
|
|
|
2021-11-18 18:12:02 +08:00
|
|
|
int ocelot_vcap_policer_del(struct ocelot *ocelot, u32 pol_ix)
|
2020-06-20 23:43:47 +08:00
|
|
|
{
|
|
|
|
struct qos_policer_conf pp = {0};
|
2021-11-18 18:12:02 +08:00
|
|
|
struct vcap_policer_entry *tmp, *n;
|
|
|
|
u8 z = 0;
|
|
|
|
|
|
|
|
list_for_each_entry_safe(tmp, n, &ocelot->vcap_pol.pol_list, list)
|
|
|
|
if (tmp->pol_ix == pol_ix) {
|
|
|
|
z = refcount_dec_and_test(&tmp->refcount);
|
|
|
|
if (z) {
|
|
|
|
list_del(&tmp->list);
|
|
|
|
kfree(tmp);
|
|
|
|
}
|
2020-06-20 23:43:47 +08:00
|
|
|
}
|
|
|
|
|
2021-11-18 18:12:02 +08:00
|
|
|
if (z) {
|
|
|
|
pp.mode = MSCC_QOS_RATE_MODE_DISABLED;
|
2022-05-03 20:01:49 +08:00
|
|
|
return qos_policer_conf_set(ocelot, pol_ix, &pp);
|
2021-11-18 18:12:02 +08:00
|
|
|
}
|
2020-06-20 23:43:47 +08:00
|
|
|
|
2021-11-18 18:12:02 +08:00
|
|
|
return 0;
|
2020-06-20 23:43:47 +08:00
|
|
|
}
|
2021-11-18 18:12:02 +08:00
|
|
|
EXPORT_SYMBOL(ocelot_vcap_policer_del);
|
2020-06-20 23:43:47 +08:00
|
|
|
|
2022-03-17 04:41:41 +08:00
|
|
|
static int
|
|
|
|
ocelot_vcap_filter_add_aux_resources(struct ocelot *ocelot,
|
|
|
|
struct ocelot_vcap_filter *filter,
|
|
|
|
struct netlink_ext_ack *extack)
|
2019-05-31 15:16:56 +08:00
|
|
|
{
|
2022-03-17 04:41:42 +08:00
|
|
|
struct ocelot_mirror *m;
|
2021-11-18 18:12:02 +08:00
|
|
|
int ret;
|
2019-05-31 15:16:56 +08:00
|
|
|
|
2022-03-17 04:41:42 +08:00
|
|
|
if (filter->block_id == VCAP_IS2 && filter->action.mirror_ena) {
|
|
|
|
m = ocelot_mirror_get(ocelot, filter->egress_port.value,
|
|
|
|
extack);
|
|
|
|
if (IS_ERR(m))
|
|
|
|
return PTR_ERR(m);
|
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 20:02:22 +08:00
|
|
|
if (filter->block_id == VCAP_IS2 && filter->action.police_ena) {
|
2021-11-18 18:12:02 +08:00
|
|
|
ret = ocelot_vcap_policer_add(ocelot, filter->action.pol_ix,
|
|
|
|
&filter->action.pol);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
2020-03-29 19:51:57 +08:00
|
|
|
}
|
|
|
|
|
2022-03-17 04:41:41 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
ocelot_vcap_filter_del_aux_resources(struct ocelot *ocelot,
|
|
|
|
struct ocelot_vcap_filter *filter)
|
|
|
|
{
|
|
|
|
if (filter->block_id == VCAP_IS2 && filter->action.police_ena)
|
|
|
|
ocelot_vcap_policer_del(ocelot, filter->action.pol_ix);
|
2022-03-17 04:41:42 +08:00
|
|
|
|
|
|
|
if (filter->block_id == VCAP_IS2 && filter->action.mirror_ena)
|
|
|
|
ocelot_mirror_put(ocelot);
|
2022-03-17 04:41:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static int ocelot_vcap_filter_add_to_block(struct ocelot *ocelot,
|
|
|
|
struct ocelot_vcap_block *block,
|
|
|
|
struct ocelot_vcap_filter *filter,
|
|
|
|
struct netlink_ext_ack *extack)
|
|
|
|
{
|
2022-05-03 20:01:48 +08:00
|
|
|
struct list_head *pos = &block->rules;
|
2022-03-17 04:41:41 +08:00
|
|
|
struct ocelot_vcap_filter *tmp;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = ocelot_vcap_filter_add_aux_resources(ocelot, filter, extack);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
2019-05-31 15:16:56 +08:00
|
|
|
block->count++;
|
|
|
|
|
2022-05-03 20:01:48 +08:00
|
|
|
list_for_each_entry(tmp, &block->rules, list) {
|
|
|
|
if (filter->prio < tmp->prio) {
|
|
|
|
pos = &tmp->list;
|
2019-05-31 15:16:56 +08:00
|
|
|
break;
|
2022-05-03 20:01:48 +08:00
|
|
|
}
|
2019-05-31 15:16:56 +08:00
|
|
|
}
|
2022-05-03 20:01:46 +08:00
|
|
|
list_add_tail(&filter->list, pos);
|
2021-11-18 18:12:02 +08:00
|
|
|
|
|
|
|
return 0;
|
2019-05-31 15:16:56 +08:00
|
|
|
}
|
|
|
|
|
2021-01-29 09:00:01 +08:00
|
|
|
static bool ocelot_vcap_filter_equal(const struct ocelot_vcap_filter *a,
|
|
|
|
const struct ocelot_vcap_filter *b)
|
|
|
|
{
|
|
|
|
return !memcmp(&a->id, &b->id, sizeof(struct ocelot_vcap_id));
|
|
|
|
}
|
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
static int ocelot_vcap_block_get_filter_index(struct ocelot_vcap_block *block,
|
|
|
|
struct ocelot_vcap_filter *filter)
|
2019-05-31 15:16:56 +08:00
|
|
|
{
|
2020-06-20 23:43:46 +08:00
|
|
|
struct ocelot_vcap_filter *tmp;
|
net: mscc: ocelot: return error if VCAP filter is not found
Although it doesn't look like it is possible to hit these conditions
from user space, there are 2 separate, but related, issues.
First, the ocelot_vcap_block_get_filter_index function, née
ocelot_ace_rule_get_index_id prior to the aae4e500e106 ("net: mscc:
ocelot: generalize the "ACE/ACL" names") rename, does not do what the
author probably intended. If the desired filter entry is not present in
the ACL block, this function returns an index equal to the total number
of filters, instead of -1, which is maybe what was intended, judging
from the curious initialization with -1, and the "++index" idioms.
Either way, none of the callers seems to expect this behavior.
Second issue, the callers don't actually check the return value at all.
So in case the filter is not found in the rule list, propagate the
return code.
So update the callers and also take the opportunity to get rid of the
odd coding idioms that appear to work but don't.
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:22 +08:00
|
|
|
int index = 0;
|
2019-05-31 15:16:56 +08:00
|
|
|
|
|
|
|
list_for_each_entry(tmp, &block->rules, list) {
|
2021-01-29 09:00:01 +08:00
|
|
|
if (ocelot_vcap_filter_equal(filter, tmp))
|
net: mscc: ocelot: return error if VCAP filter is not found
Although it doesn't look like it is possible to hit these conditions
from user space, there are 2 separate, but related, issues.
First, the ocelot_vcap_block_get_filter_index function, née
ocelot_ace_rule_get_index_id prior to the aae4e500e106 ("net: mscc:
ocelot: generalize the "ACE/ACL" names") rename, does not do what the
author probably intended. If the desired filter entry is not present in
the ACL block, this function returns an index equal to the total number
of filters, instead of -1, which is maybe what was intended, judging
from the curious initialization with -1, and the "++index" idioms.
Either way, none of the callers seems to expect this behavior.
Second issue, the callers don't actually check the return value at all.
So in case the filter is not found in the rule list, propagate the
return code.
So update the callers and also take the opportunity to get rid of the
odd coding idioms that appear to work but don't.
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:22 +08:00
|
|
|
return index;
|
|
|
|
index++;
|
2019-05-31 15:16:56 +08:00
|
|
|
}
|
net: mscc: ocelot: return error if VCAP filter is not found
Although it doesn't look like it is possible to hit these conditions
from user space, there are 2 separate, but related, issues.
First, the ocelot_vcap_block_get_filter_index function, née
ocelot_ace_rule_get_index_id prior to the aae4e500e106 ("net: mscc:
ocelot: generalize the "ACE/ACL" names") rename, does not do what the
author probably intended. If the desired filter entry is not present in
the ACL block, this function returns an index equal to the total number
of filters, instead of -1, which is maybe what was intended, judging
from the curious initialization with -1, and the "++index" idioms.
Either way, none of the callers seems to expect this behavior.
Second issue, the callers don't actually check the return value at all.
So in case the filter is not found in the rule list, propagate the
return code.
So update the callers and also take the opportunity to get rid of the
odd coding idioms that appear to work but don't.
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:22 +08:00
|
|
|
|
|
|
|
return -ENOENT;
|
2019-05-31 15:16:56 +08:00
|
|
|
}
|
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
static struct ocelot_vcap_filter*
|
2020-09-30 06:27:32 +08:00
|
|
|
ocelot_vcap_block_find_filter_by_index(struct ocelot_vcap_block *block,
|
|
|
|
int index)
|
2019-05-31 15:16:56 +08:00
|
|
|
{
|
2020-06-20 23:43:46 +08:00
|
|
|
struct ocelot_vcap_filter *tmp;
|
2019-05-31 15:16:56 +08:00
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
list_for_each_entry(tmp, &block->rules, list) {
|
|
|
|
if (i == index)
|
|
|
|
return tmp;
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2020-09-30 06:27:32 +08:00
|
|
|
struct ocelot_vcap_filter *
|
2021-09-30 20:53:30 +08:00
|
|
|
ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block,
|
|
|
|
unsigned long cookie, bool tc_offload)
|
2020-09-30 06:27:32 +08:00
|
|
|
{
|
|
|
|
struct ocelot_vcap_filter *filter;
|
|
|
|
|
|
|
|
list_for_each_entry(filter, &block->rules, list)
|
2021-01-29 09:00:01 +08:00
|
|
|
if (filter->id.tc_offload == tc_offload &&
|
|
|
|
filter->id.cookie == cookie)
|
2020-09-30 06:27:32 +08:00
|
|
|
return filter;
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
net: dsa: felix: perform switch setup for tag_8021q
Unlike sja1105, the only other user of the software-defined tag_8021q.c
tagger format, the implementation we choose for the Felix DSA switch
driver preserves full functionality under a vlan_filtering bridge
(i.e. IP termination works through the DSA user ports under all
circumstances).
The tag_8021q protocol just wants:
- Identifying the ingress switch port based on the RX VLAN ID, as seen
by the CPU. We achieve this by using the TCAM engines (which are also
used for tc-flower offload) to push the RX VLAN as a second, outer
tag, on egress towards the CPU port.
- Steering traffic injected into the switch from the network stack
towards the correct front port based on the TX VLAN, and consuming
(popping) that header on the switch's egress.
A tc-flower pseudocode of the static configuration done by the driver
would look like this:
$ tc qdisc add dev <cpu-port> clsact
$ for eth in swp0 swp1 swp2 swp3; do \
tc filter add dev <cpu-port> egress flower indev ${eth} \
action vlan push id <rxvlan> protocol 802.1ad; \
tc filter add dev <cpu-port> ingress protocol 802.1Q flower
vlan_id <txvlan> action vlan pop \
action mirred egress redirect dev ${eth}; \
done
but of course since DSA does not register network interfaces for the CPU
port, this configuration would be impossible for the user to do. Also,
due to the same reason, it is impossible for the user to inadvertently
delete these rules using tc. These rules do not collide in any way with
tc-flower, they just consume some TCAM space, which is something we can
live with.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2021-01-29 09:00:09 +08:00
|
|
|
EXPORT_SYMBOL(ocelot_vcap_block_find_filter_by_id);
|
2020-09-30 06:27:32 +08:00
|
|
|
|
2020-04-18 03:03:08 +08:00
|
|
|
/* If @on=false, then SNAP, ARP, IP and OAM frames will not match on keys based
|
|
|
|
* on destination and source MAC addresses, but only on higher-level protocol
|
|
|
|
* information. The only frame types to match on keys containing MAC addresses
|
|
|
|
* in this case are non-SNAP, non-ARP, non-IP and non-OAM frames.
|
|
|
|
*
|
|
|
|
* If @on=true, then the above frame types (SNAP, ARP, IP and OAM) will match
|
|
|
|
* on MAC_ETYPE keys such as destination and source MAC on this ingress port.
|
|
|
|
* However the setting has the side effect of making these frames not matching
|
|
|
|
* on any _other_ keys than MAC_ETYPE ones.
|
|
|
|
*/
|
|
|
|
static void ocelot_match_all_as_mac_etype(struct ocelot *ocelot, int port,
|
2020-10-02 20:02:26 +08:00
|
|
|
int lookup, bool on)
|
2020-04-18 03:03:08 +08:00
|
|
|
{
|
|
|
|
u32 val = 0;
|
|
|
|
|
|
|
|
if (on)
|
2020-10-02 20:02:26 +08:00
|
|
|
val = ANA_PORT_VCAP_S2_CFG_S2_SNAP_DIS(BIT(lookup)) |
|
|
|
|
ANA_PORT_VCAP_S2_CFG_S2_ARP_DIS(BIT(lookup)) |
|
|
|
|
ANA_PORT_VCAP_S2_CFG_S2_IP_TCPUDP_DIS(BIT(lookup)) |
|
|
|
|
ANA_PORT_VCAP_S2_CFG_S2_IP_OTHER_DIS(BIT(lookup)) |
|
|
|
|
ANA_PORT_VCAP_S2_CFG_S2_OAM_DIS(BIT(lookup));
|
2020-04-18 03:03:08 +08:00
|
|
|
|
|
|
|
ocelot_rmw_gix(ocelot, val,
|
2020-10-02 20:02:26 +08:00
|
|
|
ANA_PORT_VCAP_S2_CFG_S2_SNAP_DIS(BIT(lookup)) |
|
|
|
|
ANA_PORT_VCAP_S2_CFG_S2_ARP_DIS(BIT(lookup)) |
|
|
|
|
ANA_PORT_VCAP_S2_CFG_S2_IP_TCPUDP_DIS(BIT(lookup)) |
|
|
|
|
ANA_PORT_VCAP_S2_CFG_S2_IP_OTHER_DIS(BIT(lookup)) |
|
|
|
|
ANA_PORT_VCAP_S2_CFG_S2_OAM_DIS(BIT(lookup)),
|
2020-04-18 03:03:08 +08:00
|
|
|
ANA_PORT_VCAP_S2_CFG, port);
|
|
|
|
}
|
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
static bool
|
|
|
|
ocelot_vcap_is_problematic_mac_etype(struct ocelot_vcap_filter *filter)
|
2020-04-18 03:03:08 +08:00
|
|
|
{
|
2020-04-21 00:27:42 +08:00
|
|
|
u16 proto, mask;
|
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
if (filter->key_type != OCELOT_VCAP_KEY_ETYPE)
|
2020-04-18 03:03:08 +08:00
|
|
|
return false;
|
2020-04-21 00:27:42 +08:00
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
proto = ntohs(*(__be16 *)filter->key.etype.etype.value);
|
|
|
|
mask = ntohs(*(__be16 *)filter->key.etype.etype.mask);
|
2020-04-21 00:27:42 +08:00
|
|
|
|
|
|
|
/* ETH_P_ALL match, so all protocols below are included */
|
|
|
|
if (mask == 0)
|
2020-04-18 03:03:08 +08:00
|
|
|
return true;
|
2020-04-21 00:27:42 +08:00
|
|
|
if (proto == ETH_P_ARP)
|
2020-04-18 03:03:08 +08:00
|
|
|
return true;
|
2020-04-21 00:27:42 +08:00
|
|
|
if (proto == ETH_P_IP)
|
|
|
|
return true;
|
|
|
|
if (proto == ETH_P_IPV6)
|
|
|
|
return true;
|
|
|
|
|
2020-04-18 03:03:08 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
static bool
|
|
|
|
ocelot_vcap_is_problematic_non_mac_etype(struct ocelot_vcap_filter *filter)
|
2020-04-18 03:03:08 +08:00
|
|
|
{
|
2020-06-20 23:43:46 +08:00
|
|
|
if (filter->key_type == OCELOT_VCAP_KEY_SNAP)
|
2020-04-18 03:03:08 +08:00
|
|
|
return true;
|
2020-06-20 23:43:46 +08:00
|
|
|
if (filter->key_type == OCELOT_VCAP_KEY_ARP)
|
2020-04-18 03:03:08 +08:00
|
|
|
return true;
|
2020-06-20 23:43:46 +08:00
|
|
|
if (filter->key_type == OCELOT_VCAP_KEY_IPV4)
|
2020-04-18 03:03:08 +08:00
|
|
|
return true;
|
2020-06-20 23:43:46 +08:00
|
|
|
if (filter->key_type == OCELOT_VCAP_KEY_IPV6)
|
2020-04-18 03:03:08 +08:00
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
static bool
|
|
|
|
ocelot_exclusive_mac_etype_filter_rules(struct ocelot *ocelot,
|
|
|
|
struct ocelot_vcap_filter *filter)
|
2020-04-18 03:03:08 +08:00
|
|
|
{
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 20:02:22 +08:00
|
|
|
struct ocelot_vcap_block *block = &ocelot->block[filter->block_id];
|
2020-06-20 23:43:46 +08:00
|
|
|
struct ocelot_vcap_filter *tmp;
|
2020-04-18 03:03:08 +08:00
|
|
|
unsigned long port;
|
|
|
|
int i;
|
|
|
|
|
2020-10-02 20:02:26 +08:00
|
|
|
/* We only have the S2_IP_TCPUDP_DIS set of knobs for VCAP IS2 */
|
|
|
|
if (filter->block_id != VCAP_IS2)
|
|
|
|
return true;
|
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
if (ocelot_vcap_is_problematic_mac_etype(filter)) {
|
2020-04-18 03:03:08 +08:00
|
|
|
/* Search for any non-MAC_ETYPE rules on the port */
|
|
|
|
for (i = 0; i < block->count; i++) {
|
2020-09-30 06:27:32 +08:00
|
|
|
tmp = ocelot_vcap_block_find_filter_by_index(block, i);
|
2020-06-20 23:43:46 +08:00
|
|
|
if (tmp->ingress_port_mask & filter->ingress_port_mask &&
|
2020-10-02 20:02:26 +08:00
|
|
|
tmp->lookup == filter->lookup &&
|
2020-06-20 23:43:46 +08:00
|
|
|
ocelot_vcap_is_problematic_non_mac_etype(tmp))
|
2020-04-18 03:03:08 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
for_each_set_bit(port, &filter->ingress_port_mask,
|
2020-04-18 03:03:08 +08:00
|
|
|
ocelot->num_phys_ports)
|
2020-10-02 20:02:26 +08:00
|
|
|
ocelot_match_all_as_mac_etype(ocelot, port,
|
|
|
|
filter->lookup, true);
|
2020-06-20 23:43:46 +08:00
|
|
|
} else if (ocelot_vcap_is_problematic_non_mac_etype(filter)) {
|
2020-04-18 03:03:08 +08:00
|
|
|
/* Search for any MAC_ETYPE rules on the port */
|
|
|
|
for (i = 0; i < block->count; i++) {
|
2020-09-30 06:27:32 +08:00
|
|
|
tmp = ocelot_vcap_block_find_filter_by_index(block, i);
|
2020-06-20 23:43:46 +08:00
|
|
|
if (tmp->ingress_port_mask & filter->ingress_port_mask &&
|
2020-10-02 20:02:26 +08:00
|
|
|
tmp->lookup == filter->lookup &&
|
2020-06-20 23:43:46 +08:00
|
|
|
ocelot_vcap_is_problematic_mac_etype(tmp))
|
2020-04-18 03:03:08 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
for_each_set_bit(port, &filter->ingress_port_mask,
|
2020-04-18 03:03:08 +08:00
|
|
|
ocelot->num_phys_ports)
|
2020-10-02 20:02:26 +08:00
|
|
|
ocelot_match_all_as_mac_etype(ocelot, port,
|
|
|
|
filter->lookup, false);
|
2020-04-18 03:03:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
int ocelot_vcap_filter_add(struct ocelot *ocelot,
|
|
|
|
struct ocelot_vcap_filter *filter,
|
|
|
|
struct netlink_ext_ack *extack)
|
2019-05-31 15:16:56 +08:00
|
|
|
{
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 20:02:22 +08:00
|
|
|
struct ocelot_vcap_block *block = &ocelot->block[filter->block_id];
|
2021-11-18 18:12:02 +08:00
|
|
|
int i, index, ret;
|
2019-05-31 15:16:56 +08:00
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
if (!ocelot_exclusive_mac_etype_filter_rules(ocelot, filter)) {
|
2020-04-18 03:03:08 +08:00
|
|
|
NL_SET_ERR_MSG_MOD(extack,
|
2020-10-02 20:02:26 +08:00
|
|
|
"Cannot mix MAC_ETYPE with non-MAC_ETYPE rules, use the other IS2 lookup");
|
2020-04-18 03:03:08 +08:00
|
|
|
return -EBUSY;
|
|
|
|
}
|
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
/* Add filter to the linked list */
|
2022-03-17 04:41:41 +08:00
|
|
|
ret = ocelot_vcap_filter_add_to_block(ocelot, block, filter, extack);
|
2021-11-18 18:12:02 +08:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
2019-05-31 15:16:56 +08:00
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
/* Get the index of the inserted filter */
|
|
|
|
index = ocelot_vcap_block_get_filter_index(block, filter);
|
net: mscc: ocelot: return error if VCAP filter is not found
Although it doesn't look like it is possible to hit these conditions
from user space, there are 2 separate, but related, issues.
First, the ocelot_vcap_block_get_filter_index function, née
ocelot_ace_rule_get_index_id prior to the aae4e500e106 ("net: mscc:
ocelot: generalize the "ACE/ACL" names") rename, does not do what the
author probably intended. If the desired filter entry is not present in
the ACL block, this function returns an index equal to the total number
of filters, instead of -1, which is maybe what was intended, judging
from the curious initialization with -1, and the "++index" idioms.
Either way, none of the callers seems to expect this behavior.
Second issue, the callers don't actually check the return value at all.
So in case the filter is not found in the rule list, propagate the
return code.
So update the callers and also take the opportunity to get rid of the
odd coding idioms that appear to work but don't.
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:22 +08:00
|
|
|
if (index < 0)
|
|
|
|
return index;
|
2019-05-31 15:16:56 +08:00
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
/* Move down the rules to make place for the new filter */
|
net: mscc: ocelot: simplify tc-flower offload structures
The ocelot tc-flower offload binds a second flow block callback (apart
from the one for matchall) just because it uses a different block
private structure (ocelot_port_private for matchall, ocelot_port_block
for flower).
But ocelot_port_block just appears to be boilerplate, and doesn't help
with anything in particular at all, it's just useless glue between the
(global!) struct ocelot_acl_block *block pointer, and a per-netdevice
struct ocelot_port_private *priv.
So let's just simplify that, and make struct ocelot_port_private be the
private structure for the block offload. This makes us able to use the
same flow callback as in the case of matchall.
This also reveals that the struct ocelot_acl_block *block is used rather
strangely, as mentioned above: it is defined globally, allocated at
probe time, and freed at unbind time. So just move the structure to the
main ocelot structure, which gives further opportunity for
simplification.
Also get rid of backpointers from struct ocelot_acl_block and struct
ocelot_ace_rule back to struct ocelot, by reworking the function
prototypes, where necessary, to use a more DSA-friendly "struct ocelot
*ocelot, int port" format.
And finally, remove the debugging prints that were added during
development, since they provide no useful information at this point.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Reviewed-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-02-29 22:31:06 +08:00
|
|
|
for (i = block->count - 1; i > index; i--) {
|
2020-06-20 23:43:46 +08:00
|
|
|
struct ocelot_vcap_filter *tmp;
|
|
|
|
|
2020-09-30 06:27:32 +08:00
|
|
|
tmp = ocelot_vcap_block_find_filter_by_index(block, i);
|
net: mscc: ocelot: avoid corrupting hardware counters when moving VCAP filters
Given the following order of operations:
(1) we add filter A using tc-flower
(2) we send a packet that matches it
(3) we read the filter's statistics to find a hit count of 1
(4) we add a second filter B with a higher preference than A, and A
moves one position to the right to make room in the TCAM for it
(5) we send another packet, and this matches the second filter B
(6) we read the filter statistics again.
When this happens, the hit count of filter A is 2 and of filter B is 1,
despite a single packet having matched each filter.
Furthermore, in an alternate history, reading the filter stats a second
time between steps (3) and (4) makes the hit count of filter A remain at
1 after step (6), as expected.
The reason why this happens has to do with the filter->stats.pkts field,
which is written to hardware through the call path below:
vcap_entry_set
/ | \
/ | \
/ | \
/ | \
es0_entry_set is1_entry_set is2_entry_set
\ | /
\ | /
\ | /
vcap_data_set(data.counter, ...)
The primary role of filter->stats.pkts is to transport the filter hit
counters from the last readout all the way from vcap_entry_get() ->
ocelot_vcap_filter_stats_update() -> ocelot_cls_flower_stats().
The reason why vcap_entry_set() writes it to hardware is so that the
counters (saturating and having a limited bit width) are cleared
after each user space readout.
The writing of filter->stats.pkts to hardware during the TCAM entry
movement procedure is an unintentional consequence of the code design,
because the hit count isn't up to date at this point.
So at step (4), when filter A is moved by ocelot_vcap_filter_add() to
make room for filter B, the hardware hit count is 0 (no packet matched
on it in the meantime), but filter->stats.pkts is 1, because the last
readout saw the earlier packet. The movement procedure programs the old
hit count back to hardware, so this creates the impression to user space
that more packets have been matched than they really were.
The bug can be seen when running the gact_drop_and_ok_test() from the
tc_actions.sh selftest.
Fix the issue by reading back the hit count to tmp->stats.pkts before
migrating the VCAP filter. Sure, this is a best-effort technique, since
the packets that hit the rule between vcap_entry_get() and
vcap_entry_set() won't be counted, but at least it allows the counters
to be reliably used for selftests where the traffic is under control.
The vcap_entry_get() name is a bit unintuitive, but it only reads back
the counter portion of the TCAM entry, not the entire entry.
The index from which we retrieve the counter is also a bit unintuitive
(i - 1 during add, i + 1 during del), but this is the way in which TCAM
entry movement works. The "entry index" isn't a stored integer for a
TCAM filter, instead it is dynamically computed by
ocelot_vcap_block_get_filter_index() based on the entry's position in
the &block->rules list. That position (as well as block->count) is
automatically updated by ocelot_vcap_filter_add_to_block() on add, and
by ocelot_vcap_block_remove_filter() on del. So "i" is the new filter
index, and "i - 1" or "i + 1" respectively are the old addresses of that
TCAM entry (we only support installing/deleting one filter at a time).
Fixes: b596229448dd ("net: mscc: ocelot: Add support for tcam")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-05-05 07:55:03 +08:00
|
|
|
/* Read back the filter's counters before moving it */
|
|
|
|
vcap_entry_get(ocelot, i - 1, tmp);
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 20:02:22 +08:00
|
|
|
vcap_entry_set(ocelot, i, tmp);
|
2019-05-31 15:16:56 +08:00
|
|
|
}
|
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
/* Now insert the new filter */
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 20:02:22 +08:00
|
|
|
vcap_entry_set(ocelot, index, filter);
|
2019-05-31 15:16:56 +08:00
|
|
|
return 0;
|
|
|
|
}
|
2021-01-29 09:00:00 +08:00
|
|
|
EXPORT_SYMBOL(ocelot_vcap_filter_add);
|
2019-05-31 15:16:56 +08:00
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
static void ocelot_vcap_block_remove_filter(struct ocelot *ocelot,
|
|
|
|
struct ocelot_vcap_block *block,
|
|
|
|
struct ocelot_vcap_filter *filter)
|
2019-05-31 15:16:56 +08:00
|
|
|
{
|
2022-03-03 22:01:20 +08:00
|
|
|
struct ocelot_vcap_filter *tmp, *n;
|
2019-05-31 15:16:56 +08:00
|
|
|
|
2022-03-03 22:01:20 +08:00
|
|
|
list_for_each_entry_safe(tmp, n, &block->rules, list) {
|
2021-01-29 09:00:01 +08:00
|
|
|
if (ocelot_vcap_filter_equal(filter, tmp)) {
|
2022-03-17 04:41:41 +08:00
|
|
|
ocelot_vcap_filter_del_aux_resources(ocelot, tmp);
|
2022-03-03 22:01:20 +08:00
|
|
|
list_del(&tmp->list);
|
2019-05-31 15:16:56 +08:00
|
|
|
kfree(tmp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
block->count--;
|
|
|
|
}
|
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
int ocelot_vcap_filter_del(struct ocelot *ocelot,
|
|
|
|
struct ocelot_vcap_filter *filter)
|
2019-05-31 15:16:56 +08:00
|
|
|
{
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 20:02:22 +08:00
|
|
|
struct ocelot_vcap_block *block = &ocelot->block[filter->block_id];
|
2020-06-20 23:43:46 +08:00
|
|
|
struct ocelot_vcap_filter del_filter;
|
2019-05-31 15:16:56 +08:00
|
|
|
int i, index;
|
|
|
|
|
2022-05-05 07:55:00 +08:00
|
|
|
/* Need to inherit the block_id so that vcap_entry_set()
|
|
|
|
* does not get confused and knows where to install it.
|
|
|
|
*/
|
2020-06-20 23:43:46 +08:00
|
|
|
memset(&del_filter, 0, sizeof(del_filter));
|
2022-05-05 07:55:00 +08:00
|
|
|
del_filter.block_id = filter->block_id;
|
2019-06-04 04:49:53 +08:00
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
/* Gets index of the filter */
|
|
|
|
index = ocelot_vcap_block_get_filter_index(block, filter);
|
net: mscc: ocelot: return error if VCAP filter is not found
Although it doesn't look like it is possible to hit these conditions
from user space, there are 2 separate, but related, issues.
First, the ocelot_vcap_block_get_filter_index function, née
ocelot_ace_rule_get_index_id prior to the aae4e500e106 ("net: mscc:
ocelot: generalize the "ACE/ACL" names") rename, does not do what the
author probably intended. If the desired filter entry is not present in
the ACL block, this function returns an index equal to the total number
of filters, instead of -1, which is maybe what was intended, judging
from the curious initialization with -1, and the "++index" idioms.
Either way, none of the callers seems to expect this behavior.
Second issue, the callers don't actually check the return value at all.
So in case the filter is not found in the rule list, propagate the
return code.
So update the callers and also take the opportunity to get rid of the
odd coding idioms that appear to work but don't.
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:22 +08:00
|
|
|
if (index < 0)
|
|
|
|
return index;
|
2019-05-31 15:16:56 +08:00
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
/* Delete filter */
|
|
|
|
ocelot_vcap_block_remove_filter(ocelot, block, filter);
|
2019-05-31 15:16:56 +08:00
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
/* Move up all the blocks over the deleted filter */
|
net: mscc: ocelot: simplify tc-flower offload structures
The ocelot tc-flower offload binds a second flow block callback (apart
from the one for matchall) just because it uses a different block
private structure (ocelot_port_private for matchall, ocelot_port_block
for flower).
But ocelot_port_block just appears to be boilerplate, and doesn't help
with anything in particular at all, it's just useless glue between the
(global!) struct ocelot_acl_block *block pointer, and a per-netdevice
struct ocelot_port_private *priv.
So let's just simplify that, and make struct ocelot_port_private be the
private structure for the block offload. This makes us able to use the
same flow callback as in the case of matchall.
This also reveals that the struct ocelot_acl_block *block is used rather
strangely, as mentioned above: it is defined globally, allocated at
probe time, and freed at unbind time. So just move the structure to the
main ocelot structure, which gives further opportunity for
simplification.
Also get rid of backpointers from struct ocelot_acl_block and struct
ocelot_ace_rule back to struct ocelot, by reworking the function
prototypes, where necessary, to use a more DSA-friendly "struct ocelot
*ocelot, int port" format.
And finally, remove the debugging prints that were added during
development, since they provide no useful information at this point.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Tested-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Reviewed-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-02-29 22:31:06 +08:00
|
|
|
for (i = index; i < block->count; i++) {
|
2020-06-20 23:43:46 +08:00
|
|
|
struct ocelot_vcap_filter *tmp;
|
|
|
|
|
2020-09-30 06:27:32 +08:00
|
|
|
tmp = ocelot_vcap_block_find_filter_by_index(block, i);
|
net: mscc: ocelot: avoid corrupting hardware counters when moving VCAP filters
Given the following order of operations:
(1) we add filter A using tc-flower
(2) we send a packet that matches it
(3) we read the filter's statistics to find a hit count of 1
(4) we add a second filter B with a higher preference than A, and A
moves one position to the right to make room in the TCAM for it
(5) we send another packet, and this matches the second filter B
(6) we read the filter statistics again.
When this happens, the hit count of filter A is 2 and of filter B is 1,
despite a single packet having matched each filter.
Furthermore, in an alternate history, reading the filter stats a second
time between steps (3) and (4) makes the hit count of filter A remain at
1 after step (6), as expected.
The reason why this happens has to do with the filter->stats.pkts field,
which is written to hardware through the call path below:
vcap_entry_set
/ | \
/ | \
/ | \
/ | \
es0_entry_set is1_entry_set is2_entry_set
\ | /
\ | /
\ | /
vcap_data_set(data.counter, ...)
The primary role of filter->stats.pkts is to transport the filter hit
counters from the last readout all the way from vcap_entry_get() ->
ocelot_vcap_filter_stats_update() -> ocelot_cls_flower_stats().
The reason why vcap_entry_set() writes it to hardware is so that the
counters (saturating and having a limited bit width) are cleared
after each user space readout.
The writing of filter->stats.pkts to hardware during the TCAM entry
movement procedure is an unintentional consequence of the code design,
because the hit count isn't up to date at this point.
So at step (4), when filter A is moved by ocelot_vcap_filter_add() to
make room for filter B, the hardware hit count is 0 (no packet matched
on it in the meantime), but filter->stats.pkts is 1, because the last
readout saw the earlier packet. The movement procedure programs the old
hit count back to hardware, so this creates the impression to user space
that more packets have been matched than they really were.
The bug can be seen when running the gact_drop_and_ok_test() from the
tc_actions.sh selftest.
Fix the issue by reading back the hit count to tmp->stats.pkts before
migrating the VCAP filter. Sure, this is a best-effort technique, since
the packets that hit the rule between vcap_entry_get() and
vcap_entry_set() won't be counted, but at least it allows the counters
to be reliably used for selftests where the traffic is under control.
The vcap_entry_get() name is a bit unintuitive, but it only reads back
the counter portion of the TCAM entry, not the entire entry.
The index from which we retrieve the counter is also a bit unintuitive
(i - 1 during add, i + 1 during del), but this is the way in which TCAM
entry movement works. The "entry index" isn't a stored integer for a
TCAM filter, instead it is dynamically computed by
ocelot_vcap_block_get_filter_index() based on the entry's position in
the &block->rules list. That position (as well as block->count) is
automatically updated by ocelot_vcap_filter_add_to_block() on add, and
by ocelot_vcap_block_remove_filter() on del. So "i" is the new filter
index, and "i - 1" or "i + 1" respectively are the old addresses of that
TCAM entry (we only support installing/deleting one filter at a time).
Fixes: b596229448dd ("net: mscc: ocelot: Add support for tcam")
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2022-05-05 07:55:03 +08:00
|
|
|
/* Read back the filter's counters before moving it */
|
|
|
|
vcap_entry_get(ocelot, i + 1, tmp);
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 20:02:22 +08:00
|
|
|
vcap_entry_set(ocelot, i, tmp);
|
2019-05-31 15:16:56 +08:00
|
|
|
}
|
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
/* Now delete the last filter, because it is duplicated */
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 20:02:22 +08:00
|
|
|
vcap_entry_set(ocelot, block->count, &del_filter);
|
2019-05-31 15:16:56 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2021-01-29 09:00:00 +08:00
|
|
|
EXPORT_SYMBOL(ocelot_vcap_filter_del);
|
2019-05-31 15:16:56 +08:00
|
|
|
|
net: mscc: ocelot: create a function that replaces an existing VCAP filter
VCAP (Versatile Content Aware Processor) is the TCAM-based engine behind
tc flower offload on ocelot, among other things. The ingress port mask
on which VCAP rules match is present as a bit field in the actual key of
the rule. This means that it is possible for a rule to be shared among
multiple source ports. When the rule is added one by one on each desired
port, that the ingress port mask of the key must be edited and rewritten
to hardware.
But the API in ocelot_vcap.c does not allow for this. For one thing,
ocelot_vcap_filter_add() and ocelot_vcap_filter_del() are not symmetric,
because ocelot_vcap_filter_add() works with a preallocated and
prepopulated filter and programs it to hardware, and
ocelot_vcap_filter_del() does both the job of removing the specified
filter from hardware, as well as kfreeing it. That is to say, the only
option of editing a filter in place, which is to delete it, modify the
structure and add it back, does not work because it results in
use-after-free.
This patch introduces ocelot_vcap_filter_replace, which trivially
reprograms a VCAP entry to hardware, at the exact same index at which it
existed before, without modifying any list or allocating any memory.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Acked-by: Richard Cochran <richardcochran@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2021-11-27 01:28:42 +08:00
|
|
|
int ocelot_vcap_filter_replace(struct ocelot *ocelot,
|
|
|
|
struct ocelot_vcap_filter *filter)
|
|
|
|
{
|
|
|
|
struct ocelot_vcap_block *block = &ocelot->block[filter->block_id];
|
|
|
|
int index;
|
|
|
|
|
|
|
|
index = ocelot_vcap_block_get_filter_index(block, filter);
|
|
|
|
if (index < 0)
|
|
|
|
return index;
|
|
|
|
|
|
|
|
vcap_entry_set(ocelot, index, filter);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(ocelot_vcap_filter_replace);
|
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
int ocelot_vcap_filter_stats_update(struct ocelot *ocelot,
|
|
|
|
struct ocelot_vcap_filter *filter)
|
2019-05-31 15:16:56 +08:00
|
|
|
{
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 20:02:22 +08:00
|
|
|
struct ocelot_vcap_block *block = &ocelot->block[filter->block_id];
|
2020-09-30 06:27:33 +08:00
|
|
|
struct ocelot_vcap_filter tmp;
|
2019-05-31 15:16:56 +08:00
|
|
|
int index;
|
|
|
|
|
2020-06-20 23:43:46 +08:00
|
|
|
index = ocelot_vcap_block_get_filter_index(block, filter);
|
net: mscc: ocelot: return error if VCAP filter is not found
Although it doesn't look like it is possible to hit these conditions
from user space, there are 2 separate, but related, issues.
First, the ocelot_vcap_block_get_filter_index function, née
ocelot_ace_rule_get_index_id prior to the aae4e500e106 ("net: mscc:
ocelot: generalize the "ACE/ACL" names") rename, does not do what the
author probably intended. If the desired filter entry is not present in
the ACL block, this function returns an index equal to the total number
of filters, instead of -1, which is maybe what was intended, judging
from the curious initialization with -1, and the "++index" idioms.
Either way, none of the callers seems to expect this behavior.
Second issue, the callers don't actually check the return value at all.
So in case the filter is not found in the rule list, propagate the
return code.
So update the callers and also take the opportunity to get rid of the
odd coding idioms that appear to work but don't.
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:22 +08:00
|
|
|
if (index < 0)
|
|
|
|
return index;
|
|
|
|
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 20:02:22 +08:00
|
|
|
vcap_entry_get(ocelot, index, filter);
|
2019-05-31 15:16:56 +08:00
|
|
|
|
|
|
|
/* After we get the result we need to clear the counters */
|
2020-09-30 06:27:33 +08:00
|
|
|
tmp = *filter;
|
|
|
|
tmp.stats.pkts = 0;
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 20:02:22 +08:00
|
|
|
vcap_entry_set(ocelot, index, &tmp);
|
2019-05-31 15:16:56 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
static void ocelot_vcap_init_one(struct ocelot *ocelot,
|
|
|
|
const struct vcap_props *vcap)
|
2019-05-31 15:16:56 +08:00
|
|
|
{
|
2019-06-04 04:49:53 +08:00
|
|
|
struct vcap_data data;
|
2019-05-31 15:16:56 +08:00
|
|
|
|
2019-06-04 04:49:53 +08:00
|
|
|
memset(&data, 0, sizeof(data));
|
2020-02-29 22:31:10 +08:00
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
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);
|
2019-05-31 15:16:56 +08:00
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
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,
|
2019-05-31 15:16:56 +08:00
|
|
|
VCAP_SEL_ACTION | VCAP_SEL_COUNTER);
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
}
|
|
|
|
|
2020-09-30 06:27:26 +08:00
|
|
|
static void ocelot_vcap_detect_constants(struct ocelot *ocelot,
|
|
|
|
struct vcap_props *vcap)
|
|
|
|
{
|
|
|
|
int counter_memory_width;
|
|
|
|
int num_default_actions;
|
|
|
|
int version;
|
|
|
|
|
|
|
|
version = ocelot_target_read(ocelot, vcap->target,
|
|
|
|
VCAP_CONST_VCAP_VER);
|
|
|
|
/* Only version 0 VCAP supported for now */
|
|
|
|
if (WARN_ON(version != 0))
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Width in bits of type-group field */
|
|
|
|
vcap->tg_width = ocelot_target_read(ocelot, vcap->target,
|
|
|
|
VCAP_CONST_ENTRY_TG_WIDTH);
|
|
|
|
/* Number of subwords per TCAM row */
|
|
|
|
vcap->sw_count = ocelot_target_read(ocelot, vcap->target,
|
|
|
|
VCAP_CONST_ENTRY_SWCNT);
|
|
|
|
/* Number of rows in TCAM. There can be this many full keys, or double
|
|
|
|
* this number half keys, or 4 times this number quarter keys.
|
|
|
|
*/
|
|
|
|
vcap->entry_count = ocelot_target_read(ocelot, vcap->target,
|
|
|
|
VCAP_CONST_ENTRY_CNT);
|
|
|
|
/* Assuming there are 4 subwords per TCAM row, their layout in the
|
|
|
|
* actual TCAM (not in the cache) would be:
|
|
|
|
*
|
|
|
|
* | SW 3 | TG 3 | SW 2 | TG 2 | SW 1 | TG 1 | SW 0 | TG 0 |
|
|
|
|
*
|
|
|
|
* (where SW=subword and TG=Type-Group).
|
|
|
|
*
|
|
|
|
* What VCAP_CONST_ENTRY_CNT is giving us is the width of one full TCAM
|
|
|
|
* row. But when software accesses the TCAM through the cache
|
|
|
|
* registers, the Type-Group values are written through another set of
|
|
|
|
* registers VCAP_TG_DAT, and therefore, it appears as though the 4
|
|
|
|
* subwords are contiguous in the cache memory.
|
|
|
|
* Important mention: regardless of the number of key entries per row
|
|
|
|
* (and therefore of key size: 1 full key or 2 half keys or 4 quarter
|
|
|
|
* keys), software always has to configure 4 Type-Group values. For
|
|
|
|
* example, in the case of 1 full key, the driver needs to set all 4
|
|
|
|
* Type-Group to be full key.
|
|
|
|
*
|
|
|
|
* For this reason, we need to fix up the value that the hardware is
|
|
|
|
* giving us. We don't actually care about the width of the entry in
|
|
|
|
* the TCAM. What we care about is the width of the entry in the cache
|
|
|
|
* registers, which is how we get to interact with it. And since the
|
|
|
|
* VCAP_ENTRY_DAT cache registers access only the subwords and not the
|
|
|
|
* Type-Groups, this means we need to subtract the width of the
|
|
|
|
* Type-Groups when packing and unpacking key entry data in a TCAM row.
|
|
|
|
*/
|
|
|
|
vcap->entry_width = ocelot_target_read(ocelot, vcap->target,
|
|
|
|
VCAP_CONST_ENTRY_WIDTH);
|
|
|
|
vcap->entry_width -= vcap->tg_width * vcap->sw_count;
|
|
|
|
num_default_actions = ocelot_target_read(ocelot, vcap->target,
|
|
|
|
VCAP_CONST_ACTION_DEF_CNT);
|
|
|
|
vcap->action_count = vcap->entry_count + num_default_actions;
|
|
|
|
vcap->action_width = ocelot_target_read(ocelot, vcap->target,
|
|
|
|
VCAP_CONST_ACTION_WIDTH);
|
|
|
|
/* The width of the counter memory, this is the complete width of all
|
|
|
|
* counter-fields associated with one full-word entry. There is one
|
|
|
|
* counter per entry sub-word (see CAP_CORE::ENTRY_SWCNT for number of
|
|
|
|
* subwords.)
|
|
|
|
*/
|
|
|
|
vcap->counter_words = vcap->sw_count;
|
|
|
|
counter_memory_width = ocelot_target_read(ocelot, vcap->target,
|
|
|
|
VCAP_CONST_CNT_WIDTH);
|
|
|
|
vcap->counter_width = counter_memory_width / vcap->counter_words;
|
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: generalize existing code for VCAP
In the Ocelot switches there are 3 TCAMs: VCAP ES0, IS1 and IS2, which
have the same configuration interface, but different sets of keys and
actions. The driver currently only supports VCAP IS2.
In preparation of VCAP IS1 and ES0 support, the existing code must be
generalized to work with any VCAP.
In that direction, we should move the structures that depend upon VCAP
instantiation, like vcap_is2_keys and vcap_is2_actions, out of struct
ocelot and into struct vcap_props .keys and .actions, a structure that
is replicated 3 times, once per VCAP. We'll pass that structure as an
argument to each function that does the key and action packing - only
the control logic needs to distinguish between ocelot->vcap[VCAP_IS2]
or IS1 or ES0.
Another change is to make use of the newly introduced ocelot_target_read
and ocelot_target_write API, since the 3 VCAPs have the same registers
but put at different addresses.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-30 06:27:23 +08:00
|
|
|
int ocelot_vcap_init(struct ocelot *ocelot)
|
|
|
|
{
|
2022-05-03 20:01:50 +08:00
|
|
|
struct qos_policer_conf cpu_drop = {
|
|
|
|
.mode = MSCC_QOS_RATE_MODE_DATA,
|
|
|
|
};
|
|
|
|
int ret, i;
|
2019-05-31 15:16:56 +08:00
|
|
|
|
|
|
|
/* Create a policer that will drop the frames for the cpu.
|
|
|
|
* This policer will be used as action in the acl rules to drop
|
|
|
|
* frames.
|
|
|
|
*/
|
2022-05-03 20:01:50 +08:00
|
|
|
ret = qos_policer_conf_set(ocelot, OCELOT_POLICER_DISCARD, &cpu_drop);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
2019-05-31 15:16:56 +08:00
|
|
|
|
2020-09-30 06:27:26 +08:00
|
|
|
for (i = 0; i < OCELOT_NUM_VCAP_BLOCKS; i++) {
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 20:02:22 +08:00
|
|
|
struct ocelot_vcap_block *block = &ocelot->block[i];
|
2020-09-30 06:27:26 +08:00
|
|
|
struct vcap_props *vcap = &ocelot->vcap[i];
|
|
|
|
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 20:02:22 +08:00
|
|
|
INIT_LIST_HEAD(&block->rules);
|
|
|
|
|
2020-09-30 06:27:26 +08:00
|
|
|
ocelot_vcap_detect_constants(ocelot, vcap);
|
|
|
|
ocelot_vcap_init_one(ocelot, vcap);
|
|
|
|
}
|
|
|
|
|
net: mscc: ocelot: create TCAM skeleton from tc filter chains
For Ocelot switches, there are 2 ingress pipelines for flow offload
rules: VCAP IS1 (Ingress Classification) and IS2 (Security Enforcement).
IS1 and IS2 support different sets of actions. The pipeline order for a
packet on ingress is:
Basic classification -> VCAP IS1 -> VCAP IS2
Furthermore, IS1 is looked up 3 times, and IS2 is looked up twice (each
TCAM entry can be configured to match only on the first lookup, or only
on the second, or on both etc).
Because the TCAMs are completely independent in hardware, and because of
the fixed pipeline, we actually have very limited options when it comes
to offloading complex rules to them while still maintaining the same
semantics with the software data path.
This patch maps flow offload rules to ingress TCAMs according to a
predefined chain index number. There is going to be a script in
selftests that clarifies the usage model.
There is also an egress TCAM (VCAP ES0, the Egress Rewriter), which is
modeled on top of the default chain 0 of the egress qdisc, because it
doesn't have multiple lookups.
Suggested-by: Allan W. Nielsen <allan.nielsen@microchip.com>
Co-developed-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Xiaoliang Yang <xiaoliang.yang_1@nxp.com>
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 20:02:22 +08:00
|
|
|
INIT_LIST_HEAD(&ocelot->dummy_rules);
|
2022-02-16 22:30:10 +08:00
|
|
|
INIT_LIST_HEAD(&ocelot->traps);
|
2021-11-18 18:12:02 +08:00
|
|
|
INIT_LIST_HEAD(&ocelot->vcap_pol.pol_list);
|
2019-05-31 15:16:56 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|