be2net: refactor be_get_resources() code
authorSathya Perla <sathya.perla@emulex.com>
Tue, 27 Aug 2013 11:27:32 +0000 (16:57 +0530)
committerDavid S. Miller <davem@davemloft.net>
Tue, 27 Aug 2013 19:57:04 +0000 (15:57 -0400)
1) use be_resources{} struct to query/store HW resource limits
2) The HW queue/resource limits for BE2/BE3 chips are mostly called out
   in driver as constants.  Code to handle this is scattered across various
   places in be_setup(). Consolidate this code into BEx_get_resources().
   For Lancer-R, Skyhawk-R, these limits are queried from FW.

Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/emulex/benet/be.h
drivers/net/ethernet/emulex/benet/be_cmds.c
drivers/net/ethernet/emulex/benet/be_cmds.h
drivers/net/ethernet/emulex/benet/be_main.c
drivers/net/ethernet/emulex/benet/be_roce.c
drivers/net/ethernet/emulex/benet/be_roce.h

index 7c5f9f2c5e03a773bcfe628b29e16aa32ba31b89..8b416355879f6af2afb9108a5d51e65a83c70465 100644 (file)
@@ -101,12 +101,15 @@ static inline char *nic_name(struct pci_dev *pdev)
 
 #define BE3_MAX_RSS_QS         8
 #define BE2_MAX_RSS_QS         4
+#define BE3_MAX_TX_QS          8
 #define MAX_RSS_QS             BE3_MAX_RSS_QS
 #define MAX_RX_QS              (MAX_RSS_QS + 1) /* RSS qs + 1 def Rx */
+#define MAX_EVT_QS             MAX_RSS_QS
 
 #define MAX_TX_QS              8
 #define MAX_ROCE_EQS           5
 #define MAX_MSIX_VECTORS       (MAX_RSS_QS + MAX_ROCE_EQS) /* RSS qs + RoCE */
+#define MIN_MSIX_VECTORS       1
 #define BE_TX_BUDGET           256
 #define BE_NAPI_WEIGHT         64
 #define MAX_RX_POST            BE_NAPI_WEIGHT /* Frags posted at a time */
@@ -353,6 +356,18 @@ struct phy_info {
        u32 supported;
 };
 
