aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/emulex/benet
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/emulex/benet')
-rw-r--r--drivers/net/ethernet/emulex/benet/be.h7
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.c178
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.h33
-rw-r--r--drivers/net/ethernet/emulex/benet/be_ethtool.c73
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c164
5 files changed, 238 insertions, 217 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index 4ccaf9af6fc9..8d09615da585 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -34,7 +34,7 @@
#include "be_hw.h"
#include "be_roce.h"
-#define DRV_VER "4.9.224.0u"
+#define DRV_VER "10.0.600.0u"
#define DRV_NAME "be2net"
#define BE_NAME "Emulex BladeEngine2"
#define BE3_NAME "Emulex BladeEngine3"
@@ -42,7 +42,7 @@
#define OC_NAME_BE OC_NAME "(be3)"
#define OC_NAME_LANCER OC_NAME "(Lancer)"
#define OC_NAME_SH OC_NAME "(Skyhawk)"
-#define DRV_DESC "Emulex OneConnect 10Gbps NIC Driver"
+#define DRV_DESC "Emulex OneConnect NIC Driver"
#define BE_VENDOR_ID 0x19a2
#define EMULEX_VENDOR_ID 0x10df
@@ -283,7 +283,6 @@ struct be_rx_compl_info {
u32 rss_hash;
u16 vlan_tag;
u16 pkt_size;
- u16 rxq_idx;
u16 port;
u8 vlanf;
u8 num_rcvd;
@@ -493,7 +492,7 @@ struct be_adapter {
u16 pvid;
struct phy_info phy;
u8 wol_cap;
- bool wol;
+ bool wol_en;
u32 uc_macs; /* Count of secondary UC MAC programmed */
u16 asic_rev;
u16 qnq_vid;
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index 94c35c8d799d..48076a6370c3 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -1101,23 +1101,22 @@ static int be_cmd_mccq_ext_create(struct be_adapter *adapter,
OPCODE_COMMON_MCC_CREATE_EXT, sizeof(*req), wrb, NULL);
req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
- if (lancer_chip(adapter)) {
- req->hdr.version = 1;
- req->cq_id = cpu_to_le16(cq->id);
-
- AMAP_SET_BITS(struct amap_mcc_context_lancer, ring_size, ctxt,
- be_encoded_q_len(mccq->len));
- AMAP_SET_BITS(struct amap_mcc_context_lancer, valid, ctxt, 1);
- AMAP_SET_BITS(struct amap_mcc_context_lancer, async_cq_id,
- ctxt, cq->id);
- AMAP_SET_BITS(struct amap_mcc_context_lancer, async_cq_valid,
- ctxt, 1);
-
- } else {
+ if (BEx_chip(adapter)) {
AMAP_SET_BITS(struct amap_mcc_context_be, valid, ctxt, 1);
AMAP_SET_BITS(struct amap_mcc_context_be, ring_size, ctxt,
be_encoded_q_len(mccq->len));
AMAP_SET_BITS(struct amap_mcc_context_be, cq_id, ctxt, cq->id);
+ } else {
+ req->hdr.version = 1;
+ req->cq_id = cpu_to_le16(cq->id);
+
+ AMAP_SET_BITS(struct amap_mcc_context_v1, ring_size, ctxt,
+ be_encoded_q_len(mccq->len));
+ AMAP_SET_BITS(struct amap_mcc_context_v1, valid, ctxt, 1);
+ AMAP_SET_BITS(struct amap_mcc_context_v1, async_cq_id,
+ ctxt, cq->id);
+ AMAP_SET_BITS(struct amap_mcc_context_v1, async_cq_valid,
+ ctxt, 1);
}
/* Subscribe to Link State and Group 5 Events(bits 1 and 5 set) */
@@ -1187,7 +1186,7 @@ int be_cmd_mccq_create(struct be_adapter *adapter,
int status;
status = be_cmd_mccq_ext_create(adapter, mccq, cq);
- if (status && !lancer_chip(adapter)) {
+ if (status && BEx_chip(adapter)) {
dev_warn(&adapter->pdev->dev, "Upgrade to F/W ver 2.102.235.0 "
"or newer to avoid conflicting priorities between NIC "
"and FCoE traffic");
@@ -2692,6 +2691,13 @@ int be_cmd_get_fn_privileges(struct be_adapter *adapter, u32 *privilege,
struct be_cmd_resp_get_fn_privileges *resp =
embedded_payload(wrb);
*privilege = le32_to_cpu(resp->privilege_mask);
+
+ /* In UMC mode FW does not return right privileges.
+ * Override with correct privilege equivalent to PF.
+ */
+ if (BEx_chip(adapter) && be_is_mc(adapter) &&
+ be_physfn(adapter))
+ *privilege = MAX_PRIVILEGES;
}
err:
@@ -2736,7 +2742,8 @@ err:
* If pmac_id is returned, pmac_id_valid is returned as true
*/
int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac,
- bool *pmac_id_valid, u32 *pmac_id, u8 domain)
+ bool *pmac_id_valid, u32 *pmac_id, u32 if_handle,
+ u8 domain)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_get_mac_list *req;
@@ -2774,7 +2781,7 @@ int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac,
req->mac_type = MAC_ADDRESS_TYPE_NETWORK;
if (*pmac_id_valid) {
req->mac_id = cpu_to_le32(*pmac_id);
- req->iface_id = cpu_to_le16(adapter->if_handle);
+ req->iface_id = cpu_to_le16(if_handle);
req->perm_override = 0;
} else {
req->perm_override = 1;
@@ -2827,17 +2834,21 @@ out:
return status;
}
-int be_cmd_get_active_mac(struct be_adapter *adapter, u32 curr_pmac_id, u8 *mac)
+int be_cmd_get_active_mac(struct be_adapter *adapter, u32 curr_pmac_id, u8 *mac,
+ u32 if_handle, bool active, u32 domain)
{
- bool active = true;
+ if (!active)
+ be_cmd_get_mac_from_list(adapter, mac, &active, &curr_pmac_id,
+ if_handle, domain);
if (BEx_chip(adapter))
return be_cmd_mac_addr_query(adapter, mac, false,
- adapter->if_handle, curr_pmac_id);
+ if_handle, curr_pmac_id);
else
/* Fetch the MAC address using pmac_id */
return be_cmd_get_mac_from_list(adapter, mac, &active,
- &curr_pmac_id, 0);
+ &curr_pmac_id,
+ if_handle, domain);
}
int be_cmd_get_perm_mac(struct be_adapter *adapter, u8 *mac)
@@ -2856,7 +2867,7 @@ int be_cmd_get_perm_mac(struct be_adapter *adapter, u8 *mac)
adapter->if_handle, 0);
} else {
status = be_cmd_get_mac_from_list(adapter, mac, &pmac_valid,
- NULL, 0);
+ NULL, adapter->if_handle, 0);
}
return status;
@@ -2917,7 +2928,8 @@ int be_cmd_set_mac(struct be_adapter *adapter, u8 *mac, int if_id, u32 dom)
int status;
status = be_cmd_get_mac_from_list(adapter, old_mac, &active_mac,
- &pmac_id, dom);
+ &pmac_id, if_id, dom);
+
if (!status && active_mac)
be_cmd_pmac_del(adapter, if_id, pmac_id, dom);
@@ -2997,7 +3009,7 @@ int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid,
ctxt, intf_id);
AMAP_SET_BITS(struct amap_get_hsw_req_context, pvid_valid, ctxt, 1);
- if (!BEx_chip(adapter)) {
+ if (!BEx_chip(adapter) && mode) {
AMAP_SET_BITS(struct amap_get_hsw_req_context, interface_id,
ctxt, adapter->hba_port_num);
AMAP_SET_BITS(struct amap_get_hsw_req_context, pport, ctxt, 1);
@@ -3028,14 +3040,16 @@ int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_acpi_wol_magic_config_v1 *req;
- int status;
- int payload_len = sizeof(*req);
+ int status = 0;
struct be_dma_mem cmd;
if (!be_cmd_allowed(adapter, OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG,
CMD_SUBSYSTEM_ETH))
return -EPERM;
+ if (be_is_wol_excluded(adapter))
+ return status;
+
if (mutex_lock_interruptible(&adapter->mbox_lock))
return -1;
@@ -3060,7 +3074,7 @@ int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter)
be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ETH,
OPCODE_ETH_ACPI_WOL_MAGIC_CONFIG,
- payload_len, wrb, &cmd);
+ sizeof(*req), wrb, &cmd);
req->hdr.version = 1;
req->query_options = BE_GET_WOL_CAP;
@@ -3070,13 +3084,9 @@ int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter)
struct be_cmd_resp_acpi_wol_magic_config_v1 *resp;
resp = (struct be_cmd_resp_acpi_wol_magic_config_v1 *) cmd.va;
- /* the command could succeed misleadingly on old f/w
- * which is not aware of the V1 version. fake an error. */
- if (resp->hdr.response_length < payload_len) {
- status = -1;
- goto err;
- }
adapter->wol_cap = resp->wol_settings;
+ if (adapter->wol_cap & BE_WOL_CAP)
+ adapter->wol_en = true;
}
err:
mutex_unlock(&adapter->mbox_lock);
@@ -3085,6 +3095,76 @@ err:
return status;
}
+
+int be_cmd_set_fw_log_level(struct be_adapter *adapter, u32 level)
+{
+ struct be_dma_mem extfat_cmd;
+ struct be_fat_conf_params *cfgs;
+ int status;
+ int i, j;
+
+ memset(&extfat_cmd, 0, sizeof(struct be_dma_mem));
+ extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps);
+ extfat_cmd.va = pci_alloc_consistent(adapter->pdev, extfat_cmd.size,
+ &extfat_cmd.dma);
+ if (!extfat_cmd.va)
+ return -ENOMEM;
+
+ status = be_cmd_get_ext_fat_capabilites(adapter, &extfat_cmd);
+ if (status)
+ goto err;
+
+ cfgs = (struct be_fat_conf_params *)
+ (extfat_cmd.va + sizeof(struct be_cmd_resp_hdr));
+ for (i = 0; i < le32_to_cpu(cfgs->num_modules); i++) {
+ u32 num_modes = le32_to_cpu(cfgs->module[i].num_modes);
+ for (j = 0; j < num_modes; j++) {
+ if (cfgs->module[i].trace_lvl[j].mode == MODE_UART)
+ cfgs->module[i].trace_lvl[j].dbg_lvl =
+ cpu_to_le32(level);
+ }
+ }
+
+ status = be_cmd_set_ext_fat_capabilites(adapter, &extfat_cmd, cfgs);
+err:
+ pci_free_consistent(adapter->pdev, extfat_cmd.size, extfat_cmd.va,
+ extfat_cmd.dma);
+ return status;
+}
+
+int be_cmd_get_fw_log_level(struct be_adapter *adapter)
+{
+ struct be_dma_mem extfat_cmd;
+ struct be_fat_conf_params *cfgs;
+ int status, j;
+ int level = 0;
+
+ memset(&extfat_cmd, 0, sizeof(struct be_dma_mem));
+ extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps);
+ extfat_cmd.va = pci_alloc_consistent(adapter->pdev, extfat_cmd.size,
+ &extfat_cmd.dma);
+
+ if (!extfat_cmd.va) {
+ dev_err(&adapter->pdev->dev, "%s: Memory allocation failure\n",
+ __func__);
+ goto err;
+ }
+
+ status = be_cmd_get_ext_fat_capabilites(adapter, &extfat_cmd);
+ if (!status) {
+ cfgs = (struct be_fat_conf_params *)(extfat_cmd.va +
+ sizeof(struct be_cmd_resp_hdr));
+ for (j = 0; j < le32_to_cpu(cfgs->module[0].num_modes); j++) {
+ if (cfgs->module[0].trace_lvl[j].mode == MODE_UART)
+ level = cfgs->module[0].trace_lvl[j].dbg_lvl;
+ }
+ }
+ pci_free_consistent(adapter->pdev, extfat_cmd.size, extfat_cmd.va,
+ extfat_cmd.dma);
+err:
+ return level;
+}
+
int be_cmd_get_ext_fat_capabilites(struct be_adapter *adapter,
struct be_dma_mem *cmd)
{
@@ -3609,6 +3689,40 @@ int be_cmd_intr_set(struct be_adapter *adapter, bool intr_enable)
return status;
}
+/* Uses MBOX */
+int be_cmd_get_active_profile(struct be_adapter *adapter, u16 *profile_id)
+{
+ struct be_cmd_req_get_active_profile *req;
+ struct be_mcc_wrb *wrb;
+ int status;
+
+ if (mutex_lock_interruptible(&adapter->mbox_lock))
+ return -1;
+
+ wrb = wrb_from_mbox(adapter);
+ if (!wrb) {
+ status = -EBUSY;
+ goto err;
+ }
+
+ req = embedded_payload(wrb);
+
+ be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+ OPCODE_COMMON_GET_ACTIVE_PROFILE, sizeof(*req),
+ wrb, NULL);
+
+ status = be_mbox_notify_wait(adapter);
+ if (!status) {
+ struct be_cmd_resp_get_active_profile *resp =
+ embedded_payload(wrb);
+ *profile_id = le16_to_cpu(resp->active_profile_id);
+ }
+
+err:
+ mutex_unlock(&adapter->mbox_lock);
+ return status;
+}
+
int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload,
int wrb_payload_size, u16 *cmd_status, u16 *ext_status)
{
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index 0075686276aa..fc4e076dc202 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -216,6 +216,7 @@ struct be_mcc_mailbox {
#define OPCODE_COMMON_GET_FUNC_CONFIG 160
#define OPCODE_COMMON_GET_PROFILE_CONFIG 164
#define OPCODE_COMMON_SET_PROFILE_CONFIG 165
+#define OPCODE_COMMON_GET_ACTIVE_PROFILE 167
#define OPCODE_COMMON_SET_HSW_CONFIG 153
#define OPCODE_COMMON_GET_FN_PRIVILEGES 170
#define OPCODE_COMMON_READ_OBJECT 171
@@ -452,7 +453,7 @@ struct amap_mcc_context_be {
u8 rsvd2[32];
} __packed;
-struct amap_mcc_context_lancer {
+struct amap_mcc_context_v1 {
u8 async_cq_id[16];
u8 ring_size[4];
u8 rsvd0[12];
@@ -476,7 +477,7 @@ struct be_cmd_req_mcc_ext_create {
u16 num_pages;
u16 cq_id;
u32 async_event_bitmap[1];
- u8 context[sizeof(struct amap_mcc_context_be) / 8];
+ u8 context[sizeof(struct amap_mcc_context_v1) / 8];
struct phys_addr pages[8];
} __packed;
@@ -1097,6 +1098,14 @@ struct be_cmd_resp_query_fw_cfg {
u32 function_caps;
};
+/* Is BE in a multi-channel mode */
+static inline bool be_is_mc(struct be_adapter *adapter)
+{
+ return adapter->function_mode & FLEX10_MODE ||
+ adapter->function_mode & VNIC_MODE ||
+ adapter->function_mode & UMC_ENABLED;
+}
+
/******************** RSS Config ****************************************/
/* RSS type Input parameters used to compute RX hash
* RSS_ENABLE_IPV4 SRC IPv4, DST IPv4
@@ -1917,6 +1926,17 @@ struct be_cmd_resp_set_profile_config {
struct be_cmd_resp_hdr hdr;
};
+struct be_cmd_req_get_active_profile {
+ struct be_cmd_req_hdr hdr;
+ u32 rsvd;
+} __packed;
+
+struct be_cmd_resp_get_active_profile {
+ struct be_cmd_resp_hdr hdr;
+ u16 active_profile_id;
+ u16 next_profile_id;
+} __packed;
+
struct be_cmd_enable_disable_vf {
struct be_cmd_req_hdr hdr;
u8 enable;
@@ -2037,8 +2057,10 @@ int be_cmd_get_fn_privileges(struct be_adapter *adapter, u32 *privilege,
int be_cmd_set_fn_privileges(struct be_adapter *adapter, u32 privileges,
u32 vf_num);
int be_cmd_get_mac_from_list(struct be_adapter *adapter, u8 *mac,
- bool *pmac_id_active, u32 *pmac_id, u8 domain);
-int be_cmd_get_active_mac(struct be_adapter *adapter, u32 pmac_id, u8 *mac);
+ bool *pmac_id_active, u32 *pmac_id,
+ u32 if_handle, u8 domain);
+int be_cmd_get_active_mac(struct be_adapter *adapter, u32 pmac_id, u8 *mac,
+ u32 if_handle, bool active, u32 domain);
int be_cmd_get_perm_mac(struct be_adapter *adapter, u8 *mac);
int be_cmd_set_mac_list(struct be_adapter *adapter, u8 *mac_array, u8 mac_count,
u32 domain);
@@ -2048,6 +2070,8 @@ int be_cmd_set_hsw_config(struct be_adapter *adapter, u16 pvid, u32 domain,
int be_cmd_get_hsw_config(struct be_adapter *adapter, u16 *pvid, u32 domain,
u16 intf_id, u8 *mode);
int be_cmd_get_acpi_wol_cap(struct be_adapter *adapter);
+int be_cmd_set_fw_log_level(struct be_adapter *adapter, u32 level);
+int be_cmd_get_fw_log_level(struct be_adapter *adapter);
int be_cmd_get_ext_fat_capabilites(struct be_adapter *adapter,
struct be_dma_mem *cmd);
int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter,
@@ -2063,6 +2087,7 @@ int be_cmd_get_func_config(struct be_adapter *adapter,
int be_cmd_get_profile_config(struct be_adapter *adapter,
struct be_resources *res, u8 domain);
int be_cmd_set_profile_config(struct be_adapter *adapter, u32 bps, u8 domain);
+int be_cmd_get_active_profile(struct be_adapter *adapter, u16 *profile);
int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg,
int vf_num);
int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain);
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
index 08330034d9ef..05be0070f55f 100644
--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
+++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -713,12 +713,13 @@ be_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
{
struct be_adapter *adapter = netdev_priv(netdev);
- if (be_is_wol_supported(adapter)) {
+ if (adapter->wol_cap & BE_WOL_CAP) {
wol->supported |= WAKE_MAGIC;
- if (adapter->wol)
+ if (adapter->wol_en)
wol->wolopts |= WAKE_MAGIC;
- } else
+ } else {
wol->wolopts = 0;
+ }
memset(&wol->sopass, 0, sizeof(wol->sopass));
}
@@ -730,15 +731,15 @@ be_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
if (wol->wolopts & ~WAKE_MAGIC)
return -EOPNOTSUPP;
- if (!be_is_wol_supported(adapter)) {
+ if (!(adapter->wol_cap & BE_WOL_CAP)) {
dev_warn(&adapter->pdev->dev, "WOL not supported\n");
return -EOPNOTSUPP;
}
if (wol->wolopts & WAKE_MAGIC)
- adapter->wol = true;
+ adapter->wol_en = true;
else
- adapter->wol = false;
+ adapter->wol_en = false;
return 0;
}
@@ -904,73 +905,21 @@ static u32 be_get_msg_level(struct net_device *netdev)
{
struct be_adapter *adapter = netdev_priv(netdev);
- if (lancer_chip(adapter)) {
- dev_err(&adapter->pdev->dev, "Operation not supported\n");
- return -EOPNOTSUPP;
- }
-
return adapter->msg_enable;
}
-static void be_set_fw_log_level(struct be_adapter *adapter, u32 level)
-{
- struct be_dma_mem extfat_cmd;
- struct be_fat_conf_params *cfgs;
- int status;
- int i, j;
-
- memset(&extfat_cmd, 0, sizeof(struct be_dma_mem));
- extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps);
- extfat_cmd.va = pci_alloc_consistent(adapter->pdev, extfat_cmd.size,
- &extfat_cmd.dma);
- if (!extfat_cmd.va) {
- dev_err(&adapter->pdev->dev, "%s: Memory allocation failure\n",
- __func__);
- goto err;
- }
- status = be_cmd_get_ext_fat_capabilites(adapter, &extfat_cmd);
- if (!status) {
- cfgs = (struct be_fat_conf_params *)(extfat_cmd.va +
- sizeof(struct be_cmd_resp_hdr));
- for (i = 0; i < le32_to_cpu(cfgs->num_modules); i++) {
- u32 num_modes = le32_to_cpu(cfgs->module[i].num_modes);
- for (j = 0; j < num_modes; j++) {
- if (cfgs->module[i].trace_lvl[j].mode ==
- MODE_UART)
- cfgs->module[i].trace_lvl[j].dbg_lvl =
- cpu_to_le32(level);
- }
- }
- status = be_cmd_set_ext_fat_capabilites(adapter, &extfat_cmd,
- cfgs);
- if (status)
- dev_err(&adapter->pdev->dev,
- "Message level set failed\n");
- } else {
- dev_err(&adapter->pdev->dev, "Message level get failed\n");
- }
-
- pci_free_consistent(adapter->pdev, extfat_cmd.size, extfat_cmd.va,
- extfat_cmd.dma);
-err:
- return;
-}
-
static void be_set_msg_level(struct net_device *netdev, u32 level)
{
struct be_adapter *adapter = netdev_priv(netdev);
- if (lancer_chip(adapter)) {
- dev_err(&adapter->pdev->dev, "Operation not supported\n");
- return;
- }
-
if (adapter->msg_enable == level)
return;
if ((level & NETIF_MSG_HW) != (adapter->msg_enable & NETIF_MSG_HW))
- be_set_fw_log_level(adapter, level & NETIF_MSG_HW ?
- FW_LOG_LEVEL_DEFAULT : FW_LOG_LEVEL_FATAL);
+ if (BEx_chip(adapter))
+ be_cmd_set_fw_log_level(adapter, level & NETIF_MSG_HW ?
+ FW_LOG_LEVEL_DEFAULT :
+ FW_LOG_LEVEL_FATAL);
adapter->msg_enable = level;
return;
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index a37039d353c5..04ac9c6a0d39 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -121,12 +121,6 @@ static const char * const ue_status_hi_desc[] = {
"Unknown"
};
-/* Is BE in a multi-channel mode */
-static inline bool be_is_mc(struct be_adapter *adapter) {
- return (adapter->function_mode & FLEX10_MODE ||
- adapter->function_mode & VNIC_MODE ||
- adapter->function_mode & UMC_ENABLED);
-}
static void be_queue_free(struct be_adapter *adapter, struct be_queue_info *q)
{
@@ -258,6 +252,12 @@ static int be_mac_addr_set(struct net_device *netdev, void *p)
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
+ /* Proceed further only if, User provided MAC is different
+ * from active MAC
+ */
+ if (ether_addr_equal(addr->sa_data, netdev->dev_addr))
+ return 0;
+
/* 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
@@ -280,14 +280,15 @@ static int be_mac_addr_set(struct net_device *netdev, void *p)
/* Decide if the new MAC is successfully activated only after
* querying the FW
*/
- status = be_cmd_get_active_mac(adapter, curr_pmac_id, mac);
+ status = be_cmd_get_active_mac(adapter, curr_pmac_id, mac,
+ adapter->if_handle, true, 0);
if (status)
goto err;
/* 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)) {
+ if (!ether_addr_equal(addr->sa_data, mac)) {
status = -EPERM;
goto err;
}
@@ -1096,8 +1097,6 @@ static int be_vid_config(struct be_adapter *adapter)
dev_info(&adapter->pdev->dev,
"Disabling VLAN Promiscuous mode.\n");
adapter->flags &= ~BE_FLAGS_VLAN_PROMISC;
- dev_info(&adapter->pdev->dev,
- "Re-Enabling HW VLAN filtering\n");
}
}
}
@@ -1105,12 +1104,12 @@ static int be_vid_config(struct be_adapter *adapter)
return status;
set_vlan_promisc:
- dev_warn(&adapter->pdev->dev, "Exhausted VLAN HW filters.\n");
+ if (adapter->flags & BE_FLAGS_VLAN_PROMISC)
+ return 0;
status = be_cmd_rx_filter(adapter, BE_FLAGS_VLAN_PROMISC, ON);
if (!status) {
dev_info(&adapter->pdev->dev, "Enable VLAN Promiscuous mode\n");
- dev_info(&adapter->pdev->dev, "Disabling HW VLAN filtering\n");
adapter->flags |= BE_FLAGS_VLAN_PROMISC;
} else
dev_err(&adapter->pdev->dev,
@@ -1123,19 +1122,18 @@ static int be_vlan_add_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;
adapter->vlan_tag[vid] = 1;
- if (adapter->vlans_added <= (be_max_vlans(adapter) + 1))
- status = be_vid_config(adapter);
+ adapter->vlans_added++;
- if (!status)
- adapter->vlans_added++;
- else
+ status = be_vid_config(adapter);
+ if (status) {
+ adapter->vlans_added--;
adapter->vlan_tag[vid] = 0;
+ }
ret:
return status;
}
@@ -1150,9 +1148,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 <= be_max_vlans(adapter))
- status = be_vid_config(adapter);
-
+ status = be_vid_config(adapter);
if (!status)
adapter->vlans_added--;
else
@@ -1442,12 +1438,12 @@ static inline bool csum_passed(struct be_rx_compl_info *rxcp)
(rxcp->ip_csum || rxcp->ipv6);
}
-static struct be_rx_page_info *get_rx_page_info(struct be_rx_obj *rxo,
- u16 frag_idx)
+static struct be_rx_page_info *get_rx_page_info(struct be_rx_obj *rxo)
{
struct be_adapter *adapter = rxo->adapter;
struct be_rx_page_info *rx_page_info;
struct be_queue_info *rxq = &rxo->q;
+ u16 frag_idx = rxq->tail;
rx_page_info = &rxo->page_info_tbl[frag_idx];
BUG_ON(!rx_page_info->page);
@@ -1459,6 +1455,7 @@ static struct be_rx_page_info *get_rx_page_info(struct be_rx_obj *rxo,
rx_page_info->last_page_user = false;
}
+ queue_tail_inc(rxq);
atomic_dec(&rxq->used);
return rx_page_info;
}
@@ -1467,15 +1464,13 @@ static struct be_rx_page_info *get_rx_page_info(struct be_rx_obj *rxo,
static void be_rx_compl_discard(struct be_rx_obj *rxo,
struct be_rx_compl_info *rxcp)
{
- struct be_queue_info *rxq = &rxo->q;
struct be_rx_page_info *page_info;
u16 i, num_rcvd = rxcp->num_rcvd;
for (i = 0; i < num_rcvd; i++) {
- page_info = get_rx_page_info(rxo, rxcp->rxq_idx);
+ page_info = get_rx_page_info(rxo);
put_page(page_info->page);
memset(page_info, 0, sizeof(*page_info));
- index_inc(&rxcp->rxq_idx, rxq->len);
}
}
@@ -1486,13 +1481,12 @@ static void be_rx_compl_discard(struct be_rx_obj *rxo,
static void skb_fill_rx_data(struct be_rx_obj *rxo, struct sk_buff *skb,
struct be_rx_compl_info *rxcp)
{
- struct be_queue_info *rxq = &rxo->q;
struct be_rx_page_info *page_info;
u16 i, j;
u16 hdr_len, curr_frag_len, remaining;
u8 *start;
- page_info = get_rx_page_info(rxo, rxcp->rxq_idx);
+ page_info = get_rx_page_info(rxo);
start = page_address(page_info->page) + page_info->page_offset;
prefetch(start);
@@ -1526,10 +1520,9 @@ static void skb_fill_rx_data(struct be_rx_obj *rxo, struct sk_buff *skb,
}
/* More frags present for this completion */
- index_inc(&rxcp->rxq_idx, rxq->len);
remaining = rxcp->pkt_size - curr_frag_len;
for (i = 1, j = 0; i < rxcp->num_rcvd; i++) {
- page_info = get_rx_page_info(rxo, rxcp->rxq_idx);
+ page_info = get_rx_page_info(rxo);
curr_frag_len = min(remaining, rx_frag_size);
/* Coalesce all frags from the same physical page in one slot */
@@ -1550,7 +1543,6 @@ static void skb_fill_rx_data(struct be_rx_obj *rxo, struct sk_buff *skb,
skb->data_len += curr_frag_len;
skb->truesize += rx_frag_size;
remaining -= curr_frag_len;
- index_inc(&rxcp->rxq_idx, rxq->len);
page_info->page = NULL;
}
BUG_ON(j > MAX_SKB_FRAGS);
@@ -1581,7 +1573,7 @@ static void be_rx_compl_process(struct be_rx_obj *rxo, struct napi_struct *napi,
skb->protocol = eth_type_trans(skb, netdev);
skb_record_rx_queue(skb, rxo - &adapter->rx_obj[0]);
if (netdev->features & NETIF_F_RXHASH)
- skb->rxhash = rxcp->rss_hash;
+ skb_set_hash(skb, rxcp->rss_hash, PKT_HASH_TYPE_L3);
skb_mark_napi_id(skb, napi);
if (rxcp->vlanf)
@@ -1598,7 +1590,6 @@ static void be_rx_compl_process_gro(struct be_rx_obj *rxo,
struct be_adapter *adapter = rxo->adapter;
struct be_rx_page_info *page_info;
struct sk_buff *skb = NULL;
- struct be_queue_info *rxq = &rxo->q;
u16 remaining, curr_frag_len;
u16 i, j;
@@ -1610,7 +1601,7 @@ static void be_rx_compl_process_gro(struct be_rx_obj *rxo,
remaining = rxcp->pkt_size;
for (i = 0, j = -1; i < rxcp->num_rcvd; i++) {
- page_info = get_rx_page_info(rxo, rxcp->rxq_idx);
+ page_info = get_rx_page_info(rxo);
curr_frag_len = min(remaining, rx_frag_size);
@@ -1628,7 +1619,6 @@ static void be_rx_compl_process_gro(struct be_rx_obj *rxo,
skb_frag_size_add(&skb_shinfo(skb)->frags[j], curr_frag_len);
skb->truesize += rx_frag_size;
remaining -= curr_frag_len;
- index_inc(&rxcp->rxq_idx, rxq->len);
memset(page_info, 0, sizeof(*page_info));
}
BUG_ON(j > MAX_SKB_FRAGS);
@@ -1639,7 +1629,7 @@ static void be_rx_compl_process_gro(struct be_rx_obj *rxo,
skb->ip_summed = CHECKSUM_UNNECESSARY;
skb_record_rx_queue(skb, rxo - &adapter->rx_obj[0]);
if (adapter->netdev->features & NETIF_F_RXHASH)
- skb->rxhash = rxcp->rss_hash;
+ skb_set_hash(skb, rxcp->rss_hash, PKT_HASH_TYPE_L3);
skb_mark_napi_id(skb, napi);
if (rxcp->vlanf)
@@ -1663,8 +1653,6 @@ static void be_parse_rx_compl_v1(struct be_eth_rx_compl *compl,
AMAP_GET_BITS(struct amap_eth_rx_compl_v1, l4_cksm, compl);
rxcp->ipv6 =
AMAP_GET_BITS(struct amap_eth_rx_compl_v1, ip_version, compl);
- rxcp->rxq_idx =
- AMAP_GET_BITS(struct amap_eth_rx_compl_v1, fragndx, compl);
rxcp->num_rcvd =
AMAP_GET_BITS(struct amap_eth_rx_compl_v1, numfrags, compl);
rxcp->pkt_type =
@@ -1695,8 +1683,6 @@ static void be_parse_rx_compl_v0(struct be_eth_rx_compl *compl,
AMAP_GET_BITS(struct amap_eth_rx_compl_v0, l4_cksm, compl);
rxcp->ipv6 =
AMAP_GET_BITS(struct amap_eth_rx_compl_v0, ip_version, compl);
- rxcp->rxq_idx =
- AMAP_GET_BITS(struct amap_eth_rx_compl_v0, fragndx, compl);
rxcp->num_rcvd =
AMAP_GET_BITS(struct amap_eth_rx_compl_v0, numfrags, compl);
rxcp->pkt_type =
@@ -1921,7 +1907,6 @@ static void be_rx_cq_clean(struct be_rx_obj *rxo)
struct be_rx_compl_info *rxcp;
struct be_adapter *adapter = rxo->adapter;
int flush_wait = 0;
- u16 tail;
/* Consume pending rx completions.
* Wait for the flush completion (identified by zero num_rcvd)
@@ -1954,9 +1939,8 @@ static void be_rx_cq_clean(struct be_rx_obj *rxo)
be_cq_notify(adapter, rx_cq->id, false, 0);
/* Then free posted rx buffers that were not used */
- tail = (rxq->head + rxq->len - atomic_read(&rxq->used)) % rxq->len;
- for (; atomic_read(&rxq->used) > 0; index_inc(&tail, rxq->len)) {
- page_info = get_rx_page_info(rxo, tail);
+ while (atomic_read(&rxq->used) > 0) {
+ page_info = get_rx_page_info(rxo);
put_page(page_info->page);
memset(page_info, 0, sizeof(*page_info));
}
@@ -2891,14 +2875,11 @@ 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 = false;
for_all_vfs(adapter, vf_cfg, vf) {
- be_cmd_get_mac_from_list(adapter, mac, &active,
- &vf_cfg->pmac_id, 0);
-
- status = be_cmd_mac_addr_query(adapter, mac, false,
- vf_cfg->if_handle, 0);
+ status = be_cmd_get_active_mac(adapter, vf_cfg->pmac_id,
+ mac, vf_cfg->if_handle,
+ false, vf+1);
if (status)
return status;
memcpy(vf_cfg->mac_addr, mac, ETH_ALEN);
@@ -3240,6 +3221,7 @@ static int be_get_resources(struct be_adapter *adapter)
/* 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,
@@ -3249,6 +3231,13 @@ static int be_get_config(struct be_adapter *adapter)
if (status)
return status;
+ if (be_physfn(adapter)) {
+ status = be_cmd_get_active_profile(adapter, &profile_id);
+ if (!status)
+ dev_info(&adapter->pdev->dev,
+ "Using profile 0x%x\n", profile_id);
+ }
+
status = be_get_resources(adapter);
if (status)
return status;
@@ -3403,11 +3392,6 @@ static int be_setup(struct be_adapter *adapter)
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.
- */
- if (be_is_mc(adapter))
- adapter->cmd_privileges = MAX_PRIVILEGES;
status = be_mac_setup(adapter);
if (status)
@@ -3426,6 +3410,8 @@ static int be_setup(struct be_adapter *adapter)
be_set_rx_mode(adapter->netdev);
+ be_cmd_get_acpi_wol_cap(adapter);
+
be_cmd_get_flow_control(adapter, &tx_fc, &rx_fc);
if (rx_fc != adapter->rx_fc || tx_fc != adapter->tx_fc)
@@ -4295,74 +4281,22 @@ static void be_remove(struct pci_dev *pdev)
free_netdev(adapter->netdev);
}
-bool be_is_wol_supported(struct be_adapter *adapter)
-{
- return ((adapter->wol_cap & BE_WOL_CAP) &&
- !be_is_wol_excluded(adapter)) ? true : false;
-}
-
-u32 be_get_fw_log_level(struct be_adapter *adapter)
-{
- struct be_dma_mem extfat_cmd;
- struct be_fat_conf_params *cfgs;
- int status;
- u32 level = 0;
- int j;
-
- if (lancer_chip(adapter))
- return 0;
-
- memset(&extfat_cmd, 0, sizeof(struct be_dma_mem));
- extfat_cmd.size = sizeof(struct be_cmd_resp_get_ext_fat_caps);
- extfat_cmd.va = pci_alloc_consistent(adapter->pdev, extfat_cmd.size,
- &extfat_cmd.dma);
-
- if (!extfat_cmd.va) {
- dev_err(&adapter->pdev->dev, "%s: Memory allocation failure\n",
- __func__);
- goto err;
- }
-
- status = be_cmd_get_ext_fat_capabilites(adapter, &extfat_cmd);
- if (!status) {
- cfgs = (struct be_fat_conf_params *)(extfat_cmd.va +
- sizeof(struct be_cmd_resp_hdr));
- for (j = 0; j < le32_to_cpu(cfgs->module[0].num_modes); j++) {
- if (cfgs->module[0].trace_lvl[j].mode == MODE_UART)
- level = cfgs->module[0].trace_lvl[j].dbg_lvl;
- }
- }
- pci_free_consistent(adapter->pdev, extfat_cmd.size, extfat_cmd.va,
- extfat_cmd.dma);
-err:
- return level;
-}
-
static int be_get_initial_config(struct be_adapter *adapter)
{
- int status;
- u32 level;
+ int status, level;
status = be_cmd_get_cntl_attributes(adapter);
if (status)
return status;
- status = be_cmd_get_acpi_wol_cap(adapter);
- if (status) {
- /* in case of a failure to get wol capabillities
- * check the exclusion list to determine WOL capability */
- if (!be_is_wol_excluded(adapter))
- adapter->wol_cap |= BE_WOL_CAP;
- }
-
- if (be_is_wol_supported(adapter))
- adapter->wol = true;
-
/* Must be a power of 2 or else MODULO will BUG_ON */
adapter->be_get_temp_freq = 64;
- level = be_get_fw_log_level(adapter);
- adapter->msg_enable = level <= FW_LOG_LEVEL_DEFAULT ? NETIF_MSG_HW : 0;
+ if (BEx_chip(adapter)) {
+ level = be_cmd_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;
@@ -4625,7 +4559,7 @@ static int be_suspend(struct pci_dev *pdev, pm_message_t state)
struct be_adapter *adapter = pci_get_drvdata(pdev);
struct net_device *netdev = adapter->netdev;
- if (adapter->wol)
+ if (adapter->wol_en)
be_setup_wol(adapter, true);
be_intr_set(adapter, false);
@@ -4681,7 +4615,7 @@ static int be_resume(struct pci_dev *pdev)
msecs_to_jiffies(1000));
netif_device_attach(netdev);
- if (adapter->wol)
+ if (adapter->wol_en)
be_setup_wol(adapter, false);
return 0;