Commit 92bf14ab authored by Sathya Perla's avatar Sathya Perla Committed by David S. Miller

be2net: refactor be_get_resources() code

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: default avatarSathya Perla <sathya.perla@emulex.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 150d58c7
...@@ -101,12 +101,15 @@ static inline char *nic_name(struct pci_dev *pdev) ...@@ -101,12 +101,15 @@ static inline char *nic_name(struct pci_dev *pdev)
#define BE3_MAX_RSS_QS 8 #define BE3_MAX_RSS_QS 8
#define BE2_MAX_RSS_QS 4 #define BE2_MAX_RSS_QS 4
#define BE3_MAX_TX_QS 8
#define MAX_RSS_QS BE3_MAX_RSS_QS #define MAX_RSS_QS BE3_MAX_RSS_QS
#define MAX_RX_QS (MAX_RSS_QS + 1) /* RSS qs + 1 def Rx */ #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_TX_QS 8
#define MAX_ROCE_EQS 5 #define MAX_ROCE_EQS 5
#define MAX_MSIX_VECTORS (MAX_RSS_QS + MAX_ROCE_EQS) /* RSS qs + RoCE */ #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_TX_BUDGET 256
#define BE_NAPI_WEIGHT 64 #define BE_NAPI_WEIGHT 64
#define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */ #define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */
...@@ -353,6 +356,18 @@ struct phy_info { ...@@ -353,6 +356,18 @@ struct phy_info {
u32 supported; 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 be_adapter {
struct pci_dev *pdev; struct pci_dev *pdev;
struct net_device *netdev; struct net_device *netdev;
...@@ -370,18 +385,19 @@ struct be_adapter { ...@@ -370,18 +385,19 @@ struct be_adapter {
spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */ spinlock_t mcc_lock; /* For serializing mcc cmds to BE card */
spinlock_t mcc_cq_lock; spinlock_t mcc_cq_lock;
u32 num_msix_vec; u16 cfg_num_qs; /* configured via set-channels */
u32 num_evt_qs; u16 num_evt_qs;
struct be_eq_obj eq_obj[MAX_MSIX_VECTORS]; u16 num_msix_vec;
struct be_eq_obj eq_obj[MAX_EVT_QS];
struct msix_entry msix_entries[MAX_MSIX_VECTORS]; struct msix_entry msix_entries[MAX_MSIX_VECTORS];
bool isr_registered; bool isr_registered;
/* TX Rings */ /* TX Rings */
u32 num_tx_qs; u16 num_tx_qs;
struct be_tx_obj tx_obj[MAX_TX_QS]; struct be_tx_obj tx_obj[MAX_TX_QS];
/* Rx rings */ /* Rx rings */
u32 num_rx_qs; u16 num_rx_qs;
struct be_rx_obj rx_obj[MAX_RX_QS]; struct be_rx_obj rx_obj[MAX_RX_QS];
u32 big_page_size; /* Compounded page size shared by rx wrbs */ u32 big_page_size; /* Compounded page size shared by rx wrbs */
...@@ -431,8 +447,8 @@ struct be_adapter { ...@@ -431,8 +447,8 @@ struct be_adapter {
u32 flash_status; u32 flash_status;
struct completion flash_compl; struct completion flash_compl;
u32 num_vfs; /* Number of VFs provisioned by PF driver */ struct be_resources res; /* resources available for the func */
u32 dev_num_vfs; /* Number of VFs supported by HW */ u16 num_vfs; /* Number of VFs provisioned by PF */
u8 virtfn; u8 virtfn;
struct be_vf_cfg *vf_cfg; struct be_vf_cfg *vf_cfg;
bool be3_native; bool be3_native;
...@@ -447,21 +463,13 @@ struct be_adapter { ...@@ -447,21 +463,13 @@ struct be_adapter {
u16 qnq_vid; u16 qnq_vid;
u32 msg_enable; u32 msg_enable;
int be_get_temp_freq; 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; u8 pf_number;
u64 rss_flags; u64 rss_flags;
}; };
#define be_physfn(adapter) (!adapter->virtfn) #define be_physfn(adapter) (!adapter->virtfn)
#define sriov_enabled(adapter) (adapter->num_vfs > 0) #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)) be_physfn(adapter))
#define for_all_vfs(adapter, vf_cfg, i) \ #define for_all_vfs(adapter, vf_cfg, i) \
for (i = 0, vf_cfg = &adapter->vf_cfg[i]; i < adapter->num_vfs; \ for (i = 0, vf_cfg = &adapter->vf_cfg[i]; i < adapter->num_vfs; \
...@@ -470,6 +478,26 @@ struct be_adapter { ...@@ -470,6 +478,26 @@ struct be_adapter {
#define ON 1 #define ON 1
#define OFF 0 #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 || \ #define lancer_chip(adapter) (adapter->pdev->device == OC_DEVICE_ID3 || \
adapter->pdev->device == OC_DEVICE_ID4) adapter->pdev->device == OC_DEVICE_ID4)
......
...@@ -1776,8 +1776,7 @@ int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value) ...@@ -1776,8 +1776,7 @@ int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value)
*/ */
req->if_flags_mask |= req->if_flags_mask |=
cpu_to_le32(BE_IF_FLAGS_MCAST_PROMISCUOUS & 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)); req->mcast_num = cpu_to_le32(netdev_mc_count(adapter->netdev));
netdev_for_each_mc_addr(ha, adapter->netdev) netdev_for_each_mc_addr(ha, adapter->netdev)
memcpy(req->mcast_mac[i++].byte, ha->addr, ETH_ALEN); 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, ...@@ -3103,8 +3102,26 @@ static struct be_pcie_res_desc *be_get_pcie_desc(u8 devfn, u8 *buf,
return NULL; 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 */ /* 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_mcc_wrb *wrb;
struct be_cmd_req_get_func_config *req; struct be_cmd_req_get_func_config *req;
...@@ -3152,18 +3169,7 @@ int be_cmd_get_func_config(struct be_adapter *adapter) ...@@ -3152,18 +3169,7 @@ int be_cmd_get_func_config(struct be_adapter *adapter)
} }
adapter->pf_number = desc->pf_num; adapter->pf_number = desc->pf_num;
adapter->max_pmac_cnt = le16_to_cpu(desc->unicast_mac_count); be_copy_nic_desc(res, desc);
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;
} }
err: err:
mutex_unlock(&adapter->mbox_lock); mutex_unlock(&adapter->mbox_lock);
...@@ -3234,8 +3240,8 @@ static int be_cmd_get_profile_config_mccq(struct be_adapter *adapter, ...@@ -3234,8 +3240,8 @@ static int be_cmd_get_profile_config_mccq(struct be_adapter *adapter,
} }
/* Uses sync mcc, if MCCQ is already created otherwise mbox */ /* Uses sync mcc, if MCCQ is already created otherwise mbox */
int be_cmd_get_profile_config(struct be_adapter *adapter, u32 *cap_flags, int be_cmd_get_profile_config(struct be_adapter *adapter,
u16 *txq_count, u8 domain) struct be_resources *res, u8 domain)
{ {
struct be_cmd_resp_get_profile_config *resp; struct be_cmd_resp_get_profile_config *resp;
struct be_pcie_res_desc *pcie; struct be_pcie_res_desc *pcie;
...@@ -3264,15 +3270,12 @@ int be_cmd_get_profile_config(struct be_adapter *adapter, u32 *cap_flags, ...@@ -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, pcie = be_get_pcie_desc(adapter->pdev->devfn, resp->func_param,
desc_count); desc_count);
if (pcie) 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); nic = be_get_nic_desc(resp->func_param, desc_count);
if (nic) { if (nic)
if (cap_flags) be_copy_nic_desc(res, nic);
*cap_flags = le32_to_cpu(nic->cap_flags);
if (txq_count)
*txq_count = le16_to_cpu(nic->txq_count);
}
err: err:
if (cmd.va) if (cmd.va)
pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma); pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
......
...@@ -1980,10 +1980,10 @@ extern int lancer_initiate_dump(struct be_adapter *adapter); ...@@ -1980,10 +1980,10 @@ extern int lancer_initiate_dump(struct be_adapter *adapter);
extern bool dump_present(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 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_query_port_name(struct be_adapter *adapter, u8 *port_name);
extern int be_cmd_get_func_config(struct be_adapter *adapter); int be_cmd_get_func_config(struct be_adapter *adapter,
extern int be_cmd_get_profile_config(struct be_adapter *adapter, u32 *cap_flags, struct be_resources *res);
u16 *txq_count, u8 domain); 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, extern int be_cmd_set_profile_config(struct be_adapter *adapter, u32 bps,
u8 domain); u8 domain);
extern int be_cmd_get_if_id(struct be_adapter *adapter, extern int be_cmd_get_if_id(struct be_adapter *adapter,
......
...@@ -1001,7 +1001,7 @@ static int be_vid_config(struct be_adapter *adapter) ...@@ -1001,7 +1001,7 @@ static int be_vid_config(struct be_adapter *adapter)
if (adapter->promiscuous) if (adapter->promiscuous)
return 0; return 0;
if (adapter->vlans_added > adapter->max_vlans) if (adapter->vlans_added > be_max_vlans(adapter))
goto set_vlan_promisc; goto set_vlan_promisc;
/* Construct VLAN Table to give to HW */ /* 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) ...@@ -1042,7 +1042,7 @@ static int be_vlan_add_vid(struct net_device *netdev, __be16 proto, u16 vid)
goto ret; goto ret;
adapter->vlan_tag[vid] = 1; 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); status = be_vid_config(adapter);
if (!status) if (!status)
...@@ -1068,7 +1068,7 @@ static int be_vlan_rem_vid(struct net_device *netdev, __be16 proto, u16 vid) ...@@ -1068,7 +1068,7 @@ static int be_vlan_rem_vid(struct net_device *netdev, __be16 proto, u16 vid)
goto ret; goto ret;
adapter->vlan_tag[vid] = 0; 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); status = be_vid_config(adapter);
if (!status) if (!status)
...@@ -1101,7 +1101,7 @@ static void be_set_rx_mode(struct net_device *netdev) ...@@ -1101,7 +1101,7 @@ static void be_set_rx_mode(struct net_device *netdev)
/* Enable multicast promisc if num configured exceeds what we support */ /* Enable multicast promisc if num configured exceeds what we support */
if (netdev->flags & IFF_ALLMULTI || 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); be_cmd_rx_filter(adapter, IFF_ALLMULTI, ON);
goto done; goto done;
} }
...@@ -1115,7 +1115,7 @@ static void be_set_rx_mode(struct net_device *netdev) ...@@ -1115,7 +1115,7 @@ static void be_set_rx_mode(struct net_device *netdev)
adapter->pmac_id[i], 0); 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); be_cmd_rx_filter(adapter, IFF_PROMISC, ON);
adapter->promiscuous = true; adapter->promiscuous = true;
goto done; goto done;
...@@ -1924,7 +1924,8 @@ static int be_evt_queues_create(struct be_adapter *adapter) ...@@ -1924,7 +1924,8 @@ static int be_evt_queues_create(struct be_adapter *adapter)
struct be_eq_obj *eqo; struct be_eq_obj *eqo;
int i, rc; 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) { for_all_evt_queues(adapter, eqo, i) {
eqo->adapter = adapter; eqo->adapter = adapter;
...@@ -2013,25 +2014,13 @@ static void be_tx_queues_destroy(struct be_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) static int be_tx_cqs_create(struct be_adapter *adapter)
{ {
struct be_queue_info *cq, *eq; struct be_queue_info *cq, *eq;
int status;
struct be_tx_obj *txo; 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) { if (adapter->num_tx_qs != MAX_TX_QS) {
rtnl_lock(); rtnl_lock();
netif_set_real_num_tx_queues(adapter->netdev, netif_set_real_num_tx_queues(adapter->netdev,
...@@ -2098,11 +2087,15 @@ static int be_rx_cqs_create(struct be_adapter *adapter) ...@@ -2098,11 +2087,15 @@ static int be_rx_cqs_create(struct be_adapter *adapter)
struct be_rx_obj *rxo; struct be_rx_obj *rxo;
int rc, i; int rc, i;
/* We'll create as many RSS rings as there are irqs. /* We can create as many RSS rings as there are EQs. */
* But when there's only one irq there's no use creating RSS rings 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) ? if (adapter->num_rx_qs > 1)
num_irqs(adapter) + 1 : 1; adapter->num_rx_qs++;
if (adapter->num_rx_qs != MAX_RX_QS) { if (adapter->num_rx_qs != MAX_RX_QS) {
rtnl_lock(); rtnl_lock();
netif_set_real_num_rx_queues(adapter->netdev, netif_set_real_num_rx_queues(adapter->netdev,
...@@ -2375,35 +2368,20 @@ static void be_msix_disable(struct be_adapter *adapter) ...@@ -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) static int be_msix_enable(struct be_adapter *adapter)
{ {
#define BE_MIN_MSIX_VECTORS 1 int i, status, num_vec;
int i, status, num_vec, num_roce_vec = 0;
struct device *dev = &adapter->pdev->dev; struct device *dev = &adapter->pdev->dev;
/* If RSS queues are not used, need a vec for default RX Q */ /* If RoCE is supported, program the max number of NIC vectors that
num_vec = min(be_num_rss_want(adapter), num_online_cpus()); * may be configured via set-channels, along with vectors needed for
if (be_roce_supported(adapter)) { * RoCe. Else, just program the number we'll use initially.
num_roce_vec = min_t(u32, MAX_ROCE_MSIX_VECTORS, */
(num_online_cpus() + 1)); if (be_roce_supported(adapter))
num_roce_vec = min(num_roce_vec, MAX_ROCE_EQS); num_vec = min_t(int, 2 * be_max_eqs(adapter),
num_vec += num_roce_vec; 2 * num_online_cpus());
num_vec = min(num_vec, MAX_MSIX_VECTORS); else
} num_vec = adapter->cfg_num_qs;
num_vec = max(num_vec, BE_MIN_MSIX_VECTORS);
for (i = 0; i < num_vec; i++) for (i = 0; i < num_vec; i++)
adapter->msix_entries[i].entry = i; adapter->msix_entries[i].entry = i;
...@@ -2411,7 +2389,7 @@ static int be_msix_enable(struct be_adapter *adapter) ...@@ -2411,7 +2389,7 @@ static int be_msix_enable(struct be_adapter *adapter)
status = pci_enable_msix(adapter->pdev, adapter->msix_entries, num_vec); status = pci_enable_msix(adapter->pdev, adapter->msix_entries, num_vec);
if (status == 0) { if (status == 0) {
goto done; goto done;
} else if (status >= BE_MIN_MSIX_VECTORS) { } else if (status >= MIN_MSIX_VECTORS) {
num_vec = status; num_vec = status;
status = pci_enable_msix(adapter->pdev, adapter->msix_entries, status = pci_enable_msix(adapter->pdev, adapter->msix_entries,
num_vec); num_vec);
...@@ -2420,23 +2398,22 @@ static int be_msix_enable(struct be_adapter *adapter) ...@@ -2420,23 +2398,22 @@ static int be_msix_enable(struct be_adapter *adapter)
} }
dev_warn(dev, "MSIx enable failed\n"); dev_warn(dev, "MSIx enable failed\n");
/* INTx is not supported in VFs, so fail probe if enable_msix fails */ /* INTx is not supported in VFs, so fail probe if enable_msix fails */
if (!be_physfn(adapter)) if (!be_physfn(adapter))
return status; return status;
return 0; return 0;
done: done:
if (be_roce_supported(adapter)) { if (be_roce_supported(adapter) && num_vec > MIN_MSIX_VECTORS) {
if (num_vec > num_roce_vec) { adapter->num_msix_roce_vec = num_vec / 2;
adapter->num_msix_vec = num_vec - num_roce_vec; dev_info(dev, "enabled %d MSI-x vector(s) for RoCE\n",
adapter->num_msix_roce_vec = adapter->num_msix_roce_vec);
num_vec - adapter->num_msix_vec; }
} else {
adapter->num_msix_vec = num_vec; adapter->num_msix_vec = num_vec - adapter->num_msix_roce_vec;
adapter->num_msix_roce_vec = 0;
} dev_info(dev, "enabled %d MSI-x vector(s) for NIC\n",
} else adapter->num_msix_vec);
adapter->num_msix_vec = num_vec;
dev_info(dev, "enabled %d MSI-x vector(s)\n", adapter->num_msix_vec);
return 0; return 0;
} }
...@@ -2829,6 +2806,7 @@ static int be_clear(struct be_adapter *adapter) ...@@ -2829,6 +2806,7 @@ static int be_clear(struct be_adapter *adapter)
static int be_vfs_if_create(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; struct be_vf_cfg *vf_cfg;
u32 cap_flags, en_flags, vf; u32 cap_flags, en_flags, vf;
int status; int status;
...@@ -2837,9 +2815,12 @@ static int be_vfs_if_create(struct be_adapter *adapter) ...@@ -2837,9 +2815,12 @@ static int be_vfs_if_create(struct be_adapter *adapter)
BE_IF_FLAGS_MULTICAST; BE_IF_FLAGS_MULTICAST;
for_all_vfs(adapter, vf_cfg, vf) { for_all_vfs(adapter, vf_cfg, vf) {
if (!BE3_chip(adapter)) if (!BE3_chip(adapter)) {
be_cmd_get_profile_config(adapter, &cap_flags, status = be_cmd_get_profile_config(adapter, &res,
NULL, vf + 1); vf + 1);
if (!status)
cap_flags = res.if_cap_flags;
}
/* If a FW profile exists, then cap_flags are updated */ /* If a FW profile exists, then cap_flags are updated */
en_flags = cap_flags & (BE_IF_FLAGS_UNTAGGED | en_flags = cap_flags & (BE_IF_FLAGS_UNTAGGED |
...@@ -2885,10 +2866,10 @@ static int be_vf_setup(struct be_adapter *adapter) ...@@ -2885,10 +2866,10 @@ static int be_vf_setup(struct be_adapter *adapter)
dev_warn(dev, "Ignoring num_vfs=%d setting\n", num_vfs); dev_warn(dev, "Ignoring num_vfs=%d setting\n", num_vfs);
adapter->num_vfs = old_vfs; adapter->num_vfs = old_vfs;
} else { } 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", dev_info(dev, "Device supports %d VFs and not %d\n",
adapter->dev_num_vfs, num_vfs); be_max_vfs(adapter), num_vfs);
adapter->num_vfs = min_t(u16, num_vfs, adapter->dev_num_vfs); adapter->num_vfs = min_t(u16, num_vfs, be_max_vfs(adapter));
if (!adapter->num_vfs) if (!adapter->num_vfs)
return 0; return 0;
} }
...@@ -2967,6 +2948,51 @@ static int be_vf_setup(struct be_adapter *adapter) ...@@ -2967,6 +2948,51 @@ static int be_vf_setup(struct be_adapter *adapter)
return status; 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) static void be_setup_init(struct be_adapter *adapter)
{ {
adapter->vlan_prio_bmap = 0xff; adapter->vlan_prio_bmap = 0xff;
...@@ -2980,76 +3006,56 @@ static void be_setup_init(struct be_adapter *adapter) ...@@ -2980,76 +3006,56 @@ static void be_setup_init(struct be_adapter *adapter)
adapter->cmd_privileges = MIN_PRIVILEGES; 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; struct device *dev = &adapter->pdev->dev;
int pos, status; struct be_resources res = {0};
bool profile_present = false; int status;
u16 txq_count = 0;
if (!BEx_chip(adapter)) { if (BEx_chip(adapter)) {
status = be_cmd_get_func_config(adapter); BEx_get_resources(adapter, &res);
if (!status) adapter->res = res;
profile_present = true;
} else if (BE3_chip(adapter) && be_physfn(adapter)) {
be_cmd_get_profile_config(adapter, NULL, &txq_count, 0);
} }
if (profile_present) { /* For BE3 only check if FW suggests a different max-txqs value */
adapter->max_tx_queues = min_t(u16, adapter->max_tx_queues, if (BE3_chip(adapter)) {
MAX_TX_QS); status = be_cmd_get_profile_config(adapter, &res, 0);
adapter->max_rss_queues = min_t(u16, adapter->max_rss_queues, if (!status && res.max_tx_qs)
BE3_MAX_RSS_QS); adapter->res.max_tx_qs =
adapter->max_event_queues = min_t(u16, min(adapter->res.max_tx_qs, res.max_tx_qs);
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) /* For Lancer, SH etc read per-function resource limits from FW.
adapter->max_vlans = BE_NUM_VLANS_SUPPORTED/8; * GET_FUNC_CONFIG returns per function guaranteed limits.
else * GET_PROFILE_CONFIG returns PCI-E related limits PF-pool limits
adapter->max_vlans = BE_NUM_VLANS_SUPPORTED; */
if (!BEx_chip(adapter)) {
status = be_cmd_get_func_config(adapter, &res);
if (status)
return status;
adapter->max_mcast_mac = BE_MAX_MC; /* If RoCE may be enabled stash away half the EQs for RoCE */
adapter->max_tx_queues = txq_count ? txq_count : MAX_TX_QS; if (be_roce_supported(adapter))
adapter->max_tx_queues = min_t(u16, adapter->max_tx_queues, res.max_evt_qs /= 2;
MAX_TX_QS); adapter->res = res;
adapter->max_rss_queues = (adapter->be3_native) ?
BE3_MAX_RSS_QS : BE2_MAX_RSS_QS;
adapter->max_event_queues = BE3_MAX_RSS_QS;
adapter->if_cap_flags = BE_IF_FLAGS_UNTAGGED | if (be_physfn(adapter)) {
BE_IF_FLAGS_BROADCAST | status = be_cmd_get_profile_config(adapter, &res, 0);
BE_IF_FLAGS_MULTICAST | if (status)
BE_IF_FLAGS_PASS_L3L4_ERRORS | return status;
BE_IF_FLAGS_MCAST_PROMISCUOUS | adapter->res.max_vfs = res.max_vfs;
BE_IF_FLAGS_VLAN_PROMISCUOUS | }
BE_IF_FLAGS_PROMISCUOUS;
if (adapter->function_caps & BE_FUNCTION_CAPS_RSS) dev_info(dev, "Max: txqs %d, rxqs %d, rss %d, eqs %d, vfs %d\n",
adapter->if_cap_flags |= BE_IF_FLAGS_RSS; 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); return 0;
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;
}
} }
/* Routine to query per function resource limits */ /* Routine to query per function resource limits */
...@@ -3062,20 +3068,22 @@ static int be_get_config(struct be_adapter *adapter) ...@@ -3062,20 +3068,22 @@ static int be_get_config(struct be_adapter *adapter)
&adapter->function_caps, &adapter->function_caps,
&adapter->asic_rev); &adapter->asic_rev);
if (status) 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 */ /* primary mac needs 1 pmac entry */
adapter->pmac_id = kcalloc(adapter->max_pmac_cnt + 1, adapter->pmac_id = kcalloc(be_max_uc(adapter) + 1, sizeof(u32),
sizeof(u32), GFP_KERNEL); GFP_KERNEL);
if (!adapter->pmac_id) { if (!adapter->pmac_id)
status = -ENOMEM; return -ENOMEM;
goto err;
}
err: /* Sanitize cfg_num_qs based on HW and platform limits */
return status; adapter->cfg_num_qs = min(adapter->cfg_num_qs, be_max_qs(adapter));
return 0;
} }
static int be_mac_setup(struct be_adapter *adapter) static int be_mac_setup(struct be_adapter *adapter)
...@@ -3151,8 +3159,8 @@ static int be_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; BE_IF_FLAGS_MULTICAST | BE_IF_FLAGS_PASS_L3L4_ERRORS;
if (adapter->function_caps & BE_FUNCTION_CAPS_RSS) if (adapter->function_caps & BE_FUNCTION_CAPS_RSS)
en_flags |= BE_IF_FLAGS_RSS; en_flags |= BE_IF_FLAGS_RSS;
en_flags = en_flags & adapter->if_cap_flags; en_flags = en_flags & be_if_cap_flags(adapter);
status = be_cmd_if_create(adapter, adapter->if_cap_flags, en_flags, status = be_cmd_if_create(adapter, be_if_cap_flags(adapter), en_flags,
&adapter->if_handle, 0); &adapter->if_handle, 0);
if (status != 0) if (status != 0)
goto err; goto err;
...@@ -3178,8 +3186,8 @@ static int be_setup(struct be_adapter *adapter) ...@@ -3178,8 +3186,8 @@ static int be_setup(struct be_adapter *adapter)
be_cmd_set_flow_control(adapter, adapter->tx_fc, be_cmd_set_flow_control(adapter, adapter->tx_fc,
adapter->rx_fc); adapter->rx_fc);
if (be_physfn(adapter)) { if (be_physfn(adapter) && num_vfs) {
if (adapter->dev_num_vfs) if (be_max_vfs(adapter))
be_vf_setup(adapter); be_vf_setup(adapter);
else else
dev_warn(dev, "device doesn't support SRIOV\n"); dev_warn(dev, "device doesn't support SRIOV\n");
...@@ -4045,6 +4053,7 @@ static int be_get_initial_config(struct be_adapter *adapter) ...@@ -4045,6 +4053,7 @@ static int be_get_initial_config(struct be_adapter *adapter)
level = be_get_fw_log_level(adapter); level = be_get_fw_log_level(adapter);
adapter->msg_enable = level <= FW_LOG_LEVEL_DEFAULT ? NETIF_MSG_HW : 0; adapter->msg_enable = level <= FW_LOG_LEVEL_DEFAULT ? NETIF_MSG_HW : 0;
adapter->cfg_num_qs = netif_get_num_default_rss_queues();
return 0; return 0;
} }
......
...@@ -60,7 +60,7 @@ static void _be_roce_dev_add(struct be_adapter *adapter) ...@@ -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; num_vec = adapter->num_msix_vec + adapter->num_msix_roce_vec;
dev_info.intr_mode = BE_INTERRUPT_MODE_MSIX; 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, /* provide start index of the vector,
* so in case of linear usage, * so in case of linear usage,
* it can use the base as starting point. * it can use the base as starting point.
......
...@@ -29,7 +29,7 @@ enum be_interrupt_mode { ...@@ -29,7 +29,7 @@ enum be_interrupt_mode {
BE_INTERRUPT_MODE_MSI = 2, BE_INTERRUPT_MODE_MSI = 2,
}; };
#define MAX_ROCE_MSIX_VECTORS 16 #define MAX_MSIX_VECTORS 32
struct be_dev_info { struct be_dev_info {
u8 __iomem *db; u8 __iomem *db;
u64 unmapped_db; u64 unmapped_db;
...@@ -45,7 +45,7 @@ struct be_dev_info { ...@@ -45,7 +45,7 @@ struct be_dev_info {
struct { struct {
int num_vectors; int num_vectors;
int start_vector; int start_vector;
u32 vector_list[MAX_ROCE_MSIX_VECTORS]; u32 vector_list[MAX_MSIX_VECTORS];
} msix; } msix;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment