net/bnxt: fix enable/disable VLAN filtering
[dpdk.git] / drivers / net / bnxt / bnxt_ethdev.c
index 88df82b..83f475d 100644 (file)
@@ -439,8 +439,11 @@ skip_cosq_cfg:
 
        /* enable uio/vfio intr/eventfd mapping */
        rc = rte_intr_enable(intr_handle);
+#ifndef RTE_EXEC_ENV_FREEBSD
+       /* In FreeBSD OS, nic_uio driver does not support interrupts */
        if (rc)
                goto err_free;
+#endif
 
        rc = bnxt_get_hwrm_link_config(bp, &new);
        if (rc) {
@@ -458,6 +461,10 @@ skip_cosq_cfg:
        }
        bnxt_print_link_info(bp->eth_dev);
 
+       bp->mark_table = rte_zmalloc("bnxt_mark_table", BNXT_MARK_TABLE_SZ, 0);
+       if (!bp->mark_table)
+               PMD_DRV_LOG(ERR, "Allocation of mark table failed\n");
+
        return 0;
 
 err_free:
@@ -740,8 +747,10 @@ static int bnxt_scattered_rx(struct rte_eth_dev *eth_dev)
 }
 
 static eth_rx_burst_t
-bnxt_receive_function(__rte_unused struct rte_eth_dev *eth_dev)
+bnxt_receive_function(struct rte_eth_dev *eth_dev)
 {
+       struct bnxt *bp = eth_dev->data->dev_private;
+
 #ifdef RTE_ARCH_X86
 #ifndef RTE_LIBRTE_IEEE1588
        /*
@@ -762,6 +771,7 @@ bnxt_receive_function(__rte_unused struct rte_eth_dev *eth_dev)
                DEV_RX_OFFLOAD_VLAN_FILTER))) {
                PMD_DRV_LOG(INFO, "Using vector mode receive for port %d\n",
                            eth_dev->data->port_id);
+               bp->flags |= BNXT_FLAG_RX_VECTOR_PKT_MODE;
                return bnxt_recv_pkts_vec;
        }
        PMD_DRV_LOG(INFO, "Vector mode receive disabled for port %d\n",
@@ -773,6 +783,7 @@ bnxt_receive_function(__rte_unused struct rte_eth_dev *eth_dev)
                    eth_dev->data->dev_conf.rxmode.offloads);
 #endif
 #endif
+       bp->flags &= ~BNXT_FLAG_RX_VECTOR_PKT_MODE;
        return bnxt_recv_pkts;
 }
 
@@ -956,6 +967,8 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
        bnxt_int_handler(eth_dev);
        bnxt_shutdown_nic(bp);
        bnxt_hwrm_if_change(bp, 0);
+       memset(bp->mark_table, 0, BNXT_MARK_TABLE_SZ);
+       bp->flags &= ~BNXT_FLAG_RX_VECTOR_PKT_MODE;
        bp->dev_stopped = 1;
        bp->rx_cosq_cnt = 0;
 }
@@ -976,6 +989,9 @@ static void bnxt_dev_close_op(struct rte_eth_dev *eth_dev)
                bp->grp_info = NULL;
        }
 
+       rte_free(bp->mark_table);
+       bp->mark_table = NULL;
+
        bnxt_dev_uninit(eth_dev);
 }
 
@@ -1844,18 +1860,12 @@ static int bnxt_del_dflt_mac_filter(struct bnxt *bp,
 }
 
 static int
-bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask)
+bnxt_config_vlan_hw_filter(struct bnxt *bp, uint64_t rx_offloads)
 {
-       struct bnxt *bp = dev->data->dev_private;
-       uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
        struct bnxt_vnic_info *vnic;
        unsigned int i;
        int rc;
 
-       rc = is_bnxt_in_error(bp);
-       if (rc)
-               return rc;
-
        vnic = BNXT_GET_DEFAULT_VNIC(bp);
        if (!(rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER)) {
                /* Remove any VLAN filters programmed */
@@ -1879,6 +1889,28 @@ bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask)
        PMD_DRV_LOG(DEBUG, "VLAN Filtering: %d\n",
                    !!(rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER));
 
