]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/net/ethernet/emulex/benet/be_main.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[karo-tx-linux.git] / drivers / net / ethernet / emulex / benet / be_main.c
index 3d91a5ec61a4e7a6cd37249d5bad08ee451eeb09..3224d28cdad4384d4322bd5765d503ef9ace1ca1 100644 (file)
@@ -21,6 +21,7 @@
 #include "be_cmds.h"
 #include <asm/div64.h>
 #include <linux/aer.h>
+#include <linux/if_bridge.h>
 
 MODULE_VERSION(DRV_VER);
 MODULE_DEVICE_TABLE(pci, be_dev_ids);
@@ -145,8 +146,8 @@ static int be_queue_alloc(struct be_adapter *adapter, struct be_queue_info *q,
        q->len = len;
        q->entry_size = entry_size;
        mem->size = len * entry_size;
-       mem->va = dma_alloc_coherent(&adapter->pdev->dev, mem->size, &mem->dma,
-                                    GFP_KERNEL | __GFP_ZERO);
+       mem->va = dma_zalloc_coherent(&adapter->pdev->dev, mem->size, &mem->dma,
+                                     GFP_KERNEL);
        if (!mem->va)
                return -ENOMEM;
        return 0;
@@ -247,54 +248,54 @@ void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, u16 num_popped)
 static int be_mac_addr_set(struct net_device *netdev, void *p)
 {
        struct be_adapter *adapter = netdev_priv(netdev);
+       struct device *dev = &adapter->pdev->dev;
        struct sockaddr *addr = p;
-       int status = 0;
-       u8 current_mac[ETH_ALEN];
-       u32 pmac_id = adapter->pmac_id[0];
-       bool active_mac = true;
+       int status;
+       u8 mac[ETH_ALEN];
+       u32 old_pmac_id = adapter->pmac_id[0], curr_pmac_id = 0;
 
        if (!is_valid_ether_addr(addr->sa_data))
                return -EADDRNOTAVAIL;
 
-       /* For BE VF, MAC address is already activated by PF.
-        * Hence only operation left is updating netdev->devaddr.
-        * Update it if user is passing the same MAC which was used
-        * during configuring VF MAC from PF(Hypervisor).
+       /* The PMAC_ADD cmd may fail if the VF doesn't have FILTMGMT
+        * privilege or if PF did not provision the new MAC address.
+        * On BE3, this cmd will always fail if the VF doesn't have the
+        * FILTMGMT privilege. This failure is OK, only if the PF programmed
+        * the MAC for the VF.
         */
-       if (!lancer_chip(adapter) && !be_physfn(adapter)) {
-               status = be_cmd_mac_addr_query(adapter, current_mac,
-                                              false, adapter->if_handle, 0);
-               if (!status && !memcmp(current_mac, addr->sa_data, ETH_ALEN))
-                       goto done;
-               else
-                       goto err;
-       }
+       status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data,
+                                adapter->if_handle, &adapter->pmac_id[0], 0);
+       if (!status) {
+               curr_pmac_id = adapter->pmac_id[0];
 
-       if (!memcmp(addr->sa_data, netdev->dev_addr, ETH_ALEN))
-               goto done;
+               /* Delete the old programmed MAC. This call may fail if the
+                * old MAC was already deleted by the PF driver.
+                */
+               if (adapter->pmac_id[0] != old_pmac_id)
+                       be_cmd_pmac_del(adapter, adapter->if_handle,
+                                       old_pmac_id, 0);
+       }
 
-       /* For Lancer check if any MAC is active.
-        * If active, get its mac id.
+       /* Decide if the new MAC is successfully activated only after
+        * querying the FW
         */
-       if (lancer_chip(adapter) && !be_physfn(adapter))
-               be_cmd_get_mac_from_list(adapter, current_mac, &active_mac,
-                                        &pmac_id, 0);
-
-       status = be_cmd_pmac_add(adapter, (u8 *)addr->sa_data,
-                                adapter->if_handle,
-                                &adapter->pmac_id[0], 0);
-
+       status = be_cmd_get_active_mac(adapter, curr_pmac_id, mac);
        if (status)
                goto err;
 
-       if (active_mac)
-               be_cmd_pmac_del(adapter, adapter->if_handle,
-                               pmac_id, 0);
-done:
+       /* The MAC change did not happen, either due to lack of privilege
+        * or PF didn't pre-provision.
+        */
+       if (memcmp(addr->sa_data, mac, ETH_ALEN)) {
+               status = -EPERM;
+               goto err;
+       }
+
        memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+       dev_info(dev, "MAC address changed to %pM\n", mac);
        return 0;
 err:
-       dev_err(&adapter->pdev->dev, "MAC %pM set Failed\n", addr->sa_data);
+       dev_warn(dev, "MAC address change to %pM failed\n", addr->sa_data);
        return status;
 }
 
@@ -472,7 +473,7 @@ static void accumulate_16bit_val(u32 *acc, u16 val)
        ACCESS_ONCE(*acc) = newacc;
 }
 
-void populate_erx_stats(struct be_adapter *adapter,
+static void populate_erx_stats(struct be_adapter *adapter,
                        struct be_rx_obj *rxo,
                        u32 erx_stat)
 {
@@ -1001,7 +1002,7 @@ static int be_vid_config(struct be_adapter *adapter)
        if (adapter->promiscuous)
                return 0;
 
-       if (adapter->vlans_added > adapter->max_vlans)
+       if (adapter->vlans_added > be_max_vlans(adapter))
                goto set_vlan_promisc;
 
        /* Construct VLAN Table to give to HW */
@@ -1042,7 +1043,7 @@ static int be_vlan_add_vid(struct net_device *netdev, __be16 proto, u16 vid)
                goto ret;
 
        adapter->vlan_tag[vid] = 1;
-       if (adapter->vlans_added <= (adapter->max_vlans + 1))
+       if (adapter->vlans_added <= (be_max_vlans(adapter) + 1))
                status = be_vid_config(adapter);
 
        if (!status)
@@ -1068,7 +1069,7 @@ static int be_vlan_rem_vid(struct net_device *netdev, __be16 proto, u16 vid)
                goto ret;
 
        adapter->vlan_tag[vid] = 0;
-       if (adapter->vlans_added <= adapter->max_vlans)
+       if (adapter->vlans_added <= be_max_vlans(adapter))
                status = be_vid_config(adapter);
 
        if (!status)
@@ -1101,7 +1102,7 @@ static void be_set_rx_mode(struct net_device *netdev)
 
        /* Enable multicast promisc if num configured exceeds what we support */
        if (netdev->flags & IFF_ALLMULTI ||
-           netdev_mc_count(netdev) > adapter->max_mcast_mac) {
+           netdev_mc_count(netdev) > be_max_mc(adapter)) {
                be_cmd_rx_filter(adapter, IFF_ALLMULTI, ON);
                goto done;
        }
@@ -1115,7 +1116,7 @@ static void be_set_rx_mode(struct net_device *netdev)
                                        adapter->pmac_id[i], 0);
                }
 