+struct be_resources {
+       u16 max_vfs;            /* Total VFs "really" supported by FW/HW */
+       u16 max_mcast_mac;
+       u16 max_tx_qs;
+       u16 max_rss_qs;
+       u16 max_rx_qs;
+       u16 max_uc_mac;         /* Max UC MACs programmable */
+       u16 max_vlans;          /* Number of vlans supported */
+       u16 max_evt_qs;
+       u32 if_cap_flags;
+};
+
 struct be_adapter {
        struct pci_dev *pdev;
        struct net_device *netdev;
@@ -370,18 +385,19 @@ struct be_adapter {
        spinlock_t mcc_lock;    /* For serializing mcc cmds to BE card */
        spinlock_t mcc_cq_lock;
 
-       u32 num_msix_vec;
-       u32 num_evt_qs;
-       struct be_eq_obj eq_obj[MAX_MSIX_VECTORS];
+       u16 cfg_num_qs;         /* configured via set-channels */
+       u16 num_evt_qs;
+       u16 num_msix_vec;
+       struct be_eq_obj eq_obj[MAX_EVT_QS];
        struct msix_entry msix_entries[MAX_MSIX_VECTORS];
        bool isr_registered;
 
        /* TX Rings */
-       u32 num_tx_qs;
+       u16 num_tx_qs;
        struct be_tx_obj tx_obj[MAX_TX_QS];
 
        /* Rx rings */
-       u32 num_rx_qs;
+       u16 num_rx_qs;
        struct be_rx_obj rx_obj[MAX_RX_QS];
        u32 big_page_size;      /* Compounded page size shared by rx wrbs */
 
@@ -431,8 +447,8 @@ struct be_adapter {
        u32 flash_status;
        struct completion flash_compl;
 
-       u32 num_vfs;            /* Number of VFs provisioned by PF driver */
-       u32 dev_num_vfs;        /* Number of VFs supported by HW */
+       struct be_resources res;        /* resources available for the func */
+       u16 num_vfs;                    /* Number of VFs provisioned by PF */
        u8 virtfn;
        struct be_vf_cfg *vf_cfg;
        bool be3_native;
@@ -447,21 +463,13 @@ struct be_adapter {
        u16 qnq_vid;
        u32 msg_enable;
        int be_get_temp_freq;
-       u16 max_mcast_mac;
-       u16 max_tx_queues;
-       u16 max_rss_queues;
-       u16 max_rx_queues;
-       u16 max_pmac_cnt;
-       u16 max_vlans;
-       u16 max_event_queues;
-       u32 if_cap_flags;
        u8 pf_number;
        u64 rss_flags;
 };
 
 #define be_physfn(adapter)             (!adapter->virtfn)
 #define        sriov_enabled(adapter)          (adapter->num_vfs > 0)
-#define        sriov_want(adapter)             (adapter->dev_num_vfs && num_vfs && \
+#define sriov_want(adapter)             (be_max_vfs(adapter) && num_vfs && \
                                         be_physfn(adapter))
 #define for_all_vfs(adapter, vf_cfg, i)                                        \
        for (i = 0, vf_cfg = &adapter->vf_cfg[i]; i < adapter->num_vfs; \
@@ -470,6 +478,26 @@ struct be_adapter {
 #define ON                             1
 #define OFF                            0
 
+#define be_max_vlans(adapter)          (adapter->res.max_vlans)
+#define be_max_uc(adapter)             (adapter->res.max_uc_mac)
+#define be_max_mc(adapter)             (adapter->res.max_mcast_mac)
+#define be_max_vfs(adapter)            (adapter->res.max_vfs)
+#define be_max_rss(adapter)            (adapter->res.max_rss_qs)
+#define be_max_txqs(adapter)           (adapter->res.max_tx_qs)
+#define be_max_prio_txqs(adapter)      (adapter->res.max_prio_tx_qs)
+#define be_max_rxqs(adapter)           (adapter->res.max_rx_qs)
+#define be_max_eqs(adapter)            (adapter->res.max_evt_qs)
+#define be_if_cap_flags(adapter)       (adapter->res.if_cap_flags)
+
+static inline u16 be_max_qs(struct be_adapter *adapter)
+{
+       /* If no RSS, need atleast the one def RXQ */
+       u16 num = max_t(u16, be_max_rss(adapter), 1);
+
+       num = min(num, be_max_eqs(adapter));
+       return min_t(u16, num, num_online_cpus());
+}
+
 #define lancer_chip(adapter)   (adapter->pdev->device == OC_DEVICE_ID3 || \
                                 adapter->pdev->device == OC_DEVICE_ID4)
 
index bc6f95814998e669f68128469e619d99c7152156..5458a4357ae046dc8b0109de6e50ad5db0240400 100644 (file)
@@ -1776,8 +1776,7 @@ int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value)
                 */
                req->if_flags_mask |=
                        cpu_to_le32(BE_IF_FLAGS_MCAST_PROMISCUOUS &
-                                   adapter->if_cap_flags);
-
+                                   be_if_cap_flags(adapter));
                req->mcast_num = cpu_to_le32(netdev_mc_count(adapter->netdev));
                netdev_for_each_mc_addr(ha, adapter->netdev)
                        memcpy(req->mcast_mac[i++].byte, ha->addr, ETH_ALEN);
@@ -3103,8 +3102,26 @@ static struct be_pcie_res_desc *be_get_pcie_desc(u8 devfn, u8 *buf,
        return NULL;
 }
 
+static void be_copy_nic_desc(struct be_resources *res,
+                            struct be_nic_res_desc *desc)
+{
+       res->max_uc_mac = le16_to_cpu(desc->unicast_mac_count);
+       res->max_vlans = le16_to_cpu(desc->vlan_count);
+       res->max_mcast_mac = le16_to_cpu(desc->mcast_mac_count);
+       res->max_tx_qs = le16_to_cpu(desc->txq_count);
+       res->max_rss_qs = le16_to_cpu(desc->rssq_count);
+       res->max_rx_qs = le16_to_cpu(desc->rq_count);
+       res->max_evt_qs = le16_to_cpu(desc->eq_count);
+       /* Clear flags that driver is not interested in */
+       res->if_cap_flags = le32_to_cpu(desc->cap_flags) &
+                               BE_IF_CAP_FLAGS_WANT;
+       /* Need 1 RXQ as the default RXQ */
+       if (res->max_rss_qs && res->max_rss_qs == res->max_rx_qs)
+               res->max_rss_qs -= 1;
+}
+
 /* Uses Mbox */
-int be_cmd_get_func_config(struct be_adapter *adapter)
+int be_cmd_get_func_config(struct be_adapter *adapter, struct be_resources *res)
 {
        struct be_mcc_wrb *wrb;
        struct be_cmd_req_get_func_config *req;
@@ -3152,18 +3169,7 @@ int be_cmd_get_func_config(struct be_adapter *adapter)
                }
 
                adapter->pf_number = desc->pf_num;
-               adapter->max_pmac_cnt = le16_to_cpu(desc->unicast_mac_count);
-               adapter->max_vlans = le16_to_cpu(desc->vlan_count);
-               adapter->max_mcast_mac = le16_to_cpu(desc->mcast_mac_count);
-               adapter->max_tx_queues = le16_to_cpu(desc->txq_count);
-               adapter->max_rss_queues = le16_to_cpu(desc->rssq_count);
-               adapter->max_rx_queues = le16_to_cpu(desc->rq_count);
-
-               adapter->max_event_queues = le16_to_cpu(desc->eq_count);
-               adapter->if_cap_flags = le32_to_cpu(desc->cap_flags);
-
-               /* Clear flags that driver is not interested in */
-               adapter->if_cap_flags &=  BE_IF_CAP_FLAGS_WANT;
+               be_copy_nic_desc(res, desc);
        }
 err:
        mutex_unlock(&adapter->mbox_lock);
