Message ID | 20211209151631.138326-3-boon.leong.ong@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | net: stmmac: add EthType Rx Frame steering | expand |
Hi BL, On Thu Dec 09 2021, Ong Boon Leong wrote: > This patch adds basic support for EtherType RX frame steering for > LLDP and PTP using the hardware offload capabilities. Maybe add an example here for users? |tc filter add dev eno1 parent ffff: protocol 0x88f7 flower hw_tc 4 |tc filter add dev eno1 parent ffff: protocol 0x88cc flower hw_tc 4 > > Signed-off-by: Ong Boon Leong <boon.leong.ong@intel.com> Something is not quite correct. The use of the etype variable generates new warnings. For instance: |drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c:768:25: warning: restricted __be16 degrades to integer |drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c:768:25: warning: restricted __be16 degrades to integer |drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c:817:22: warning: restricted __be16 degrades to integer |drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c:817:22: warning: restricted __be16 degrades to integer However, the steering works as expected. Thanks! Thanks, Kurt
On Thu Dec 09 2021, Ong Boon Leong wrote: > This patch adds basic support for EtherType RX frame steering for > LLDP and PTP using the hardware offload capabilities. > > Signed-off-by: Ong Boon Leong <boon.leong.ong@intel.com> [snip] > + if (match.mask->n_proto) { > + __be16 etype = ntohs(match.key->n_proto); n_proto is be16. The ntohs() call will produce an u16. Delta patch below. Thanks, Kurt diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 35ff7c835018..d64e42308eb6 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -182,7 +182,7 @@ enum stmmac_rfs_type { struct stmmac_rfs_entry { unsigned long cookie; - __be16 etype; + u16 etype; int in_use; int type; int idx; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c index cb7400943bb0..afa918185cf7 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c @@ -759,7 +759,7 @@ static int tc_add_ethtype_flow(struct stmmac_priv *priv, flow_rule_match_basic(rule, &match); if (match.mask->n_proto) { - __be16 etype = ntohs(match.key->n_proto); + u16 etype = ntohs(match.key->n_proto); if (match.mask->n_proto != ETHER_TYPE_FULL_MASK) { netdev_err(priv->dev, "Only full mask is supported for EthType filter");
On 2021-12-10 11:10:04 [+0100], Kurt Kanzenbach wrote: > > + if (match.mask->n_proto) { > > + __be16 etype = ntohs(match.key->n_proto); > > n_proto is be16. The ntohs() call will produce an u16. While at it, could we be please remove that __force in ETHER_TYPE_FULL_MASK and use cpu_to_be16() macro? > Thanks, > Kurt Sebastian
>[snip] > >> + if (match.mask->n_proto) { >> + __be16 etype = ntohs(match.key->n_proto); > >n_proto is be16. The ntohs() call will produce an u16. > >Delta patch below. > >Thanks, >Kurt > >diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h >b/drivers/net/ethernet/stmicro/stmmac/stmmac.h >index 35ff7c835018..d64e42308eb6 100644 >--- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h >+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h >@@ -182,7 +182,7 @@ enum stmmac_rfs_type { > > struct stmmac_rfs_entry { > unsigned long cookie; >- __be16 etype; >+ u16 etype; > int in_use; > int type; > int idx; >diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c >b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c >index cb7400943bb0..afa918185cf7 100644 >--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c >+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c >@@ -759,7 +759,7 @@ static int tc_add_ethtype_flow(struct stmmac_priv >*priv, > flow_rule_match_basic(rule, &match); > > if (match.mask->n_proto) { >- __be16 etype = ntohs(match.key->n_proto); >+ u16 etype = ntohs(match.key->n_proto); > > if (match.mask->n_proto != ETHER_TYPE_FULL_MASK) { > netdev_err(priv->dev, "Only full mask is supported for EthType >filter"); Thanks for the suggestion. I will incorporate in v2 patch after we conclude if the tc flower hw_tc interface used for specifying RxQ queue is agreeable by community.
>On 2021-12-10 11:10:04 [+0100], Kurt Kanzenbach wrote: >> > + if (match.mask->n_proto) { >> > + __be16 etype = ntohs(match.key->n_proto); >> >> n_proto is be16. The ntohs() call will produce an u16. > >While at it, could we be please remove that __force in >ETHER_TYPE_FULL_MASK and use cpu_to_be16() macro? > >> Thanks, >> Kurt > >Sebastian Thanks. Will do.
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 18a262ef17f..ce12b2fbd80 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -174,11 +174,14 @@ struct stmmac_flow_entry { /* Rx Frame Steering */ enum stmmac_rfs_type { STMMAC_RFS_T_VLAN, + STMMAC_RFS_T_LLDP, + STMMAC_RFS_T_1588, STMMAC_RFS_T_MAX, }; struct stmmac_rfs_entry { unsigned long cookie; + __be16 etype; int in_use; int type; int tc; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c index d0a2b289f46..de7ce4697a5 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_tc.c @@ -237,6 +237,8 @@ static int tc_rfs_init(struct stmmac_priv *priv) int i; priv->rfs_entries_max[STMMAC_RFS_T_VLAN] = 8; + priv->rfs_entries_max[STMMAC_RFS_T_LLDP] = 1; + priv->rfs_entries_max[STMMAC_RFS_T_1588] = 1; for (i = 0; i < STMMAC_RFS_T_MAX; i++) priv->rfs_entries_total += priv->rfs_entries_max[i]; @@ -451,6 +453,8 @@ static int tc_parse_flow_actions(struct stmmac_priv *priv, return 0; } +#define ETHER_TYPE_FULL_MASK ((__force __be16)~0) + static int tc_add_basic_flow(struct stmmac_priv *priv, struct flow_cls_offload *cls, struct stmmac_flow_entry *entry) @@ -464,6 +468,7 @@ static int tc_add_basic_flow(struct stmmac_priv *priv, return -EINVAL; flow_rule_match_basic(rule, &match); + entry->ip_proto = match.key->ip_proto; return 0; } @@ -724,6 +729,114 @@ static int tc_del_vlan_flow(struct stmmac_priv *priv, return 0; } +static int tc_add_ethtype_flow(struct stmmac_priv *priv, + struct flow_cls_offload *cls) +{ + struct stmmac_rfs_entry *entry = tc_find_rfs(priv, cls, false); + struct flow_rule *rule = flow_cls_offload_flow_rule(cls); + struct flow_dissector *dissector = rule->match.dissector; + int tc = tc_classid_to_hwtc(priv->dev, cls->classid); + struct flow_match_basic match; + + if (!entry) { + entry = tc_find_rfs(priv, cls, true); + if (!entry) + return -ENOENT; + } + + /* Nothing to do here */ + if (!dissector_uses_key(dissector, FLOW_DISSECTOR_KEY_BASIC)) + return -EINVAL; + + if (tc < 0) { + netdev_err(priv->dev, "Invalid traffic class\n"); + return -EINVAL; + } + + flow_rule_match_basic(rule, &match); + + if (match.mask->n_proto) { + __be16 etype = ntohs(match.key->n_proto); + + if (match.mask->n_proto != ETHER_TYPE_FULL_MASK) { + netdev_err(priv->dev, "Only full mask is supported for EthType filter"); + return -EINVAL; + } + switch (etype) { + case ETH_P_LLDP: + if (priv->rfs_entries_cnt[STMMAC_RFS_T_LLDP] >= + priv->rfs_entries_max[STMMAC_RFS_T_LLDP]) + return -ENOENT; + + entry->type = STMMAC_RFS_T_LLDP; + priv->rfs_entries_cnt[STMMAC_RFS_T_LLDP]++; + + stmmac_rx_queue_routing(priv, priv->hw, + PACKET_DCBCPQ, tc); + break; + case ETH_P_1588: + if (priv->rfs_entries_cnt[STMMAC_RFS_T_1588] >= + priv->rfs_entries_max[STMMAC_RFS_T_1588]) + return -ENOENT; + + entry->type = STMMAC_RFS_T_1588; + priv->rfs_entries_cnt[STMMAC_RFS_T_1588]++; + + stmmac_rx_queue_routing(priv, priv->hw, + PACKET_PTPQ, tc); + break; + default: + netdev_err(priv->dev, "EthType(0x%x) is not supported", etype); + return -EINVAL; + } + + entry->in_use = true; + entry->cookie = cls->cookie; + entry->tc = tc; + entry->etype = etype; + + return 0; + } + + return -EINVAL; +} + +static int tc_del_ethtype_flow(struct stmmac_priv *priv, + struct flow_cls_offload *cls) +{ + struct stmmac_rfs_entry *entry = tc_find_rfs(priv, cls, false); + + if (!entry || !entry->in_use || + entry->type < STMMAC_RFS_T_LLDP || + entry->type > STMMAC_RFS_T_1588) + return -ENOENT; + + switch (entry->etype) { + case ETH_P_LLDP: + stmmac_rx_queue_routing(priv, priv->hw, + PACKET_DCBCPQ, 0); + priv->rfs_entries_cnt[STMMAC_RFS_T_LLDP]--; + break; + case ETH_P_1588: + stmmac_rx_queue_routing(priv, priv->hw, + PACKET_PTPQ, 0); + priv->rfs_entries_cnt[STMMAC_RFS_T_1588]--; + break; + default: + netdev_err(priv->dev, "EthType(0x%x) is not supported", + entry->etype); + return -EINVAL; + } + + entry->in_use = false; + entry->cookie = 0; + entry->tc = 0; + entry->etype = 0; + entry->type = 0; + + return 0; +} + static int tc_add_flow_cls(struct stmmac_priv *priv, struct flow_cls_offload *cls) { @@ -733,6 +846,10 @@ static int tc_add_flow_cls(struct stmmac_priv *priv, if (!ret) return ret; + ret = tc_add_ethtype_flow(priv, cls); + if (!ret) + return ret; + return tc_add_vlan_flow(priv, cls); } @@ -745,6 +862,10 @@ static int tc_del_flow_cls(struct stmmac_priv *priv, if (!ret) return ret; + ret = tc_del_ethtype_flow(priv, cls); + if (!ret) + return ret; + return tc_del_vlan_flow(priv, cls); }
This patch adds basic support for EtherType RX frame steering for LLDP and PTP using the hardware offload capabilities. Signed-off-by: Ong Boon Leong <boon.leong.ong@intel.com> --- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 3 + .../net/ethernet/stmicro/stmmac/stmmac_tc.c | 121 ++++++++++++++++++ 2 files changed, 124 insertions(+)