-               if (netdev_uc_count(netdev) > adapter->max_pmac_cnt) {
+               if (netdev_uc_count(netdev) > be_max_uc(adapter)) {
                        be_cmd_rx_filter(adapter, IFF_PROMISC, ON);
                        adapter->promiscuous = true;
                        goto done;
@@ -1146,9 +1147,6 @@ static int be_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
        struct be_adapter *adapter = netdev_priv(netdev);
        struct be_vf_cfg *vf_cfg = &adapter->vf_cfg[vf];
        int status;
-       bool active_mac = false;
-       u32 pmac_id;
-       u8 old_mac[ETH_ALEN];
 
        if (!sriov_enabled(adapter))
                return -EPERM;
@@ -1156,20 +1154,15 @@ static int be_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
        if (!is_valid_ether_addr(mac) || vf >= adapter->num_vfs)
                return -EINVAL;
 
-       if (lancer_chip(adapter)) {
-               status = be_cmd_get_mac_from_list(adapter, old_mac, &active_mac,
-                                                 &pmac_id, vf + 1);
-               if (!status && active_mac)
-                       be_cmd_pmac_del(adapter, vf_cfg->if_handle,
-                                       pmac_id, vf + 1);
-
-               status = be_cmd_set_mac_list(adapter,  mac, 1, vf + 1);
-       } else {
-               status = be_cmd_pmac_del(adapter, vf_cfg->if_handle,
-                                        vf_cfg->pmac_id, vf + 1);
+       if (BEx_chip(adapter)) {
+               be_cmd_pmac_del(adapter, vf_cfg->if_handle, vf_cfg->pmac_id,
+                               vf + 1);
 
                status = be_cmd_pmac_add(adapter, mac, vf_cfg->if_handle,
                                         &vf_cfg->pmac_id, vf + 1);
+       } else {
+               status = be_cmd_set_mac(adapter, mac, vf_cfg->if_handle,
+                                       vf + 1);
        }
 
        if (status)
@@ -1220,14 +1213,14 @@ static int be_set_vf_vlan(struct net_device *netdev,
                        adapter->vf_cfg[vf].vlan_tag = vlan;
 
                        status = be_cmd_set_hsw_config(adapter, vlan,
-                               vf + 1, adapter->vf_cfg[vf].if_handle);
+                               vf + 1, adapter->vf_cfg[vf].if_handle, 0);
                }
        } else {
                /* Reset Transparent Vlan Tagging. */
                adapter->vf_cfg[vf].vlan_tag = 0;
                vlan = adapter->vf_cfg[vf].def_vid;
                status = be_cmd_set_hsw_config(adapter, vlan, vf + 1,
-                       adapter->vf_cfg[vf].if_handle);
+                       adapter->vf_cfg[vf].if_handle, 0);
        }
 
 
@@ -1490,8 +1483,9 @@ static void be_rx_compl_process(struct be_rx_obj *rxo,
 }
 
 /* Process the RX completion indicated by rxcp when GRO is enabled */
-void be_rx_compl_process_gro(struct be_rx_obj *rxo, struct napi_struct *napi,
-                            struct be_rx_compl_info *rxcp)
+static void be_rx_compl_process_gro(struct be_rx_obj *rxo,
+                                   struct napi_struct *napi,
+                                   struct be_rx_compl_info *rxcp)
 {
        struct be_adapter *adapter = rxo->adapter;
        struct be_rx_page_info *page_info;
@@ -1920,6 +1914,7 @@ static void be_evt_queues_destroy(struct be_adapter *adapter)
                if (eqo->q.created) {
                        be_eq_clean(eqo);
                        be_cmd_q_destroy(adapter, &eqo->q, QTYPE_EQ);
+                       netif_napi_del(&eqo->napi);
                }
                be_queue_free(adapter, &eqo->q);
        }
@@ -1931,9 +1926,12 @@ static int be_evt_queues_create(struct be_adapter *adapter)
        struct be_eq_obj *eqo;
        int i, rc;
 
-       adapter->num_evt_qs = num_irqs(adapter);
+       adapter->num_evt_qs = min_t(u16, num_irqs(adapter),
+                                   adapter->cfg_num_qs);
 
        for_all_evt_queues(adapter, eqo, i) {
+               netif_napi_add(adapter->netdev, &eqo->napi, be_poll,
+                              BE_NAPI_WEIGHT);
                eqo->adapter = adapter;
                eqo->tx_budget = BE_TX_BUDGET;
                eqo->idx = i;
@@ -1946,7 +1944,7 @@ static int be_evt_queues_create(struct be_adapter *adapter)
                if (rc)
                        return rc;
 
-               rc = be_cmd_eq_create(adapter, eq, eqo->cur_eqd);
+               rc = be_cmd_eq_create(adapter, eqo);
                if (rc)
                        return rc;
        }
@@ -2020,31 +2018,13 @@ static void be_tx_queues_destroy(struct be_adapter *adapter)
        }
 }
 
-static int be_num_txqs_want(struct be_adapter *adapter)
-{
-       if ((!lancer_chip(adapter) && sriov_want(adapter)) ||
-           be_is_mc(adapter) ||
-           (!lancer_chip(adapter) && !be_physfn(adapter)) ||
-           BE2_chip(adapter))
-               return 1;
-       else
-               return adapter->max_tx_queues;
-}
-
-static int be_tx_cqs_create(struct be_adapter *adapter)
+static int be_tx_qs_create(struct be_adapter *adapter)
 {
        struct be_queue_info *cq, *eq;
-       int status;
        struct be_tx_obj *txo;
-       u8 i;
+       int status, i;
 
-       adapter->num_tx_qs = be_num_txqs_want(adapter);
-       if (adapter->num_tx_qs != MAX_TX_QS) {
-               rtnl_lock();
-               netif_set_real_num_tx_queues(adapter->netdev,
-                       adapter->num_tx_qs);
-               rtnl_unlock();
-       }
+       adapter->num_tx_qs = min(adapter->num_evt_qs, be_max_txqs(adapter));
 
        for_all_tx_queues(adapter, txo, i) {
                cq = &txo->cq;
@@ -2060,16 +2040,7 @@ static int be_tx_cqs_create(struct be_adapter *adapter)
                status = be_cmd_cq_create(adapter, cq, eq, false, 3);
                if (status)
                        return status;
-       }
-       return 0;
-}
 