+       return 0;
+}
+
+static int
+bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask)
+{
+       uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads;
+       struct bnxt *bp = dev->data->dev_private;
+       unsigned int i;
+       int rc;
+
+       rc = is_bnxt_in_error(bp);
+       if (rc)
+               return rc;
+
+       if (mask & ETH_VLAN_FILTER_MASK) {
+               /* Enable or disable VLAN filtering */
+               rc = bnxt_config_vlan_hw_filter(bp, rx_offloads);
+               if (rc)
+                       return rc;
+       }
+
        if (mask & ETH_VLAN_STRIP_MASK) {
                /* Enable or disable VLAN stripping */
                for (i = 0; i < bp->nr_vnics; i++) {
@@ -1968,7 +2000,6 @@ 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 = BNXT_GET_DEFAULT_VNIC(bp);
-       struct bnxt_filter_info *filter;
        int rc;
 
        rc = is_bnxt_in_error(bp);
@@ -1981,32 +2012,23 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev,
        if (rte_is_zero_ether_addr(addr))
                return -EINVAL;
 
-       STAILQ_FOREACH(filter, &vnic->filter, next) {
-               /* Default Filter is at Index 0 */
-               if (filter->mac_index != 0)
-                       continue;
-
-               memcpy(filter->l2_addr, addr, RTE_ETHER_ADDR_LEN);
-               memset(filter->l2_addr_mask, 0xff, RTE_ETHER_ADDR_LEN);
-               filter->flags |= HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX |
-                       HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_OUTERMOST;
-               filter->enables |=
-                       HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR |
-                       HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK;
+       /* Check if the requested MAC is already added */
+       if (memcmp(addr, bp->mac_addr, RTE_ETHER_ADDR_LEN) == 0)
+               return 0;
 
-               rc = bnxt_hwrm_set_l2_filter(bp, vnic->fw_vnic_id, filter);
-               if (rc) {
-                       memcpy(filter->l2_addr, bp->mac_addr,
-                              RTE_ETHER_ADDR_LEN);
-                       return rc;
-               }
+       /* Destroy filter and re-create it */
+       bnxt_del_dflt_mac_filter(bp, vnic);
 
-               memcpy(bp->mac_addr, addr, RTE_ETHER_ADDR_LEN);
-               PMD_DRV_LOG(DEBUG, "Set MAC addr\n");
-               return 0;
+       memcpy(bp->mac_addr, addr, RTE_ETHER_ADDR_LEN);
+       if (dev->data->dev_conf.rxmode.offloads & DEV_RX_OFFLOAD_VLAN_FILTER) {
+               /* This filter will allow only untagged packets */
+               rc = bnxt_add_vlan_filter(bp, 0);
+       } else {
+               rc = bnxt_add_mac_filter(bp, vnic, addr, 0, 0);
        }
 
-       return 0;
+       PMD_DRV_LOG(DEBUG, "Set MAC addr\n");
+       return rc;
 }
 
 static int
@@ -4217,18 +4239,6 @@ static int bnxt_alloc_ctx_mem_blk(struct bnxt *bp,
 
                memset(mz->addr, 0, mz->len);
                mz_phys_addr = mz->iova;
-               if ((unsigned long)mz->addr == mz_phys_addr) {
-                       PMD_DRV_LOG(DEBUG,
-                                   "physical address same as virtual\n");
-                       PMD_DRV_LOG(DEBUG, "Using rte_mem_virt2iova()\n");
-                       mz_phys_addr = rte_mem_virt2iova(mz->addr);
-                       if (mz_phys_addr == RTE_BAD_IOVA) {
-                               PMD_DRV_LOG(ERR,
-                                       "unable to map addr to phys memory\n");
-                               return -ENOMEM;
-                       }
-               }
-               rte_mem_lock_page(((char *)mz->addr));
 
                rmem->pg_tbl = mz->addr;
                rmem->pg_tbl_map = mz_phys_addr;
@@ -4252,22 +4262,8 @@ static int bnxt_alloc_ctx_mem_blk(struct bnxt *bp,
 
        memset(mz->addr, 0, mz->len);
        mz_phys_addr = mz->iova;
-       if ((unsigned long)mz->addr == mz_phys_addr) {
-               PMD_DRV_LOG(DEBUG,
-                           "Memzone physical address same as virtual.\n");
-               PMD_DRV_LOG(DEBUG, "Using rte_mem_virt2iova()\n");
-               for (sz = 0; sz < mem_size; sz += BNXT_PAGE_SIZE)
-                       rte_mem_lock_page(((char *)mz->addr) + sz);
-               mz_phys_addr = rte_mem_virt2iova(mz->addr);
-               if (mz_phys_addr == RTE_BAD_IOVA) {
-                       PMD_DRV_LOG(ERR,
-                                   "unable to map addr to phys memory\n");
-                       return -ENOMEM;
-               }
-       }
 
        for (sz = 0, i = 0; sz < mem_size; sz += BNXT_PAGE_SIZE, i++) {
-               rte_mem_lock_page(((char *)mz->addr) + sz);
                rmem->pg_arr[i] = ((char *)mz->addr) + sz;
                rmem->dma_arr[i] = mz_phys_addr + sz;
 
@@ -4444,18 +4440,6 @@ static int bnxt_alloc_stats_mem(struct bnxt *bp)
        }
        memset(mz->addr, 0, mz->len);
        mz_phys_addr = mz->iova;
-       if ((unsigned long)mz->addr == mz_phys_addr) {
-               PMD_DRV_LOG(DEBUG,
-                           "Memzone physical address same as virtual.\n");
-               PMD_DRV_LOG(DEBUG,
-                           "Using rte_mem_virt2iova()\n");
-               mz_phys_addr = rte_mem_virt2iova(mz->addr);
-               if (mz_phys_addr == RTE_BAD_IOVA) {
-                       PMD_DRV_LOG(ERR,
-                                   "Can't map address to physical memory\n");
-                       return -ENOMEM;
-               }
-       }
 
        bp->rx_mem_zone = (const void *)mz;
        bp->hw_rx_port_stats = mz->addr;
@@ -4482,17 +4466,6 @@ static int bnxt_alloc_stats_mem(struct bnxt *bp)
        }
        memset(mz->addr, 0, mz->len);
        mz_phys_addr = mz->iova;
-       if ((unsigned long)mz->addr == mz_phys_addr) {
-               PMD_DRV_LOG(DEBUG,
-                           "Memzone physical address same as virtual\n");
-               PMD_DRV_LOG(DEBUG, "Using rte_mem_virt2iova()\n");
-               mz_phys_addr = rte_mem_virt2iova(mz->addr);
-               if (mz_phys_addr == RTE_BAD_IOVA) {
-                       PMD_DRV_LOG(ERR,
-                                   "Can't map address to physical memory\n");
-                       return -ENOMEM;
-               }
-       }
 
        bp->tx_mem_zone = (const void *)mz;
        bp->hw_tx_port_stats = mz->addr;
@@ -4775,6 +4748,7 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
        bp = eth_dev->data->dev_private;
 
        bp->dev_stopped = 1;
+       bp->flags &= ~BNXT_FLAG_RX_VECTOR_PKT_MODE;
 
        if (bnxt_vf_pciid(pci_dev->id.device_id))
                bp->flags |= BNXT_FLAG_VF;