@@ -3234,8 +3240,8 @@ err:
 }
 
 /* Uses sync mcc, if MCCQ is already created otherwise mbox */
-int be_cmd_get_profile_config(struct be_adapter *adapter, u32 *cap_flags,
-                             u16 *txq_count, u8 domain)
+int be_cmd_get_profile_config(struct be_adapter *adapter,
+                             struct be_resources *res, u8 domain)
 {
        struct be_cmd_resp_get_profile_config *resp;
        struct be_pcie_res_desc *pcie;
@@ -3264,15 +3270,12 @@ int be_cmd_get_profile_config(struct be_adapter *adapter, u32 *cap_flags,
        pcie =  be_get_pcie_desc(adapter->pdev->devfn, resp->func_param,
                                 desc_count);
        if (pcie)
-               adapter->dev_num_vfs = le16_to_cpu(pcie->num_vfs);
+               res->max_vfs = le16_to_cpu(pcie->num_vfs);
 
        nic = be_get_nic_desc(resp->func_param, desc_count);
-       if (nic) {
-               if (cap_flags)
-                       *cap_flags = le32_to_cpu(nic->cap_flags);
-               if (txq_count)
-                       *txq_count = le16_to_cpu(nic->txq_count);
-       }
+       if (nic)
+               be_copy_nic_desc(res, nic);
+
 err:
        if (cmd.va)
                pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
index 8ebed17b57f183646e1f40f1147d3a322f2c43f7..52f3d4ca00565f08be6d24510095f1466fc2d5f7 100644 (file)
@@ -1980,10 +1980,10 @@ extern int lancer_initiate_dump(struct be_adapter *adapter);
 extern bool dump_present(struct be_adapter *adapter);
 extern int lancer_test_and_set_rdy_state(struct be_adapter *adapter);
 extern int be_cmd_query_port_name(struct be_adapter *adapter, u8 *port_name);
-extern int be_cmd_get_func_config(struct be_adapter *adapter);
-extern int be_cmd_get_profile_config(struct be_adapter *adapter, u32 *cap_flags,
-                                    u16 *txq_count, u8 domain);
-
+int be_cmd_get_func_config(struct be_adapter *adapter,
+                          struct be_resources *res);
+int be_cmd_get_profile_config(struct be_adapter *adapter,
+                             struct be_resources *res, u8 domain);
 extern int be_cmd_set_profile_config(struct be_adapter *adapter, u32 bps,
                                     u8 domain);
 extern int be_cmd_get_if_id(struct be_adapter *adapter,
index 6f040d851eb2c4ebd9742cc56dbb53db017796cd..d34ea98ea2c45c5b22bd89efcdedc53469eda3ab 100644 (file)
@@ -1001,7 +1001,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 +1042,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 +1068,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 +1101,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 +1115,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;
@@ -1924,7 +1924,8 @@ 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) {
                eqo->adapter = adapter;
@@ -2013,25 +2014,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)
 {
        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);
+       adapter->num_tx_qs = min(adapter->num_evt_qs, be_max_txqs(adapter));
        if (adapter->num_tx_qs != MAX_TX_QS) {
                rtnl_lock();
                netif_set_real_num_tx_queues(adapter->netdev,
@@ -2098,11 +2087,15 @@ 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 > 1)
+               adapter->num_rx_qs++;
+
        if (adapter->num_rx_qs != MAX_RX_QS) {
                rtnl_lock();
                netif_set_real_num_rx_queues(adapter->netdev,
@@ -2375,35 +2368,20 @@ static void be_msix_disable(struct be_adapter *adapter)
        }
 }
 
-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;
@@ -2411,7 +2389,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);
@@ -2420,23 +2398,22 @@ 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;
 }
 
@@ -2829,6 +2806,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;
@@ -2837,9 +2815,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 |
@@ -2885,10 +2866,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;
        }