-static int be_tx_qs_create(struct be_adapter *adapter)
-{
-       struct be_tx_obj *txo;
-       int i, status;
-
-       for_all_tx_queues(adapter, txo, i) {
                status = be_queue_alloc(adapter, &txo->q, TX_Q_LEN,
                                        sizeof(struct be_eth_wrb));
                if (status)
@@ -2105,17 +2076,14 @@ static int be_rx_cqs_create(struct be_adapter *adapter)
        struct be_rx_obj *rxo;
        int rc, i;
 
-       /* We'll create as many RSS rings as there are irqs.
-        * But when there's only one irq there's no use creating RSS rings
+       /* We can create as many RSS rings as there are EQs. */
+       adapter->num_rx_qs = adapter->num_evt_qs;
+
+       /* We'll use RSS only if atleast 2 RSS rings are supported.
+        * When RSS is used, we'll need a default RXQ for non-IP traffic.
         */
-       adapter->num_rx_qs = (num_irqs(adapter) > 1) ?
-                               num_irqs(adapter) + 1 : 1;
-       if (adapter->num_rx_qs != MAX_RX_QS) {
-               rtnl_lock();
-               netif_set_real_num_rx_queues(adapter->netdev,
-                                            adapter->num_rx_qs);
-               rtnl_unlock();
-       }
+       if (adapter->num_rx_qs > 1)
+               adapter->num_rx_qs++;
 
        adapter->big_page_size = (1 << get_order(rx_frag_size)) * PAGE_SIZE;
        for_all_rx_queues(adapter, rxo, i) {
@@ -2379,38 +2347,24 @@ static void be_msix_disable(struct be_adapter *adapter)
        if (msix_enabled(adapter)) {
                pci_disable_msix(adapter->pdev);
                adapter->num_msix_vec = 0;
+               adapter->num_msix_roce_vec = 0;
        }
 }
 
-static uint be_num_rss_want(struct be_adapter *adapter)
-{
-       u32 num = 0;
-
-       if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) &&
-           (lancer_chip(adapter) ||
-            (!sriov_want(adapter) && be_physfn(adapter)))) {
-               num = adapter->max_rss_queues;
-               num = min_t(u32, num, (u32)netif_get_num_default_rss_queues());
-       }
-       return num;
-}
-
 static int be_msix_enable(struct be_adapter *adapter)
 {
-#define BE_MIN_MSIX_VECTORS            1
-       int i, status, num_vec, num_roce_vec = 0;
+       int i, status, num_vec;
        struct device *dev = &adapter->pdev->dev;
 
-       /* If RSS queues are not used, need a vec for default RX Q */
-       num_vec = min(be_num_rss_want(adapter), num_online_cpus());
-       if (be_roce_supported(adapter)) {
-               num_roce_vec = min_t(u32, MAX_ROCE_MSIX_VECTORS,
-                                       (num_online_cpus() + 1));
-               num_roce_vec = min(num_roce_vec, MAX_ROCE_EQS);
-               num_vec += num_roce_vec;
-               num_vec = min(num_vec, MAX_MSIX_VECTORS);
-       }
-       num_vec = max(num_vec, BE_MIN_MSIX_VECTORS);
+       /* If RoCE is supported, program the max number of NIC vectors that
+        * may be configured via set-channels, along with vectors needed for
+        * RoCe. Else, just program the number we'll use initially.
+        */
+       if (be_roce_supported(adapter))
+               num_vec = min_t(int, 2 * be_max_eqs(adapter),
+                               2 * num_online_cpus());
+       else
+               num_vec = adapter->cfg_num_qs;
 
        for (i = 0; i < num_vec; i++)
                adapter->msix_entries[i].entry = i;
@@ -2418,7 +2372,7 @@ static int be_msix_enable(struct be_adapter *adapter)
        status = pci_enable_msix(adapter->pdev, adapter->msix_entries, num_vec);
        if (status == 0) {
                goto done;
-       } else if (status >= BE_MIN_MSIX_VECTORS) {
+       } else if (status >= MIN_MSIX_VECTORS) {
                num_vec = status;
                status = pci_enable_msix(adapter->pdev, adapter->msix_entries,
                                         num_vec);
@@ -2427,30 +2381,29 @@ static int be_msix_enable(struct be_adapter *adapter)
        }
 
        dev_warn(dev, "MSIx enable failed\n");
+
        /* INTx is not supported in VFs, so fail probe if enable_msix fails */
        if (!be_physfn(adapter))
                return status;
        return 0;
 done:
-       if (be_roce_supported(adapter)) {
-               if (num_vec > num_roce_vec) {
-                       adapter->num_msix_vec = num_vec - num_roce_vec;
-                       adapter->num_msix_roce_vec =
-                               num_vec - adapter->num_msix_vec;
-               } else {
-                       adapter->num_msix_vec = num_vec;
-                       adapter->num_msix_roce_vec = 0;
-               }
-       } else
-               adapter->num_msix_vec = num_vec;
-       dev_info(dev, "enabled %d MSI-x vector(s)\n", adapter->num_msix_vec);
+       if (be_roce_supported(adapter) && num_vec > MIN_MSIX_VECTORS) {
+               adapter->num_msix_roce_vec = num_vec / 2;
+               dev_info(dev, "enabled %d MSI-x vector(s) for RoCE\n",
+                        adapter->num_msix_roce_vec);
+       }
+
+       adapter->num_msix_vec = num_vec - adapter->num_msix_roce_vec;
+
+       dev_info(dev, "enabled %d MSI-x vector(s) for NIC\n",
+                adapter->num_msix_vec);
        return 0;
 }
 
 static inline int be_msix_vec_get(struct be_adapter *adapter,
                                struct be_eq_obj *eqo)
 {
-       return adapter->msix_entries[eqo->idx].vector;
+       return adapter->msix_entries[eqo->msix_idx].vector;
 }
 
 static int be_msix_register(struct be_adapter *adapter)
@@ -2690,8 +2643,8 @@ static int be_setup_wol(struct be_adapter *adapter, bool enable)
        memset(mac, 0, ETH_ALEN);
 
        cmd.size = sizeof(struct be_cmd_req_acpi_wol_magic_config);
-       cmd.va = dma_alloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma,
-                                   GFP_KERNEL | __GFP_ZERO);
+       cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma,
+                                    GFP_KERNEL);
        if (cmd.va == NULL)
                return -1;
 
@@ -2735,13 +2688,13 @@ static int be_vf_eth_addr_config(struct be_adapter *adapter)
        be_vf_eth_addr_generate(adapter, mac);
 
        for_all_vfs(adapter, vf_cfg, vf) {
-               if (lancer_chip(adapter)) {
-                       status = be_cmd_set_mac_list(adapter,  mac, 1, vf + 1);
-               } else {
+               if (BEx_chip(adapter))
                        status = be_cmd_pmac_add(adapter, mac,
                                                 vf_cfg->if_handle,
                                                 &vf_cfg->pmac_id, vf + 1);
-               }
+               else
+                       status = be_cmd_set_mac(adapter, mac, vf_cfg->if_handle,
+                                               vf + 1);
 
                if (status)
                        dev_err(&adapter->pdev->dev,
@@ -2759,7 +2712,7 @@ static int be_vfs_mac_query(struct be_adapter *adapter)
        int status, vf;
        u8 mac[ETH_ALEN];
        struct be_vf_cfg *vf_cfg;
-       bool active;
+       bool active = false;
 
        for_all_vfs(adapter, vf_cfg, vf) {
                be_cmd_get_mac_from_list(adapter, mac, &active,
@@ -2788,11 +2741,12 @@ static void be_vf_clear(struct be_adapter *adapter)
        pci_disable_sriov(adapter->pdev);
 
        for_all_vfs(adapter, vf_cfg, vf) {
-               if (lancer_chip(adapter))
-                       be_cmd_set_mac_list(adapter, NULL, 0, vf + 1);
-               else
+               if (BEx_chip(adapter))
                        be_cmd_pmac_del(adapter, vf_cfg->if_handle,
                                        vf_cfg->pmac_id, vf + 1);
+               else
+                       be_cmd_set_mac(adapter, NULL, vf_cfg->if_handle,
+                                      vf + 1);
 
                be_cmd_if_destroy(adapter, vf_cfg->if_handle, vf + 1);
        }
@@ -2801,28 +2755,40 @@ done:
        adapter->num_vfs = 0;
 }
 
-static int be_clear(struct be_adapter *adapter)
+static void be_clear_queues(struct be_adapter *adapter)
 {
-       int i = 1;
+       be_mcc_queues_destroy(adapter);
+       be_rx_cqs_destroy(adapter);
+       be_tx_queues_destroy(adapter);
+       be_evt_queues_destroy(adapter);
+}
 
+static void be_cancel_worker(struct be_adapter *adapter)
+{
        if (adapter->flags & BE_FLAGS_WORKER_SCHEDULED) {
                cancel_delayed_work_sync(&adapter->work);
                adapter->flags &= ~BE_FLAGS_WORKER_SCHEDULED;
        }
+}
+
+static int be_clear(struct be_adapter *adapter)
+{
+       int i;
+
+       be_cancel_worker(adapter);
 
        if (sriov_enabled(adapter))
                be_vf_clear(adapter);
 
-       for (; adapter->uc_macs > 0; adapter->uc_macs--, i++)
+       /* delete the primary mac along with the uc-mac list */
+       for (i = 0; i < (adapter->uc_macs + 1); i++)
                be_cmd_pmac_del(adapter, adapter->if_handle,
-                       adapter->pmac_id[i], 0);
+                               adapter->pmac_id[i], 0);
+       adapter->uc_macs = 0;
 
        be_cmd_if_destroy(adapter, adapter->if_handle,  0);
 
-       be_mcc_queues_destroy(adapter);
-       be_rx_cqs_destroy(adapter);
-       be_tx_queues_destroy(adapter);
-       be_evt_queues_destroy(adapter);
+       be_clear_queues(adapter);
 
        kfree(adapter->pmac_id);
        adapter->pmac_id = NULL;
@@ -2833,6 +2799,7 @@ static int be_clear(struct be_adapter *adapter)
 
 static int be_vfs_if_create(struct be_adapter *adapter)
 {
+       struct be_resources res = {0};
        struct be_vf_cfg *vf_cfg;
        u32 cap_flags, en_flags, vf;
        int status;
@@ -2841,9 +2808,12 @@ static int be_vfs_if_create(struct be_adapter *adapter)
                    BE_IF_FLAGS_MULTICAST;
 
        for_all_vfs(adapter, vf_cfg, vf) {
-               if (!BE3_chip(adapter))
-                       be_cmd_get_profile_config(adapter, &cap_flags,
-                                                 NULL, vf + 1);
+               if (!BE3_chip(adapter)) {
+                       status = be_cmd_get_profile_config(adapter, &res,
+                                                          vf + 1);
+                       if (!status)
+                               cap_flags = res.if_cap_flags;
+               }
 
                /* If a FW profile exists, then cap_flags are updated */
                en_flags = cap_flags & (BE_IF_FLAGS_UNTAGGED |
@@ -2880,6 +2850,7 @@ static int be_vf_setup(struct be_adapter *adapter)
        u16 def_vlan, lnk_speed;
        int status, old_vfs, vf;
        struct device *dev = &adapter->pdev->dev;
+       u32 privileges;
 
        old_vfs = pci_num_vf(adapter->pdev);
        if (old_vfs) {
@@ -2888,10 +2859,10 @@ static int be_vf_setup(struct be_adapter *adapter)
                        dev_warn(dev, "Ignoring num_vfs=%d setting\n", num_vfs);
                adapter->num_vfs = old_vfs;
        } else {
-               if (num_vfs > adapter->dev_num_vfs)
+               if (num_vfs > be_max_vfs(adapter))
                        dev_info(dev, "Device supports %d VFs and not %d\n",
-                                adapter->dev_num_vfs, num_vfs);
-               adapter->num_vfs = min_t(u16, num_vfs, adapter->dev_num_vfs);
+                                be_max_vfs(adapter), num_vfs);
+               adapter->num_vfs = min_t(u16, num_vfs, be_max_vfs(adapter));
                if (!adapter->num_vfs)
                        return 0;
        }
@@ -2923,6 +2894,18 @@ static int be_vf_setup(struct be_adapter *adapter)
        }
 
        for_all_vfs(adapter, vf_cfg, vf) {
+               /* Allow VFs to programs MAC/VLAN filters */
+               status = be_cmd_get_fn_privileges(adapter, &privileges, vf + 1);
+               if (!status && !(privileges & BE_PRIV_FILTMGMT)) {
+                       status = be_cmd_set_fn_privileges(adapter,
+                                                         privileges |
+                                                         BE_PRIV_FILTMGMT,
+                                                         vf + 1);
+                       if (!status)
+                               dev_info(dev, "VF%d has FILTMGMT privilege\n",
+                                        vf);
+               }
+
                /* BE3 FW, by default, caps VF TX-rate to 100mbps.
                 * Allow full available bandwidth
                 */
@@ -2935,7 +2918,7 @@ static int be_vf_setup(struct be_adapter *adapter)
                        vf_cfg->tx_rate = lnk_speed;
 
                status = be_cmd_get_hsw_config(adapter, &def_vlan,
-                                              vf + 1, vf_cfg->if_handle);
+                                              vf + 1, vf_cfg->if_handle, NULL);
                if (status)
                        goto err;
                vf_cfg->def_vid = def_vlan;
@@ -2958,6 +2941,51 @@ err:
        return status;
 }
 
+/* On BE2/BE3 FW does not suggest the supported limits */
+static void BEx_get_resources(struct be_adapter *adapter,
+                             struct be_resources *res)
+{
+       struct pci_dev *pdev = adapter->pdev;
+       bool use_sriov = false;
+
+       if (BE3_chip(adapter) && be_physfn(adapter)) {
+               int max_vfs;
+
+               max_vfs = pci_sriov_get_totalvfs(pdev);
+               res->max_vfs = max_vfs > 0 ? min(MAX_VFS, max_vfs) : 0;
+               use_sriov = res->max_vfs && num_vfs;
+       }
+
+       if (be_physfn(adapter))
+               res->max_uc_mac = BE_UC_PMAC_COUNT;
+       else
+               res->max_uc_mac = BE_VF_UC_PMAC_COUNT;
+
+       if (adapter->function_mode & FLEX10_MODE)
+               res->max_vlans = BE_NUM_VLANS_SUPPORTED/8;
+       else
+               res->max_vlans = BE_NUM_VLANS_SUPPORTED;
+       res->max_mcast_mac = BE_MAX_MC;
+
+       if (BE2_chip(adapter) || use_sriov || be_is_mc(adapter) ||
+           !be_physfn(adapter))
+               res->max_tx_qs = 1;
+       else
+               res->max_tx_qs = BE3_MAX_TX_QS;
+
+       if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) &&
+           !use_sriov && be_physfn(adapter))
+               res->max_rss_qs = (adapter->be3_native) ?
+                                          BE3_MAX_RSS_QS : BE2_MAX_RSS_QS;
+       res->max_rx_qs = res->max_rss_qs + 1;
+
+       res->max_evt_qs = be_physfn(adapter) ? BE3_MAX_EVT_QS : 1;
+
+       res->if_cap_flags = BE_IF_CAP_FLAGS_WANT;
+       if (!(adapter->function_caps & BE_FUNCTION_CAPS_RSS))
+               res->if_cap_flags &= ~BE_IF_FLAGS_RSS;
+}
+
 static void be_setup_init(struct be_adapter *adapter)
 {
        adapter->vlan_prio_bmap = 0xff;
@@ -2971,118 +2999,56 @@ static void be_setup_init(struct be_adapter *adapter)
                adapter->cmd_privileges = MIN_PRIVILEGES;
 }
 
-static int be_get_mac_addr(struct be_adapter *adapter, u8 *mac, u32 if_handle,
-                          bool *active_mac, u32 *pmac_id)
+static int be_get_resources(struct be_adapter *adapter)
 {
-       int status = 0;
-
-       if (!is_zero_ether_addr(adapter->netdev->perm_addr)) {
-               memcpy(mac, adapter->netdev->dev_addr, ETH_ALEN);
-               if (!lancer_chip(adapter) && !be_physfn(adapter))
-                       *active_mac = true;
-               else
-                       *active_mac = false;
+       struct device *dev = &adapter->pdev->dev;
+       struct be_resources res = {0};
+       int status;
 
-               return status;
+       if (BEx_chip(adapter)) {
+               BEx_get_resources(adapter, &res);
+               adapter->res = res;
        }
 
-       if (lancer_chip(adapter)) {
-               status = be_cmd_get_mac_from_list(adapter, mac,
-                                                 active_mac, pmac_id, 0);
-               if (*active_mac) {
-                       status = be_cmd_mac_addr_query(adapter, mac, false,
-                                                      if_handle, *pmac_id);
-               }
-       } else if (be_physfn(adapter)) {
-               /* For BE3, for PF get permanent MAC */
-               status = be_cmd_mac_addr_query(adapter, mac, true, 0, 0);
-               *active_mac = false;
-       } else {
-               /* For BE3, for VF get soft MAC assigned by PF*/
-               status = be_cmd_mac_addr_query(adapter, mac, false,
-                                              if_handle, 0);
-               *active_mac = true;
+       /* For BE3 only check if FW suggests a different max-txqs value */
+       if (BE3_chip(adapter)) {
+               status = be_cmd_get_profile_config(adapter, &res, 0);
+               if (!status && res.max_tx_qs)
+                       adapter->res.max_tx_qs =
+                               min(adapter->res.max_tx_qs, res.max_tx_qs);
        }
-       return status;
-}
-
-static void be_get_resources(struct be_adapter *adapter)
-{
-       u16 dev_num_vfs;
-       int pos, status;
-       bool profile_present = false;
-       u16 txq_count = 0;
 
+       /* For Lancer, SH etc read per-function resource limits from FW.
+        * GET_FUNC_CONFIG returns per function guaranteed limits.
+        * GET_PROFILE_CONFIG returns PCI-E related limits PF-pool limits
+        */
        if (!BEx_chip(adapter)) {
-               status = be_cmd_get_func_config(adapter);
-               if (!status)
-                       profile_present = true;
-       } else if (BE3_chip(adapter) && be_physfn(adapter)) {
-               be_cmd_get_profile_config(adapter, NULL, &txq_count, 0);
-       }
-
-       if (profile_present) {
-               /* Sanity fixes for Lancer */
-               adapter->max_pmac_cnt = min_t(u16, adapter->max_pmac_cnt,
-                                             BE_UC_PMAC_COUNT);
-               adapter->max_vlans = min_t(u16, adapter->max_vlans,
-                                          BE_NUM_VLANS_SUPPORTED);
-               adapter->max_mcast_mac = min_t(u16, adapter->max_mcast_mac,
-                                              BE_MAX_MC);
-               adapter->max_tx_queues = min_t(u16, adapter->max_tx_queues,
-                                              MAX_TX_QS);
-               adapter->max_rss_queues = min_t(u16, adapter->max_rss_queues,
-                                               BE3_MAX_RSS_QS);
-               adapter->max_event_queues = min_t(u16,
-                                                 adapter->max_event_queues,
-                                                 BE3_MAX_RSS_QS);
-
-               if (adapter->max_rss_queues &&
-                   adapter->max_rss_queues == adapter->max_rx_queues)
-                       adapter->max_rss_queues -= 1;
-
-               if (adapter->max_event_queues < adapter->max_rss_queues)
-                       adapter->max_rss_queues = adapter->max_event_queues;
-
-       } else {
-               if (be_physfn(adapter))
-                       adapter->max_pmac_cnt = BE_UC_PMAC_COUNT;
-               else
-                       adapter->max_pmac_cnt = BE_VF_UC_PMAC_COUNT;
-
-               if (adapter->function_mode & FLEX10_MODE)
-                       adapter->max_vlans = BE_NUM_VLANS_SUPPORTED/8;
-               else
-                       adapter->max_vlans = BE_NUM_VLANS_SUPPORTED;
+               status = be_cmd_get_func_config(adapter, &res);
+               if (status)
+                       return status;
 
-               adapter->max_mcast_mac = BE_MAX_MC;
-               adapter->max_tx_queues = txq_count ? txq_count : MAX_TX_QS;
-               adapter->max_tx_queues = min_t(u16, adapter->max_tx_queues,
-                                              MAX_TX_QS);
-               adapter->max_rss_queues = (adapter->be3_native) ?
-                                          BE3_MAX_RSS_QS : BE2_MAX_RSS_QS;
-               adapter->max_event_queues = BE3_MAX_RSS_QS;
+               /* If RoCE may be enabled stash away half the EQs for RoCE */
+               if (be_roce_supported(adapter))
+                       res.max_evt_qs /= 2;
+               adapter->res = res;
 
-               adapter->if_cap_flags = BE_IF_FLAGS_UNTAGGED |
-                                       BE_IF_FLAGS_BROADCAST |
-                                       BE_IF_FLAGS_MULTICAST |
-                                       BE_IF_FLAGS_PASS_L3L4_ERRORS |
-                                       BE_IF_FLAGS_MCAST_PROMISCUOUS |
-                                       BE_IF_FLAGS_VLAN_PROMISCUOUS |
-                                       BE_IF_FLAGS_PROMISCUOUS;
+               if (be_physfn(adapter)) {
+                       status = be_cmd_get_profile_config(adapter, &res, 0);
+                       if (status)
+                               return status;
+                       adapter->res.max_vfs = res.max_vfs;
+               }
 
-               if (adapter->function_caps & BE_FUNCTION_CAPS_RSS)
-                       adapter->if_cap_flags |= BE_IF_FLAGS_RSS;
+               dev_info(dev, "Max: txqs %d, rxqs %d, rss %d, eqs %d, vfs %d\n",
+                        be_max_txqs(adapter), be_max_rxqs(adapter),
+                        be_max_rss(adapter), be_max_eqs(adapter),
+                        be_max_vfs(adapter));
+               dev_info(dev, "Max: uc-macs %d, mc-macs %d, vlans %d\n",
+                        be_max_uc(adapter), be_max_mc(adapter),
+                        be_max_vlans(adapter));
        }
 
-       pos = pci_find_ext_capability(adapter->pdev, PCI_EXT_CAP_ID_SRIOV);
-       if (pos) {
-               pci_read_config_word(adapter->pdev, pos + PCI_SRIOV_TOTAL_VF,
-                                    &dev_num_vfs);
-               if (BE3_chip(adapter))
-                       dev_num_vfs = min_t(u16, dev_num_vfs, MAX_VFS);
-               adapter->dev_num_vfs = dev_num_vfs;
-       }
+       return 0;
 }
 
 /* Routine to query per function resource limits */
@@ -3095,100 +3061,171 @@ static int be_get_config(struct be_adapter *adapter)
                                     &adapter->function_caps,
                                     &adapter->asic_rev);
        if (status)
-               goto err;
+               return status;
 
-       be_get_resources(adapter);
+       status = be_get_resources(adapter);
+       if (status)
+               return status;
 
        /* primary mac needs 1 pmac entry */
-       adapter->pmac_id = kcalloc(adapter->max_pmac_cnt + 1,
-                                  sizeof(u32), GFP_KERNEL);
-       if (!adapter->pmac_id) {
-               status = -ENOMEM;
-               goto err;
-       }
+       adapter->pmac_id = kcalloc(be_max_uc(adapter) + 1, sizeof(u32),
+                                  GFP_KERNEL);
+       if (!adapter->pmac_id)
+               return -ENOMEM;
 
-err:
-       return status;
+       /* Sanitize cfg_num_qs based on HW and platform limits */
+       adapter->cfg_num_qs = min(adapter->cfg_num_qs, be_max_qs(adapter));
+
+       return 0;
 }
 
-static int be_setup(struct be_adapter *adapter)
+static int be_mac_setup(struct be_adapter *adapter)
 {
-       struct device *dev = &adapter->pdev->dev;
-       u32 en_flags;
-       u32 tx_fc, rx_fc;
-       int status;
        u8 mac[ETH_ALEN];
-       bool active_mac;
+       int status;
 
-       be_setup_init(adapter);
+       if (is_zero_ether_addr(adapter->netdev->dev_addr)) {
+               status = be_cmd_get_perm_mac(adapter, mac);
+               if (status)
+                       return status;
 
-       if (!lancer_chip(adapter))
-               be_cmd_req_native_mode(adapter);
+               memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN);
+               memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN);
+       } else {
+               /* Maybe the HW was reset; dev_addr must be re-programmed */
+               memcpy(mac, adapter->netdev->dev_addr, ETH_ALEN);
+       }
 
