Hi Kirill, > -----Original Message----- > From: dev [mailto:dev-boun...@dpdk.org] On Behalf Of Kirill Rybalchenko > Sent: Friday, September 1, 2017 4:03 PM > To: dev@dpdk.org > Cc: Rybalchenko, Kirill <kirill.rybalche...@intel.com>; Chilikin, Andrey > <andrey.chili...@intel.com>; Xing, Beilei <beilei.x...@intel.com>; > Wu, Jingjing <jingjing...@intel.com> > Subject: [dpdk-dev] [PATCH v2 1/4] net/i40e: implement dynamic mapping of sw > flow types to hw pctypes > > Implement dynamic mapping of software flow types to hardware pctypes. > This allows to add new flow types and pctypes for DDP without changing > API of the driver. The mapping table is located in private > data area for particular network adapter and can be individually > modified with set of appropriate functions. > > Signed-off-by: Kirill Rybalchenko <kirill.rybalche...@intel.com> > --- > v2 > Re-arrange patchset to avoid compillation errors. > Remove usage of statically defined flow types and pctypes. > --- > drivers/net/i40e/i40e_ethdev.c | 347 > ++++++++++---------------------------- > drivers/net/i40e/i40e_ethdev.h | 16 +- > drivers/net/i40e/i40e_ethdev_vf.c | 36 ++-- > drivers/net/i40e/i40e_fdir.c | 51 +++--- > drivers/net/i40e/i40e_flow.c | 2 +- > drivers/net/i40e/i40e_rxtx.c | 57 +++++++ > drivers/net/i40e/i40e_rxtx.h | 1 + > 7 files changed, 190 insertions(+), 320 deletions(-) > > diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c > index 8e0580c..56a96f5 100644 > --- a/drivers/net/i40e/i40e_ethdev.c > +++ b/drivers/net/i40e/i40e_ethdev.c > @@ -1062,6 +1062,7 @@ eth_i40e_dev_init(struct rte_eth_dev *dev) > return 0; > } > i40e_set_default_ptype_table(dev); > + i40e_set_default_pctype_table(dev); > pci_dev = RTE_ETH_DEV_TO_PCI(dev); > intr_handle = &pci_dev->intr_handle; > > @@ -2971,7 +2972,7 @@ i40e_dev_info_get(struct rte_eth_dev *dev, struct > rte_eth_dev_info *dev_info) > dev_info->hash_key_size = (I40E_PFQF_HKEY_MAX_INDEX + 1) * > sizeof(uint32_t); > dev_info->reta_size = pf->hash_lut_size; > - dev_info->flow_type_rss_offloads = I40E_RSS_OFFLOAD_ALL; > + dev_info->flow_type_rss_offloads = pf->adapter->flow_types_msk; > > dev_info->default_rxconf = (struct rte_eth_rxconf) { > .rx_thresh = { > @@ -6562,104 +6563,36 @@ i40e_vsi_delete_mac(struct i40e_vsi *vsi, struct > ether_addr *addr) > > /* Configure hash enable flags for RSS */ > uint64_t > -i40e_config_hena(uint64_t flags, enum i40e_mac_type type) > +i40e_config_hena(uint64_t flags, struct i40e_adapter *adapter) > {
As a nit here and in few other functions below, to keep more conventional order of parameters: i40e_config_hena(struct i40e_adapter *adapter, ....) probably even better: 'const struct i40e_adapter *adapter' whenever possible. > uint64_t hena = 0; > + int i; > > if (!flags) > return hena; > > - if (flags & ETH_RSS_FRAG_IPV4) > - hena |= 1ULL << I40E_FILTER_PCTYPE_FRAG_IPV4; > - if (flags & ETH_RSS_NONFRAG_IPV4_TCP) { > - if (type == I40E_MAC_X722) { > - hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP) | > - (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP_SYN_NO_ACK); > - } else > - hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_TCP; > - } > - if (flags & ETH_RSS_NONFRAG_IPV4_UDP) { > - if (type == I40E_MAC_X722) { > - hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP) | > - (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV4_UDP) | > - (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV4_UDP); > - } else > - hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_UDP; > - } > - if (flags & ETH_RSS_NONFRAG_IPV4_SCTP) > - hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_SCTP; > - if (flags & ETH_RSS_NONFRAG_IPV4_OTHER) > - hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER; > - if (flags & ETH_RSS_FRAG_IPV6) > - hena |= 1ULL << I40E_FILTER_PCTYPE_FRAG_IPV6; > - if (flags & ETH_RSS_NONFRAG_IPV6_TCP) { > - if (type == I40E_MAC_X722) { > - hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP) | > - (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP_SYN_NO_ACK); > - } else > - hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_TCP; > + for (i = 0; i < I40E_FLOW_TYPE_MAX; i++) { > + if (flags & (1ULL << i)) > + hena |= adapter->pcypes_tbl[i]; > } > - if (flags & ETH_RSS_NONFRAG_IPV6_UDP) { > - if (type == I40E_MAC_X722) { > - hena |= (1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) | > - (1ULL << I40E_FILTER_PCTYPE_NONF_UNICAST_IPV6_UDP) | > - (1ULL << I40E_FILTER_PCTYPE_NONF_MULTICAST_IPV6_UDP); > - } else > - hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_UDP; > - } > - if (flags & ETH_RSS_NONFRAG_IPV6_SCTP) > - hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_SCTP; > - if (flags & ETH_RSS_NONFRAG_IPV6_OTHER) > - hena |= 1ULL << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER; > - if (flags & ETH_RSS_L2_PAYLOAD) > - hena |= 1ULL << I40E_FILTER_PCTYPE_L2_PAYLOAD; > > return hena; > } > ... > > -enum i40e_filter_pctype > -i40e_flowtype_to_pctype(uint16_t flow_type) > -{ > - static const enum i40e_filter_pctype pctype_table[] = { > - [RTE_ETH_FLOW_FRAG_IPV4] = I40E_FILTER_PCTYPE_FRAG_IPV4, > - [RTE_ETH_FLOW_NONFRAG_IPV4_UDP] = > - I40E_FILTER_PCTYPE_NONF_IPV4_UDP, > - [RTE_ETH_FLOW_NONFRAG_IPV4_TCP] = > - I40E_FILTER_PCTYPE_NONF_IPV4_TCP, > - [RTE_ETH_FLOW_NONFRAG_IPV4_SCTP] = > - I40E_FILTER_PCTYPE_NONF_IPV4_SCTP, > - [RTE_ETH_FLOW_NONFRAG_IPV4_OTHER] = > - I40E_FILTER_PCTYPE_NONF_IPV4_OTHER, > - [RTE_ETH_FLOW_FRAG_IPV6] = I40E_FILTER_PCTYPE_FRAG_IPV6, > - [RTE_ETH_FLOW_NONFRAG_IPV6_UDP] = > - I40E_FILTER_PCTYPE_NONF_IPV6_UDP, > - [RTE_ETH_FLOW_NONFRAG_IPV6_TCP] = > - I40E_FILTER_PCTYPE_NONF_IPV6_TCP, > - [RTE_ETH_FLOW_NONFRAG_IPV6_SCTP] = > - I40E_FILTER_PCTYPE_NONF_IPV6_SCTP, > - [RTE_ETH_FLOW_NONFRAG_IPV6_OTHER] = > - I40E_FILTER_PCTYPE_NONF_IPV6_OTHER, > - [RTE_ETH_FLOW_L2_PAYLOAD] = I40E_FILTER_PCTYPE_L2_PAYLOAD, > - }; > +uint16_t > +i40e_flowtype_to_pctype(uint16_t flow_type, struct i40e_adapter *adapter) > +{ > + int i; > + uint64_t pctype_mask; > > - return pctype_table[flow_type]; > + if (flow_type < I40E_FLOW_TYPE_MAX) { > + pctype_mask = adapter->pcypes_tbl[flow_type]; > + for (i = I40E_PCTYPE_MAX - 1; i >= 0; i--) { > + if (pctype_mask & (1ULL << i)) > + return (uint16_t)i; So, each pcypes_tbl[] would always have only one bit set? If so, wouldn't it be more convenient to store only bit index? > + } > + } > + return 0; As I can see, that function would return 0 for both adapter->pcypes_tbl[flow_type] == 0 and adapter->pcypes_tbl[flow_type] == 1 Is that intended? Konstantin > } >