summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/emulex
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/emulex')
-rw-r--r--drivers/net/ethernet/emulex/benet/be.h2
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.c55
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.h6
-rw-r--r--drivers/net/ethernet/emulex/benet/be_ethtool.c57
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c96
5 files changed, 113 insertions, 103 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index d266c86..cf4c05b 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -110,6 +110,7 @@ static inline char *nic_name(struct pci_dev *pdev)
#define MAX_RX_POST BE_NAPI_WEIGHT /* Frags posted at a time */
#define RX_FRAGS_REFILL_WM (RX_Q_LEN - MAX_RX_POST)
+#define MAX_VFS 30 /* Max VFs supported by BE3 FW */
#define FW_VER_LEN 32
struct be_dma_mem {
@@ -336,7 +337,6 @@ struct phy_info {
u16 auto_speeds_supported;
u16 fixed_speeds_supported;
int link_speed;
- int forced_port_speed;
u32 dac_cable_len;
u32 advertising;
u32 supported;
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index 8c63d06..af60bb2 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -120,7 +120,7 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
if (compl_status == MCC_STATUS_UNAUTHORIZED_REQUEST) {
dev_warn(&adapter->pdev->dev,
- "opcode %d-%d is not permitted\n",
+ "VF is not privileged to issue opcode %d-%d\n",
opcode, subsystem);
} else {
extd_status = (compl->status >> CQE_STATUS_EXTD_SHIFT) &
@@ -165,14 +165,13 @@ static void be_async_grp5_cos_priority_process(struct be_adapter *adapter,
}
}
-/* Grp5 QOS Speed evt */
+/* Grp5 QOS Speed evt: qos_link_speed is in units of 10 Mbps */
static void be_async_grp5_qos_speed_process(struct be_adapter *adapter,
struct be_async_event_grp5_qos_link_speed *evt)
{
- if (evt->physical_port == adapter->port_num) {
- /* qos_link_speed is in units of 10 Mbps */
- adapter->phy.link_speed = evt->qos_link_speed * 10;
- }
+ if (adapter->phy.link_speed >= 0 &&
+ evt->physical_port == adapter->port_num)
+ adapter->phy.link_speed = le16_to_cpu(evt->qos_link_speed) * 10;
}
/*Grp5 PVID evt*/
@@ -717,7 +716,7 @@ int be_cmd_eq_create(struct be_adapter *adapter,
/* Use MCC */
int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
- u8 type, bool permanent, u32 if_handle, u32 pmac_id)
+ bool permanent, u32 if_handle, u32 pmac_id)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_mac_query *req;
@@ -734,7 +733,7 @@ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_NTWK_MAC_QUERY, sizeof(*req), wrb, NULL);
- req->type = type;
+ req->type = MAC_ADDRESS_TYPE_NETWORK;
if (permanent) {
req->permanent = 1;
} else {
@@ -1326,9 +1325,28 @@ err:
return status;
}
-/* Uses synchronous mcc */
-int be_cmd_link_status_query(struct be_adapter *adapter, u8 *mac_speed,
- u16 *link_speed, u8 *link_status, u32 dom)
+static int be_mac_to_link_speed(int mac_speed)
+{
+ switch (mac_speed) {
+ case PHY_LINK_SPEED_ZERO:
+ return 0;
+ case PHY_LINK_SPEED_10MBPS:
+ return 10;
+ case PHY_LINK_SPEED_100MBPS:
+ return 100;
+ case PHY_LINK_SPEED_1GBPS:
+ return 1000;
+ case PHY_LINK_SPEED_10GBPS:
+ return 10000;
+ }
+ return 0;
+}
+
+/* Uses synchronous mcc
+ * Returns link_speed in Mbps
+ */
+int be_cmd_link_status_query(struct be_adapter *adapter, u16 *link_speed,
+ u8 *link_status, u32 dom)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_link_status *req;
@@ -1357,11 +1375,13 @@ int be_cmd_link_status_query(struct be_adapter *adapter, u8 *mac_speed,
status = be_mcc_notify_wait(adapter);
if (!status) {
struct be_cmd_resp_link_status *resp = embedded_payload(wrb);
- if (resp->mac_speed != PHY_LINK_SPEED_ZERO) {
- if (link_speed)
- *link_speed = le16_to_cpu(resp->link_speed);
- if (mac_speed)
- *mac_speed = resp->mac_speed;
+ if (link_speed) {
+ *link_speed = resp->link_speed ?
+ le16_to_cpu(resp->link_speed) * 10 :
+ be_mac_to_link_speed(resp->mac_speed);
+
+ if (!resp->logical_link_status)
+ *link_speed = 0;
}
if (link_status)
*link_status = resp->logical_link_status;
@@ -2405,6 +2425,9 @@ int be_cmd_req_native_mode(struct be_adapter *adapter)
struct be_cmd_resp_set_func_cap *resp = embedded_payload(wrb);
adapter->be3_native = le32_to_cpu(resp->cap_flags) &
CAPABILITY_BE3_NATIVE_ERX_API;
+ if (!adapter->be3_native)
+ dev_warn(&adapter->pdev->dev,
+ "adapter not in advanced mode\n");
}
err:
mutex_unlock(&adapter->mbox_lock);
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index 250f19b..0936e21 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -1687,7 +1687,7 @@ struct be_cmd_req_set_ext_fat_caps {
extern int be_pci_fnum_get(struct be_adapter *adapter);
extern int be_fw_wait_ready(struct be_adapter *adapter);
extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
- u8 type, bool permanent, u32 if_handle, u32 pmac_id);
+ bool permanent, u32 if_handle, u32 pmac_id);
extern int be_cmd_pmac_add(struct be_adapter *adapter, u8 *mac_addr,
u32 if_id, u32 *pmac_id, u32 domain);
extern int be_cmd_pmac_del(struct be_adapter *adapter, u32 if_id,
@@ -1714,8 +1714,8 @@ extern int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q,
int type);
extern int be_cmd_rxq_destroy(struct be_adapter *adapter,
struct be_queue_info *q);
-extern int be_cmd_link_status_query(struct be_adapter *adapter, u8 *mac_speed,
- u16 *link_speed, u8 *link_status, u32 dom);
+extern int be_cmd_link_status_query(struct be_adapter *adapter, u16 *link_speed,
+ u8 *link_status, u32 dom);
extern int be_cmd_reset(struct be_adapter *adapter);
extern int be_cmd_get_stats(struct be_adapter *adapter,
struct be_dma_mem *nonemb_cmd);
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
index c0e7006..8e6fb0b 100644
--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
+++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -512,28 +512,6 @@ static u32 convert_to_et_setting(u32 if_type, u32 if_speeds)
return val;
}
-static int convert_to_et_speed(u32 be_speed)
-{
- int et_speed = SPEED_10000;
-
- switch (be_speed) {
- case PHY_LINK_SPEED_10MBPS:
- et_speed = SPEED_10;
- break;
- case PHY_LINK_SPEED_100MBPS:
- et_speed = SPEED_100;
- break;
- case PHY_LINK_SPEED_1GBPS:
- et_speed = SPEED_1000;
- break;
- case PHY_LINK_SPEED_10GBPS:
- et_speed = SPEED_10000;
- break;
- }
-
- return et_speed;
-}
-
bool be_pause_supported(struct be_adapter *adapter)
{
return (adapter->phy.interface_type == PHY_TYPE_SFP_PLUS_10GB ||
@@ -544,27 +522,16 @@ bool be_pause_supported(struct be_adapter *adapter)
static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
{
struct be_adapter *adapter = netdev_priv(netdev);
- u8 port_speed = 0;
- u16 link_speed = 0;
u8 link_status;
- u32 et_speed = 0;
+ u16 link_speed = 0;
int status;
- if (adapter->phy.link_speed < 0 || !(netdev->flags & IFF_UP)) {
- if (adapter->phy.forced_port_speed < 0) {
- status = be_cmd_link_status_query(adapter, &port_speed,
- &link_speed, &link_status, 0);
- if (!status)
- be_link_status_update(adapter, link_status);
- if (link_speed)
- et_speed = link_speed * 10;
- else if (link_status)
- et_speed = convert_to_et_speed(port_speed);
- } else {
- et_speed = adapter->phy.forced_port_speed;
- }
-
- ethtool_cmd_speed_set(ecmd, et_speed);
+ if (adapter->phy.link_speed < 0) {
+ status = be_cmd_link_status_query(adapter, &link_speed,
+ &link_status, 0);
+ if (!status)
+ be_link_status_update(adapter, link_status);
+ ethtool_cmd_speed_set(ecmd, link_speed);
status = be_cmd_get_phy_info(adapter);
if (status)
@@ -773,8 +740,8 @@ static void
be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data)
{
struct be_adapter *adapter = netdev_priv(netdev);
- u8 mac_speed = 0;
- u16 qos_link_speed = 0;
+ int status;
+ u8 link_status = 0;
memset(data, 0, sizeof(u64) * ETHTOOL_TESTS_NUM);
@@ -798,11 +765,11 @@ be_self_test(struct net_device *netdev, struct ethtool_test *test, u64 *data)
test->flags |= ETH_TEST_FL_FAILED;
}
- if (be_cmd_link_status_query(adapter, &mac_speed,
- &qos_link_speed, NULL, 0) != 0) {
+ status = be_cmd_link_status_query(adapter, NULL, &link_status, 0);
+ if (status) {
test->flags |= ETH_TEST_FL_FAILED;
data[4] = -1;
- } else if (!mac_speed) {
+ } else if (!link_status) {
test->flags |= ETH_TEST_FL_FAILED;
data[4] = 1;
}
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 95d1047..eb3f2cb 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -20,6 +20,7 @@
#include "be.h"
#include "be_cmds.h"
#include <asm/div64.h>
+#include <linux/aer.h>
MODULE_VERSION(DRV_VER);
MODULE_DEVICE_TABLE(pci, be_dev_ids);
@@ -240,9 +241,8 @@ static int be_mac_addr_set(struct net_device *netdev, void *p)
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
- status = be_cmd_mac_addr_query(adapter, current_mac,
- MAC_ADDRESS_TYPE_NETWORK, false,
- adapter->if_handle, 0);
+ status = be_cmd_mac_addr_query(adapter, current_mac, false,
+ adapter->if_handle, 0);
if (status)
goto err;
@@ -1075,7 +1075,7 @@ static int be_set_vf_tx_rate(struct net_device *netdev,
static int be_find_vfs(struct be_adapter *adapter, int vf_state)
{
struct pci_dev *dev, *pdev = adapter->pdev;
- int vfs = 0, assigned_vfs = 0, pos, vf_fn;
+ int vfs = 0, assigned_vfs = 0, pos;
u16 offset, stride;
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
@@ -1086,9 +1086,7 @@ static int be_find_vfs(struct be_adapter *adapter, int vf_state)
dev = pci_get_device(pdev->vendor, PCI_ANY_ID, NULL);
while (dev) {
- vf_fn = (pdev->devfn + offset + stride * vfs) & 0xFFFF;
- if (dev->is_virtfn && dev->devfn == vf_fn &&
- dev->bus->number == pdev->bus->number) {
+ if (dev->is_virtfn && pci_physfn(dev) == pdev) {
vfs++;
if (dev->dev_flags & PCI_DEV_FLAGS_ASSIGNED)
assigned_vfs++;
@@ -1896,6 +1894,8 @@ static int be_tx_qs_create(struct be_adapter *adapter)
return status;
}
+ dev_info(&adapter->pdev->dev, "created %d TX queue(s)\n",
+ adapter->num_tx_qs);
return 0;
}
@@ -1946,10 +1946,9 @@ static int be_rx_cqs_create(struct be_adapter *adapter)
return rc;
}
- if (adapter->num_rx_qs != MAX_RX_QS)
- dev_info(&adapter->pdev->dev,
- "Created only %d receive queues\n", adapter->num_rx_qs);
-
+ dev_info(&adapter->pdev->dev,
+ "created %d RSS queue(s) and 1 default RX queue\n",
+ adapter->num_rx_qs - 1);
return 0;
}
@@ -2176,8 +2175,7 @@ static uint be_num_rss_want(struct be_adapter *adapter)
{
u32 num = 0;
if ((adapter->function_caps & BE_FUNCTION_CAPS_RSS) &&
- !sriov_want(adapter) && be_physfn(adapter) &&
- !be_is_mc(adapter)) {
+ !sriov_want(adapter) && be_physfn(adapter)) {
num = (adapter->be3_native) ? BE3_MAX_RSS_QS : BE2_MAX_RSS_QS;
num = min_t(u32, num, (u32)netif_get_num_default_rss_queues());
}
@@ -2188,6 +2186,7 @@ static void be_msix_enable(struct be_adapter *adapter)
{
#define BE_MIN_MSIX_VECTORS 1
int i, status, num_vec, num_roce_vec = 0;
+ 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());
@@ -2212,6 +2211,8 @@ static void be_msix_enable(struct be_adapter *adapter)
num_vec) == 0)
goto done;
}
+
+ dev_warn(dev, "MSIx enable failed\n");
return;
done:
if (be_roce_supported(adapter)) {
@@ -2225,6 +2226,7 @@ done:
}
} else
adapter->num_msix_vec = num_vec;
+ dev_info(dev, "enabled %d MSI-x vector(s)\n", adapter->num_msix_vec);
return;
}
@@ -2441,8 +2443,7 @@ static int be_open(struct net_device *netdev)
be_eq_notify(adapter, eqo->q.id, true, false, 0);
}
- status = be_cmd_link_status_query(adapter, NULL, NULL,
- &link_status, 0);
+ status = be_cmd_link_status_query(adapter, NULL, &link_status, 0);
if (!status)
be_link_status_update(adapter, link_status);
@@ -2646,8 +2647,8 @@ static int be_vf_setup(struct be_adapter *adapter)
}
for_all_vfs(adapter, vf_cfg, vf) {
- status = be_cmd_link_status_query(adapter, NULL, &lnk_speed,
- NULL, vf + 1);
+ lnk_speed = 1000;
+ status = be_cmd_set_qos(adapter, lnk_speed, vf + 1);
if (status)
goto err;
vf_cfg->tx_rate = lnk_speed * 10;
@@ -2671,7 +2672,6 @@ static void be_setup_init(struct be_adapter *adapter)
adapter->be3_native = false;
adapter->promiscuous = false;
adapter->eq_next_idx = 0;
- adapter->phy.forced_port_speed = -1;
}
static int be_get_mac_addr(struct be_adapter *adapter, u8 *mac, u32 if_handle,
@@ -2693,21 +2693,16 @@ static int be_get_mac_addr(struct be_adapter *adapter, u8 *mac, u32 if_handle,
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,
- MAC_ADDRESS_TYPE_NETWORK,
- false, if_handle,
- *pmac_id);
+ 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,
- MAC_ADDRESS_TYPE_NETWORK, true,
- 0, 0);
+ 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,
- MAC_ADDRESS_TYPE_NETWORK, false,
+ status = be_cmd_mac_addr_query(adapter, mac, false,
if_handle, 0);
*active_mac = true;
}
@@ -2724,6 +2719,8 @@ static int be_get_config(struct be_adapter *adapter)
if (pos) {
pci_read_config_word(adapter->pdev, pos + PCI_SRIOV_TOTAL_VF,
&dev_num_vfs);
+ if (!lancer_chip(adapter))
+ dev_num_vfs = min_t(u16, dev_num_vfs, MAX_VFS);
adapter->dev_num_vfs = dev_num_vfs;
}
return 0;
@@ -3437,6 +3434,7 @@ static void be_ctrl_cleanup(struct be_adapter *adapter)
if (mem->va)
dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va,
mem->dma);
+ kfree(adapter->pmac_id);
}
static int be_ctrl_init(struct be_adapter *adapter)
@@ -3473,6 +3471,12 @@ static int be_ctrl_init(struct be_adapter *adapter)
}
memset(rx_filter->va, 0, rx_filter->size);
+ /* primary mac needs 1 pmac entry */
+ adapter->pmac_id = kcalloc(adapter->max_pmac_cnt + 1,
+ sizeof(*adapter->pmac_id), GFP_KERNEL);
+ if (!adapter->pmac_id)
+ return -ENOMEM;
+
mutex_init(&adapter->mbox_lock);
spin_lock_init(&adapter->mcc_lock);
spin_lock_init(&adapter->mcc_cq_lock);
@@ -3543,6 +3547,8 @@ static void __devexit be_remove(struct pci_dev *pdev)
be_ctrl_cleanup(adapter);
+ pci_disable_pcie_error_reporting(pdev);
+
pci_set_drvdata(pdev, NULL);
pci_release_regions(pdev);
pci_disable_device(pdev);
@@ -3609,12 +3615,6 @@ static int be_get_initial_config(struct be_adapter *adapter)
else
adapter->max_pmac_cnt = BE_VF_UC_PMAC_COUNT;
- /* primary mac needs 1 pmac entry */
- adapter->pmac_id = kcalloc(adapter->max_pmac_cnt + 1,
- sizeof(u32), GFP_KERNEL);
- if (!adapter->pmac_id)
- return -ENOMEM;
-
status = be_cmd_get_cntl_attributes(adapter);
if (status)
return status;
@@ -3800,6 +3800,23 @@ static bool be_reset_required(struct be_adapter *adapter)
return be_find_vfs(adapter, ENABLED) > 0 ? false : true;
}
+static char *mc_name(struct be_adapter *adapter)
+{
+ if (adapter->function_mode & FLEX10_MODE)
+ return "FLEX10";
+ else if (adapter->function_mode & VNIC_MODE)
+ return "vNIC";
+ else if (adapter->function_mode & UMC_ENABLED)
+ return "UMC";
+ else
+ return "";
+}
+
+static inline char *func_name(struct be_adapter *adapter)
+{
+ return be_physfn(adapter) ? "PF" : "VF";
+}
+
static int __devinit be_probe(struct pci_dev *pdev,
const struct pci_device_id *pdev_id)
{
@@ -3844,6 +3861,10 @@ static int __devinit be_probe(struct pci_dev *pdev,
}
}
+ status = pci_enable_pcie_error_reporting(pdev);
+ if (status)
+ dev_err(&pdev->dev, "Could not use PCIe error reporting\n");
+
status = be_ctrl_init(adapter);
if (status)
goto free_netdev;
@@ -3886,7 +3907,7 @@ static int __devinit be_probe(struct pci_dev *pdev,
status = be_setup(adapter);
if (status)
- goto msix_disable;
+ goto stats_clean;
be_netdev_init(netdev);
status = register_netdev(netdev);
@@ -3900,15 +3921,13 @@ static int __devinit be_probe(struct pci_dev *pdev,
be_cmd_query_port_name(adapter, &port_name);
- dev_info(&pdev->dev, "%s: %s port %c\n", netdev->name, nic_name(pdev),
- port_name);
+ dev_info(&pdev->dev, "%s: %s %s port %c\n", nic_name(pdev),
+ func_name(adapter), mc_name(adapter), port_name);
return 0;
unsetup:
be_clear(adapter);
-msix_disable:
- be_msix_disable(adapter);
stats_clean:
be_stats_cleanup(adapter);
ctrl_clean:
@@ -4066,6 +4085,7 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev)
if (status)
return PCI_ERS_RESULT_DISCONNECT;
+ pci_cleanup_aer_uncorrect_error_status(pdev);
return PCI_ERS_RESULT_RECOVERED;
}
OpenPOWER on IntegriCloud