-       status = be_get_config(adapter);
+       /* On BE3 VFs this cmd may fail due to lack of privilege.
+        * Ignore the failure as in this case pmac_id is fetched
+        * in the IFACE_CREATE cmd.
+        */
+       be_cmd_pmac_add(adapter, mac, adapter->if_handle,
+                       &adapter->pmac_id[0], 0);
+       return 0;
+}
+
+static void be_schedule_worker(struct be_adapter *adapter)
+{
+       schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
+       adapter->flags |= BE_FLAGS_WORKER_SCHEDULED;
+}
+
+static int be_setup_queues(struct be_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       int status;
+
+       status = be_evt_queues_create(adapter);
        if (status)
                goto err;
 
-       status = be_msix_enable(adapter);
+       status = be_tx_qs_create(adapter);
        if (status)
                goto err;
 
-       status = be_evt_queues_create(adapter);
+       status = be_rx_cqs_create(adapter);
        if (status)
                goto err;
 
-       status = be_tx_cqs_create(adapter);
+       status = be_mcc_queues_create(adapter);
        if (status)
                goto err;
 
-       status = be_rx_cqs_create(adapter);
+       status = netif_set_real_num_rx_queues(netdev, adapter->num_rx_qs);
        if (status)
                goto err;
 
-       status = be_mcc_queues_create(adapter);
+       status = netif_set_real_num_tx_queues(netdev, adapter->num_tx_qs);
        if (status)
                goto err;
 
-       be_cmd_get_fn_privileges(adapter, &adapter->cmd_privileges, 0);
-       /* In UMC mode FW does not return right privileges.
-        * Override with correct privilege equivalent to PF.
+       return 0;
+err:
+       dev_err(&adapter->pdev->dev, "queue_setup failed\n");
+       return status;
+}
+
+int be_update_queues(struct be_adapter *adapter)
+{
+       struct net_device *netdev = adapter->netdev;
+       int status;
+
+       if (netif_running(netdev))
+               be_close(netdev);
+
+       be_cancel_worker(adapter);
+
+       /* If any vectors have been shared with RoCE we cannot re-program
+        * the MSIx table.
         */
-       if (be_is_mc(adapter))
-               adapter->cmd_privileges = MAX_PRIVILEGES;
+       if (!adapter->num_msix_roce_vec)
+               be_msix_disable(adapter);
 
-       en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
-                       BE_IF_FLAGS_MULTICAST | BE_IF_FLAGS_PASS_L3L4_ERRORS;
+       be_clear_queues(adapter);
 
-       if (adapter->function_caps & BE_FUNCTION_CAPS_RSS)
-               en_flags |= BE_IF_FLAGS_RSS;
+       if (!msix_enabled(adapter)) {
+               status = be_msix_enable(adapter);
+               if (status)
+                       return status;
+       }
 
-       en_flags = en_flags & adapter->if_cap_flags;
+       status = be_setup_queues(adapter);
+       if (status)
+               return status;
 
-       status = be_cmd_if_create(adapter, adapter->if_cap_flags, en_flags,
-                                 &adapter->if_handle, 0);
-       if (status != 0)
+       be_schedule_worker(adapter);
+
+       if (netif_running(netdev))
+               status = be_open(netdev);
+
+       return status;
+}
+
+static int be_setup(struct be_adapter *adapter)
+{
+       struct device *dev = &adapter->pdev->dev;
+       u32 tx_fc, rx_fc, en_flags;
+       int status;
+
+       be_setup_init(adapter);
+
+       if (!lancer_chip(adapter))
+               be_cmd_req_native_mode(adapter);
+
+       status = be_get_config(adapter);
+       if (status)
                goto err;
 
-       memset(mac, 0, ETH_ALEN);
-       active_mac = false;
-       status = be_get_mac_addr(adapter, mac, adapter->if_handle,
-                                &active_mac, &adapter->pmac_id[0]);
-       if (status != 0)
+       status = be_msix_enable(adapter);
+       if (status)
                goto err;
 
-       if (!active_mac) {
-               status = be_cmd_pmac_add(adapter, mac, adapter->if_handle,
-                                        &adapter->pmac_id[0], 0);
-               if (status != 0)
-                       goto err;
-       }
+       en_flags = BE_IF_FLAGS_UNTAGGED | BE_IF_FLAGS_BROADCAST |
+                  BE_IF_FLAGS_MULTICAST | BE_IF_FLAGS_PASS_L3L4_ERRORS;
+       if (adapter->function_caps & BE_FUNCTION_CAPS_RSS)
+               en_flags |= BE_IF_FLAGS_RSS;
+       en_flags = en_flags & be_if_cap_flags(adapter);
+       status = be_cmd_if_create(adapter, be_if_cap_flags(adapter), en_flags,
+                                 &adapter->if_handle, 0);
+       if (status)
+               goto err;
 
-       if (is_zero_ether_addr(adapter->netdev->dev_addr)) {
-               memcpy(adapter->netdev->dev_addr, mac, ETH_ALEN);
-               memcpy(adapter->netdev->perm_addr, mac, ETH_ALEN);
-       }
+       /* Updating real_num_tx/rx_queues() requires rtnl_lock() */
+       rtnl_lock();
+       status = be_setup_queues(adapter);
+       rtnl_unlock();
+       if (status)
+               goto err;
 
-       status = be_tx_qs_create(adapter);
+       be_cmd_get_fn_privileges(adapter, &adapter->cmd_privileges, 0);
+       /* In UMC mode FW does not return right privileges.
+        * Override with correct privilege equivalent to PF.
+        */
+       if (be_is_mc(adapter))
+               adapter->cmd_privileges = MAX_PRIVILEGES;
+
+       status = be_mac_setup(adapter);
        if (status)
                goto err;
 
@@ -3205,8 +3242,8 @@ static int be_setup(struct be_adapter *adapter)
                be_cmd_set_flow_control(adapter, adapter->tx_fc,
                                        adapter->rx_fc);
 
-       if (be_physfn(adapter)) {
-               if (adapter->dev_num_vfs)
+       if (be_physfn(adapter) && num_vfs) {
+               if (be_max_vfs(adapter))
                        be_vf_setup(adapter);
                else
                        dev_warn(dev, "device doesn't support SRIOV\n");
@@ -3216,8 +3253,7 @@ static int be_setup(struct be_adapter *adapter)
        if (!status && be_pause_supported(adapter))
                adapter->phy.fc_autoneg = 1;
 
-       schedule_delayed_work(&adapter->work, msecs_to_jiffies(1000));
-       adapter->flags |= BE_FLAGS_WORKER_SCHEDULED;
+       be_schedule_worker(adapter);
        return 0;
 err:
        be_clear(adapter);
@@ -3241,7 +3277,7 @@ static void be_netpoll(struct net_device *netdev)
 #endif
 
 #define FW_FILE_HDR_SIGN       "ServerEngines Corp. "
-char flash_cookie[2][16] =      {"*** SE FLAS", "H DIRECTORY *** "};
+static char flash_cookie[2][16] =      {"*** SE FLAS", "H DIRECTORY *** "};
 
 static bool be_flash_redboot(struct be_adapter *adapter,
                        const u8 *p, u32 img_start, int image_size,
@@ -3298,7 +3334,7 @@ static bool is_comp_in_ufi(struct be_adapter *adapter,
 
 }
 
-struct flash_section_info *get_fsec_info(struct be_adapter *adapter,
+static struct flash_section_info *get_fsec_info(struct be_adapter *adapter,
                                         int header_size,
                                         const struct firmware *fw)
 {
@@ -3760,6 +3796,74 @@ fw_exit:
        return status;
 }
 
+static int be_ndo_bridge_setlink(struct net_device *dev,
+                                   struct nlmsghdr *nlh)
+{
+       struct be_adapter *adapter = netdev_priv(dev);
+       struct nlattr *attr, *br_spec;
+       int rem;
+       int status = 0;
+       u16 mode = 0;
+
+       if (!sriov_enabled(adapter))
+               return -EOPNOTSUPP;
+
+       br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
+
+       nla_for_each_nested(attr, br_spec, rem) {
+               if (nla_type(attr) != IFLA_BRIDGE_MODE)
+                       continue;
+
+               mode = nla_get_u16(attr);
+               if (mode != BRIDGE_MODE_VEPA && mode != BRIDGE_MODE_VEB)
+                       return -EINVAL;
+
+               status = be_cmd_set_hsw_config(adapter, 0, 0,
+                                              adapter->if_handle,
+                                              mode == BRIDGE_MODE_VEPA ?
+                                              PORT_FWD_TYPE_VEPA :
+                                              PORT_FWD_TYPE_VEB);
+               if (status)
+                       goto err;
+
+               dev_info(&adapter->pdev->dev, "enabled switch mode: %s\n",
+                        mode == BRIDGE_MODE_VEPA ? "VEPA" : "VEB");
+
+               return status;
+       }
+err:
+       dev_err(&adapter->pdev->dev, "Failed to set switch mode %s\n",
+               mode == BRIDGE_MODE_VEPA ? "VEPA" : "VEB");
+
+       return status;
+}
+
+static int be_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
+                                   struct net_device *dev,
+                                   u32 filter_mask)
+{
+       struct be_adapter *adapter = netdev_priv(dev);
+       int status = 0;
+       u8 hsw_mode;
+
+       if (!sriov_enabled(adapter))
+               return 0;
+
+       /* BE and Lancer chips support VEB mode only */
+       if (BEx_chip(adapter) || lancer_chip(adapter)) {
+               hsw_mode = PORT_FWD_TYPE_VEB;
+       } else {
+               status = be_cmd_get_hsw_config(adapter, NULL, 0,
+                                              adapter->if_handle, &hsw_mode);
+               if (status)
+                       return 0;
+       }
+
+       return ndo_dflt_bridge_getlink(skb, pid, seq, dev,
+                                      hsw_mode == PORT_FWD_TYPE_VEPA ?
+                                      BRIDGE_MODE_VEPA : BRIDGE_MODE_VEB);
+}
+
 static const struct net_device_ops be_netdev_ops = {
        .ndo_open               = be_open,
        .ndo_stop               = be_close,
@@ -3778,13 +3882,13 @@ static const struct net_device_ops be_netdev_ops = {
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller    = be_netpoll,
 #endif
+       .ndo_bridge_setlink     = be_ndo_bridge_setlink,
+       .ndo_bridge_getlink     = be_ndo_bridge_getlink,
 };
 
 static void be_netdev_init(struct net_device *netdev)
 {
        struct be_adapter *adapter = netdev_priv(netdev);
-       struct be_eq_obj *eqo;
-       int i;
 
        netdev->hw_features |= NETIF_F_SG | NETIF_F_TSO | NETIF_F_TSO6 |
                NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |
@@ -3807,9 +3911,6 @@ static void be_netdev_init(struct net_device *netdev)
        netdev->netdev_ops = &be_netdev_ops;
 
        SET_ETHTOOL_OPS(netdev, &be_ethtool_ops);
-
-       for_all_evt_queues(adapter, eqo, i)
-               netif_napi_add(netdev, &eqo->napi, be_poll, BE_NAPI_WEIGHT);
 }
 
 static void be_unmap_pci_bars(struct be_adapter *adapter)
@@ -3916,9 +4017,9 @@ static int be_ctrl_init(struct be_adapter *adapter)
        memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox));
 
        rx_filter->size = sizeof(struct be_cmd_req_rx_filter);
-       rx_filter->va = dma_alloc_coherent(&adapter->pdev->dev, rx_filter->size,
-                                          &rx_filter->dma,
-                                          GFP_KERNEL | __GFP_ZERO);
+       rx_filter->va = dma_zalloc_coherent(&adapter->pdev->dev,
+                                           rx_filter->size, &rx_filter->dma,
+                                           GFP_KERNEL);
        if (rx_filter->va == NULL) {
                status = -ENOMEM;
                goto free_mbox;
@@ -3964,8 +4065,8 @@ static int be_stats_init(struct be_adapter *adapter)
                /* BE3 and Skyhawk */
                cmd->size = sizeof(struct be_cmd_req_get_stats_v1);
 
-       cmd->va = dma_alloc_coherent(&adapter->pdev->dev, cmd->size, &cmd->dma,
-                                    GFP_KERNEL | __GFP_ZERO);
+       cmd->va = dma_zalloc_coherent(&adapter->pdev->dev, cmd->size, &cmd->dma,
+                                     GFP_KERNEL);
        if (cmd->va == NULL)
                return -1;
        return 0;
@@ -4072,6 +4173,7 @@ static int be_get_initial_config(struct be_adapter *adapter)
        level = be_get_fw_log_level(adapter);
        adapter->msg_enable = level <= FW_LOG_LEVEL_DEFAULT ? NETIF_MSG_HW : 0;
 
+       adapter->cfg_num_qs = netif_get_num_default_rss_queues();
        return 0;
 }
 
@@ -4164,7 +4266,8 @@ static void be_worker(struct work_struct *work)
                        be_cmd_get_stats(adapter, &adapter->stats_cmd);
        }
 
-       if (MODULO(adapter->work_counter, adapter->be_get_temp_freq) == 0)
+       if (be_physfn(adapter) &&
+           MODULO(adapter->work_counter, adapter->be_get_temp_freq) == 0)
                be_cmd_get_die_temperature(adapter);
 
        for_all_rx_queues(adapter, rxo, i) {
@@ -4253,7 +4356,7 @@ static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id)
 
        status = pci_enable_pcie_error_reporting(pdev);
        if (status)
-               dev_err(&pdev->dev, "Could not use PCIe error reporting\n");
+               dev_info(&pdev->dev, "Could not use PCIe error reporting\n");
 
        status = be_ctrl_init(adapter);
        if (status)