mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-14 06:35:12 +00:00
net: lan966x: Add IS1 VCAP keyset configuration for lan966x
Add IS1 VCAP port keyset configuration for lan966x and also update debug fs support to show the keyset configuration. Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
99ce286d2d
commit
a4d9b3ec63
4 changed files with 383 additions and 16 deletions
|
@ -92,6 +92,11 @@
|
||||||
#define SE_IDX_QUEUE 0 /* 0-79 : Queue scheduler elements */
|
#define SE_IDX_QUEUE 0 /* 0-79 : Queue scheduler elements */
|
||||||
#define SE_IDX_PORT 80 /* 80-89 : Port schedular elements */
|
#define SE_IDX_PORT 80 /* 80-89 : Port schedular elements */
|
||||||
|
|
||||||
|
#define LAN966X_VCAP_CID_IS1_L0 VCAP_CID_INGRESS_L0 /* IS1 lookup 0 */
|
||||||
|
#define LAN966X_VCAP_CID_IS1_L1 VCAP_CID_INGRESS_L1 /* IS1 lookup 1 */
|
||||||
|
#define LAN966X_VCAP_CID_IS1_L2 VCAP_CID_INGRESS_L2 /* IS1 lookup 2 */
|
||||||
|
#define LAN966X_VCAP_CID_IS1_MAX (VCAP_CID_INGRESS_L3 - 1) /* IS1 Max */
|
||||||
|
|
||||||
#define LAN966X_VCAP_CID_IS2_L0 VCAP_CID_INGRESS_STAGE2_L0 /* IS2 lookup 0 */
|
#define LAN966X_VCAP_CID_IS2_L0 VCAP_CID_INGRESS_STAGE2_L0 /* IS2 lookup 0 */
|
||||||
#define LAN966X_VCAP_CID_IS2_L1 VCAP_CID_INGRESS_STAGE2_L1 /* IS2 lookup 1 */
|
#define LAN966X_VCAP_CID_IS2_L1 VCAP_CID_INGRESS_STAGE2_L1 /* IS2 lookup 1 */
|
||||||
#define LAN966X_VCAP_CID_IS2_MAX (VCAP_CID_INGRESS_STAGE2_L2 - 1) /* IS2 Max */
|
#define LAN966X_VCAP_CID_IS2_MAX (VCAP_CID_INGRESS_STAGE2_L2 - 1) /* IS2 Max */
|
||||||
|
@ -139,6 +144,39 @@ enum vcap_is2_port_sel_ipv6 {
|
||||||
VCAP_IS2_PS_IPV6_MAC_ETYPE,
|
VCAP_IS2_PS_IPV6_MAC_ETYPE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum vcap_is1_port_sel_other {
|
||||||
|
VCAP_IS1_PS_OTHER_NORMAL,
|
||||||
|
VCAP_IS1_PS_OTHER_7TUPLE,
|
||||||
|
VCAP_IS1_PS_OTHER_DBL_VID,
|
||||||
|
VCAP_IS1_PS_OTHER_DMAC_VID,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum vcap_is1_port_sel_ipv4 {
|
||||||
|
VCAP_IS1_PS_IPV4_NORMAL,
|
||||||
|
VCAP_IS1_PS_IPV4_7TUPLE,
|
||||||
|
VCAP_IS1_PS_IPV4_5TUPLE_IP4,
|
||||||
|
VCAP_IS1_PS_IPV4_DBL_VID,
|
||||||
|
VCAP_IS1_PS_IPV4_DMAC_VID,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum vcap_is1_port_sel_ipv6 {
|
||||||
|
VCAP_IS1_PS_IPV6_NORMAL,
|
||||||
|
VCAP_IS1_PS_IPV6_7TUPLE,
|
||||||
|
VCAP_IS1_PS_IPV6_5TUPLE_IP4,
|
||||||
|
VCAP_IS1_PS_IPV6_NORMAL_IP6,
|
||||||
|
VCAP_IS1_PS_IPV6_5TUPLE_IP6,
|
||||||
|
VCAP_IS1_PS_IPV6_DBL_VID,
|
||||||
|
VCAP_IS1_PS_IPV6_DMAC_VID,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum vcap_is1_port_sel_rt {
|
||||||
|
VCAP_IS1_PS_RT_NORMAL,
|
||||||
|
VCAP_IS1_PS_RT_7TUPLE,
|
||||||
|
VCAP_IS1_PS_RT_DBL_VID,
|
||||||
|
VCAP_IS1_PS_RT_DMAC_VID,
|
||||||
|
VCAP_IS1_PS_RT_FOLLOW_OTHER = 7,
|
||||||
|
};
|
||||||
|
|
||||||
struct lan966x_port;
|
struct lan966x_port;
|
||||||
|
|
||||||
struct lan966x_db {
|
struct lan966x_db {
|
||||||
|
|
|
@ -316,6 +316,42 @@ enum lan966x_target {
|
||||||
#define ANA_DROP_CFG_DROP_MC_SMAC_ENA_GET(x)\
|
#define ANA_DROP_CFG_DROP_MC_SMAC_ENA_GET(x)\
|
||||||
FIELD_GET(ANA_DROP_CFG_DROP_MC_SMAC_ENA, x)
|
FIELD_GET(ANA_DROP_CFG_DROP_MC_SMAC_ENA, x)
|
||||||
|
|
||||||
|
/* ANA:PORT:VCAP_CFG */
|
||||||
|
#define ANA_VCAP_CFG(g) __REG(TARGET_ANA, 0, 1, 28672, g, 9, 128, 12, 0, 1, 4)
|
||||||
|
|
||||||
|
#define ANA_VCAP_CFG_S1_ENA BIT(14)
|
||||||
|
#define ANA_VCAP_CFG_S1_ENA_SET(x)\
|
||||||
|
FIELD_PREP(ANA_VCAP_CFG_S1_ENA, x)
|
||||||
|
#define ANA_VCAP_CFG_S1_ENA_GET(x)\
|
||||||
|
FIELD_GET(ANA_VCAP_CFG_S1_ENA, x)
|
||||||
|
|
||||||
|
/* ANA:PORT:VCAP_S1_KEY_CFG */
|
||||||
|
#define ANA_VCAP_S1_CFG(g, r) __REG(TARGET_ANA, 0, 1, 28672, g, 9, 128, 16, r, 3, 4)
|
||||||
|
|
||||||
|
#define ANA_VCAP_S1_CFG_KEY_RT_CFG GENMASK(11, 9)
|
||||||
|
#define ANA_VCAP_S1_CFG_KEY_RT_CFG_SET(x)\
|
||||||
|
FIELD_PREP(ANA_VCAP_S1_CFG_KEY_RT_CFG, x)
|
||||||
|
#define ANA_VCAP_S1_CFG_KEY_RT_CFG_GET(x)\
|
||||||
|
FIELD_GET(ANA_VCAP_S1_CFG_KEY_RT_CFG, x)
|
||||||
|
|
||||||
|
#define ANA_VCAP_S1_CFG_KEY_IP6_CFG GENMASK(8, 6)
|
||||||
|
#define ANA_VCAP_S1_CFG_KEY_IP6_CFG_SET(x)\
|
||||||
|
FIELD_PREP(ANA_VCAP_S1_CFG_KEY_IP6_CFG, x)
|
||||||
|
#define ANA_VCAP_S1_CFG_KEY_IP6_CFG_GET(x)\
|
||||||
|
FIELD_GET(ANA_VCAP_S1_CFG_KEY_IP6_CFG, x)
|
||||||
|
|
||||||
|
#define ANA_VCAP_S1_CFG_KEY_IP4_CFG GENMASK(5, 3)
|
||||||
|
#define ANA_VCAP_S1_CFG_KEY_IP4_CFG_SET(x)\
|
||||||
|
FIELD_PREP(ANA_VCAP_S1_CFG_KEY_IP4_CFG, x)
|
||||||
|
#define ANA_VCAP_S1_CFG_KEY_IP4_CFG_GET(x)\
|
||||||
|
FIELD_GET(ANA_VCAP_S1_CFG_KEY_IP4_CFG, x)
|
||||||
|
|
||||||
|
#define ANA_VCAP_S1_CFG_KEY_OTHER_CFG GENMASK(2, 0)
|
||||||
|
#define ANA_VCAP_S1_CFG_KEY_OTHER_CFG_SET(x)\
|
||||||
|
FIELD_PREP(ANA_VCAP_S1_CFG_KEY_OTHER_CFG, x)
|
||||||
|
#define ANA_VCAP_S1_CFG_KEY_OTHER_CFG_GET(x)\
|
||||||
|
FIELD_GET(ANA_VCAP_S1_CFG_KEY_OTHER_CFG, x)
|
||||||
|
|
||||||
/* ANA:PORT:VCAP_S2_CFG */
|
/* ANA:PORT:VCAP_S2_CFG */
|
||||||
#define ANA_VCAP_S2_CFG(g) __REG(TARGET_ANA, 0, 1, 28672, g, 9, 128, 28, 0, 1, 4)
|
#define ANA_VCAP_S2_CFG(g) __REG(TARGET_ANA, 0, 1, 28672, g, 9, 128, 28, 0, 1, 4)
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,124 @@
|
||||||
#include "vcap_api.h"
|
#include "vcap_api.h"
|
||||||
#include "vcap_api_client.h"
|
#include "vcap_api_client.h"
|
||||||
|
|
||||||
static void lan966x_vcap_port_keys(struct lan966x_port *port,
|
static void lan966x_vcap_is1_port_keys(struct lan966x_port *port,
|
||||||
struct vcap_admin *admin,
|
struct vcap_admin *admin,
|
||||||
struct vcap_output_print *out)
|
struct vcap_output_print *out)
|
||||||
|
{
|
||||||
|
struct lan966x *lan966x = port->lan966x;
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
out->prf(out->dst, " port[%d] (%s): ", port->chip_port,
|
||||||
|
netdev_name(port->dev));
|
||||||
|
|
||||||
|
val = lan_rd(lan966x, ANA_VCAP_CFG(port->chip_port));
|
||||||
|
out->prf(out->dst, "\n state: ");
|
||||||
|
if (ANA_VCAP_CFG_S1_ENA_GET(val))
|
||||||
|
out->prf(out->dst, "on");
|
||||||
|
else
|
||||||
|
out->prf(out->dst, "off");
|
||||||
|
|
||||||
|
for (int l = 0; l < admin->lookups; ++l) {
|
||||||
|
out->prf(out->dst, "\n Lookup %d: ", l);
|
||||||
|
|
||||||
|
out->prf(out->dst, "\n other: ");
|
||||||
|
switch (ANA_VCAP_S1_CFG_KEY_OTHER_CFG_GET(val)) {
|
||||||
|
case VCAP_IS1_PS_OTHER_NORMAL:
|
||||||
|
out->prf(out->dst, "normal");
|
||||||
|
break;
|
||||||
|
case VCAP_IS1_PS_OTHER_7TUPLE:
|
||||||
|
out->prf(out->dst, "7tuple");
|
||||||
|
break;
|
||||||
|
case VCAP_IS1_PS_OTHER_DBL_VID:
|
||||||
|
out->prf(out->dst, "dbl_vid");
|
||||||
|
break;
|
||||||
|
case VCAP_IS1_PS_OTHER_DMAC_VID:
|
||||||
|
out->prf(out->dst, "dmac_vid");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
out->prf(out->dst, "-");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
out->prf(out->dst, "\n ipv4: ");
|
||||||
|
switch (ANA_VCAP_S1_CFG_KEY_IP4_CFG_GET(val)) {
|
||||||
|
case VCAP_IS1_PS_IPV4_NORMAL:
|
||||||
|
out->prf(out->dst, "normal");
|
||||||
|
break;
|
||||||
|
case VCAP_IS1_PS_IPV4_7TUPLE:
|
||||||
|
out->prf(out->dst, "7tuple");
|
||||||
|
break;
|
||||||
|
case VCAP_IS1_PS_IPV4_5TUPLE_IP4:
|
||||||
|
out->prf(out->dst, "5tuple_ipv4");
|
||||||
|
break;
|
||||||
|
case VCAP_IS1_PS_IPV4_DBL_VID:
|
||||||
|
out->prf(out->dst, "dbl_vid");
|
||||||
|
break;
|
||||||
|
case VCAP_IS1_PS_IPV4_DMAC_VID:
|
||||||
|
out->prf(out->dst, "dmac_vid");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
out->prf(out->dst, "-");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
out->prf(out->dst, "\n ipv6: ");
|
||||||
|
switch (ANA_VCAP_S1_CFG_KEY_IP6_CFG_GET(val)) {
|
||||||
|
case VCAP_IS1_PS_IPV6_NORMAL:
|
||||||
|
out->prf(out->dst, "normal");
|
||||||
|
break;
|
||||||
|
case VCAP_IS1_PS_IPV6_7TUPLE:
|
||||||
|
out->prf(out->dst, "7tuple");
|
||||||
|
break;
|
||||||
|
case VCAP_IS1_PS_IPV6_5TUPLE_IP4:
|
||||||
|
out->prf(out->dst, "5tuple_ip4");
|
||||||
|
break;
|
||||||
|
case VCAP_IS1_PS_IPV6_NORMAL_IP6:
|
||||||
|
out->prf(out->dst, "normal_ip6");
|
||||||
|
break;
|
||||||
|
case VCAP_IS1_PS_IPV6_5TUPLE_IP6:
|
||||||
|
out->prf(out->dst, "5tuple_ip6");
|
||||||
|
break;
|
||||||
|
case VCAP_IS1_PS_IPV6_DBL_VID:
|
||||||
|
out->prf(out->dst, "dbl_vid");
|
||||||
|
break;
|
||||||
|
case VCAP_IS1_PS_IPV6_DMAC_VID:
|
||||||
|
out->prf(out->dst, "dmac_vid");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
out->prf(out->dst, "-");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
out->prf(out->dst, "\n rt: ");
|
||||||
|
switch (ANA_VCAP_S1_CFG_KEY_RT_CFG_GET(val)) {
|
||||||
|
case VCAP_IS1_PS_RT_NORMAL:
|
||||||
|
out->prf(out->dst, "normal");
|
||||||
|
break;
|
||||||
|
case VCAP_IS1_PS_RT_7TUPLE:
|
||||||
|
out->prf(out->dst, "7tuple");
|
||||||
|
break;
|
||||||
|
case VCAP_IS1_PS_RT_DBL_VID:
|
||||||
|
out->prf(out->dst, "dbl_vid");
|
||||||
|
break;
|
||||||
|
case VCAP_IS1_PS_RT_DMAC_VID:
|
||||||
|
out->prf(out->dst, "dmac_vid");
|
||||||
|
break;
|
||||||
|
case VCAP_IS1_PS_RT_FOLLOW_OTHER:
|
||||||
|
out->prf(out->dst, "follow_other");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
out->prf(out->dst, "-");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out->prf(out->dst, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lan966x_vcap_is2_port_keys(struct lan966x_port *port,
|
||||||
|
struct vcap_admin *admin,
|
||||||
|
struct vcap_output_print *out)
|
||||||
{
|
{
|
||||||
struct lan966x *lan966x = port->lan966x;
|
struct lan966x *lan966x = port->lan966x;
|
||||||
u32 val;
|
u32 val;
|
||||||
|
@ -88,7 +203,17 @@ int lan966x_vcap_port_info(struct net_device *dev,
|
||||||
vcap = &vctrl->vcaps[admin->vtype];
|
vcap = &vctrl->vcaps[admin->vtype];
|
||||||
|
|
||||||
out->prf(out->dst, "%s:\n", vcap->name);
|
out->prf(out->dst, "%s:\n", vcap->name);
|
||||||
lan966x_vcap_port_keys(port, admin, out);
|
switch (admin->vtype) {
|
||||||
|
case VCAP_TYPE_IS2:
|
||||||
|
lan966x_vcap_is2_port_keys(port, admin, out);
|
||||||
|
break;
|
||||||
|
case VCAP_TYPE_IS1:
|
||||||
|
lan966x_vcap_is1_port_keys(port, admin, out);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
out->prf(out->dst, " no info\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#define STREAMSIZE (64 * 4)
|
#define STREAMSIZE (64 * 4)
|
||||||
|
|
||||||
|
#define LAN966X_IS1_LOOKUPS 3
|
||||||
#define LAN966X_IS2_LOOKUPS 2
|
#define LAN966X_IS2_LOOKUPS 2
|
||||||
|
|
||||||
static struct lan966x_vcap_inst {
|
static struct lan966x_vcap_inst {
|
||||||
|
@ -19,6 +20,15 @@ static struct lan966x_vcap_inst {
|
||||||
int count; /* number of available addresses */
|
int count; /* number of available addresses */
|
||||||
bool ingress; /* is vcap in the ingress path */
|
bool ingress; /* is vcap in the ingress path */
|
||||||
} lan966x_vcap_inst_cfg[] = {
|
} lan966x_vcap_inst_cfg[] = {
|
||||||
|
{
|
||||||
|
.vtype = VCAP_TYPE_IS1, /* IS1-0 */
|
||||||
|
.tgt_inst = 1,
|
||||||
|
.lookups = LAN966X_IS1_LOOKUPS,
|
||||||
|
.first_cid = LAN966X_VCAP_CID_IS1_L0,
|
||||||
|
.last_cid = LAN966X_VCAP_CID_IS1_MAX,
|
||||||
|
.count = 768,
|
||||||
|
.ingress = true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.vtype = VCAP_TYPE_IS2, /* IS2-0 */
|
.vtype = VCAP_TYPE_IS2, /* IS2-0 */
|
||||||
.tgt_inst = 2,
|
.tgt_inst = 2,
|
||||||
|
@ -72,7 +82,21 @@ static void __lan966x_vcap_range_init(struct lan966x *lan966x,
|
||||||
lan966x_vcap_wait_update(lan966x, admin->tgt_inst);
|
lan966x_vcap_wait_update(lan966x, admin->tgt_inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lan966x_vcap_cid_to_lookup(int cid)
|
static int lan966x_vcap_is1_cid_to_lookup(int cid)
|
||||||
|
{
|
||||||
|
int lookup = 0;
|
||||||
|
|
||||||
|
if (cid >= LAN966X_VCAP_CID_IS1_L1 &&
|
||||||
|
cid < LAN966X_VCAP_CID_IS1_L2)
|
||||||
|
lookup = 1;
|
||||||
|
else if (cid >= LAN966X_VCAP_CID_IS1_L2 &&
|
||||||
|
cid < LAN966X_VCAP_CID_IS1_MAX)
|
||||||
|
lookup = 2;
|
||||||
|
|
||||||
|
return lookup;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int lan966x_vcap_is2_cid_to_lookup(int cid)
|
||||||
{
|
{
|
||||||
if (cid >= LAN966X_VCAP_CID_IS2_L1 &&
|
if (cid >= LAN966X_VCAP_CID_IS2_L1 &&
|
||||||
cid < LAN966X_VCAP_CID_IS2_MAX)
|
cid < LAN966X_VCAP_CID_IS2_MAX)
|
||||||
|
@ -81,6 +105,67 @@ static int lan966x_vcap_cid_to_lookup(int cid)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return the list of keysets for the vcap port configuration */
|
||||||
|
static int
|
||||||
|
lan966x_vcap_is1_get_port_keysets(struct net_device *ndev, int lookup,
|
||||||
|
struct vcap_keyset_list *keysetlist,
|
||||||
|
u16 l3_proto)
|
||||||
|
{
|
||||||
|
struct lan966x_port *port = netdev_priv(ndev);
|
||||||
|
struct lan966x *lan966x = port->lan966x;
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
val = lan_rd(lan966x, ANA_VCAP_S1_CFG(port->chip_port, lookup));
|
||||||
|
|
||||||
|
/* Collect all keysets for the port in a list */
|
||||||
|
if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IP) {
|
||||||
|
switch (ANA_VCAP_S1_CFG_KEY_IP4_CFG_GET(val)) {
|
||||||
|
case VCAP_IS1_PS_IPV4_7TUPLE:
|
||||||
|
vcap_keyset_list_add(keysetlist, VCAP_KFS_7TUPLE);
|
||||||
|
break;
|
||||||
|
case VCAP_IS1_PS_IPV4_5TUPLE_IP4:
|
||||||
|
vcap_keyset_list_add(keysetlist, VCAP_KFS_5TUPLE_IP4);
|
||||||
|
break;
|
||||||
|
case VCAP_IS1_PS_IPV4_NORMAL:
|
||||||
|
vcap_keyset_list_add(keysetlist, VCAP_KFS_NORMAL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_IPV6) {
|
||||||
|
switch (ANA_VCAP_S1_CFG_KEY_IP6_CFG_GET(val)) {
|
||||||
|
case VCAP_IS1_PS_IPV6_NORMAL:
|
||||||
|
case VCAP_IS1_PS_IPV6_NORMAL_IP6:
|
||||||
|
vcap_keyset_list_add(keysetlist, VCAP_KFS_NORMAL);
|
||||||
|
vcap_keyset_list_add(keysetlist, VCAP_KFS_NORMAL_IP6);
|
||||||
|
break;
|
||||||
|
case VCAP_IS1_PS_IPV6_5TUPLE_IP6:
|
||||||
|
vcap_keyset_list_add(keysetlist, VCAP_KFS_5TUPLE_IP6);
|
||||||
|
break;
|
||||||
|
case VCAP_IS1_PS_IPV6_7TUPLE:
|
||||||
|
vcap_keyset_list_add(keysetlist, VCAP_KFS_7TUPLE);
|
||||||
|
break;
|
||||||
|
case VCAP_IS1_PS_IPV6_5TUPLE_IP4:
|
||||||
|
vcap_keyset_list_add(keysetlist, VCAP_KFS_5TUPLE_IP4);
|
||||||
|
break;
|
||||||
|
case VCAP_IS1_PS_IPV6_DMAC_VID:
|
||||||
|
vcap_keyset_list_add(keysetlist, VCAP_KFS_DMAC_VID);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ANA_VCAP_S1_CFG_KEY_OTHER_CFG_GET(val)) {
|
||||||
|
case VCAP_IS1_PS_OTHER_7TUPLE:
|
||||||
|
vcap_keyset_list_add(keysetlist, VCAP_KFS_7TUPLE);
|
||||||
|
break;
|
||||||
|
case VCAP_IS1_PS_OTHER_NORMAL:
|
||||||
|
vcap_keyset_list_add(keysetlist, VCAP_KFS_NORMAL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
lan966x_vcap_is2_get_port_keysets(struct net_device *dev, int lookup,
|
lan966x_vcap_is2_get_port_keysets(struct net_device *dev, int lookup,
|
||||||
struct vcap_keyset_list *keysetlist,
|
struct vcap_keyset_list *keysetlist,
|
||||||
|
@ -180,11 +265,26 @@ lan966x_vcap_validate_keyset(struct net_device *dev,
|
||||||
if (!kslist || kslist->cnt == 0)
|
if (!kslist || kslist->cnt == 0)
|
||||||
return VCAP_KFS_NO_VALUE;
|
return VCAP_KFS_NO_VALUE;
|
||||||
|
|
||||||
lookup = lan966x_vcap_cid_to_lookup(rule->vcap_chain_id);
|
|
||||||
keysetlist.max = ARRAY_SIZE(keysets);
|
keysetlist.max = ARRAY_SIZE(keysets);
|
||||||
keysetlist.keysets = keysets;
|
keysetlist.keysets = keysets;
|
||||||
err = lan966x_vcap_is2_get_port_keysets(dev, lookup, &keysetlist,
|
|
||||||
l3_proto);
|
switch (admin->vtype) {
|
||||||
|
case VCAP_TYPE_IS1:
|
||||||
|
lookup = lan966x_vcap_is1_cid_to_lookup(rule->vcap_chain_id);
|
||||||
|
err = lan966x_vcap_is1_get_port_keysets(dev, lookup, &keysetlist,
|
||||||
|
l3_proto);
|
||||||
|
break;
|
||||||
|
case VCAP_TYPE_IS2:
|
||||||
|
lookup = lan966x_vcap_is2_cid_to_lookup(rule->vcap_chain_id);
|
||||||
|
err = lan966x_vcap_is2_get_port_keysets(dev, lookup, &keysetlist,
|
||||||
|
l3_proto);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pr_err("vcap type: %s not supported\n",
|
||||||
|
lan966x_vcaps[admin->vtype].name);
|
||||||
|
return VCAP_KFS_NO_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
return VCAP_KFS_NO_VALUE;
|
return VCAP_KFS_NO_VALUE;
|
||||||
|
|
||||||
|
@ -197,17 +297,32 @@ lan966x_vcap_validate_keyset(struct net_device *dev,
|
||||||
return VCAP_KFS_NO_VALUE;
|
return VCAP_KFS_NO_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool lan966x_vcap_is_first_chain(struct vcap_rule *rule)
|
static bool lan966x_vcap_is2_is_first_chain(struct vcap_rule *rule)
|
||||||
{
|
{
|
||||||
return (rule->vcap_chain_id >= LAN966X_VCAP_CID_IS2_L0 &&
|
return (rule->vcap_chain_id >= LAN966X_VCAP_CID_IS2_L0 &&
|
||||||
rule->vcap_chain_id < LAN966X_VCAP_CID_IS2_L1);
|
rule->vcap_chain_id < LAN966X_VCAP_CID_IS2_L1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lan966x_vcap_add_default_fields(struct net_device *dev,
|
static void lan966x_vcap_is1_add_default_fields(struct lan966x_port *port,
|
||||||
struct vcap_admin *admin,
|
struct vcap_admin *admin,
|
||||||
struct vcap_rule *rule)
|
struct vcap_rule *rule)
|
||||||
|
{
|
||||||
|
u32 value, mask;
|
||||||
|
u32 lookup;
|
||||||
|
|
||||||
|
if (vcap_rule_get_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK,
|
||||||
|
&value, &mask))
|
||||||
|
vcap_rule_add_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK, 0,
|
||||||
|
~BIT(port->chip_port));
|
||||||
|
|
||||||
|
lookup = lan966x_vcap_is1_cid_to_lookup(rule->vcap_chain_id);
|
||||||
|
vcap_rule_add_key_u32(rule, VCAP_KF_LOOKUP_INDEX, lookup, 0x3);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void lan966x_vcap_is2_add_default_fields(struct lan966x_port *port,
|
||||||
|
struct vcap_admin *admin,
|
||||||
|
struct vcap_rule *rule)
|
||||||
{
|
{
|
||||||
struct lan966x_port *port = netdev_priv(dev);
|
|
||||||
u32 value, mask;
|
u32 value, mask;
|
||||||
|
|
||||||
if (vcap_rule_get_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK,
|
if (vcap_rule_get_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK,
|
||||||
|
@ -215,7 +330,7 @@ static void lan966x_vcap_add_default_fields(struct net_device *dev,
|
||||||
vcap_rule_add_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK, 0,
|
vcap_rule_add_key_u32(rule, VCAP_KF_IF_IGR_PORT_MASK, 0,
|
||||||
~BIT(port->chip_port));
|
~BIT(port->chip_port));
|
||||||
|
|
||||||
if (lan966x_vcap_is_first_chain(rule))
|
if (lan966x_vcap_is2_is_first_chain(rule))
|
||||||
vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
|
vcap_rule_add_key_bit(rule, VCAP_KF_LOOKUP_FIRST_IS,
|
||||||
VCAP_BIT_1);
|
VCAP_BIT_1);
|
||||||
else
|
else
|
||||||
|
@ -223,6 +338,26 @@ static void lan966x_vcap_add_default_fields(struct net_device *dev,
|
||||||
VCAP_BIT_0);
|
VCAP_BIT_0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void lan966x_vcap_add_default_fields(struct net_device *dev,
|
||||||
|
struct vcap_admin *admin,
|
||||||
|
struct vcap_rule *rule)
|
||||||
|
{
|
||||||
|
struct lan966x_port *port = netdev_priv(dev);
|
||||||
|
|
||||||
|
switch (admin->vtype) {
|
||||||
|
case VCAP_TYPE_IS1:
|
||||||
|
lan966x_vcap_is1_add_default_fields(port, admin, rule);
|
||||||
|
break;
|
||||||
|
case VCAP_TYPE_IS2:
|
||||||
|
lan966x_vcap_is2_add_default_fields(port, admin, rule);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pr_err("vcap type: %s not supported\n",
|
||||||
|
lan966x_vcaps[admin->vtype].name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void lan966x_vcap_cache_erase(struct vcap_admin *admin)
|
static void lan966x_vcap_cache_erase(struct vcap_admin *admin)
|
||||||
{
|
{
|
||||||
memset(admin->cache.keystream, 0, STREAMSIZE);
|
memset(admin->cache.keystream, 0, STREAMSIZE);
|
||||||
|
@ -464,8 +599,37 @@ static void lan966x_vcap_block_init(struct lan966x *lan966x,
|
||||||
static void lan966x_vcap_port_key_deselection(struct lan966x *lan966x,
|
static void lan966x_vcap_port_key_deselection(struct lan966x *lan966x,
|
||||||
struct vcap_admin *admin)
|
struct vcap_admin *admin)
|
||||||
{
|
{
|
||||||
for (int p = 0; p < lan966x->num_phys_ports; ++p)
|
u32 val;
|
||||||
lan_wr(0, lan966x, ANA_VCAP_S2_CFG(p));
|
|
||||||
|
switch (admin->vtype) {
|
||||||
|
case VCAP_TYPE_IS1:
|
||||||
|
val = ANA_VCAP_S1_CFG_KEY_IP6_CFG_SET(VCAP_IS1_PS_IPV6_5TUPLE_IP6) |
|
||||||
|
ANA_VCAP_S1_CFG_KEY_IP4_CFG_SET(VCAP_IS1_PS_IPV4_5TUPLE_IP4) |
|
||||||
|
ANA_VCAP_S1_CFG_KEY_OTHER_CFG_SET(VCAP_IS1_PS_OTHER_NORMAL);
|
||||||
|
|
||||||
|
for (int p = 0; p < lan966x->num_phys_ports; ++p) {
|
||||||
|
if (!lan966x->ports[p])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (int l = 0; l < LAN966X_IS1_LOOKUPS; ++l)
|
||||||
|
lan_wr(val, lan966x, ANA_VCAP_S1_CFG(p, l));
|
||||||
|
|
||||||
|
lan_rmw(ANA_VCAP_CFG_S1_ENA_SET(true),
|
||||||
|
ANA_VCAP_CFG_S1_ENA, lan966x,
|
||||||
|
ANA_VCAP_CFG(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case VCAP_TYPE_IS2:
|
||||||
|
for (int p = 0; p < lan966x->num_phys_ports; ++p)
|
||||||
|
lan_wr(0, lan966x, ANA_VCAP_S2_CFG(p));
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
pr_err("vcap type: %s not supported\n",
|
||||||
|
lan966x_vcaps[admin->vtype].name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int lan966x_vcap_init(struct lan966x *lan966x)
|
int lan966x_vcap_init(struct lan966x *lan966x)
|
||||||
|
@ -506,6 +670,10 @@ int lan966x_vcap_init(struct lan966x *lan966x)
|
||||||
lan_rmw(ANA_VCAP_S2_CFG_ENA_SET(true),
|
lan_rmw(ANA_VCAP_S2_CFG_ENA_SET(true),
|
||||||
ANA_VCAP_S2_CFG_ENA, lan966x,
|
ANA_VCAP_S2_CFG_ENA, lan966x,
|
||||||
ANA_VCAP_S2_CFG(lan966x->ports[p]->chip_port));
|
ANA_VCAP_S2_CFG(lan966x->ports[p]->chip_port));
|
||||||
|
|
||||||
|
lan_rmw(ANA_VCAP_CFG_S1_ENA_SET(true),
|
||||||
|
ANA_VCAP_CFG_S1_ENA, lan966x,
|
||||||
|
ANA_VCAP_CFG(lan966x->ports[p]->chip_port));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue