+ rc = is_bnxt_in_error(bp);
+ if (rc)
+ return rc;
+
+ /* These operations apply to ALL existing MAC/VLAN filters */
+ if (on)
+ return bnxt_add_vlan_filter(bp, vlan_id);
+ else
+ return bnxt_del_vlan_filter(bp, vlan_id);
+}
+
+static int bnxt_del_dflt_mac_filter(struct bnxt *bp,
+ struct bnxt_vnic_info *vnic)
+{
+ struct bnxt_filter_info *filter;
+ int rc;
+
+ filter = STAILQ_FIRST(&vnic->filter);
+ while (filter) {
+ if (filter->mac_index == 0 &&
+ !memcmp(filter->l2_addr, bp->mac_addr,
+ RTE_ETHER_ADDR_LEN)) {
+ rc = bnxt_hwrm_clear_l2_filter(bp, filter);
+ if (!rc) {
+ STAILQ_REMOVE(&vnic->filter, filter,
+ bnxt_filter_info, next);
+ bnxt_free_filter(bp, filter);
+ }
+ return rc;
+ }
+ filter = STAILQ_NEXT(filter, next);
+ }
+ return 0;
+}
+
+static int
+bnxt_config_vlan_hw_filter(struct bnxt *bp, uint64_t rx_offloads)
+{
+ struct bnxt_vnic_info *vnic;
+ unsigned int i;
+ int rc;
+
+ vnic = BNXT_GET_DEFAULT_VNIC(bp);
+ if (!(rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER)) {
+ /* Remove any VLAN filters programmed */
+ for (i = 0; i < RTE_ETHER_MAX_VLAN_ID; i++)
+ bnxt_del_vlan_filter(bp, i);
+
+ rc = bnxt_add_mac_filter(bp, vnic, NULL, 0, 0);
+ if (rc)
+ return rc;
+ } else {
+ /* Default filter will allow packets that match the
+ * dest mac. So, it has to be deleted, otherwise, we
+ * will endup receiving vlan packets for which the
+ * filter is not programmed, when hw-vlan-filter
+ * configuration is ON
+ */
+ bnxt_del_dflt_mac_filter(bp, vnic);
+ /* This filter will allow only untagged packets */
+ bnxt_add_vlan_filter(bp, 0);
+ }
+ PMD_DRV_LOG(DEBUG, "VLAN Filtering: %d\n",
+ !!(rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER));
+
+ return 0;
+}
+
+static int bnxt_free_one_vnic(struct bnxt *bp, uint16_t vnic_id)
+{
+ struct bnxt_vnic_info *vnic = &bp->vnic_info[vnic_id];
+ unsigned int i;
+ int rc;
+
+ /* Destroy vnic filters and vnic */
+ if (bp->eth_dev->data->dev_conf.rxmode.offloads &
+ DEV_RX_OFFLOAD_VLAN_FILTER) {
+ for (i = 0; i < RTE_ETHER_MAX_VLAN_ID; i++)
+ bnxt_del_vlan_filter(bp, i);
+ }
+ bnxt_del_dflt_mac_filter(bp, vnic);
+
+ rc = bnxt_hwrm_vnic_free(bp, vnic);
+ if (rc)
+ return rc;
+
+ rte_free(vnic->fw_grp_ids);
+ vnic->fw_grp_ids = NULL;
+
+ return 0;
+}
+
+static int
+bnxt_config_vlan_hw_stripping(struct bnxt *bp, uint64_t rx_offloads)
+{
+ struct bnxt_vnic_info *vnic = BNXT_GET_DEFAULT_VNIC(bp);
+ int rc;
+
+ /* Destroy, recreate and reconfigure the default vnic */
+ rc = bnxt_free_one_vnic(bp, 0);
+ if (rc)
+ return rc;
+
+ /* default vnic 0 */
+ rc = bnxt_setup_one_vnic(bp, 0);
+ if (rc)
+ return rc;
+
+ if (bp->eth_dev->data->dev_conf.rxmode.offloads &
+ DEV_RX_OFFLOAD_VLAN_FILTER) {
+ rc = bnxt_add_vlan_filter(bp, 0);
+ if (rc)
+ return rc;
+ rc = bnxt_restore_vlan_filters(bp);
+ if (rc)
+ return rc;
+ } else {
+ rc = bnxt_add_mac_filter(bp, vnic, NULL, 0, 0);
+ if (rc)
+ return rc;
+ }
+
+ rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);