| 3978 | } |
| 3979 | |
| 3980 | static int |
| 3981 | i40e_vlan_offload_set(struct rte_eth_dev *dev, int mask) |
| 3982 | { |
| 3983 | struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private); |
| 3984 | struct i40e_mac_filter_info *mac_filter; |
| 3985 | struct i40e_vsi *vsi = pf->main_vsi; |
| 3986 | struct rte_eth_rxmode *rxmode; |
| 3987 | struct i40e_mac_filter *f; |
| 3988 | int i, num; |
| 3989 | void *temp; |
| 3990 | int ret; |
| 3991 | |
| 3992 | rxmode = &dev->data->dev_conf.rxmode; |
| 3993 | if (mask & RTE_ETH_VLAN_FILTER_MASK) { |
| 3994 | if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_FILTER) |
| 3995 | i40e_vsi_config_vlan_filter(vsi, TRUE); |
| 3996 | else |
| 3997 | i40e_vsi_config_vlan_filter(vsi, FALSE); |
| 3998 | } |
| 3999 | |
| 4000 | if (mask & RTE_ETH_VLAN_STRIP_MASK) { |
| 4001 | /* Enable or disable VLAN stripping */ |
| 4002 | if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_STRIP) |
| 4003 | i40e_vsi_config_vlan_stripping(vsi, TRUE); |
| 4004 | else |
| 4005 | i40e_vsi_config_vlan_stripping(vsi, FALSE); |
| 4006 | } |
| 4007 | |
| 4008 | if (mask & RTE_ETH_VLAN_EXTEND_MASK) { |
| 4009 | i = 0; |
| 4010 | num = vsi->mac_num; |
| 4011 | mac_filter = rte_zmalloc("mac_filter_info_data", |
| 4012 | num * sizeof(*mac_filter), 0); |
| 4013 | if (mac_filter == NULL) { |
| 4014 | PMD_DRV_LOG(ERR, "failed to allocate memory"); |
| 4015 | return I40E_ERR_NO_MEMORY; |
| 4016 | } |
| 4017 | |
| 4018 | /* |
| 4019 | * Outer VLAN processing is supported after firmware v8.4, kernel driver |
| 4020 | * also change the default behavior to support this feature. To align with |
| 4021 | * kernel driver, set switch config in 'i40e_vlan_tpie_set' to support for |
| 4022 | * outer VLAN processing. But it is forbidden for firmware to change the |
| 4023 | * Inner/Outer VLAN configuration while there are MAC/VLAN filters in the |
| 4024 | * switch table. Therefore, we need to clear the MAC table before setting |
| 4025 | * config, and then restore the MAC table after setting. This feature is |
| 4026 | * recommended to be used in firmware v8.6. |
| 4027 | */ |
| 4028 | /* Remove all existing mac */ |
| 4029 | RTE_TAILQ_FOREACH_SAFE(f, &vsi->mac_list, next, temp) { |
| 4030 | mac_filter[i] = f->mac_info; |
| 4031 | ret = i40e_vsi_delete_mac(vsi, &f->mac_info.mac_addr); |
| 4032 | if (ret) |
| 4033 | PMD_DRV_LOG(ERR, "i40e vsi delete mac fail."); |
| 4034 | i++; |
| 4035 | } |
| 4036 | if (rxmode->offloads & RTE_ETH_RX_OFFLOAD_VLAN_EXTEND) { |
| 4037 | i40e_vsi_config_double_vlan(vsi, TRUE); |
no test coverage detected