"P1_OB_LINK ",
"HOST_GPIO ",
"MBOX ",
- "AXGMAC0",
- "AXGMAC1",
- "JTAG",
- "MPU_INTPEND"
+ "ERX2 ",
+ "SPARE ",
+ "JTAG ",
+ "MPU_INTPEND "
};
/* UE Status High CSR */
static const char * const ue_status_hi_desc[] = {
"HOST5",
"HOST6",
"HOST7",
- "HOST8",
- "HOST9",
+ "ECRC",
+ "Poison TLP",
"NETC",
- "Unknown",
- "Unknown",
- "Unknown",
- "Unknown",
- "Unknown",
- "Unknown",
- "Unknown",
+ "PERIPH",
+ "LLTXULP",
+ "D2P",
+ "RCON",
+ "LDMA",
+ "LLTXP",
+ "LLTXPB",
"Unknown"
};
static int be_vlan_rem_vid(struct net_device *netdev, __be16 proto, u16 vid)
{
struct be_adapter *adapter = netdev_priv(netdev);
- int status = 0;
/* Packets with VID 0 are always received by Lancer by default */
if (lancer_chip(adapter) && vid == 0)
- goto ret;
+ return 0;
clear_bit(vid, adapter->vids);
- status = be_vid_config(adapter);
- if (!status)
- adapter->vlans_added--;
- else
- set_bit(vid, adapter->vids);
-ret:
- return status;
+ adapter->vlans_added--;
+
+ return be_vid_config(adapter);
}
static void be_clear_promisc(struct be_adapter *adapter)
vf + 1);
}
- if (status)
- dev_err(&adapter->pdev->dev, "MAC %pM set on VF %d Failed\n",
- mac, vf);
- else
- memcpy(vf_cfg->mac_addr, mac, ETH_ALEN);
+ if (status) {
+ dev_err(&adapter->pdev->dev, "MAC %pM set on VF %d Failed: %#x",
+ mac, vf, status);
+ return be_cmd_status(status);
+ }
- return status;
+ ether_addr_copy(vf_cfg->mac_addr, mac);
+
+ return 0;
}
static int be_get_vf_config(struct net_device *netdev, int vf,
vf + 1, vf_cfg->if_handle, 0);
}
- if (!status)
- vf_cfg->vlan_tag = vlan;
- else
- dev_info(&adapter->pdev->dev,
- "VLAN %d config on VF %d failed\n", vlan, vf);
- return status;
+ if (status) {
+ dev_err(&adapter->pdev->dev,
+ "VLAN %d config on VF %d failed : %#x\n", vlan,
+ vf, status);
+ return be_cmd_status(status);
+ }
+
+ vf_cfg->vlan_tag = vlan;
+
+ return 0;
}
static int be_set_vf_tx_rate(struct net_device *netdev, int vf,
if (!link_status) {
dev_err(dev, "TX-rate setting not allowed when link is down\n");
- status = -EPERM;
+ status = -ENETDOWN;
goto err;
}
err:
dev_err(dev, "TX-rate setting of %dMbps on VF%d failed\n",
max_tx_rate, vf);
- return status;
+ return be_cmd_status(status);
}
static int be_set_vf_link_state(struct net_device *netdev, int vf,
int link_state)
return -EINVAL;
status = be_cmd_set_logical_link_config(adapter, link_state, vf+1);
- if (!status)
- adapter->vf_cfg[vf].plink_tracking = link_state;
+ if (status) {
+ dev_err(&adapter->pdev->dev,
+ "Link state change on VF %d failed: %#x\n", vf, status);
+ return be_cmd_status(status);
+ }
- return status;
+ adapter->vf_cfg[vf].plink_tracking = link_state;
+
+ return 0;
}
static void be_aic_update(struct be_aic_obj *aic, u64 rx_pkts, u64 tx_pkts,
for_all_evt_queues(adapter, eqo, i) {
napi_enable(&eqo->napi);
be_enable_busy_poll(eqo);
- be_eq_notify(adapter, eqo->q.id, true, false, 0);
+ be_eq_notify(adapter, eqo->q.id, true, true, 0);
}
adapter->flags |= BE_FLAGS_NAPI_ENABLED;
cmd.va = dma_zalloc_coherent(&adapter->pdev->dev, cmd.size, &cmd.dma,
GFP_KERNEL);
if (cmd.va == NULL)
- return -1;
+ return -ENOMEM;
if (enable) {
status = pci_write_config_dword(adapter->pdev,
if (sriov_enabled(adapter))
be_vf_clear(adapter);
+ /* Re-configure FW to distribute resources evenly across max-supported
+ * number of VFs, only when VFs are not already enabled.
+ */
+ if (be_physfn(adapter) && !pci_vfs_assigned(adapter->pdev))
+ be_cmd_set_sriov_config(adapter, adapter->pool_res,
+ pci_sriov_get_totalvfs(adapter->pdev));
+
#ifdef CONFIG_BE2NET_VXLAN
be_disable_vxlan_offloads(adapter);
#endif
u32 privileges;
old_vfs = pci_num_vf(adapter->pdev);
- if (old_vfs) {
- dev_info(dev, "%d VFs are already enabled\n", old_vfs);
- if (old_vfs != num_vfs)
- dev_warn(dev, "Ignoring num_vfs=%d setting\n", num_vfs);
- adapter->num_vfs = old_vfs;
- } else {
- if (num_vfs > be_max_vfs(adapter))
- dev_info(dev, "Device supports %d VFs and not %d\n",
- be_max_vfs(adapter), num_vfs);
- adapter->num_vfs = min_t(u16, num_vfs, be_max_vfs(adapter));
- if (!adapter->num_vfs)
- return 0;
- }
status = be_vf_setup_init(adapter);
if (status)
if (status)
goto err;
}
- } else {
- status = be_vfs_if_create(adapter);
- if (status)
- goto err;
- }
- if (old_vfs) {
status = be_vfs_mac_query(adapter);
if (status)
goto err;
} else {
+ status = be_vfs_if_create(adapter);
+ if (status)
+ goto err;
+
status = be_vf_eth_addr_config(adapter);
if (status)
goto err;
static u8 be_convert_mc_type(u32 function_mode)
{
- if (function_mode & VNIC_MODE && function_mode & FLEX10_MODE)
+ if (function_mode & VNIC_MODE && function_mode & QNQ_MODE)
return vNIC1;
- else if (function_mode & FLEX10_MODE)
+ else if (function_mode & QNQ_MODE)
return FLEX10;
else if (function_mode & VNIC_MODE)
return vNIC2;
static void BEx_get_resources(struct be_adapter *adapter,
struct be_resources *res)
{
- struct pci_dev *pdev = adapter->pdev;
- bool use_sriov = false;
- int max_vfs = 0;
-
- if (be_physfn(adapter) && BE3_chip(adapter)) {
- be_cmd_get_profile_config(adapter, res, 0);
- /* Some old versions of BE3 FW don't report max_vfs value */
- if (res->max_vfs == 0) {
- max_vfs = pci_sriov_get_totalvfs(pdev);
- res->max_vfs = max_vfs > 0 ? min(MAX_VFS, max_vfs) : 0;
- }
- use_sriov = res->max_vfs && sriov_want(adapter);
- }
+ bool use_sriov = adapter->num_vfs ? 1 : 0;
if (be_physfn(adapter))
res->max_uc_mac = BE_UC_PMAC_COUNT;
adapter->cmd_privileges = MIN_PRIVILEGES;
}
+static int be_get_sriov_config(struct be_adapter *adapter)
+{
+ struct device *dev = &adapter->pdev->dev;
+ struct be_resources res = {0};
+ int status, max_vfs, old_vfs;
+
+ status = be_cmd_get_profile_config(adapter, &res, 0);
+ if (status)
+ return status;
+
+ adapter->pool_res = res;
+
+ /* Some old versions of BE3 FW don't report max_vfs value */
+ if (BE3_chip(adapter) && !res.max_vfs) {
+ max_vfs = pci_sriov_get_totalvfs(adapter->pdev);
+ res.max_vfs = max_vfs > 0 ? min(MAX_VFS, max_vfs) : 0;
+ }
+
+ adapter->pool_res.max_vfs = res.max_vfs;
+ pci_sriov_set_totalvfs(adapter->pdev, be_max_vfs(adapter));
+
+ if (!be_max_vfs(adapter)) {
+ if (num_vfs)
+ dev_warn(dev, "device doesn't support SRIOV\n");
+ adapter->num_vfs = 0;
+ return 0;
+ }
+
+ /* validate num_vfs module param */
+ old_vfs = pci_num_vf(adapter->pdev);
+ if (old_vfs) {
+ dev_info(dev, "%d VFs are already enabled\n", old_vfs);
+ if (old_vfs != num_vfs)
+ dev_warn(dev, "Ignoring num_vfs=%d setting\n", num_vfs);
+ adapter->num_vfs = old_vfs;
+ } else {
+ if (num_vfs > be_max_vfs(adapter)) {
+ dev_info(dev, "Resources unavailable to init %d VFs\n",
+ num_vfs);
+ dev_info(dev, "Limiting to %d VFs\n",
+ be_max_vfs(adapter));
+ }
+ adapter->num_vfs = min_t(u16, num_vfs, be_max_vfs(adapter));
+ }
+
+ return 0;
+}
+
static int be_get_resources(struct be_adapter *adapter)
{
struct device *dev = &adapter->pdev->dev;
res.max_evt_qs /= 2;
adapter->res = res;
- if (be_physfn(adapter)) {
- status = be_cmd_get_profile_config(adapter, &res, 0);
- if (status)
- return status;
- adapter->res.max_vfs = res.max_vfs;
- }
-
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),
return 0;
}
-/* Routine to query per function resource limits */
static int be_get_config(struct be_adapter *adapter)
{
u16 profile_id;
int status;
- status = be_cmd_query_fw_cfg(adapter, &adapter->port_num,
- &adapter->function_mode,
- &adapter->function_caps,
- &adapter->asic_rev);
+ status = be_cmd_query_fw_cfg(adapter);
if (status)
return status;
if (!status)
dev_info(&adapter->pdev->dev,
"Using profile 0x%x\n", profile_id);
+
+ status = be_get_sriov_config(adapter);
+ if (status)
+ return status;
+
+ /* When the HW is in SRIOV capable configuration, the PF-pool
+ * resources are equally distributed across the max-number of
+ * VFs. The user may request only a subset of the max-vfs to be
+ * enabled. Based on num_vfs, redistribute the resources across
+ * num_vfs so that each VF will have access to more number of
+ * resources. This facility is not available in BE3 FW.
+ * Also, this is done by FW in Lancer chip.
+ */
+ if (!pci_num_vf(adapter->pdev)) {
+ status = be_cmd_set_sriov_config(adapter,
+ adapter->pool_res,
+ adapter->num_vfs);
+ if (status)
+ return status;
+ }
}
status = be_get_resources(adapter);
if (status)
goto err;
- be_cmd_get_fw_ver(adapter, adapter->fw_ver, adapter->fw_on_flash);
+ be_cmd_get_fw_ver(adapter);
if (BE2_chip(adapter) && fw_major_num(adapter->fw_ver) < 4) {
dev_err(dev, "Firmware on card is old(%s), IRQs may not work.",
be_cmd_set_logical_link_config(adapter,
IFLA_VF_LINK_STATE_AUTO, 0);
- if (sriov_want(adapter)) {
- if (be_max_vfs(adapter))
- be_vf_setup(adapter);
- else
- dev_warn(dev, "device doesn't support SRIOV\n");
- }
+ if (adapter->num_vfs)
+ be_vf_setup(adapter);
status = be_cmd_get_phy_info(adapter);
if (!status && be_pause_supported(adapter))
fsec = get_fsec_info(adapter, filehdr_size + img_hdrs_size, fw);
if (!fsec) {
dev_err(dev, "Invalid Cookie. FW image may be corrupted\n");
- return -1;
+ return -EINVAL;
}
for (i = 0; i < le32_to_cpu(fsec->fsec_hdr.num_images); i++) {
&flash_cmd,
num_imgs);
else {
- status = -1;
+ status = -EINVAL;
dev_err(&adapter->pdev->dev,
"Can't load BE3 UFI on BE3R\n");
}
if (ufi_type == UFI_TYPE2)
status = be_flash_BEx(adapter, fw, &flash_cmd, 0);
else if (ufi_type == -1)
- status = -1;
+ status = -EINVAL;
dma_free_coherent(&adapter->pdev->dev, flash_cmd.size, flash_cmd.va,
flash_cmd.dma);
if (!netif_running(adapter->netdev)) {
dev_err(&adapter->pdev->dev,
"Firmware load not allowed (interface is down)\n");
- return -1;
+ return -ENETDOWN;
}
status = request_firmware(&fw, fw_file, &adapter->pdev->dev);
status = be_fw_download(adapter, fw);
if (!status)
- be_cmd_get_fw_ver(adapter, adapter->fw_ver,
- adapter->fw_on_flash);
+ be_cmd_get_fw_ver(adapter);
fw_exit:
release_firmware(fw);
cmd->va = dma_zalloc_coherent(&adapter->pdev->dev, cmd->size, &cmd->dma,
GFP_KERNEL);
if (cmd->va == NULL)
- return -1;
+ return -ENOMEM;
return 0;
}