@@ -2967,6 +2948,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) ? 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;
@@ -2980,76 +3006,56 @@ static void be_setup_init(struct be_adapter *adapter)
                adapter->cmd_privileges = MIN_PRIVILEGES;
 }
 
-static void be_get_resources(struct be_adapter *adapter)
+static int be_get_resources(struct be_adapter *adapter)
 {
-       u16 dev_num_vfs;
-       int pos, status;
-       bool profile_present = false;
-       u16 txq_count = 0;
+       struct device *dev = &adapter->pdev->dev;
+       struct be_resources res = {0};
+       int status;
 
-       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 (BEx_chip(adapter)) {
+               BEx_get_resources(adapter, &res);
+               adapter->res = res;
        }
 
-       if (profile_present) {
-               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;
+       /* 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);
+       }
 
-               if (adapter->function_mode & FLEX10_MODE)
-                       adapter->max_vlans = BE_NUM_VLANS_SUPPORTED/8;
-               else
-                       adapter->max_vlans = BE_NUM_VLANS_SUPPORTED;
+       /* 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, &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 */
@@ -3062,20 +3068,22 @@ 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_mac_setup(struct be_adapter *adapter)
@@ -3151,8 +3159,8 @@ static int be_setup(struct be_adapter *adapter)
                        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 & adapter->if_cap_flags;
-       status = be_cmd_if_create(adapter, adapter->if_cap_flags, en_flags,
+       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 != 0)
                goto err;
@@ -3178,8 +3186,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");
@@ -4045,6 +4053,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;
 }
 
index 645e846daa5ccc22963aff64ebe511221e2acba4..9cd5415fe017dc359d2aae2e679eddc40e75f5e0 100644 (file)
@@ -60,7 +60,7 @@ static void _be_roce_dev_add(struct be_adapter *adapter)
                 */
                num_vec = adapter->num_msix_vec + adapter->num_msix_roce_vec;
                dev_info.intr_mode = BE_INTERRUPT_MODE_MSIX;
-               dev_info.msix.num_vectors = min(num_vec, MAX_ROCE_MSIX_VECTORS);
+               dev_info.msix.num_vectors = min(num_vec, MAX_MSIX_VECTORS);
                /* provide start index of the vector,
                 * so in case of linear usage,
                 * it can use the base as starting point.
index 27657299846337eafec3321f3b8e9c3afde72d8b..2cd1129e19af960185a3f706d9ab5ed165e409a7 100644 (file)
@@ -29,7 +29,7 @@ enum be_interrupt_mode {
        BE_INTERRUPT_MODE_MSI   = 2,
 };
 
-#define MAX_ROCE_MSIX_VECTORS   16
+#define MAX_MSIX_VECTORS               32
 struct be_dev_info {
        u8 __iomem *db;
        u64 unmapped_db;
@@ -45,7 +45,7 @@ struct be_dev_info {
        struct {
                int num_vectors;
                int start_vector;
-               u32 vector_list[MAX_ROCE_MSIX_VECTORS];
+               u32 vector_list[MAX_MSIX_VECTORS];
        } msix;
 };