Commit b95d9e2c authored by Steen Hegelund's avatar Steen Hegelund Committed by David S. Miller

net: microchip: sparx5: Add ES2 VCAP keyset configuration for Sparx5

This adds the ES2 VCAP port keyset configuration for Sparx5 and also
updates the debugFS support to show the keyset configuration and the egress
port mask.
Signed-off-by: default avatarSteen Hegelund <steen.hegelund@microchip.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9d712b8d
...@@ -284,6 +284,119 @@ static void sparx5_vcap_is2_port_stickies(struct sparx5 *sparx5, ...@@ -284,6 +284,119 @@ static void sparx5_vcap_is2_port_stickies(struct sparx5 *sparx5,
out->prf(out->dst, "\n"); out->prf(out->dst, "\n");
} }
static void sparx5_vcap_es2_port_keys(struct sparx5 *sparx5,
struct vcap_admin *admin,
struct sparx5_port *port,
struct vcap_output_print *out)
{
int lookup;
u32 value;
out->prf(out->dst, " port[%02d] (%s): ", port->portno,
netdev_name(port->ndev));
for (lookup = 0; lookup < admin->lookups; ++lookup) {
out->prf(out->dst, "\n Lookup %d: ", lookup);
/* Get lookup state */
value = spx5_rd(sparx5, EACL_VCAP_ES2_KEY_SEL(port->portno,
lookup));
out->prf(out->dst, "\n state: ");
if (EACL_VCAP_ES2_KEY_SEL_KEY_ENA_GET(value))
out->prf(out->dst, "on");
else
out->prf(out->dst, "off");
out->prf(out->dst, "\n arp: ");
switch (EACL_VCAP_ES2_KEY_SEL_ARP_KEY_SEL_GET(value)) {
case VCAP_ES2_PS_ARP_MAC_ETYPE:
out->prf(out->dst, "mac_etype");
break;
case VCAP_ES2_PS_ARP_ARP:
out->prf(out->dst, "arp");
break;
}
out->prf(out->dst, "\n ipv4: ");
switch (EACL_VCAP_ES2_KEY_SEL_IP4_KEY_SEL_GET(value)) {
case VCAP_ES2_PS_IPV4_MAC_ETYPE:
out->prf(out->dst, "mac_etype");
break;
case VCAP_ES2_PS_IPV4_IP_7TUPLE:
out->prf(out->dst, "ip_7tuple");
break;
case VCAP_ES2_PS_IPV4_IP4_TCP_UDP_VID:
out->prf(out->dst, "ip4_tcp_udp ip4_vid");
break;
case VCAP_ES2_PS_IPV4_IP4_TCP_UDP_OTHER:
out->prf(out->dst, "ip4_tcp_udp ip4_other");
break;
case VCAP_ES2_PS_IPV4_IP4_VID:
out->prf(out->dst, "ip4_vid");
break;
case VCAP_ES2_PS_IPV4_IP4_OTHER:
out->prf(out->dst, "ip4_other");
break;
}
out->prf(out->dst, "\n ipv6: ");
switch (EACL_VCAP_ES2_KEY_SEL_IP6_KEY_SEL_GET(value)) {
case VCAP_ES2_PS_IPV6_MAC_ETYPE:
out->prf(out->dst, "mac_etype");
break;
case VCAP_ES2_PS_IPV6_IP_7TUPLE:
out->prf(out->dst, "ip_7tuple");
break;
case VCAP_ES2_PS_IPV6_IP_7TUPLE_VID:
out->prf(out->dst, "ip_7tuple ip6_vid");
break;
case VCAP_ES2_PS_IPV6_IP_7TUPLE_STD:
out->prf(out->dst, "ip_7tuple ip6_std");
break;
case VCAP_ES2_PS_IPV6_IP6_VID:
out->prf(out->dst, "ip6_vid");
break;
case VCAP_ES2_PS_IPV6_IP6_STD:
out->prf(out->dst, "ip6_std");
break;
case VCAP_ES2_PS_IPV6_IP4_DOWNGRADE:
out->prf(out->dst, "ip4_downgrade");
break;
}
}
out->prf(out->dst, "\n");
}
static void sparx5_vcap_es2_port_stickies(struct sparx5 *sparx5,
struct vcap_admin *admin,
struct vcap_output_print *out)
{
int lookup;
u32 value;
out->prf(out->dst, " Sticky bits: ");
for (lookup = 0; lookup < admin->lookups; ++lookup) {
value = spx5_rd(sparx5, EACL_SEC_LOOKUP_STICKY(lookup));
out->prf(out->dst, "\n Lookup %d: ", lookup);
if (EACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP_7TUPLE_STICKY_GET(value))
out->prf(out->dst, " ip_7tuple");
if (EACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP6_VID_STICKY_GET(value))
out->prf(out->dst, " ip6_vid");
if (EACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP6_STD_STICKY_GET(value))
out->prf(out->dst, " ip6_std");
if (EACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP4_TCPUDP_STICKY_GET(value))
out->prf(out->dst, " ip4_tcp_udp");
if (EACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP4_VID_STICKY_GET(value))
out->prf(out->dst, " ip4_vid");
if (EACL_SEC_LOOKUP_STICKY_SEC_TYPE_IP4_OTHER_STICKY_GET(value))
out->prf(out->dst, " ip4_other");
if (EACL_SEC_LOOKUP_STICKY_SEC_TYPE_ARP_STICKY_GET(value))
out->prf(out->dst, " arp");
if (EACL_SEC_LOOKUP_STICKY_SEC_TYPE_MAC_ETYPE_STICKY_GET(value))
out->prf(out->dst, " mac_etype");
/* Clear stickies */
spx5_wr(value, sparx5, EACL_SEC_LOOKUP_STICKY(lookup));
}
out->prf(out->dst, "\n");
}
/* Provide port information via a callback interface */ /* Provide port information via a callback interface */
int sparx5_port_info(struct net_device *ndev, int sparx5_port_info(struct net_device *ndev,
struct vcap_admin *admin, struct vcap_admin *admin,
...@@ -305,6 +418,10 @@ int sparx5_port_info(struct net_device *ndev, ...@@ -305,6 +418,10 @@ int sparx5_port_info(struct net_device *ndev,
sparx5_vcap_is2_port_keys(sparx5, admin, port, out); sparx5_vcap_is2_port_keys(sparx5, admin, port, out);
sparx5_vcap_is2_port_stickies(sparx5, admin, out); sparx5_vcap_is2_port_stickies(sparx5, admin, out);
break; break;
case VCAP_TYPE_ES2:
sparx5_vcap_es2_port_keys(sparx5, admin, port, out);
sparx5_vcap_es2_port_stickies(sparx5, admin, out);
break;
default: default:
out->prf(out->dst, " no info\n"); out->prf(out->dst, " no info\n");
break; break;
......
...@@ -32,6 +32,11 @@ ...@@ -32,6 +32,11 @@
#define SPARX5_VCAP_CID_IS2_MAX \ #define SPARX5_VCAP_CID_IS2_MAX \
(VCAP_CID_INGRESS_STAGE2_L3 + VCAP_CID_LOOKUP_SIZE - 1) /* IS2 Max */ (VCAP_CID_INGRESS_STAGE2_L3 + VCAP_CID_LOOKUP_SIZE - 1) /* IS2 Max */
#define SPARX5_VCAP_CID_ES2_L0 VCAP_CID_EGRESS_STAGE2_L0 /* ES2 lookup 0 */
#define SPARX5_VCAP_CID_ES2_L1 VCAP_CID_EGRESS_STAGE2_L1 /* ES2 lookup 1 */
#define SPARX5_VCAP_CID_ES2_MAX \
(VCAP_CID_EGRESS_STAGE2_L1 + VCAP_CID_LOOKUP_SIZE - 1) /* ES2 Max */
/* IS0 port keyset selection control */ /* IS0 port keyset selection control */
/* IS0 ethernet, IPv4, IPv6 traffic type keyset generation */ /* IS0 ethernet, IPv4, IPv6 traffic type keyset generation */
...@@ -129,6 +134,35 @@ enum vcap_is2_port_sel_arp { ...@@ -129,6 +134,35 @@ enum vcap_is2_port_sel_arp {
VCAP_IS2_PS_ARP_ARP, VCAP_IS2_PS_ARP_ARP,
}; };
/* ES2 port keyset selection control */
/* ES2 IPv4 traffic type keyset generation */
enum vcap_es2_port_sel_ipv4 {
VCAP_ES2_PS_IPV4_MAC_ETYPE,
VCAP_ES2_PS_IPV4_IP_7TUPLE,
VCAP_ES2_PS_IPV4_IP4_TCP_UDP_VID,
VCAP_ES2_PS_IPV4_IP4_TCP_UDP_OTHER,
VCAP_ES2_PS_IPV4_IP4_VID,
VCAP_ES2_PS_IPV4_IP4_OTHER,
};
/* ES2 IPv6 traffic type keyset generation */
enum vcap_es2_port_sel_ipv6 {
VCAP_ES2_PS_IPV6_MAC_ETYPE,
VCAP_ES2_PS_IPV6_IP_7TUPLE,
VCAP_ES2_PS_IPV6_IP_7TUPLE_VID,
VCAP_ES2_PS_IPV6_IP_7TUPLE_STD,
VCAP_ES2_PS_IPV6_IP6_VID,
VCAP_ES2_PS_IPV6_IP6_STD,
VCAP_ES2_PS_IPV6_IP4_DOWNGRADE,
};
/* ES2 ARP traffic type keyset generation */
enum vcap_es2_port_sel_arp {
VCAP_ES2_PS_ARP_MAC_ETYPE,
VCAP_ES2_PS_ARP_ARP,
};
/* Get the port keyset for the vcap lookup */ /* Get the port keyset for the vcap lookup */
int sparx5_vcap_get_port_keyset(struct net_device *ndev, int sparx5_vcap_get_port_keyset(struct net_device *ndev,
struct vcap_admin *admin, struct vcap_admin *admin,
......
...@@ -44,11 +44,14 @@ static void vcap_debugfs_show_rule_keyfield(struct vcap_control *vctrl, ...@@ -44,11 +44,14 @@ static void vcap_debugfs_show_rule_keyfield(struct vcap_control *vctrl,
out->prf(out->dst, "%pI4h/%pI4h", &data->u32.value, out->prf(out->dst, "%pI4h/%pI4h", &data->u32.value,
&data->u32.mask); &data->u32.mask);
} else if (key == VCAP_KF_ETYPE || } else if (key == VCAP_KF_ETYPE ||
key == VCAP_KF_IF_IGR_PORT_MASK) { key == VCAP_KF_IF_IGR_PORT_MASK ||
key == VCAP_KF_IF_EGR_PORT_MASK) {
hex = true; hex = true;
} else { } else {
u32 fmsk = (1 << keyfield[key].width) - 1; u32 fmsk = (1 << keyfield[key].width) - 1;
if (keyfield[key].width == 32)
fmsk = ~0;
out->prf(out->dst, "%u/%u", data->u32.value & fmsk, out->prf(out->dst, "%u/%u", data->u32.value & fmsk,
data->u32.mask & fmsk); data->u32.mask & fmsk);
} }
......
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