Commit 63e35645 authored by Steen Hegelund's avatar Steen Hegelund Committed by Paolo Abeni

net: microchip: sparx5: Add support for IS0 VCAP ethernet protocol types

This allows the IS0 VCAP to have its own list of supported ethernet
protocol types matching what is supported by the VCAPs port lookup
classification.
Signed-off-by: default avatarSteen Hegelund <steen.hegelund@microchip.com>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 81e164c4
...@@ -36,16 +36,6 @@ struct sparx5_tc_flower_parse_usage { ...@@ -36,16 +36,6 @@ struct sparx5_tc_flower_parse_usage {
unsigned int used_keys; unsigned int used_keys;
}; };
/* These protocols have dedicated keysets in IS2 and a TC dissector
* ETH_P_ARP does not have a TC dissector
*/
static u16 sparx5_tc_known_etypes[] = {
ETH_P_ALL,
ETH_P_ARP,
ETH_P_IP,
ETH_P_IPV6,
};
enum sparx5_is2_arp_opcode { enum sparx5_is2_arp_opcode {
SPX5_IS2_ARP_REQUEST, SPX5_IS2_ARP_REQUEST,
SPX5_IS2_ARP_REPLY, SPX5_IS2_ARP_REPLY,
...@@ -59,18 +49,6 @@ enum tc_arp_opcode { ...@@ -59,18 +49,6 @@ enum tc_arp_opcode {
TC_ARP_OP_REPLY, TC_ARP_OP_REPLY,
}; };
static bool sparx5_tc_is_known_etype(u16 etype)
{
int idx;
/* For now this only knows about IS2 traffic classification */
for (idx = 0; idx < ARRAY_SIZE(sparx5_tc_known_etypes); ++idx)
if (sparx5_tc_known_etypes[idx] == etype)
return true;
return false;
}
static int sparx5_tc_flower_handler_ethaddr_usage(struct sparx5_tc_flower_parse_usage *st) static int sparx5_tc_flower_handler_ethaddr_usage(struct sparx5_tc_flower_parse_usage *st)
{ {
enum vcap_key_field smac_key = VCAP_KF_L2_SMAC; enum vcap_key_field smac_key = VCAP_KF_L2_SMAC;
...@@ -273,7 +251,7 @@ sparx5_tc_flower_handler_basic_usage(struct sparx5_tc_flower_parse_usage *st) ...@@ -273,7 +251,7 @@ sparx5_tc_flower_handler_basic_usage(struct sparx5_tc_flower_parse_usage *st)
if (mt.mask->n_proto) { if (mt.mask->n_proto) {
st->l3_proto = be16_to_cpu(mt.key->n_proto); st->l3_proto = be16_to_cpu(mt.key->n_proto);
if (!sparx5_tc_is_known_etype(st->l3_proto)) { if (!sparx5_vcap_is_known_etype(st->admin, st->l3_proto)) {
err = vcap_rule_add_key_u32(st->vrule, VCAP_KF_ETYPE, err = vcap_rule_add_key_u32(st->vrule, VCAP_KF_ETYPE,
st->l3_proto, ~0); st->l3_proto, ~0);
if (err) if (err)
......
...@@ -106,6 +106,21 @@ static struct sparx5_vcap_inst { ...@@ -106,6 +106,21 @@ static struct sparx5_vcap_inst {
}, },
}; };
/* These protocols have dedicated keysets in IS0 and a TC dissector */
static u16 sparx5_vcap_is0_known_etypes[] = {
ETH_P_ALL,
ETH_P_IP,
ETH_P_IPV6,
};
/* These protocols have dedicated keysets in IS2 and a TC dissector */
static u16 sparx5_vcap_is2_known_etypes[] = {
ETH_P_ALL,
ETH_P_ARP,
ETH_P_IP,
ETH_P_IPV6,
};
static void sparx5_vcap_type_err(struct sparx5 *sparx5, static void sparx5_vcap_type_err(struct sparx5 *sparx5,
struct vcap_admin *admin, struct vcap_admin *admin,
const char *fname) const char *fname)
...@@ -277,10 +292,6 @@ static int sparx5_vcap_is0_get_port_keysets(struct net_device *ndev, ...@@ -277,10 +292,6 @@ static int sparx5_vcap_is0_get_port_keysets(struct net_device *ndev,
value = spx5_rd(sparx5, ANA_CL_ADV_CL_CFG(portno, lookup)); value = spx5_rd(sparx5, ANA_CL_ADV_CL_CFG(portno, lookup));
/* Check if the port keyset selection is enabled */
if (!ANA_CL_ADV_CL_CFG_LOOKUP_ENA_GET(value))
return -ENOENT;
/* Collect all keysets for the port in a list */ /* Collect all keysets for the port in a list */
if (l3_proto == ETH_P_ALL) if (l3_proto == ETH_P_ALL)
sparx5_vcap_is0_get_port_etype_keysets(keysetlist, value); sparx5_vcap_is0_get_port_etype_keysets(keysetlist, value);
...@@ -333,10 +344,7 @@ static int sparx5_vcap_is2_get_port_keysets(struct net_device *ndev, ...@@ -333,10 +344,7 @@ static int sparx5_vcap_is2_get_port_keysets(struct net_device *ndev,
int portno = port->portno; int portno = port->portno;
u32 value; u32 value;
/* Check if the port keyset selection is enabled */
value = spx5_rd(sparx5, ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup)); value = spx5_rd(sparx5, ANA_ACL_VCAP_S2_KEY_SEL(portno, lookup));
if (!ANA_ACL_VCAP_S2_KEY_SEL_KEY_SEL_ENA_GET(value))
return -ENOENT;
/* Collect all keysets for the port in a list */ /* Collect all keysets for the port in a list */
if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_ARP) { if (l3_proto == ETH_P_ALL || l3_proto == ETH_P_ARP) {
...@@ -456,6 +464,30 @@ int sparx5_vcap_get_port_keyset(struct net_device *ndev, ...@@ -456,6 +464,30 @@ int sparx5_vcap_get_port_keyset(struct net_device *ndev,
return err; return err;
} }
/* Check if the ethertype is supported by the vcap port classification */
bool sparx5_vcap_is_known_etype(struct vcap_admin *admin, u16 etype)
{
const u16 *known_etypes;
int size, idx;
switch (admin->vtype) {
case VCAP_TYPE_IS0:
known_etypes = sparx5_vcap_is0_known_etypes;
size = ARRAY_SIZE(sparx5_vcap_is0_known_etypes);
break;
case VCAP_TYPE_IS2:
known_etypes = sparx5_vcap_is2_known_etypes;
size = ARRAY_SIZE(sparx5_vcap_is2_known_etypes);
break;
default:
return false;
}
for (idx = 0; idx < size; ++idx)
if (known_etypes[idx] == etype)
return true;
return false;
}
/* API callback used for validating a field keyset (check the port keysets) */ /* API callback used for validating a field keyset (check the port keysets) */
static enum vcap_keyfield_set static enum vcap_keyfield_set
sparx5_vcap_validate_keyset(struct net_device *ndev, sparx5_vcap_validate_keyset(struct net_device *ndev,
......
...@@ -136,4 +136,7 @@ int sparx5_vcap_get_port_keyset(struct net_device *ndev, ...@@ -136,4 +136,7 @@ int sparx5_vcap_get_port_keyset(struct net_device *ndev,
u16 l3_proto, u16 l3_proto,
struct vcap_keyset_list *kslist); struct vcap_keyset_list *kslist);
/* Check if the ethertype is supported by the vcap port classification */
bool sparx5_vcap_is_known_etype(struct vcap_admin *admin, u16 etype);
#endif /* __SPARX5_VCAP_IMPL_H__ */ #endif /* __SPARX5_VCAP_IMPL_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment