net/bnxt: reset filter indices on free
[dpdk.git] / drivers / net / bnxt / bnxt_ethdev.c
index b1e831b..146f04b 100644 (file)
@@ -758,6 +758,7 @@ bnxt_receive_function(__rte_unused struct rte_eth_dev *eth_dev)
                DEV_RX_OFFLOAD_UDP_CKSUM |
                DEV_RX_OFFLOAD_TCP_CKSUM |
                DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM |
+               DEV_RX_OFFLOAD_RSS_HASH |
                DEV_RX_OFFLOAD_VLAN_FILTER))) {
                PMD_DRV_LOG(INFO, "Using vector mode receive for port %d\n",
                            eth_dev->data->port_id);
@@ -1006,8 +1007,6 @@ static void bnxt_mac_addr_remove_op(struct rte_eth_dev *eth_dev,
                                STAILQ_REMOVE(&vnic->filter, filter,
                                                bnxt_filter_info, next);
                                bnxt_hwrm_clear_l2_filter(bp, filter);
-                               filter->mac_index = INVALID_MAC_INDEX;
-                               memset(&filter->l2_addr, 0, RTE_ETHER_ADDR_LEN);
                                bnxt_free_filter(bp, filter);
                        }
                        filter = temp_filter;
@@ -1054,7 +1053,6 @@ static int bnxt_add_mac_filter(struct bnxt *bp, struct bnxt_vnic_info *vnic,
                else
                        STAILQ_INSERT_TAIL(&vnic->filter, filter, next);
        } else {
-               memset(&filter->l2_addr, 0, RTE_ETHER_ADDR_LEN);
                bnxt_free_filter(bp, filter);
        }
 
@@ -1270,7 +1268,7 @@ static int bnxt_reta_update_op(struct rte_eth_dev *eth_dev,
 {
        struct bnxt *bp = eth_dev->data->dev_private;
        struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
-       struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
+       struct bnxt_vnic_info *vnic = BNXT_GET_DEFAULT_VNIC(bp);
        uint16_t tbl_size = bnxt_rss_hash_tbl_size(bp);
        uint16_t idx, sft;
        int i, rc;
@@ -1327,7 +1325,7 @@ static int bnxt_reta_query_op(struct rte_eth_dev *eth_dev,
                              uint16_t reta_size)
 {
        struct bnxt *bp = eth_dev->data->dev_private;
-       struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
+       struct bnxt_vnic_info *vnic = BNXT_GET_DEFAULT_VNIC(bp);
        uint16_t tbl_size = bnxt_rss_hash_tbl_size(bp);
        uint16_t idx, sft, i;
        int rc;
@@ -1401,7 +1399,7 @@ static int bnxt_rss_hash_update_op(struct rte_eth_dev *eth_dev,
        memcpy(&bp->rss_conf, rss_conf, sizeof(*rss_conf));
 
        /* Update the default RSS VNIC(s) */
-       vnic = &bp->vnic_info[0];
+       vnic = BNXT_GET_DEFAULT_VNIC(bp);
        vnic->hash_type = bnxt_rte_to_hwrm_hash_types(rss_conf->rss_hf);
 
        /*
@@ -1427,7 +1425,7 @@ static int bnxt_rss_hash_conf_get_op(struct rte_eth_dev *eth_dev,
                                     struct rte_eth_rss_conf *rss_conf)
 {
        struct bnxt *bp = eth_dev->data->dev_private;
-       struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
+       struct bnxt_vnic_info *vnic = BNXT_GET_DEFAULT_VNIC(bp);
        int len, rc;
        uint32_t hash_types;
 
@@ -1780,7 +1778,6 @@ static int bnxt_add_vlan_filter(struct bnxt *bp, uint16_t vlan_id)
                /* Free the newly allocated filter as we were
                 * not able to create the filter in hardware.
                 */
-               filter->fw_l2_filter_id = UINT64_MAX;
                bnxt_free_filter(bp, filter);
                return rc;
        }
@@ -1830,7 +1827,6 @@ static int bnxt_del_dflt_mac_filter(struct bnxt *bp,
                                STAILQ_REMOVE(&vnic->filter, filter,
                                              bnxt_filter_info, next);
                                bnxt_free_filter(bp, filter);
-                               filter->fw_l2_filter_id = UINT64_MAX;
                        }
                        return rc;
                }
@@ -1963,7 +1959,7 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev,
 {
        struct bnxt *bp = dev->data->dev_private;
        /* Default Filter is tied to VNIC 0 */
-       struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
+       struct bnxt_vnic_info *vnic = BNXT_GET_DEFAULT_VNIC(bp);
        struct bnxt_filter_info *filter;
        int rc;
 
@@ -2377,7 +2373,7 @@ bnxt_match_and_validate_ether_filter(struct bnxt *bp,
                goto exit;
        }
 
-       vnic0 = &bp->vnic_info[0];
+       vnic0 = BNXT_GET_DEFAULT_VNIC(bp);
        vnic = &bp->vnic_info[efilter->queue];
        if (vnic == NULL) {
                PMD_DRV_LOG(ERR, "Invalid queue %d\n", efilter->queue);
@@ -2436,7 +2432,7 @@ bnxt_ethertype_filter(struct rte_eth_dev *dev,
                return -EINVAL;
        }
 
-       vnic0 = &bp->vnic_info[0];
+       vnic0 = BNXT_GET_DEFAULT_VNIC(bp);
        vnic = &bp->vnic_info[efilter->queue];
 
        switch (filter_op) {
@@ -2651,7 +2647,7 @@ bnxt_cfg_ntuple_filter(struct bnxt *bp,
                goto free_filter;
 
        vnic = &bp->vnic_info[nfilter->queue];
-       vnic0 = &bp->vnic_info[0];
+       vnic0 = BNXT_GET_DEFAULT_VNIC(bp);
        filter1 = STAILQ_FIRST(&vnic0->filter);
        if (filter1 == NULL) {
                ret = -EINVAL;
@@ -2704,14 +2700,11 @@ bnxt_cfg_ntuple_filter(struct bnxt *bp,
 
                STAILQ_REMOVE(&vnic->filter, mfilter, bnxt_filter_info, next);
                bnxt_free_filter(bp, mfilter);
-               mfilter->fw_l2_filter_id = -1;
                bnxt_free_filter(bp, bfilter);
-               bfilter->fw_l2_filter_id = -1;
        }
 
        return 0;
 free_filter:
-       bfilter->fw_l2_filter_id = -1;
        bnxt_free_filter(bp, bfilter);
        return ret;
 }
@@ -2944,7 +2937,7 @@ bnxt_parse_fdir_filter(struct bnxt *bp,
                return -EINVAL;
        }
 
-       vnic0 = &bp->vnic_info[0];
+       vnic0 = BNXT_GET_DEFAULT_VNIC(bp);
        vnic = &bp->vnic_info[fdir->action.rx_queue];
        if (vnic == NULL) {
                PMD_DRV_LOG(ERR, "Invalid queue %d\n", fdir->action.rx_queue);
@@ -3109,7 +3102,6 @@ bnxt_fdir_filter(struct rte_eth_dev *dev,
                        STAILQ_REMOVE(&vnic->filter, match,
                                      bnxt_filter_info, next);
                        bnxt_free_filter(bp, match);
-                       filter->fw_l2_filter_id = -1;
                        bnxt_free_filter(bp, filter);
                }
                break;
@@ -3142,13 +3134,12 @@ bnxt_fdir_filter(struct rte_eth_dev *dev,
        return ret;
 
 free_filter:
-       filter->fw_l2_filter_id = -1;
        bnxt_free_filter(bp, filter);
        return ret;
 }
 
 static int
-bnxt_filter_ctrl_op(struct rte_eth_dev *dev __rte_unused,
+bnxt_filter_ctrl_op(struct rte_eth_dev *dev,
                    enum rte_filter_type filter_type,
                    enum rte_filter_op filter_op, void *arg)
 {
@@ -3795,6 +3786,71 @@ static void bnxt_dev_cleanup(struct bnxt *bp)
        bnxt_uninit_resources(bp, true);
 }
 
+static int bnxt_restore_vlan_filters(struct bnxt *bp)
+{
+       struct rte_eth_dev *dev = bp->eth_dev;
+       struct rte_vlan_filter_conf *vfc;
+       int vidx, vbit, rc;
+       uint16_t vlan_id;
+
+       for (vlan_id = 1; vlan_id <= RTE_ETHER_MAX_VLAN_ID; vlan_id++) {
+               vfc = &dev->data->vlan_filter_conf;
+               vidx = vlan_id / 64;
+               vbit = vlan_id % 64;
+
+               /* Each bit corresponds to a VLAN id */
+               if (vfc->ids[vidx] & (UINT64_C(1) << vbit)) {
+                       rc = bnxt_add_vlan_filter(bp, vlan_id);
+                       if (rc)
+                               return rc;
+               }
+       }
+
+       return 0;
+}
+
+static int bnxt_restore_mac_filters(struct bnxt *bp)
+{
+       struct rte_eth_dev *dev = bp->eth_dev;
+       struct rte_eth_dev_info dev_info;
+       struct rte_ether_addr *addr;
+       uint64_t pool_mask;
+       uint32_t pool = 0;
+       uint16_t i;
+       int rc;
+
+       if (BNXT_VF(bp) & !BNXT_VF_IS_TRUSTED(bp))
+               return 0;
+
+       rc = bnxt_dev_info_get_op(dev, &dev_info);
+       if (rc)
+               return rc;
+
+       /* replay MAC address configuration */
+       for (i = 1; i < dev_info.max_mac_addrs; i++) {
+               addr = &dev->data->mac_addrs[i];
+
+               /* skip zero address */
+               if (rte_is_zero_ether_addr(addr))
+                       continue;
+
+               pool = 0;
+               pool_mask = dev->data->mac_pool_sel[i];
+
+               do {
+                       if (pool_mask & 1ULL) {
+                               rc = bnxt_mac_addr_add_op(dev, addr, i, pool);
+                               if (rc)
+                                       return rc;
+                       }
+                       pool_mask >>= 1;
+                       pool++;
+               } while (pool_mask);
+       }
+
+       return 0;
+}
+
 static int bnxt_restore_filters(struct bnxt *bp)
 {
        struct rte_eth_dev *dev = bp->eth_dev;
@@ -3805,6 +3861,11 @@ static int bnxt_restore_filters(struct bnxt *bp)
        if (dev->data->promiscuous)
                ret = bnxt_promiscuous_enable_op(dev);
 
+       ret = bnxt_restore_mac_filters(bp);
+       if (ret)
+               return ret;
+
+       ret = bnxt_restore_vlan_filters(bp);
        /* TODO restore other filters as well */
        return ret;
 }
@@ -4027,49 +4088,60 @@ static void bnxt_cancel_fw_health_check(struct bnxt *bp)
        bp->flags &= ~BNXT_FLAG_FW_HEALTH_CHECK_SCHEDULED;
 }
 
-static bool bnxt_vf_pciid(uint16_t id)
+static bool bnxt_vf_pciid(uint16_t device_id)
 {
-       if (id == BROADCOM_DEV_ID_57304_VF ||
-           id == BROADCOM_DEV_ID_57406_VF ||
-           id == BROADCOM_DEV_ID_5731X_VF ||
-           id == BROADCOM_DEV_ID_5741X_VF ||
-           id == BROADCOM_DEV_ID_57414_VF ||
-           id == BROADCOM_DEV_ID_STRATUS_NIC_VF1 ||
-           id == BROADCOM_DEV_ID_STRATUS_NIC_VF2 ||
-           id == BROADCOM_DEV_ID_58802_VF ||
-           id == BROADCOM_DEV_ID_57500_VF1 ||
-           id == BROADCOM_DEV_ID_57500_VF2)
+       switch (device_id) {
+       case BROADCOM_DEV_ID_57304_VF:
+       case BROADCOM_DEV_ID_57406_VF:
+       case BROADCOM_DEV_ID_5731X_VF:
+       case BROADCOM_DEV_ID_5741X_VF:
+       case BROADCOM_DEV_ID_57414_VF:
+       case BROADCOM_DEV_ID_STRATUS_NIC_VF1:
+       case BROADCOM_DEV_ID_STRATUS_NIC_VF2:
+       case BROADCOM_DEV_ID_58802_VF:
+       case BROADCOM_DEV_ID_57500_VF1:
+       case BROADCOM_DEV_ID_57500_VF2:
+               /* FALLTHROUGH */
                return true;
-       return false;
+       default:
+               return false;
+       }
 }
 
-static bool bnxt_thor_device(uint16_t id)
+static bool bnxt_thor_device(uint16_t device_id)
 {
-       if (id == BROADCOM_DEV_ID_57508 ||
-           id == BROADCOM_DEV_ID_57504 ||
-           id == BROADCOM_DEV_ID_57502 ||
-           id == BROADCOM_DEV_ID_57508_MF1 ||
-           id == BROADCOM_DEV_ID_57504_MF1 ||
-           id == BROADCOM_DEV_ID_57502_MF1 ||
-           id == BROADCOM_DEV_ID_57508_MF2 ||
-           id == BROADCOM_DEV_ID_57504_MF2 ||
-           id == BROADCOM_DEV_ID_57502_MF2 ||
-           id == BROADCOM_DEV_ID_57500_VF1 ||
-           id == BROADCOM_DEV_ID_57500_VF2)
+       switch (device_id) {
+       case BROADCOM_DEV_ID_57508:
+       case BROADCOM_DEV_ID_57504:
+       case BROADCOM_DEV_ID_57502:
+       case BROADCOM_DEV_ID_57508_MF1:
+       case BROADCOM_DEV_ID_57504_MF1:
+       case BROADCOM_DEV_ID_57502_MF1:
+       case BROADCOM_DEV_ID_57508_MF2:
+       case BROADCOM_DEV_ID_57504_MF2:
+       case BROADCOM_DEV_ID_57502_MF2:
+       case BROADCOM_DEV_ID_57500_VF1:
+       case BROADCOM_DEV_ID_57500_VF2:
+               /* FALLTHROUGH */
                return true;
-
-       return false;
+       default:
+               return false;
+       }
 }
 
 bool bnxt_stratus_device(struct bnxt *bp)
 {
-       uint16_t id = bp->pdev->id.device_id;
+       uint16_t device_id = bp->pdev->id.device_id;
 
-       if (id == BROADCOM_DEV_ID_STRATUS_NIC ||
-           id == BROADCOM_DEV_ID_STRATUS_NIC_VF1 ||
-           id == BROADCOM_DEV_ID_STRATUS_NIC_VF2)
+       switch (device_id) {
+       case BROADCOM_DEV_ID_STRATUS_NIC:
+       case BROADCOM_DEV_ID_STRATUS_NIC_VF1:
+       case BROADCOM_DEV_ID_STRATUS_NIC_VF2:
+               /* FALLTHROUGH */
                return true;
-       return false;
+       default:
+               return false;
+       }
 }
 
 static int bnxt_init_board(struct rte_eth_dev *eth_dev)
@@ -4091,7 +4163,7 @@ static int bnxt_init_board(struct rte_eth_dev *eth_dev)
        return 0;
 }
 
-static int bnxt_alloc_ctx_mem_blk(__rte_unused struct bnxt *bp,
+static int bnxt_alloc_ctx_mem_blk(struct bnxt *bp,
                                  struct bnxt_ctx_pg_info *ctx_pg,
                                  uint32_t mem_size,
                                  const char *suffix,