1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2017 Intel Corporation
5 #include <rte_malloc.h>
8 #include "base/i40e_prototype.h"
9 #include "base/i40e_dcb.h"
10 #include "i40e_ethdev.h"
12 #include "i40e_rxtx.h"
13 #include "rte_pmd_i40e.h"
16 rte_pmd_i40e_ping_vfs(uint16_t port, uint16_t vf)
18 struct rte_eth_dev *dev;
21 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
23 dev = &rte_eth_devices[port];
25 if (!is_i40e_supported(dev))
28 pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
30 if (vf >= pf->vf_num || !pf->vfs) {
31 PMD_DRV_LOG(ERR, "Invalid argument.");
35 i40e_notify_vf_link_status(dev, &pf->vfs[vf]);
41 rte_pmd_i40e_set_vf_mac_anti_spoof(uint16_t port, uint16_t vf_id, uint8_t on)
43 struct rte_eth_dev *dev;
47 struct i40e_vsi_context ctxt;
50 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
52 dev = &rte_eth_devices[port];
54 if (!is_i40e_supported(dev))
57 pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
59 if (vf_id >= pf->vf_num || !pf->vfs) {
60 PMD_DRV_LOG(ERR, "Invalid argument.");
64 vsi = pf->vfs[vf_id].vsi;
66 PMD_DRV_LOG(ERR, "Invalid VSI.");
70 /* Check if it has been already on or off */
71 if (vsi->info.valid_sections &
72 rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SECURITY_VALID)) {
74 if ((vsi->info.sec_flags &
75 I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK) ==
76 I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK)
77 return 0; /* already on */
79 if ((vsi->info.sec_flags &
80 I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK) == 0)
81 return 0; /* already off */
85 vsi->info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SECURITY_VALID);
87 vsi->info.sec_flags |= I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK;
89 vsi->info.sec_flags &= ~I40E_AQ_VSI_SEC_FLAG_ENABLE_MAC_CHK;
91 memset(&ctxt, 0, sizeof(ctxt));
92 rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
93 ctxt.seid = vsi->seid;
95 hw = I40E_VSI_TO_HW(vsi);
96 ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
97 if (ret != I40E_SUCCESS) {
99 PMD_DRV_LOG(ERR, "Failed to update VSI params");
106 i40e_add_rm_all_vlan_filter(struct i40e_vsi *vsi, uint8_t add)
110 struct i40e_hw *hw = I40E_VSI_TO_HW(vsi);
111 struct i40e_aqc_add_remove_vlan_element_data vlan_data = {0};
114 for (j = 0; j < I40E_VFTA_SIZE; j++) {
118 for (k = 0; k < I40E_UINT32_BIT_SIZE; k++) {
119 if (!(vsi->vfta[j] & (1 << k)))
122 vlan_id = j * I40E_UINT32_BIT_SIZE + k;
126 vlan_data.vlan_tag = rte_cpu_to_le_16(vlan_id);
128 ret = i40e_aq_add_vlan(hw, vsi->seid,
129 &vlan_data, 1, NULL);
131 ret = i40e_aq_remove_vlan(hw, vsi->seid,
132 &vlan_data, 1, NULL);
133 if (ret != I40E_SUCCESS) {
135 "Failed to add/rm vlan filter");
145 rte_pmd_i40e_set_vf_vlan_anti_spoof(uint16_t port, uint16_t vf_id, uint8_t on)
147 struct rte_eth_dev *dev;
149 struct i40e_vsi *vsi;
151 struct i40e_vsi_context ctxt;
154 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
156 dev = &rte_eth_devices[port];
158 if (!is_i40e_supported(dev))
161 pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
163 if (vf_id >= pf->vf_num || !pf->vfs) {
164 PMD_DRV_LOG(ERR, "Invalid argument.");
168 vsi = pf->vfs[vf_id].vsi;
170 PMD_DRV_LOG(ERR, "Invalid VSI.");
174 /* Check if it has been already on or off */
175 if (vsi->vlan_anti_spoof_on == on)
176 return 0; /* already on or off */
178 vsi->vlan_anti_spoof_on = on;
179 if (!vsi->vlan_filter_on) {
180 ret = i40e_add_rm_all_vlan_filter(vsi, on);
182 PMD_DRV_LOG(ERR, "Failed to add/remove VLAN filters.");
187 vsi->info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SECURITY_VALID);
189 vsi->info.sec_flags |= I40E_AQ_VSI_SEC_FLAG_ENABLE_VLAN_CHK;
191 vsi->info.sec_flags &= ~I40E_AQ_VSI_SEC_FLAG_ENABLE_VLAN_CHK;
193 memset(&ctxt, 0, sizeof(ctxt));
194 rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
195 ctxt.seid = vsi->seid;
197 hw = I40E_VSI_TO_HW(vsi);
198 ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
199 if (ret != I40E_SUCCESS) {
201 PMD_DRV_LOG(ERR, "Failed to update VSI params");
208 i40e_vsi_rm_mac_filter(struct i40e_vsi *vsi)
210 struct i40e_mac_filter *f;
211 struct i40e_macvlan_filter *mv_f;
213 enum rte_mac_filter_type filter_type;
214 int ret = I40E_SUCCESS;
217 /* remove all the MACs */
218 TAILQ_FOREACH_SAFE(f, &vsi->mac_list, next, temp) {
219 vlan_num = vsi->vlan_num;
220 filter_type = f->mac_info.filter_type;
221 if (filter_type == RTE_MACVLAN_PERFECT_MATCH ||
222 filter_type == RTE_MACVLAN_HASH_MATCH) {
224 PMD_DRV_LOG(ERR, "VLAN number shouldn't be 0");
225 return I40E_ERR_PARAM;
227 } else if (filter_type == RTE_MAC_PERFECT_MATCH ||
228 filter_type == RTE_MAC_HASH_MATCH)
231 mv_f = rte_zmalloc("macvlan_data", vlan_num * sizeof(*mv_f), 0);
233 PMD_DRV_LOG(ERR, "failed to allocate memory");
234 return I40E_ERR_NO_MEMORY;
237 for (i = 0; i < vlan_num; i++) {
238 mv_f[i].filter_type = filter_type;
239 rte_memcpy(&mv_f[i].macaddr,
240 &f->mac_info.mac_addr,
243 if (filter_type == RTE_MACVLAN_PERFECT_MATCH ||
244 filter_type == RTE_MACVLAN_HASH_MATCH) {
245 ret = i40e_find_all_vlan_for_mac(vsi, mv_f, vlan_num,
246 &f->mac_info.mac_addr);
247 if (ret != I40E_SUCCESS) {
253 ret = i40e_remove_macvlan_filters(vsi, mv_f, vlan_num);
254 if (ret != I40E_SUCCESS) {
267 i40e_vsi_restore_mac_filter(struct i40e_vsi *vsi)
269 struct i40e_mac_filter *f;
270 struct i40e_macvlan_filter *mv_f;
272 int ret = I40E_SUCCESS;
275 /* restore all the MACs */
276 TAILQ_FOREACH_SAFE(f, &vsi->mac_list, next, temp) {
277 if ((f->mac_info.filter_type == RTE_MACVLAN_PERFECT_MATCH) ||
278 (f->mac_info.filter_type == RTE_MACVLAN_HASH_MATCH)) {
280 * If vlan_num is 0, that's the first time to add mac,
281 * set mask for vlan_id 0.
283 if (vsi->vlan_num == 0) {
284 i40e_set_vlan_filter(vsi, 0, 1);
287 vlan_num = vsi->vlan_num;
288 } else if ((f->mac_info.filter_type == RTE_MAC_PERFECT_MATCH) ||
289 (f->mac_info.filter_type == RTE_MAC_HASH_MATCH))
292 mv_f = rte_zmalloc("macvlan_data", vlan_num * sizeof(*mv_f), 0);
294 PMD_DRV_LOG(ERR, "failed to allocate memory");
295 return I40E_ERR_NO_MEMORY;
298 for (i = 0; i < vlan_num; i++) {
299 mv_f[i].filter_type = f->mac_info.filter_type;
300 rte_memcpy(&mv_f[i].macaddr,
301 &f->mac_info.mac_addr,
305 if (f->mac_info.filter_type == RTE_MACVLAN_PERFECT_MATCH ||
306 f->mac_info.filter_type == RTE_MACVLAN_HASH_MATCH) {
307 ret = i40e_find_all_vlan_for_mac(vsi, mv_f, vlan_num,
308 &f->mac_info.mac_addr);
309 if (ret != I40E_SUCCESS) {
315 ret = i40e_add_macvlan_filters(vsi, mv_f, vlan_num);
316 if (ret != I40E_SUCCESS) {
329 i40e_vsi_set_tx_loopback(struct i40e_vsi *vsi, uint8_t on)
331 struct i40e_vsi_context ctxt;
338 hw = I40E_VSI_TO_HW(vsi);
340 /* Use the FW API if FW >= v5.0 */
341 if (hw->aq.fw_maj_ver < 5) {
342 PMD_INIT_LOG(ERR, "FW < v5.0, cannot enable loopback");
346 /* Check if it has been already on or off */
347 if (vsi->info.valid_sections &
348 rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SWITCH_VALID)) {
350 if ((vsi->info.switch_id &
351 I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB) ==
352 I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB)
353 return 0; /* already on */
355 if ((vsi->info.switch_id &
356 I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB) == 0)
357 return 0; /* already off */
361 /* remove all the MAC and VLAN first */
362 ret = i40e_vsi_rm_mac_filter(vsi);
364 PMD_INIT_LOG(ERR, "Failed to remove MAC filters.");
367 if (vsi->vlan_anti_spoof_on || vsi->vlan_filter_on) {
368 ret = i40e_add_rm_all_vlan_filter(vsi, 0);
370 PMD_INIT_LOG(ERR, "Failed to remove VLAN filters.");
375 vsi->info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID);
377 vsi->info.switch_id |= I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB;
379 vsi->info.switch_id &= ~I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB;
381 memset(&ctxt, 0, sizeof(ctxt));
382 rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
383 ctxt.seid = vsi->seid;
385 ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
386 if (ret != I40E_SUCCESS) {
387 PMD_DRV_LOG(ERR, "Failed to update VSI params");
391 /* add all the MAC and VLAN back */
392 ret = i40e_vsi_restore_mac_filter(vsi);
395 if (vsi->vlan_anti_spoof_on || vsi->vlan_filter_on) {
396 ret = i40e_add_rm_all_vlan_filter(vsi, 1);
405 rte_pmd_i40e_set_tx_loopback(uint16_t port, uint8_t on)
407 struct rte_eth_dev *dev;
409 struct i40e_pf_vf *vf;
410 struct i40e_vsi *vsi;
414 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
416 dev = &rte_eth_devices[port];
418 if (!is_i40e_supported(dev))
421 pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
423 /* setup PF TX loopback */
425 ret = i40e_vsi_set_tx_loopback(vsi, on);
429 /* setup TX loopback for all the VFs */
431 /* if no VF, do nothing. */
435 for (vf_id = 0; vf_id < pf->vf_num; vf_id++) {
436 vf = &pf->vfs[vf_id];
439 ret = i40e_vsi_set_tx_loopback(vsi, on);
448 rte_pmd_i40e_set_vf_unicast_promisc(uint16_t port, uint16_t vf_id, uint8_t on)
450 struct rte_eth_dev *dev;
452 struct i40e_vsi *vsi;
456 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
458 dev = &rte_eth_devices[port];
460 if (!is_i40e_supported(dev))
463 pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
465 if (vf_id >= pf->vf_num || !pf->vfs) {
466 PMD_DRV_LOG(ERR, "Invalid argument.");
470 vsi = pf->vfs[vf_id].vsi;
472 PMD_DRV_LOG(ERR, "Invalid VSI.");
476 hw = I40E_VSI_TO_HW(vsi);
478 ret = i40e_aq_set_vsi_unicast_promiscuous(hw, vsi->seid,
480 if (ret != I40E_SUCCESS) {
482 PMD_DRV_LOG(ERR, "Failed to set unicast promiscuous mode");
489 rte_pmd_i40e_set_vf_multicast_promisc(uint16_t port, uint16_t vf_id, uint8_t on)
491 struct rte_eth_dev *dev;
493 struct i40e_vsi *vsi;
497 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
499 dev = &rte_eth_devices[port];
501 if (!is_i40e_supported(dev))
504 pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
506 if (vf_id >= pf->vf_num || !pf->vfs) {
507 PMD_DRV_LOG(ERR, "Invalid argument.");
511 vsi = pf->vfs[vf_id].vsi;
513 PMD_DRV_LOG(ERR, "Invalid VSI.");
517 hw = I40E_VSI_TO_HW(vsi);
519 ret = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid,
521 if (ret != I40E_SUCCESS) {
523 PMD_DRV_LOG(ERR, "Failed to set multicast promiscuous mode");
530 rte_pmd_i40e_set_vf_mac_addr(uint16_t port, uint16_t vf_id,
531 struct ether_addr *mac_addr)
533 struct i40e_mac_filter *f;
534 struct rte_eth_dev *dev;
535 struct i40e_pf_vf *vf;
536 struct i40e_vsi *vsi;
540 if (i40e_validate_mac_addr((u8 *)mac_addr) != I40E_SUCCESS)
543 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
545 dev = &rte_eth_devices[port];
547 if (!is_i40e_supported(dev))
550 pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
552 if (vf_id >= pf->vf_num || !pf->vfs)
555 vf = &pf->vfs[vf_id];
558 PMD_DRV_LOG(ERR, "Invalid VSI.");
562 ether_addr_copy(mac_addr, &vf->mac_addr);
564 /* Remove all existing mac */
565 TAILQ_FOREACH_SAFE(f, &vsi->mac_list, next, temp)
566 if (i40e_vsi_delete_mac(vsi, &f->mac_info.mac_addr)
568 PMD_DRV_LOG(WARNING, "Delete MAC failed");
573 static const struct ether_addr null_mac_addr;
576 rte_pmd_i40e_remove_vf_mac_addr(uint16_t port, uint16_t vf_id,
577 struct ether_addr *mac_addr)
579 struct rte_eth_dev *dev;
580 struct i40e_pf_vf *vf;
581 struct i40e_vsi *vsi;
584 if (i40e_validate_mac_addr((u8 *)mac_addr) != I40E_SUCCESS)
587 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
589 dev = &rte_eth_devices[port];
591 if (!is_i40e_supported(dev))
594 pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
596 if (vf_id >= pf->vf_num || !pf->vfs)
599 vf = &pf->vfs[vf_id];
602 PMD_DRV_LOG(ERR, "Invalid VSI.");
606 if (is_same_ether_addr(mac_addr, &vf->mac_addr))
607 /* Reset the mac with NULL address */
608 ether_addr_copy(&null_mac_addr, &vf->mac_addr);
611 i40e_vsi_delete_mac(vsi, mac_addr);
616 /* Set vlan strip on/off for specific VF from host */
618 rte_pmd_i40e_set_vf_vlan_stripq(uint16_t port, uint16_t vf_id, uint8_t on)
620 struct rte_eth_dev *dev;
622 struct i40e_vsi *vsi;
625 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
627 dev = &rte_eth_devices[port];
629 if (!is_i40e_supported(dev))
632 pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
634 if (vf_id >= pf->vf_num || !pf->vfs) {
635 PMD_DRV_LOG(ERR, "Invalid argument.");
639 vsi = pf->vfs[vf_id].vsi;
644 ret = i40e_vsi_config_vlan_stripping(vsi, !!on);
645 if (ret != I40E_SUCCESS) {
647 PMD_DRV_LOG(ERR, "Failed to set VLAN stripping!");
653 int rte_pmd_i40e_set_vf_vlan_insert(uint16_t port, uint16_t vf_id,
656 struct rte_eth_dev *dev;
659 struct i40e_vsi *vsi;
660 struct i40e_vsi_context ctxt;
663 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
665 if (vlan_id > ETHER_MAX_VLAN_ID) {
666 PMD_DRV_LOG(ERR, "Invalid VLAN ID.");
670 dev = &rte_eth_devices[port];
672 if (!is_i40e_supported(dev))
675 pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
676 hw = I40E_PF_TO_HW(pf);
679 * return -ENODEV if SRIOV not enabled, VF number not configured
680 * or no queue assigned.
682 if (!hw->func_caps.sr_iov_1_1 || pf->vf_num == 0 ||
686 if (vf_id >= pf->vf_num || !pf->vfs) {
687 PMD_DRV_LOG(ERR, "Invalid VF ID.");
691 vsi = pf->vfs[vf_id].vsi;
693 PMD_DRV_LOG(ERR, "Invalid VSI.");
697 vsi->info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_VLAN_VALID);
698 vsi->info.pvid = vlan_id;
700 vsi->info.port_vlan_flags |= I40E_AQ_VSI_PVLAN_INSERT_PVID;
702 vsi->info.port_vlan_flags &= ~I40E_AQ_VSI_PVLAN_INSERT_PVID;
704 memset(&ctxt, 0, sizeof(ctxt));
705 rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
706 ctxt.seid = vsi->seid;
708 hw = I40E_VSI_TO_HW(vsi);
709 ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
710 if (ret != I40E_SUCCESS) {
712 PMD_DRV_LOG(ERR, "Failed to update VSI params");
718 int rte_pmd_i40e_set_vf_broadcast(uint16_t port, uint16_t vf_id,
721 struct rte_eth_dev *dev;
723 struct i40e_vsi *vsi;
725 struct i40e_mac_filter_info filter;
726 struct ether_addr broadcast = {
727 .addr_bytes = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff} };
730 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
733 PMD_DRV_LOG(ERR, "on should be 0 or 1.");
737 dev = &rte_eth_devices[port];
739 if (!is_i40e_supported(dev))
742 pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
743 hw = I40E_PF_TO_HW(pf);
745 if (vf_id >= pf->vf_num || !pf->vfs) {
746 PMD_DRV_LOG(ERR, "Invalid VF ID.");
751 * return -ENODEV if SRIOV not enabled, VF number not configured
752 * or no queue assigned.
754 if (!hw->func_caps.sr_iov_1_1 || pf->vf_num == 0 ||
755 pf->vf_nb_qps == 0) {
756 PMD_DRV_LOG(ERR, "SRIOV is not enabled or no queue.");
760 vsi = pf->vfs[vf_id].vsi;
762 PMD_DRV_LOG(ERR, "Invalid VSI.");
767 rte_memcpy(&filter.mac_addr, &broadcast, ETHER_ADDR_LEN);
768 filter.filter_type = RTE_MACVLAN_PERFECT_MATCH;
769 ret = i40e_vsi_add_mac(vsi, &filter);
771 ret = i40e_vsi_delete_mac(vsi, &broadcast);
774 if (ret != I40E_SUCCESS && ret != I40E_ERR_PARAM) {
776 PMD_DRV_LOG(ERR, "Failed to set VSI broadcast");
784 int rte_pmd_i40e_set_vf_vlan_tag(uint16_t port, uint16_t vf_id, uint8_t on)
786 struct rte_eth_dev *dev;
789 struct i40e_vsi *vsi;
790 struct i40e_vsi_context ctxt;
793 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
796 PMD_DRV_LOG(ERR, "on should be 0 or 1.");
800 dev = &rte_eth_devices[port];
802 if (!is_i40e_supported(dev))
805 pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
806 hw = I40E_PF_TO_HW(pf);
809 * return -ENODEV if SRIOV not enabled, VF number not configured
810 * or no queue assigned.
812 if (!hw->func_caps.sr_iov_1_1 || pf->vf_num == 0 ||
813 pf->vf_nb_qps == 0) {
814 PMD_DRV_LOG(ERR, "SRIOV is not enabled or no queue.");
818 if (vf_id >= pf->vf_num || !pf->vfs) {
819 PMD_DRV_LOG(ERR, "Invalid VF ID.");
823 vsi = pf->vfs[vf_id].vsi;
825 PMD_DRV_LOG(ERR, "Invalid VSI.");
829 vsi->info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_VLAN_VALID);
831 vsi->info.port_vlan_flags |= I40E_AQ_VSI_PVLAN_MODE_TAGGED;
832 vsi->info.port_vlan_flags &= ~I40E_AQ_VSI_PVLAN_MODE_UNTAGGED;
834 vsi->info.port_vlan_flags |= I40E_AQ_VSI_PVLAN_MODE_UNTAGGED;
835 vsi->info.port_vlan_flags &= ~I40E_AQ_VSI_PVLAN_MODE_TAGGED;
838 memset(&ctxt, 0, sizeof(ctxt));
839 rte_memcpy(&ctxt.info, &vsi->info, sizeof(vsi->info));
840 ctxt.seid = vsi->seid;
842 hw = I40E_VSI_TO_HW(vsi);
843 ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
844 if (ret != I40E_SUCCESS) {
846 PMD_DRV_LOG(ERR, "Failed to update VSI params");
853 i40e_vlan_filter_count(struct i40e_vsi *vsi)
859 for (j = 0; j < I40E_VFTA_SIZE; j++) {
863 for (k = 0; k < I40E_UINT32_BIT_SIZE; k++) {
864 if (!(vsi->vfta[j] & (1 << k)))
867 vlan_id = j * I40E_UINT32_BIT_SIZE + k;
878 int rte_pmd_i40e_set_vf_vlan_filter(uint16_t port, uint16_t vlan_id,
879 uint64_t vf_mask, uint8_t on)
881 struct rte_eth_dev *dev;
884 struct i40e_vsi *vsi;
886 int ret = I40E_SUCCESS;
888 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
890 dev = &rte_eth_devices[port];
892 if (!is_i40e_supported(dev))
895 if (vlan_id > ETHER_MAX_VLAN_ID || !vlan_id) {
896 PMD_DRV_LOG(ERR, "Invalid VLAN ID.");
901 PMD_DRV_LOG(ERR, "No VF.");
906 PMD_DRV_LOG(ERR, "on is should be 0 or 1.");
910 pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
911 hw = I40E_PF_TO_HW(pf);
914 * return -ENODEV if SRIOV not enabled, VF number not configured
915 * or no queue assigned.
917 if (!hw->func_caps.sr_iov_1_1 || pf->vf_num == 0 ||
918 pf->vf_nb_qps == 0) {
919 PMD_DRV_LOG(ERR, "SRIOV is not enabled or no queue.");
923 for (vf_idx = 0; vf_idx < pf->vf_num && ret == I40E_SUCCESS; vf_idx++) {
924 if (vf_mask & ((uint64_t)(1ULL << vf_idx))) {
925 vsi = pf->vfs[vf_idx].vsi;
927 if (!vsi->vlan_filter_on) {
928 vsi->vlan_filter_on = true;
929 i40e_aq_set_vsi_vlan_promisc(hw,
933 if (!vsi->vlan_anti_spoof_on)
934 i40e_add_rm_all_vlan_filter(
937 ret = i40e_vsi_add_vlan(vsi, vlan_id);
939 ret = i40e_vsi_delete_vlan(vsi, vlan_id);
941 if (!i40e_vlan_filter_count(vsi)) {
942 vsi->vlan_filter_on = false;
943 i40e_aq_set_vsi_vlan_promisc(hw,
952 if (ret != I40E_SUCCESS) {
954 PMD_DRV_LOG(ERR, "Failed to set VF VLAN filter, on = %d", on);
961 rte_pmd_i40e_get_vf_stats(uint16_t port,
963 struct rte_eth_stats *stats)
965 struct rte_eth_dev *dev;
967 struct i40e_vsi *vsi;
969 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
971 dev = &rte_eth_devices[port];
973 if (!is_i40e_supported(dev))
976 pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
978 if (vf_id >= pf->vf_num || !pf->vfs) {
979 PMD_DRV_LOG(ERR, "Invalid VF ID.");
983 vsi = pf->vfs[vf_id].vsi;
985 PMD_DRV_LOG(ERR, "Invalid VSI.");
989 i40e_update_vsi_stats(vsi);
991 stats->ipackets = vsi->eth_stats.rx_unicast +
992 vsi->eth_stats.rx_multicast +
993 vsi->eth_stats.rx_broadcast;
994 stats->opackets = vsi->eth_stats.tx_unicast +
995 vsi->eth_stats.tx_multicast +
996 vsi->eth_stats.tx_broadcast;
997 stats->ibytes = vsi->eth_stats.rx_bytes;
998 stats->obytes = vsi->eth_stats.tx_bytes;
999 stats->ierrors = vsi->eth_stats.rx_discards;
1000 stats->oerrors = vsi->eth_stats.tx_errors + vsi->eth_stats.tx_discards;
1006 rte_pmd_i40e_reset_vf_stats(uint16_t port,
1009 struct rte_eth_dev *dev;
1011 struct i40e_vsi *vsi;
1013 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
1015 dev = &rte_eth_devices[port];
1017 if (!is_i40e_supported(dev))
1020 pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
1022 if (vf_id >= pf->vf_num || !pf->vfs) {
1023 PMD_DRV_LOG(ERR, "Invalid VF ID.");
1027 vsi = pf->vfs[vf_id].vsi;
1029 PMD_DRV_LOG(ERR, "Invalid VSI.");
1033 vsi->offset_loaded = false;
1034 i40e_update_vsi_stats(vsi);
1040 rte_pmd_i40e_set_vf_max_bw(uint16_t port, uint16_t vf_id, uint32_t bw)
1042 struct rte_eth_dev *dev;
1044 struct i40e_vsi *vsi;
1049 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
1051 dev = &rte_eth_devices[port];
1053 if (!is_i40e_supported(dev))
1056 pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
1058 if (vf_id >= pf->vf_num || !pf->vfs) {
1059 PMD_DRV_LOG(ERR, "Invalid VF ID.");
1063 vsi = pf->vfs[vf_id].vsi;
1065 PMD_DRV_LOG(ERR, "Invalid VSI.");
1069 if (bw > I40E_QOS_BW_MAX) {
1070 PMD_DRV_LOG(ERR, "Bandwidth should not be larger than %dMbps.",
1075 if (bw % I40E_QOS_BW_GRANULARITY) {
1076 PMD_DRV_LOG(ERR, "Bandwidth should be the multiple of %dMbps.",
1077 I40E_QOS_BW_GRANULARITY);
1081 bw /= I40E_QOS_BW_GRANULARITY;
1083 hw = I40E_VSI_TO_HW(vsi);
1086 if (bw == vsi->bw_info.bw_limit) {
1088 "No change for VF max bandwidth. Nothing to do.");
1093 * VF bandwidth limitation and TC bandwidth limitation cannot be
1094 * enabled in parallel, quit if TC bandwidth limitation is enabled.
1096 * If bw is 0, means disable bandwidth limitation. Then no need to
1097 * check TC bandwidth limitation.
1100 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
1101 if ((vsi->enabled_tc & BIT_ULL(i)) &&
1102 vsi->bw_info.bw_ets_credits[i])
1105 if (i != I40E_MAX_TRAFFIC_CLASS) {
1107 "TC max bandwidth has been set on this VF,"
1108 " please disable it first.");
1113 ret = i40e_aq_config_vsi_bw_limit(hw, vsi->seid, (uint16_t)bw, 0, NULL);
1116 "Failed to set VF %d bandwidth, err(%d).",
1121 /* Store the configuration. */
1122 vsi->bw_info.bw_limit = (uint16_t)bw;
1123 vsi->bw_info.bw_max = 0;
1129 rte_pmd_i40e_set_vf_tc_bw_alloc(uint16_t port, uint16_t vf_id,
1130 uint8_t tc_num, uint8_t *bw_weight)
1132 struct rte_eth_dev *dev;
1134 struct i40e_vsi *vsi;
1136 struct i40e_aqc_configure_vsi_tc_bw_data tc_bw;
1140 bool b_change = false;
1142 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
1144 dev = &rte_eth_devices[port];
1146 if (!is_i40e_supported(dev))
1149 pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
1151 if (vf_id >= pf->vf_num || !pf->vfs) {
1152 PMD_DRV_LOG(ERR, "Invalid VF ID.");
1156 vsi = pf->vfs[vf_id].vsi;
1158 PMD_DRV_LOG(ERR, "Invalid VSI.");
1162 if (tc_num > I40E_MAX_TRAFFIC_CLASS) {
1163 PMD_DRV_LOG(ERR, "TCs should be no more than %d.",
1164 I40E_MAX_TRAFFIC_CLASS);
1169 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
1170 if (vsi->enabled_tc & BIT_ULL(i))
1173 if (sum != tc_num) {
1175 "Weight should be set for all %d enabled TCs.",
1181 for (i = 0; i < tc_num; i++) {
1182 if (!bw_weight[i]) {
1184 "The weight should be 1 at least.");
1187 sum += bw_weight[i];
1191 "The summary of the TC weight should be 100.");
1196 * Create the configuration for all the TCs.
1198 memset(&tc_bw, 0, sizeof(tc_bw));
1199 tc_bw.tc_valid_bits = vsi->enabled_tc;
1201 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
1202 if (vsi->enabled_tc & BIT_ULL(i)) {
1204 vsi->bw_info.bw_ets_share_credits[i])
1207 tc_bw.tc_bw_credits[i] = bw_weight[j];
1215 "No change for TC allocated bandwidth."
1220 hw = I40E_VSI_TO_HW(vsi);
1222 ret = i40e_aq_config_vsi_tc_bw(hw, vsi->seid, &tc_bw, NULL);
1225 "Failed to set VF %d TC bandwidth weight, err(%d).",
1230 /* Store the configuration. */
1232 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
1233 if (vsi->enabled_tc & BIT_ULL(i)) {
1234 vsi->bw_info.bw_ets_share_credits[i] = bw_weight[j];
1243 rte_pmd_i40e_set_vf_tc_max_bw(uint16_t port, uint16_t vf_id,
1244 uint8_t tc_no, uint32_t bw)
1246 struct rte_eth_dev *dev;
1248 struct i40e_vsi *vsi;
1250 struct i40e_aqc_configure_vsi_ets_sla_bw_data tc_bw;
1254 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
1256 dev = &rte_eth_devices[port];
1258 if (!is_i40e_supported(dev))
1261 pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
1263 if (vf_id >= pf->vf_num || !pf->vfs) {
1264 PMD_DRV_LOG(ERR, "Invalid VF ID.");
1268 vsi = pf->vfs[vf_id].vsi;
1270 PMD_DRV_LOG(ERR, "Invalid VSI.");
1274 if (bw > I40E_QOS_BW_MAX) {
1275 PMD_DRV_LOG(ERR, "Bandwidth should not be larger than %dMbps.",
1280 if (bw % I40E_QOS_BW_GRANULARITY) {
1281 PMD_DRV_LOG(ERR, "Bandwidth should be the multiple of %dMbps.",
1282 I40E_QOS_BW_GRANULARITY);
1286 bw /= I40E_QOS_BW_GRANULARITY;
1288 if (tc_no >= I40E_MAX_TRAFFIC_CLASS) {
1289 PMD_DRV_LOG(ERR, "TC No. should be less than %d.",
1290 I40E_MAX_TRAFFIC_CLASS);
1294 hw = I40E_VSI_TO_HW(vsi);
1296 if (!(vsi->enabled_tc & BIT_ULL(tc_no))) {
1297 PMD_DRV_LOG(ERR, "VF %d TC %d isn't enabled.",
1303 if (bw == vsi->bw_info.bw_ets_credits[tc_no]) {
1305 "No change for TC max bandwidth. Nothing to do.");
1310 * VF bandwidth limitation and TC bandwidth limitation cannot be
1311 * enabled in parallel, disable VF bandwidth limitation if it's
1313 * If bw is 0, means disable bandwidth limitation. Then no need to
1314 * care about VF bandwidth limitation configuration.
1316 if (bw && vsi->bw_info.bw_limit) {
1317 ret = i40e_aq_config_vsi_bw_limit(hw, vsi->seid, 0, 0, NULL);
1320 "Failed to disable VF(%d)"
1321 " bandwidth limitation, err(%d).",
1327 "VF max bandwidth is disabled according"
1328 " to TC max bandwidth setting.");
1332 * Get all the TCs' info to create a whole picture.
1333 * Because the incremental change isn't permitted.
1335 memset(&tc_bw, 0, sizeof(tc_bw));
1336 tc_bw.tc_valid_bits = vsi->enabled_tc;
1337 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
1338 if (vsi->enabled_tc & BIT_ULL(i)) {
1339 tc_bw.tc_bw_credits[i] =
1341 vsi->bw_info.bw_ets_credits[i]);
1344 tc_bw.tc_bw_credits[tc_no] = rte_cpu_to_le_16((uint16_t)bw);
1346 ret = i40e_aq_config_vsi_ets_sla_bw_limit(hw, vsi->seid, &tc_bw, NULL);
1349 "Failed to set VF %d TC %d max bandwidth, err(%d).",
1354 /* Store the configuration. */
1355 vsi->bw_info.bw_ets_credits[tc_no] = (uint16_t)bw;
1361 rte_pmd_i40e_set_tc_strict_prio(uint16_t port, uint8_t tc_map)
1363 struct rte_eth_dev *dev;
1365 struct i40e_vsi *vsi;
1366 struct i40e_veb *veb;
1368 struct i40e_aqc_configure_switching_comp_ets_data ets_data;
1372 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
1374 dev = &rte_eth_devices[port];
1376 if (!is_i40e_supported(dev))
1379 pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
1383 PMD_DRV_LOG(ERR, "Invalid VSI.");
1389 PMD_DRV_LOG(ERR, "Invalid VEB.");
1393 if ((tc_map & veb->enabled_tc) != tc_map) {
1395 "TC bitmap isn't the subset of enabled TCs 0x%x.",
1400 if (tc_map == veb->strict_prio_tc) {
1401 PMD_DRV_LOG(INFO, "No change for TC bitmap. Nothing to do.");
1405 hw = I40E_VSI_TO_HW(vsi);
1407 /* Disable DCBx if it's the first time to set strict priority. */
1408 if (!veb->strict_prio_tc) {
1409 ret = i40e_aq_stop_lldp(hw, true, NULL);
1412 "Failed to disable DCBx as it's already"
1416 "DCBx is disabled according to strict"
1417 " priority setting.");
1420 memset(&ets_data, 0, sizeof(ets_data));
1421 ets_data.tc_valid_bits = veb->enabled_tc;
1422 ets_data.seepage = I40E_AQ_ETS_SEEPAGE_EN_MASK;
1423 ets_data.tc_strict_priority_flags = tc_map;
1424 /* Get all TCs' bandwidth. */
1425 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
1426 if (veb->enabled_tc & BIT_ULL(i)) {
1427 /* For rubust, if bandwidth is 0, use 1 instead. */
1428 if (veb->bw_info.bw_ets_share_credits[i])
1429 ets_data.tc_bw_share_credits[i] =
1430 veb->bw_info.bw_ets_share_credits[i];
1432 ets_data.tc_bw_share_credits[i] =
1433 I40E_QOS_BW_WEIGHT_MIN;
1437 if (!veb->strict_prio_tc)
1438 ret = i40e_aq_config_switch_comp_ets(
1439 hw, veb->uplink_seid,
1440 &ets_data, i40e_aqc_opc_enable_switching_comp_ets,
1443 ret = i40e_aq_config_switch_comp_ets(
1444 hw, veb->uplink_seid,
1445 &ets_data, i40e_aqc_opc_modify_switching_comp_ets,
1448 ret = i40e_aq_config_switch_comp_ets(
1449 hw, veb->uplink_seid,
1450 &ets_data, i40e_aqc_opc_disable_switching_comp_ets,
1455 "Failed to set TCs' strict priority mode."
1460 veb->strict_prio_tc = tc_map;
1462 /* Enable DCBx again, if all the TCs' strict priority disabled. */
1464 ret = i40e_aq_start_lldp(hw, NULL);
1467 "Failed to enable DCBx, err(%d).", ret);
1472 "DCBx is enabled again according to strict"
1473 " priority setting.");
1479 #define I40E_PROFILE_INFO_SIZE sizeof(struct rte_pmd_i40e_profile_info)
1480 #define I40E_MAX_PROFILE_NUM 16
1483 i40e_generate_profile_info_sec(char *name, struct i40e_ddp_version *version,
1484 uint32_t track_id, uint8_t *profile_info_sec,
1487 struct i40e_profile_section_header *sec = NULL;
1488 struct i40e_profile_info *pinfo;
1490 sec = (struct i40e_profile_section_header *)profile_info_sec;
1492 sec->data_end = sizeof(struct i40e_profile_section_header) +
1493 sizeof(struct i40e_profile_info);
1494 sec->section.type = SECTION_TYPE_INFO;
1495 sec->section.offset = sizeof(struct i40e_profile_section_header);
1496 sec->section.size = sizeof(struct i40e_profile_info);
1497 pinfo = (struct i40e_profile_info *)(profile_info_sec +
1498 sec->section.offset);
1499 pinfo->track_id = track_id;
1500 memcpy(pinfo->name, name, I40E_DDP_NAME_SIZE);
1501 memcpy(&pinfo->version, version, sizeof(struct i40e_ddp_version));
1503 pinfo->op = I40E_DDP_ADD_TRACKID;
1505 pinfo->op = I40E_DDP_REMOVE_TRACKID;
1508 static enum i40e_status_code
1509 i40e_add_rm_profile_info(struct i40e_hw *hw, uint8_t *profile_info_sec)
1511 enum i40e_status_code status = I40E_SUCCESS;
1512 struct i40e_profile_section_header *sec;
1514 uint32_t offset = 0;
1517 sec = (struct i40e_profile_section_header *)profile_info_sec;
1518 track_id = ((struct i40e_profile_info *)(profile_info_sec +
1519 sec->section.offset))->track_id;
1521 status = i40e_aq_write_ddp(hw, (void *)sec, sec->data_end,
1522 track_id, &offset, &info, NULL);
1524 PMD_DRV_LOG(ERR, "Failed to add/remove profile info: "
1525 "offset %d, info %d",
1531 /* Check if the profile info exists */
1533 i40e_check_profile_info(uint16_t port, uint8_t *profile_info_sec)
1535 struct rte_eth_dev *dev = &rte_eth_devices[port];
1536 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1538 struct rte_pmd_i40e_profile_list *p_list;
1539 struct rte_pmd_i40e_profile_info *pinfo, *p;
1542 static const uint32_t group_mask = 0x00ff0000;
1544 pinfo = (struct rte_pmd_i40e_profile_info *)(profile_info_sec +
1545 sizeof(struct i40e_profile_section_header));
1546 if (pinfo->track_id == 0) {
1547 PMD_DRV_LOG(INFO, "Read-only profile.");
1550 buff = rte_zmalloc("pinfo_list",
1551 (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4),
1554 PMD_DRV_LOG(ERR, "failed to allocate memory");
1558 ret = i40e_aq_get_ddp_list(
1560 (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4),
1563 PMD_DRV_LOG(ERR, "Failed to get profile info list.");
1567 p_list = (struct rte_pmd_i40e_profile_list *)buff;
1568 for (i = 0; i < p_list->p_count; i++) {
1569 p = &p_list->p_info[i];
1570 if (pinfo->track_id == p->track_id) {
1571 PMD_DRV_LOG(INFO, "Profile exists.");
1576 /* profile with group id 0xff is compatible with any other profile */
1577 if ((pinfo->track_id & group_mask) == group_mask) {
1581 for (i = 0; i < p_list->p_count; i++) {
1582 p = &p_list->p_info[i];
1583 if ((p->track_id & group_mask) == 0) {
1584 PMD_DRV_LOG(INFO, "Profile of the group 0 exists.");
1589 for (i = 0; i < p_list->p_count; i++) {
1590 p = &p_list->p_info[i];
1591 if ((p->track_id & group_mask) == group_mask)
1593 if ((pinfo->track_id & group_mask) !=
1594 (p->track_id & group_mask)) {
1595 PMD_DRV_LOG(INFO, "Profile of different group exists.");
1606 rte_pmd_i40e_process_ddp_package(uint16_t port, uint8_t *buff,
1608 enum rte_pmd_i40e_package_op op)
1610 struct rte_eth_dev *dev;
1612 struct i40e_package_header *pkg_hdr;
1613 struct i40e_generic_seg_header *profile_seg_hdr;
1614 struct i40e_generic_seg_header *metadata_seg_hdr;
1616 uint8_t *profile_info_sec;
1618 enum i40e_status_code status = I40E_SUCCESS;
1619 static const uint32_t type_mask = 0xff000000;
1621 if (op != RTE_PMD_I40E_PKG_OP_WR_ADD &&
1622 op != RTE_PMD_I40E_PKG_OP_WR_ONLY &&
1623 op != RTE_PMD_I40E_PKG_OP_WR_DEL) {
1624 PMD_DRV_LOG(ERR, "Operation not supported.");
1628 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
1630 dev = &rte_eth_devices[port];
1632 if (!is_i40e_supported(dev))
1635 hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
1637 if (size < (sizeof(struct i40e_package_header) +
1638 sizeof(struct i40e_metadata_segment) +
1639 sizeof(uint32_t) * 2)) {
1640 PMD_DRV_LOG(ERR, "Buff is invalid.");
1644 pkg_hdr = (struct i40e_package_header *)buff;
1647 PMD_DRV_LOG(ERR, "Failed to fill the package structure");
1651 if (pkg_hdr->segment_count < 2) {
1652 PMD_DRV_LOG(ERR, "Segment_count should be 2 at least.");
1656 /* Find metadata segment */
1657 metadata_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_METADATA,
1659 if (!metadata_seg_hdr) {
1660 PMD_DRV_LOG(ERR, "Failed to find metadata segment header");
1663 track_id = ((struct i40e_metadata_segment *)metadata_seg_hdr)->track_id;
1664 if (track_id == I40E_DDP_TRACKID_INVALID) {
1665 PMD_DRV_LOG(ERR, "Invalid track_id");
1669 /* force read-only track_id for type 0 */
1670 if ((track_id & type_mask) == 0)
1673 /* Find profile segment */
1674 profile_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_I40E,
1676 if (!profile_seg_hdr) {
1677 PMD_DRV_LOG(ERR, "Failed to find profile segment header");
1681 profile_info_sec = rte_zmalloc(
1682 "i40e_profile_info",
1683 sizeof(struct i40e_profile_section_header) +
1684 sizeof(struct i40e_profile_info),
1686 if (!profile_info_sec) {
1687 PMD_DRV_LOG(ERR, "Failed to allocate memory");
1691 /* Check if the profile already loaded */
1692 i40e_generate_profile_info_sec(
1693 ((struct i40e_profile_segment *)profile_seg_hdr)->name,
1694 &((struct i40e_profile_segment *)profile_seg_hdr)->version,
1695 track_id, profile_info_sec,
1696 op == RTE_PMD_I40E_PKG_OP_WR_ADD);
1697 is_exist = i40e_check_profile_info(port, profile_info_sec);
1699 PMD_DRV_LOG(ERR, "Failed to check profile.");
1700 rte_free(profile_info_sec);
1704 if (op == RTE_PMD_I40E_PKG_OP_WR_ADD) {
1707 PMD_DRV_LOG(ERR, "Profile already exists.");
1708 else if (is_exist == 2)
1709 PMD_DRV_LOG(ERR, "Profile of group 0 already exists.");
1710 else if (is_exist == 3)
1711 PMD_DRV_LOG(ERR, "Profile of different group already exists");
1712 rte_free(profile_info_sec);
1715 } else if (op == RTE_PMD_I40E_PKG_OP_WR_DEL) {
1716 if (is_exist != 1) {
1717 PMD_DRV_LOG(ERR, "Profile does not exist.");
1718 rte_free(profile_info_sec);
1723 if (op == RTE_PMD_I40E_PKG_OP_WR_DEL) {
1724 status = i40e_rollback_profile(
1726 (struct i40e_profile_segment *)profile_seg_hdr,
1729 PMD_DRV_LOG(ERR, "Failed to write profile for delete.");
1730 rte_free(profile_info_sec);
1734 status = i40e_write_profile(
1736 (struct i40e_profile_segment *)profile_seg_hdr,
1739 if (op == RTE_PMD_I40E_PKG_OP_WR_ADD)
1740 PMD_DRV_LOG(ERR, "Failed to write profile for add.");
1742 PMD_DRV_LOG(ERR, "Failed to write profile.");
1743 rte_free(profile_info_sec);
1748 if (track_id && (op != RTE_PMD_I40E_PKG_OP_WR_ONLY)) {
1749 /* Modify loaded profiles info list */
1750 status = i40e_add_rm_profile_info(hw, profile_info_sec);
1752 if (op == RTE_PMD_I40E_PKG_OP_WR_ADD)
1753 PMD_DRV_LOG(ERR, "Failed to add profile to info list.");
1755 PMD_DRV_LOG(ERR, "Failed to delete profile from info list.");
1759 if (op == RTE_PMD_I40E_PKG_OP_WR_ADD ||
1760 op == RTE_PMD_I40E_PKG_OP_WR_DEL)
1761 i40e_update_customized_info(dev, buff, size, op);
1763 rte_free(profile_info_sec);
1767 /* Get number of tvl records in the section */
1769 i40e_get_tlv_section_size(struct i40e_profile_section_header *sec)
1771 unsigned int i, nb_rec, nb_tlv = 0;
1772 struct i40e_profile_tlv_section_record *tlv;
1777 /* get number of records in the section */
1778 nb_rec = sec->section.size /
1779 sizeof(struct i40e_profile_tlv_section_record);
1780 for (i = 0; i < nb_rec; ) {
1781 tlv = (struct i40e_profile_tlv_section_record *)&sec[1 + i];
1788 int rte_pmd_i40e_get_ddp_info(uint8_t *pkg_buff, uint32_t pkg_size,
1789 uint8_t *info_buff, uint32_t info_size,
1790 enum rte_pmd_i40e_package_info type)
1793 struct i40e_package_header *pkg_hdr;
1794 struct i40e_generic_seg_header *i40e_seg_hdr;
1795 struct i40e_generic_seg_header *note_seg_hdr;
1796 struct i40e_generic_seg_header *metadata_seg_hdr;
1799 PMD_DRV_LOG(ERR, "Output info buff is invalid.");
1803 if (!pkg_buff || pkg_size < (sizeof(struct i40e_package_header) +
1804 sizeof(struct i40e_metadata_segment) +
1805 sizeof(uint32_t) * 2)) {
1806 PMD_DRV_LOG(ERR, "Package buff is invalid.");
1810 pkg_hdr = (struct i40e_package_header *)pkg_buff;
1811 if (pkg_hdr->segment_count < 2) {
1812 PMD_DRV_LOG(ERR, "Segment_count should be 2 at least.");
1816 /* Find metadata segment */
1817 metadata_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_METADATA,
1820 /* Find global notes segment */
1821 note_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_NOTES,
1824 /* Find i40e profile segment */
1825 i40e_seg_hdr = i40e_find_segment_in_package(SEGMENT_TYPE_I40E, pkg_hdr);
1827 /* get global header info */
1828 if (type == RTE_PMD_I40E_PKG_INFO_GLOBAL_HEADER) {
1829 struct rte_pmd_i40e_profile_info *info =
1830 (struct rte_pmd_i40e_profile_info *)info_buff;
1832 if (info_size < sizeof(struct rte_pmd_i40e_profile_info)) {
1833 PMD_DRV_LOG(ERR, "Output info buff size is invalid.");
1837 if (!metadata_seg_hdr) {
1838 PMD_DRV_LOG(ERR, "Failed to find metadata segment header");
1842 memset(info, 0, sizeof(struct rte_pmd_i40e_profile_info));
1843 info->owner = RTE_PMD_I40E_DDP_OWNER_UNKNOWN;
1845 ((struct i40e_metadata_segment *)metadata_seg_hdr)->track_id;
1848 ((struct i40e_metadata_segment *)metadata_seg_hdr)->name,
1849 I40E_DDP_NAME_SIZE);
1850 memcpy(&info->version,
1851 &((struct i40e_metadata_segment *)metadata_seg_hdr)->version,
1852 sizeof(struct i40e_ddp_version));
1853 return I40E_SUCCESS;
1856 /* get global note size */
1857 if (type == RTE_PMD_I40E_PKG_INFO_GLOBAL_NOTES_SIZE) {
1858 if (info_size < sizeof(uint32_t)) {
1859 PMD_DRV_LOG(ERR, "Invalid information buffer size");
1862 if (note_seg_hdr == NULL)
1865 ret_size = note_seg_hdr->size;
1866 *(uint32_t *)info_buff = ret_size;
1867 return I40E_SUCCESS;
1870 /* get global note */
1871 if (type == RTE_PMD_I40E_PKG_INFO_GLOBAL_NOTES) {
1872 if (note_seg_hdr == NULL)
1874 if (info_size < note_seg_hdr->size) {
1875 PMD_DRV_LOG(ERR, "Information buffer size is too small");
1878 memcpy(info_buff, ¬e_seg_hdr[1], note_seg_hdr->size);
1879 return I40E_SUCCESS;
1882 /* get i40e segment header info */
1883 if (type == RTE_PMD_I40E_PKG_INFO_HEADER) {
1884 struct rte_pmd_i40e_profile_info *info =
1885 (struct rte_pmd_i40e_profile_info *)info_buff;
1887 if (info_size < sizeof(struct rte_pmd_i40e_profile_info)) {
1888 PMD_DRV_LOG(ERR, "Output info buff size is invalid.");
1892 if (!metadata_seg_hdr) {
1893 PMD_DRV_LOG(ERR, "Failed to find metadata segment header");
1897 if (!i40e_seg_hdr) {
1898 PMD_DRV_LOG(ERR, "Failed to find i40e segment header");
1902 memset(info, 0, sizeof(struct rte_pmd_i40e_profile_info));
1903 info->owner = RTE_PMD_I40E_DDP_OWNER_UNKNOWN;
1905 ((struct i40e_metadata_segment *)metadata_seg_hdr)->track_id;
1908 ((struct i40e_profile_segment *)i40e_seg_hdr)->name,
1909 I40E_DDP_NAME_SIZE);
1910 memcpy(&info->version,
1911 &((struct i40e_profile_segment *)i40e_seg_hdr)->version,
1912 sizeof(struct i40e_ddp_version));
1913 return I40E_SUCCESS;
1916 /* get number of devices */
1917 if (type == RTE_PMD_I40E_PKG_INFO_DEVID_NUM) {
1918 if (info_size < sizeof(uint32_t)) {
1919 PMD_DRV_LOG(ERR, "Invalid information buffer size");
1922 *(uint32_t *)info_buff =
1923 ((struct i40e_profile_segment *)i40e_seg_hdr)->device_table_count;
1924 return I40E_SUCCESS;
1927 /* get list of devices */
1928 if (type == RTE_PMD_I40E_PKG_INFO_DEVID_LIST) {
1931 ((struct i40e_profile_segment *)i40e_seg_hdr)->device_table_count;
1932 if (info_size < sizeof(struct rte_pmd_i40e_ddp_device_id) * dev_num) {
1933 PMD_DRV_LOG(ERR, "Invalid information buffer size");
1937 ((struct i40e_profile_segment *)i40e_seg_hdr)->device_table,
1938 sizeof(struct rte_pmd_i40e_ddp_device_id) * dev_num);
1939 return I40E_SUCCESS;
1942 /* get number of protocols */
1943 if (type == RTE_PMD_I40E_PKG_INFO_PROTOCOL_NUM) {
1944 struct i40e_profile_section_header *proto;
1946 if (info_size < sizeof(uint32_t)) {
1947 PMD_DRV_LOG(ERR, "Invalid information buffer size");
1950 proto = i40e_find_section_in_profile(SECTION_TYPE_PROTO,
1951 (struct i40e_profile_segment *)i40e_seg_hdr);
1952 *(uint32_t *)info_buff = i40e_get_tlv_section_size(proto);
1953 return I40E_SUCCESS;
1956 /* get list of protocols */
1957 if (type == RTE_PMD_I40E_PKG_INFO_PROTOCOL_LIST) {
1958 uint32_t i, j, nb_tlv, nb_rec, nb_proto_info;
1959 struct rte_pmd_i40e_proto_info *pinfo;
1960 struct i40e_profile_section_header *proto;
1961 struct i40e_profile_tlv_section_record *tlv;
1963 pinfo = (struct rte_pmd_i40e_proto_info *)info_buff;
1964 nb_proto_info = info_size /
1965 sizeof(struct rte_pmd_i40e_proto_info);
1966 for (i = 0; i < nb_proto_info; i++) {
1967 pinfo[i].proto_id = RTE_PMD_I40E_PROTO_UNUSED;
1968 memset(pinfo[i].name, 0, RTE_PMD_I40E_DDP_NAME_SIZE);
1970 proto = i40e_find_section_in_profile(SECTION_TYPE_PROTO,
1971 (struct i40e_profile_segment *)i40e_seg_hdr);
1972 nb_tlv = i40e_get_tlv_section_size(proto);
1974 return I40E_SUCCESS;
1975 if (nb_proto_info < nb_tlv) {
1976 PMD_DRV_LOG(ERR, "Invalid information buffer size");
1979 /* get number of records in the section */
1980 nb_rec = proto->section.size /
1981 sizeof(struct i40e_profile_tlv_section_record);
1982 tlv = (struct i40e_profile_tlv_section_record *)&proto[1];
1983 for (i = j = 0; i < nb_rec; j++) {
1984 pinfo[j].proto_id = tlv->data[0];
1985 snprintf(pinfo[j].name, I40E_DDP_NAME_SIZE, "%s",
1986 (const char *)&tlv->data[1]);
1988 tlv = &tlv[tlv->len];
1990 return I40E_SUCCESS;
1993 /* get number of packet classification types */
1994 if (type == RTE_PMD_I40E_PKG_INFO_PCTYPE_NUM) {
1995 struct i40e_profile_section_header *pctype;
1997 if (info_size < sizeof(uint32_t)) {
1998 PMD_DRV_LOG(ERR, "Invalid information buffer size");
2001 pctype = i40e_find_section_in_profile(SECTION_TYPE_PCTYPE,
2002 (struct i40e_profile_segment *)i40e_seg_hdr);
2003 *(uint32_t *)info_buff = i40e_get_tlv_section_size(pctype);
2004 return I40E_SUCCESS;
2007 /* get list of packet classification types */
2008 if (type == RTE_PMD_I40E_PKG_INFO_PCTYPE_LIST) {
2009 uint32_t i, j, nb_tlv, nb_rec, nb_proto_info;
2010 struct rte_pmd_i40e_ptype_info *pinfo;
2011 struct i40e_profile_section_header *pctype;
2012 struct i40e_profile_tlv_section_record *tlv;
2014 pinfo = (struct rte_pmd_i40e_ptype_info *)info_buff;
2015 nb_proto_info = info_size /
2016 sizeof(struct rte_pmd_i40e_ptype_info);
2017 for (i = 0; i < nb_proto_info; i++)
2018 memset(&pinfo[i], RTE_PMD_I40E_PROTO_UNUSED,
2019 sizeof(struct rte_pmd_i40e_ptype_info));
2020 pctype = i40e_find_section_in_profile(SECTION_TYPE_PCTYPE,
2021 (struct i40e_profile_segment *)i40e_seg_hdr);
2022 nb_tlv = i40e_get_tlv_section_size(pctype);
2024 return I40E_SUCCESS;
2025 if (nb_proto_info < nb_tlv) {
2026 PMD_DRV_LOG(ERR, "Invalid information buffer size");
2030 /* get number of records in the section */
2031 nb_rec = pctype->section.size /
2032 sizeof(struct i40e_profile_tlv_section_record);
2033 tlv = (struct i40e_profile_tlv_section_record *)&pctype[1];
2034 for (i = j = 0; i < nb_rec; j++) {
2035 memcpy(&pinfo[j], tlv->data,
2036 sizeof(struct rte_pmd_i40e_ptype_info));
2038 tlv = &tlv[tlv->len];
2040 return I40E_SUCCESS;
2043 /* get number of packet types */
2044 if (type == RTE_PMD_I40E_PKG_INFO_PTYPE_NUM) {
2045 struct i40e_profile_section_header *ptype;
2047 if (info_size < sizeof(uint32_t)) {
2048 PMD_DRV_LOG(ERR, "Invalid information buffer size");
2051 ptype = i40e_find_section_in_profile(SECTION_TYPE_PTYPE,
2052 (struct i40e_profile_segment *)i40e_seg_hdr);
2053 *(uint32_t *)info_buff = i40e_get_tlv_section_size(ptype);
2054 return I40E_SUCCESS;
2057 /* get list of packet types */
2058 if (type == RTE_PMD_I40E_PKG_INFO_PTYPE_LIST) {
2059 uint32_t i, j, nb_tlv, nb_rec, nb_proto_info;
2060 struct rte_pmd_i40e_ptype_info *pinfo;
2061 struct i40e_profile_section_header *ptype;
2062 struct i40e_profile_tlv_section_record *tlv;
2064 pinfo = (struct rte_pmd_i40e_ptype_info *)info_buff;
2065 nb_proto_info = info_size /
2066 sizeof(struct rte_pmd_i40e_ptype_info);
2067 for (i = 0; i < nb_proto_info; i++)
2068 memset(&pinfo[i], RTE_PMD_I40E_PROTO_UNUSED,
2069 sizeof(struct rte_pmd_i40e_ptype_info));
2070 ptype = i40e_find_section_in_profile(SECTION_TYPE_PTYPE,
2071 (struct i40e_profile_segment *)i40e_seg_hdr);
2072 nb_tlv = i40e_get_tlv_section_size(ptype);
2074 return I40E_SUCCESS;
2075 if (nb_proto_info < nb_tlv) {
2076 PMD_DRV_LOG(ERR, "Invalid information buffer size");
2079 /* get number of records in the section */
2080 nb_rec = ptype->section.size /
2081 sizeof(struct i40e_profile_tlv_section_record);
2082 for (i = j = 0; i < nb_rec; j++) {
2083 tlv = (struct i40e_profile_tlv_section_record *)
2085 memcpy(&pinfo[j], tlv->data,
2086 sizeof(struct rte_pmd_i40e_ptype_info));
2089 return I40E_SUCCESS;
2092 PMD_DRV_LOG(ERR, "Info type %u is invalid.", type);
2097 rte_pmd_i40e_get_ddp_list(uint16_t port, uint8_t *buff, uint32_t size)
2099 struct rte_eth_dev *dev;
2101 enum i40e_status_code status = I40E_SUCCESS;
2103 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
2105 dev = &rte_eth_devices[port];
2107 if (!is_i40e_supported(dev))
2110 if (size < (I40E_PROFILE_INFO_SIZE * I40E_MAX_PROFILE_NUM + 4))
2113 hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
2115 status = i40e_aq_get_ddp_list(hw, (void *)buff,
2121 static int check_invalid_pkt_type(uint32_t pkt_type)
2123 uint32_t l2, l3, l4, tnl, il2, il3, il4;
2125 l2 = pkt_type & RTE_PTYPE_L2_MASK;
2126 l3 = pkt_type & RTE_PTYPE_L3_MASK;
2127 l4 = pkt_type & RTE_PTYPE_L4_MASK;
2128 tnl = pkt_type & RTE_PTYPE_TUNNEL_MASK;
2129 il2 = pkt_type & RTE_PTYPE_INNER_L2_MASK;
2130 il3 = pkt_type & RTE_PTYPE_INNER_L3_MASK;
2131 il4 = pkt_type & RTE_PTYPE_INNER_L4_MASK;
2134 l2 != RTE_PTYPE_L2_ETHER &&
2135 l2 != RTE_PTYPE_L2_ETHER_TIMESYNC &&
2136 l2 != RTE_PTYPE_L2_ETHER_ARP &&
2137 l2 != RTE_PTYPE_L2_ETHER_LLDP &&
2138 l2 != RTE_PTYPE_L2_ETHER_NSH &&
2139 l2 != RTE_PTYPE_L2_ETHER_VLAN &&
2140 l2 != RTE_PTYPE_L2_ETHER_QINQ &&
2141 l2 != RTE_PTYPE_L2_ETHER_PPPOE)
2145 l3 != RTE_PTYPE_L3_IPV4 &&
2146 l3 != RTE_PTYPE_L3_IPV4_EXT &&
2147 l3 != RTE_PTYPE_L3_IPV6 &&
2148 l3 != RTE_PTYPE_L3_IPV4_EXT_UNKNOWN &&
2149 l3 != RTE_PTYPE_L3_IPV6_EXT &&
2150 l3 != RTE_PTYPE_L3_IPV6_EXT_UNKNOWN)
2154 l4 != RTE_PTYPE_L4_TCP &&
2155 l4 != RTE_PTYPE_L4_UDP &&
2156 l4 != RTE_PTYPE_L4_FRAG &&
2157 l4 != RTE_PTYPE_L4_SCTP &&
2158 l4 != RTE_PTYPE_L4_ICMP &&
2159 l4 != RTE_PTYPE_L4_NONFRAG)
2163 tnl != RTE_PTYPE_TUNNEL_IP &&
2164 tnl != RTE_PTYPE_TUNNEL_GRENAT &&
2165 tnl != RTE_PTYPE_TUNNEL_VXLAN &&
2166 tnl != RTE_PTYPE_TUNNEL_NVGRE &&
2167 tnl != RTE_PTYPE_TUNNEL_GENEVE &&
2168 tnl != RTE_PTYPE_TUNNEL_GRENAT &&
2169 tnl != RTE_PTYPE_TUNNEL_GTPC &&
2170 tnl != RTE_PTYPE_TUNNEL_GTPU &&
2171 tnl != RTE_PTYPE_TUNNEL_L2TP)
2175 il2 != RTE_PTYPE_INNER_L2_ETHER &&
2176 il2 != RTE_PTYPE_INNER_L2_ETHER_VLAN &&
2177 il2 != RTE_PTYPE_INNER_L2_ETHER_QINQ)
2181 il3 != RTE_PTYPE_INNER_L3_IPV4 &&
2182 il3 != RTE_PTYPE_INNER_L3_IPV4_EXT &&
2183 il3 != RTE_PTYPE_INNER_L3_IPV6 &&
2184 il3 != RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN &&
2185 il3 != RTE_PTYPE_INNER_L3_IPV6_EXT &&
2186 il3 != RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN)
2190 il4 != RTE_PTYPE_INNER_L4_TCP &&
2191 il4 != RTE_PTYPE_INNER_L4_UDP &&
2192 il4 != RTE_PTYPE_INNER_L4_FRAG &&
2193 il4 != RTE_PTYPE_INNER_L4_SCTP &&
2194 il4 != RTE_PTYPE_INNER_L4_ICMP &&
2195 il4 != RTE_PTYPE_INNER_L4_NONFRAG)
2201 static int check_invalid_ptype_mapping(
2202 struct rte_pmd_i40e_ptype_mapping *mapping_table,
2207 for (i = 0; i < count; i++) {
2208 uint16_t ptype = mapping_table[i].hw_ptype;
2209 uint32_t pkt_type = mapping_table[i].sw_ptype;
2211 if (ptype >= I40E_MAX_PKT_TYPE)
2214 if (pkt_type == RTE_PTYPE_UNKNOWN)
2217 if (pkt_type & RTE_PMD_I40E_PTYPE_USER_DEFINE_MASK)
2220 if (check_invalid_pkt_type(pkt_type))
2228 rte_pmd_i40e_ptype_mapping_update(
2230 struct rte_pmd_i40e_ptype_mapping *mapping_items,
2234 struct rte_eth_dev *dev;
2235 struct i40e_adapter *ad;
2238 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
2240 dev = &rte_eth_devices[port];
2242 if (!is_i40e_supported(dev))
2245 if (count > I40E_MAX_PKT_TYPE)
2248 if (check_invalid_ptype_mapping(mapping_items, count))
2251 ad = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
2254 for (i = 0; i < I40E_MAX_PKT_TYPE; i++)
2255 ad->ptype_tbl[i] = RTE_PTYPE_UNKNOWN;
2258 for (i = 0; i < count; i++)
2259 ad->ptype_tbl[mapping_items[i].hw_ptype]
2260 = mapping_items[i].sw_ptype;
2265 int rte_pmd_i40e_ptype_mapping_reset(uint16_t port)
2267 struct rte_eth_dev *dev;
2269 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
2271 dev = &rte_eth_devices[port];
2273 if (!is_i40e_supported(dev))
2276 i40e_set_default_ptype_table(dev);
2281 int rte_pmd_i40e_ptype_mapping_get(
2283 struct rte_pmd_i40e_ptype_mapping *mapping_items,
2288 struct rte_eth_dev *dev;
2289 struct i40e_adapter *ad;
2293 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
2295 dev = &rte_eth_devices[port];
2297 if (!is_i40e_supported(dev))
2300 ad = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
2302 for (i = 0; i < I40E_MAX_PKT_TYPE; i++) {
2305 if (valid_only && ad->ptype_tbl[i] == RTE_PTYPE_UNKNOWN)
2307 mapping_items[n].hw_ptype = i;
2308 mapping_items[n].sw_ptype = ad->ptype_tbl[i];
2316 int rte_pmd_i40e_ptype_mapping_replace(uint16_t port,
2321 struct rte_eth_dev *dev;
2322 struct i40e_adapter *ad;
2325 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
2327 dev = &rte_eth_devices[port];
2329 if (!is_i40e_supported(dev))
2332 if (!mask && check_invalid_pkt_type(target))
2335 if (check_invalid_pkt_type(pkt_type))
2338 ad = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
2340 for (i = 0; i < I40E_MAX_PKT_TYPE; i++) {
2342 if ((target | ad->ptype_tbl[i]) == target &&
2343 (target & ad->ptype_tbl[i]))
2344 ad->ptype_tbl[i] = pkt_type;
2346 if (ad->ptype_tbl[i] == target)
2347 ad->ptype_tbl[i] = pkt_type;
2355 rte_pmd_i40e_add_vf_mac_addr(uint16_t port, uint16_t vf_id,
2356 struct ether_addr *mac_addr)
2358 struct rte_eth_dev *dev;
2359 struct i40e_pf_vf *vf;
2360 struct i40e_vsi *vsi;
2362 struct i40e_mac_filter_info mac_filter;
2365 if (i40e_validate_mac_addr((u8 *)mac_addr) != I40E_SUCCESS)
2368 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
2370 dev = &rte_eth_devices[port];
2372 if (!is_i40e_supported(dev))
2375 pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
2377 if (vf_id >= pf->vf_num || !pf->vfs)
2380 vf = &pf->vfs[vf_id];
2383 PMD_DRV_LOG(ERR, "Invalid VSI.");
2387 mac_filter.filter_type = RTE_MACVLAN_PERFECT_MATCH;
2388 ether_addr_copy(mac_addr, &mac_filter.mac_addr);
2389 ret = i40e_vsi_add_mac(vsi, &mac_filter);
2390 if (ret != I40E_SUCCESS) {
2391 PMD_DRV_LOG(ERR, "Failed to add MAC filter.");
2398 int rte_pmd_i40e_flow_type_mapping_reset(uint16_t port)
2400 struct rte_eth_dev *dev;
2402 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
2404 dev = &rte_eth_devices[port];
2406 if (!is_i40e_supported(dev))
2409 i40e_set_default_pctype_table(dev);
2414 int rte_pmd_i40e_flow_type_mapping_get(
2416 struct rte_pmd_i40e_flow_type_mapping *mapping_items)
2418 struct rte_eth_dev *dev;
2419 struct i40e_adapter *ad;
2422 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
2424 dev = &rte_eth_devices[port];
2426 if (!is_i40e_supported(dev))
2429 ad = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
2431 for (i = 0; i < I40E_FLOW_TYPE_MAX; i++) {
2432 mapping_items[i].flow_type = i;
2433 mapping_items[i].pctype = ad->pctypes_tbl[i];
2440 rte_pmd_i40e_flow_type_mapping_update(
2442 struct rte_pmd_i40e_flow_type_mapping *mapping_items,
2446 struct rte_eth_dev *dev;
2447 struct i40e_adapter *ad;
2450 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
2452 dev = &rte_eth_devices[port];
2454 if (!is_i40e_supported(dev))
2457 if (count > I40E_FLOW_TYPE_MAX)
2460 for (i = 0; i < count; i++)
2461 if (mapping_items[i].flow_type >= I40E_FLOW_TYPE_MAX ||
2462 mapping_items[i].flow_type == RTE_ETH_FLOW_UNKNOWN ||
2463 (mapping_items[i].pctype &
2464 (1ULL << I40E_FILTER_PCTYPE_INVALID)))
2467 ad = I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
2470 for (i = 0; i < I40E_FLOW_TYPE_MAX; i++)
2471 ad->pctypes_tbl[i] = 0ULL;
2472 ad->flow_types_mask = 0ULL;
2475 for (i = 0; i < count; i++) {
2476 ad->pctypes_tbl[mapping_items[i].flow_type] =
2477 mapping_items[i].pctype;
2478 if (mapping_items[i].pctype)
2479 ad->flow_types_mask |=
2480 (1ULL << mapping_items[i].flow_type);
2482 ad->flow_types_mask &=
2483 ~(1ULL << mapping_items[i].flow_type);
2486 for (i = 0, ad->pctypes_mask = 0ULL; i < I40E_FLOW_TYPE_MAX; i++)
2487 ad->pctypes_mask |= ad->pctypes_tbl[i];
2493 rte_pmd_i40e_query_vfid_by_mac(uint16_t port, const struct ether_addr *vf_mac)
2495 struct rte_eth_dev *dev;
2496 struct ether_addr *mac;
2499 struct i40e_pf_vf *vf;
2502 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
2503 dev = &rte_eth_devices[port];
2505 if (!is_i40e_supported(dev))
2508 pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
2509 vf_num = pf->vf_num;
2511 for (vf_id = 0; vf_id < vf_num; vf_id++) {
2512 vf = &pf->vfs[vf_id];
2513 mac = &vf->mac_addr;
2515 if (is_same_ether_addr(mac, vf_mac))
2523 i40e_vsi_update_queue_region_mapping(struct i40e_hw *hw,
2527 struct i40e_vsi *vsi = pf->main_vsi;
2528 uint16_t queue_offset, bsf, tc_index;
2529 struct i40e_vsi_context ctxt;
2530 struct i40e_aqc_vsi_properties_data *vsi_info;
2531 struct i40e_queue_regions *region_info =
2533 int32_t ret = -EINVAL;
2535 if (!region_info->queue_region_number) {
2536 PMD_INIT_LOG(ERR, "there is no that region id been set before");
2540 memset(&ctxt, 0, sizeof(struct i40e_vsi_context));
2542 /* Update Queue Pairs Mapping for currently enabled UPs */
2543 ctxt.seid = vsi->seid;
2544 ctxt.pf_num = hw->pf_id;
2546 ctxt.uplink_seid = vsi->uplink_seid;
2547 ctxt.info = vsi->info;
2548 vsi_info = &ctxt.info;
2550 memset(vsi_info->tc_mapping, 0, sizeof(uint16_t) * 8);
2551 memset(vsi_info->queue_mapping, 0, sizeof(uint16_t) * 16);
2553 /* Configure queue region and queue mapping parameters,
2554 * for enabled queue region, allocate queues to this region.
2557 for (i = 0; i < region_info->queue_region_number; i++) {
2558 tc_index = region_info->region[i].region_id;
2559 bsf = rte_bsf32(region_info->region[i].queue_num);
2560 queue_offset = region_info->region[i].queue_start_index;
2561 vsi_info->tc_mapping[tc_index] = rte_cpu_to_le_16(
2562 (queue_offset << I40E_AQ_VSI_TC_QUE_OFFSET_SHIFT) |
2563 (bsf << I40E_AQ_VSI_TC_QUE_NUMBER_SHIFT));
2566 /* Associate queue number with VSI, Keep vsi->nb_qps unchanged */
2567 vsi_info->mapping_flags |=
2568 rte_cpu_to_le_16(I40E_AQ_VSI_QUE_MAP_CONTIG);
2569 vsi_info->queue_mapping[0] = rte_cpu_to_le_16(vsi->base_queue);
2570 vsi_info->valid_sections |=
2571 rte_cpu_to_le_16(I40E_AQ_VSI_PROP_QUEUE_MAP_VALID);
2573 /* Update the VSI after updating the VSI queue-mapping information */
2574 ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
2576 PMD_DRV_LOG(ERR, "Failed to configure queue region mapping = %d ",
2577 hw->aq.asq_last_status);
2580 /* update the local VSI info with updated queue map */
2581 rte_memcpy(&vsi->info.tc_mapping, &ctxt.info.tc_mapping,
2582 sizeof(vsi->info.tc_mapping));
2583 rte_memcpy(&vsi->info.queue_mapping,
2584 &ctxt.info.queue_mapping,
2585 sizeof(vsi->info.queue_mapping));
2586 vsi->info.mapping_flags = ctxt.info.mapping_flags;
2587 vsi->info.valid_sections = 0;
2594 i40e_queue_region_set_region(struct i40e_pf *pf,
2595 struct rte_pmd_i40e_queue_region_conf *conf_ptr)
2598 struct i40e_vsi *main_vsi = pf->main_vsi;
2599 struct i40e_queue_regions *info = &pf->queue_region;
2600 int32_t ret = -EINVAL;
2602 if (!((rte_is_power_of_2(conf_ptr->queue_num)) &&
2603 conf_ptr->queue_num <= 64)) {
2604 PMD_DRV_LOG(ERR, "The region sizes should be any of the following values: 1, 2, 4, 8, 16, 32, 64 as long as the "
2605 "total number of queues do not exceed the VSI allocation");
2609 if (conf_ptr->region_id > I40E_REGION_MAX_INDEX) {
2610 PMD_DRV_LOG(ERR, "the queue region max index is 7");
2614 if ((conf_ptr->queue_start_index + conf_ptr->queue_num)
2615 > main_vsi->nb_used_qps) {
2616 PMD_DRV_LOG(ERR, "the queue index exceeds the VSI range");
2620 for (i = 0; i < info->queue_region_number; i++)
2621 if (conf_ptr->region_id == info->region[i].region_id)
2624 if (i == info->queue_region_number &&
2625 i <= I40E_REGION_MAX_INDEX) {
2626 info->region[i].region_id = conf_ptr->region_id;
2627 info->region[i].queue_num = conf_ptr->queue_num;
2628 info->region[i].queue_start_index =
2629 conf_ptr->queue_start_index;
2630 info->queue_region_number++;
2632 PMD_DRV_LOG(ERR, "queue region number exceeds maxnum 8 or the queue region id has been set before");
2640 i40e_queue_region_set_flowtype(struct i40e_pf *pf,
2641 struct rte_pmd_i40e_queue_region_conf *rss_region_conf)
2643 int32_t ret = -EINVAL;
2644 struct i40e_queue_regions *info = &pf->queue_region;
2646 uint16_t region_index, flowtype_index;
2648 /* For the pctype or hardware flowtype of packet,
2649 * the specific index for each type has been defined
2650 * in file i40e_type.h as enum i40e_filter_pctype.
2653 if (rss_region_conf->region_id > I40E_PFQF_HREGION_MAX_INDEX) {
2654 PMD_DRV_LOG(ERR, "the queue region max index is 7");
2658 if (rss_region_conf->hw_flowtype >= I40E_FILTER_PCTYPE_MAX) {
2659 PMD_DRV_LOG(ERR, "the hw_flowtype or PCTYPE max index is 63");
2664 for (i = 0; i < info->queue_region_number; i++)
2665 if (rss_region_conf->region_id == info->region[i].region_id)
2668 if (i == info->queue_region_number) {
2669 PMD_DRV_LOG(ERR, "that region id has not been set before");
2675 for (i = 0; i < info->queue_region_number; i++) {
2676 for (j = 0; j < info->region[i].flowtype_num; j++) {
2677 if (rss_region_conf->hw_flowtype ==
2678 info->region[i].hw_flowtype[j]) {
2679 PMD_DRV_LOG(ERR, "that hw_flowtype has been set before");
2685 flowtype_index = info->region[region_index].flowtype_num;
2686 info->region[region_index].hw_flowtype[flowtype_index] =
2687 rss_region_conf->hw_flowtype;
2688 info->region[region_index].flowtype_num++;
2694 i40e_queue_region_pf_flowtype_conf(struct i40e_hw *hw,
2697 uint8_t hw_flowtype;
2698 uint32_t pfqf_hregion;
2699 uint16_t i, j, index;
2700 struct i40e_queue_regions *info = &pf->queue_region;
2702 /* For the pctype or hardware flowtype of packet,
2703 * the specific index for each type has been defined
2704 * in file i40e_type.h as enum i40e_filter_pctype.
2707 for (i = 0; i < info->queue_region_number; i++) {
2708 for (j = 0; j < info->region[i].flowtype_num; j++) {
2709 hw_flowtype = info->region[i].hw_flowtype[j];
2710 index = hw_flowtype >> 3;
2712 i40e_read_rx_ctl(hw, I40E_PFQF_HREGION(index));
2714 if ((hw_flowtype & 0x7) == 0) {
2715 pfqf_hregion |= info->region[i].region_id <<
2716 I40E_PFQF_HREGION_REGION_0_SHIFT;
2717 pfqf_hregion |= 1 <<
2718 I40E_PFQF_HREGION_OVERRIDE_ENA_0_SHIFT;
2719 } else if ((hw_flowtype & 0x7) == 1) {
2720 pfqf_hregion |= info->region[i].region_id <<
2721 I40E_PFQF_HREGION_REGION_1_SHIFT;
2722 pfqf_hregion |= 1 <<
2723 I40E_PFQF_HREGION_OVERRIDE_ENA_1_SHIFT;
2724 } else if ((hw_flowtype & 0x7) == 2) {
2725 pfqf_hregion |= info->region[i].region_id <<
2726 I40E_PFQF_HREGION_REGION_2_SHIFT;
2727 pfqf_hregion |= 1 <<
2728 I40E_PFQF_HREGION_OVERRIDE_ENA_2_SHIFT;
2729 } else if ((hw_flowtype & 0x7) == 3) {
2730 pfqf_hregion |= info->region[i].region_id <<
2731 I40E_PFQF_HREGION_REGION_3_SHIFT;
2732 pfqf_hregion |= 1 <<
2733 I40E_PFQF_HREGION_OVERRIDE_ENA_3_SHIFT;
2734 } else if ((hw_flowtype & 0x7) == 4) {
2735 pfqf_hregion |= info->region[i].region_id <<
2736 I40E_PFQF_HREGION_REGION_4_SHIFT;
2737 pfqf_hregion |= 1 <<
2738 I40E_PFQF_HREGION_OVERRIDE_ENA_4_SHIFT;
2739 } else if ((hw_flowtype & 0x7) == 5) {
2740 pfqf_hregion |= info->region[i].region_id <<
2741 I40E_PFQF_HREGION_REGION_5_SHIFT;
2742 pfqf_hregion |= 1 <<
2743 I40E_PFQF_HREGION_OVERRIDE_ENA_5_SHIFT;
2744 } else if ((hw_flowtype & 0x7) == 6) {
2745 pfqf_hregion |= info->region[i].region_id <<
2746 I40E_PFQF_HREGION_REGION_6_SHIFT;
2747 pfqf_hregion |= 1 <<
2748 I40E_PFQF_HREGION_OVERRIDE_ENA_6_SHIFT;
2750 pfqf_hregion |= info->region[i].region_id <<
2751 I40E_PFQF_HREGION_REGION_7_SHIFT;
2752 pfqf_hregion |= 1 <<
2753 I40E_PFQF_HREGION_OVERRIDE_ENA_7_SHIFT;
2756 i40e_write_rx_ctl(hw, I40E_PFQF_HREGION(index),
2763 i40e_queue_region_set_user_priority(struct i40e_pf *pf,
2764 struct rte_pmd_i40e_queue_region_conf *rss_region_conf)
2766 struct i40e_queue_regions *info = &pf->queue_region;
2767 int32_t ret = -EINVAL;
2768 uint16_t i, j, region_index;
2770 if (rss_region_conf->user_priority >= I40E_MAX_USER_PRIORITY) {
2771 PMD_DRV_LOG(ERR, "the queue region max index is 7");
2775 if (rss_region_conf->region_id > I40E_REGION_MAX_INDEX) {
2776 PMD_DRV_LOG(ERR, "the region_id max index is 7");
2780 for (i = 0; i < info->queue_region_number; i++)
2781 if (rss_region_conf->region_id == info->region[i].region_id)
2784 if (i == info->queue_region_number) {
2785 PMD_DRV_LOG(ERR, "that region id has not been set before");
2792 for (i = 0; i < info->queue_region_number; i++) {
2793 for (j = 0; j < info->region[i].user_priority_num; j++) {
2794 if (info->region[i].user_priority[j] ==
2795 rss_region_conf->user_priority) {
2796 PMD_DRV_LOG(ERR, "that user priority has been set before");
2802 j = info->region[region_index].user_priority_num;
2803 info->region[region_index].user_priority[j] =
2804 rss_region_conf->user_priority;
2805 info->region[region_index].user_priority_num++;
2811 i40e_queue_region_dcb_configure(struct i40e_hw *hw,
2814 struct i40e_dcbx_config dcb_cfg_local;
2815 struct i40e_dcbx_config *dcb_cfg;
2816 struct i40e_queue_regions *info = &pf->queue_region;
2817 struct i40e_dcbx_config *old_cfg = &hw->local_dcbx_config;
2818 int32_t ret = -EINVAL;
2819 uint16_t i, j, prio_index, region_index;
2820 uint8_t tc_map, tc_bw, bw_lf;
2822 if (!info->queue_region_number) {
2823 PMD_DRV_LOG(ERR, "No queue region been set before");
2827 dcb_cfg = &dcb_cfg_local;
2828 memset(dcb_cfg, 0, sizeof(struct i40e_dcbx_config));
2830 /* assume each tc has the same bw */
2831 tc_bw = I40E_MAX_PERCENT / info->queue_region_number;
2832 for (i = 0; i < info->queue_region_number; i++)
2833 dcb_cfg->etscfg.tcbwtable[i] = tc_bw;
2834 /* to ensure the sum of tcbw is equal to 100 */
2835 bw_lf = I40E_MAX_PERCENT % info->queue_region_number;
2836 for (i = 0; i < bw_lf; i++)
2837 dcb_cfg->etscfg.tcbwtable[i]++;
2839 /* assume each tc has the same Transmission Selection Algorithm */
2840 for (i = 0; i < info->queue_region_number; i++)
2841 dcb_cfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS;
2843 for (i = 0; i < info->queue_region_number; i++) {
2844 for (j = 0; j < info->region[i].user_priority_num; j++) {
2845 prio_index = info->region[i].user_priority[j];
2846 region_index = info->region[i].region_id;
2847 dcb_cfg->etscfg.prioritytable[prio_index] =
2852 /* FW needs one App to configure HW */
2853 dcb_cfg->numapps = I40E_DEFAULT_DCB_APP_NUM;
2854 dcb_cfg->app[0].selector = I40E_APP_SEL_ETHTYPE;
2855 dcb_cfg->app[0].priority = I40E_DEFAULT_DCB_APP_PRIO;
2856 dcb_cfg->app[0].protocolid = I40E_APP_PROTOID_FCOE;
2858 tc_map = RTE_LEN2MASK(info->queue_region_number, uint8_t);
2860 dcb_cfg->pfc.willing = 0;
2861 dcb_cfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
2862 dcb_cfg->pfc.pfcenable = tc_map;
2864 /* Copy the new config to the current config */
2865 *old_cfg = *dcb_cfg;
2866 old_cfg->etsrec = old_cfg->etscfg;
2867 ret = i40e_set_dcb_config(hw);
2870 PMD_DRV_LOG(ERR, "Set queue region DCB Config failed, err %s aq_err %s",
2871 i40e_stat_str(hw, ret),
2872 i40e_aq_str(hw, hw->aq.asq_last_status));
2880 i40e_flush_queue_region_all_conf(struct rte_eth_dev *dev,
2881 struct i40e_hw *hw, struct i40e_pf *pf, uint16_t on)
2883 int32_t ret = -EINVAL;
2884 struct i40e_queue_regions *info = &pf->queue_region;
2885 struct i40e_vsi *main_vsi = pf->main_vsi;
2888 i40e_queue_region_pf_flowtype_conf(hw, pf);
2890 ret = i40e_vsi_update_queue_region_mapping(hw, pf);
2891 if (ret != I40E_SUCCESS) {
2892 PMD_DRV_LOG(INFO, "Failed to flush queue region mapping.");
2896 ret = i40e_queue_region_dcb_configure(hw, pf);
2897 if (ret != I40E_SUCCESS) {
2898 PMD_DRV_LOG(INFO, "Failed to flush dcb.");
2905 if (info->queue_region_number) {
2906 info->queue_region_number = 1;
2907 info->region[0].queue_num = main_vsi->nb_used_qps;
2908 info->region[0].queue_start_index = 0;
2910 ret = i40e_vsi_update_queue_region_mapping(hw, pf);
2911 if (ret != I40E_SUCCESS)
2912 PMD_DRV_LOG(INFO, "Failed to flush queue region mapping.");
2914 ret = i40e_dcb_init_configure(dev, TRUE);
2915 if (ret != I40E_SUCCESS) {
2916 PMD_DRV_LOG(INFO, "Failed to flush dcb.");
2917 pf->flags &= ~I40E_FLAG_DCB;
2920 i40e_init_queue_region_conf(dev);
2926 i40e_queue_region_pf_check_rss(struct i40e_pf *pf)
2928 struct i40e_hw *hw = I40E_PF_TO_HW(pf);
2931 hena = (uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(0));
2932 hena |= ((uint64_t)i40e_read_rx_ctl(hw, I40E_PFQF_HENA(1))) << 32;
2941 i40e_queue_region_get_all_info(struct i40e_pf *pf,
2942 struct i40e_queue_regions *regions_ptr)
2944 struct i40e_queue_regions *info = &pf->queue_region;
2946 rte_memcpy(regions_ptr, info,
2947 sizeof(struct i40e_queue_regions));
2952 int rte_pmd_i40e_rss_queue_region_conf(uint16_t port_id,
2953 enum rte_pmd_i40e_queue_region_op op_type, void *arg)
2955 struct rte_eth_dev *dev = &rte_eth_devices[port_id];
2956 struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
2957 struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
2960 RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
2962 if (!is_i40e_supported(dev))
2965 if (!(!i40e_queue_region_pf_check_rss(pf)))
2968 /* This queue region feature only support pf by now. It should
2969 * be called after dev_start, and will be clear after dev_stop.
2970 * "RTE_PMD_I40E_RSS_QUEUE_REGION_ALL_FLUSH_ON"
2971 * is just an enable function which server for other configuration,
2972 * it is for all configuration about queue region from up layer,
2973 * at first will only keep in DPDK softwarestored in driver,
2974 * only after "FLUSH_ON", it commit all configuration to HW.
2975 * Because PMD had to set hardware configuration at a time, so
2976 * it will record all up layer command at first.
2977 * "RTE_PMD_I40E_RSS_QUEUE_REGION_ALL_FLUSH_OFF" is
2978 * just clean all configuration about queue region just now,
2979 * and restore all to DPDK i40e driver default
2980 * config when start up.
2984 case RTE_PMD_I40E_RSS_QUEUE_REGION_SET:
2985 ret = i40e_queue_region_set_region(pf,
2986 (struct rte_pmd_i40e_queue_region_conf *)arg);
2988 case RTE_PMD_I40E_RSS_QUEUE_REGION_FLOWTYPE_SET:
2989 ret = i40e_queue_region_set_flowtype(pf,
2990 (struct rte_pmd_i40e_queue_region_conf *)arg);
2992 case RTE_PMD_I40E_RSS_QUEUE_REGION_USER_PRIORITY_SET:
2993 ret = i40e_queue_region_set_user_priority(pf,
2994 (struct rte_pmd_i40e_queue_region_conf *)arg);
2996 case RTE_PMD_I40E_RSS_QUEUE_REGION_ALL_FLUSH_ON:
2997 ret = i40e_flush_queue_region_all_conf(dev, hw, pf, 1);
2999 case RTE_PMD_I40E_RSS_QUEUE_REGION_ALL_FLUSH_OFF:
3000 ret = i40e_flush_queue_region_all_conf(dev, hw, pf, 0);
3002 case RTE_PMD_I40E_RSS_QUEUE_REGION_INFO_GET:
3003 ret = i40e_queue_region_get_all_info(pf,
3004 (struct i40e_queue_regions *)arg);
3007 PMD_DRV_LOG(WARNING, "op type (%d) not supported",
3012 I40E_WRITE_FLUSH(hw);
3017 int rte_pmd_i40e_flow_add_del_packet_template(
3019 const struct rte_pmd_i40e_pkt_template_conf *conf,
3022 struct rte_eth_dev *dev = &rte_eth_devices[port];
3023 struct i40e_fdir_filter_conf filter_conf;
3025 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
3027 if (!is_i40e_supported(dev))
3030 memset(&filter_conf, 0, sizeof(filter_conf));
3031 filter_conf.soft_id = conf->soft_id;
3032 filter_conf.input.flow.raw_flow.pctype = conf->input.pctype;
3033 filter_conf.input.flow.raw_flow.packet = conf->input.packet;
3034 filter_conf.input.flow.raw_flow.length = conf->input.length;
3035 filter_conf.input.flow_ext.pkt_template = true;
3037 filter_conf.action.rx_queue = conf->action.rx_queue;
3038 filter_conf.action.behavior =
3039 (enum i40e_fdir_behavior)conf->action.behavior;
3040 filter_conf.action.report_status =
3041 (enum i40e_fdir_status)conf->action.report_status;
3042 filter_conf.action.flex_off = conf->action.flex_off;
3044 return i40e_flow_add_del_fdir_filter(dev, &filter_conf, add);
3048 rte_pmd_i40e_inset_get(uint16_t port, uint8_t pctype,
3049 struct rte_pmd_i40e_inset *inset,
3050 enum rte_pmd_i40e_inset_type inset_type)
3052 struct rte_eth_dev *dev;
3055 uint32_t mask_reg[2];
3058 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
3060 dev = &rte_eth_devices[port];
3062 if (!is_i40e_supported(dev))
3068 hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
3069 memset(inset, 0, sizeof(struct rte_pmd_i40e_inset));
3071 switch (inset_type) {
3075 i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(1, pctype));
3076 inset_reg <<= I40E_32_BIT_WIDTH;
3078 i40e_read_rx_ctl(hw, I40E_GLQF_HASH_INSET(0, pctype));
3079 /* Get field mask */
3081 i40e_read_rx_ctl(hw, I40E_GLQF_HASH_MSK(0, pctype));
3083 i40e_read_rx_ctl(hw, I40E_GLQF_HASH_MSK(1, pctype));
3087 i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 1));
3088 inset_reg <<= I40E_32_BIT_WIDTH;
3090 i40e_read_rx_ctl(hw, I40E_PRTQF_FD_INSET(pctype, 0));
3092 i40e_read_rx_ctl(hw, I40E_GLQF_FD_MSK(0, pctype));
3094 i40e_read_rx_ctl(hw, I40E_GLQF_FD_MSK(1, pctype));
3096 case INSET_FDIR_FLX:
3098 i40e_read_rx_ctl(hw, I40E_PRTQF_FD_FLXINSET(pctype));
3100 i40e_read_rx_ctl(hw, I40E_PRTQF_FD_MSK(pctype, 0));
3102 i40e_read_rx_ctl(hw, I40E_PRTQF_FD_MSK(pctype, 1));
3105 PMD_DRV_LOG(ERR, "Unsupported input set type.");
3109 inset->inset = inset_reg;
3111 for (i = 0; i < 2; i++) {
3112 inset->mask[i].field_idx = ((mask_reg[i] >> 16) & 0x3F);
3113 inset->mask[i].mask = mask_reg[i] & 0xFFFF;
3120 rte_pmd_i40e_inset_set(uint16_t port, uint8_t pctype,
3121 struct rte_pmd_i40e_inset *inset,
3122 enum rte_pmd_i40e_inset_type inset_type)
3124 struct rte_eth_dev *dev;
3128 uint32_t mask_reg[2];
3131 RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
3133 dev = &rte_eth_devices[port];
3135 if (!is_i40e_supported(dev))
3141 hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
3142 pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
3144 if (pf->support_multi_driver) {
3145 PMD_DRV_LOG(ERR, "Input set configuration is not supported.");
3149 inset_reg = inset->inset;
3150 for (i = 0; i < 2; i++)
3151 mask_reg[i] = (inset->mask[i].field_idx << 16) |
3152 inset->mask[i].mask;
3154 switch (inset_type) {
3156 i40e_check_write_global_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
3157 (uint32_t)(inset_reg & UINT32_MAX));
3158 i40e_check_write_global_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
3159 (uint32_t)((inset_reg >>
3160 I40E_32_BIT_WIDTH) & UINT32_MAX));
3161 for (i = 0; i < 2; i++)
3162 i40e_check_write_global_reg(hw,
3163 I40E_GLQF_HASH_MSK(i, pctype),
3165 i40e_global_cfg_warning(I40E_WARNING_HASH_INSET);
3166 i40e_global_cfg_warning(I40E_WARNING_HASH_MSK);
3169 i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 0),
3170 (uint32_t)(inset_reg & UINT32_MAX));
3171 i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
3172 (uint32_t)((inset_reg >>
3173 I40E_32_BIT_WIDTH) & UINT32_MAX));
3174 for (i = 0; i < 2; i++)
3175 i40e_check_write_global_reg(hw,
3176 I40E_GLQF_FD_MSK(i, pctype),
3178 i40e_global_cfg_warning(I40E_WARNING_FD_MSK);
3180 case INSET_FDIR_FLX:
3181 i40e_check_write_reg(hw, I40E_PRTQF_FD_FLXINSET(pctype),
3182 (uint32_t)(inset_reg & UINT32_MAX));
3183 for (i = 0; i < 2; i++)
3184 i40e_check_write_reg(hw, I40E_PRTQF_FD_MSK(pctype, i),
3188 PMD_DRV_LOG(ERR, "Unsupported input set type.");
3192 I40E_WRITE_FLUSH(hw);