be2net: cleanup wake-on-lan code
[cascardo/linux.git] / drivers / net / ethernet / emulex / benet / be_cmds.c
index e0e8bc1..48076a6 100644 (file)
@@ -141,11 +141,17 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
                subsystem = resp_hdr->subsystem;
        }
 
+       if (opcode == OPCODE_LOWLEVEL_LOOPBACK_TEST &&
+           subsystem == CMD_SUBSYSTEM_LOWLEVEL) {
+               complete(&adapter->et_cmd_compl);
+               return 0;
+       }
+
        if (((opcode == OPCODE_COMMON_WRITE_FLASHROM) ||
             (opcode == OPCODE_COMMON_WRITE_OBJECT)) &&
            (subsystem == CMD_SUBSYSTEM_COMMON)) {
                adapter->flash_status = compl_status;
-               complete(&adapter->flash_compl);
+               complete(&adapter->et_cmd_compl);
        }
 
        if (compl_status == MCC_STATUS_SUCCESS) {
@@ -1095,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) */
@@ -1181,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");
@@ -2017,6 +2022,9 @@ int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable,
                        0x3ea83c02, 0x4a110304};
        int status;
 
+       if (!(be_if_cap_flags(adapter) & BE_IF_FLAGS_RSS))
+               return 0;
+
        if (mutex_lock_interruptible(&adapter->mbox_lock))
                return -1;
 
@@ -2160,7 +2168,7 @@ int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
        be_mcc_notify(adapter);
        spin_unlock_bh(&adapter->mcc_lock);
 
-       if (!wait_for_completion_timeout(&adapter->flash_compl,
+       if (!wait_for_completion_timeout(&adapter->et_cmd_compl,
                                         msecs_to_jiffies(60000)))
                status = -1;
        else
@@ -2255,8 +2263,8 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
        be_mcc_notify(adapter);
        spin_unlock_bh(&adapter->mcc_lock);
 
-       if (!wait_for_completion_timeout(&adapter->flash_compl,
-                       msecs_to_jiffies(40000)))
+       if (!wait_for_completion_timeout(&adapter->et_cmd_compl,
+                                        msecs_to_jiffies(40000)))
                status = -1;
        else
                status = adapter->flash_status;
@@ -2367,6 +2375,7 @@ int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
 {
        struct be_mcc_wrb *wrb;
        struct be_cmd_req_loopback_test *req;
+       struct be_cmd_resp_loopback_test *resp;
        int status;
 
        spin_lock_bh(&adapter->mcc_lock);
@@ -2381,8 +2390,8 @@ int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
 
        be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_LOWLEVEL,
                        OPCODE_LOWLEVEL_LOOPBACK_TEST, sizeof(*req), wrb, NULL);
-       req->hdr.timeout = cpu_to_le32(4);
 
+       req->hdr.timeout = cpu_to_le32(15);
        req->pattern = cpu_to_le64(pattern);
        req->src_port = cpu_to_le32(port_num);
        req->dest_port = cpu_to_le32(port_num);
@@ -2390,12 +2399,15 @@ int be_cmd_loopback_test(struct be_adapter *adapter, u32 port_num,
        req->num_pkts = cpu_to_le32(num_pkts);
        req->loopback_type = cpu_to_le32(loopback_type);
 
-       status = be_mcc_notify_wait(adapter);
-       if (!status) {
-               struct be_cmd_resp_loopback_test *resp = embedded_payload(wrb);
-               status = le32_to_cpu(resp->status);
-       }
+       be_mcc_notify(adapter);
+
+       spin_unlock_bh(&adapter->mcc_lock);
 
+       wait_for_completion(&adapter->et_cmd_compl);
+       resp = embedded_payload(wrb);
+       status = le32_to_cpu(resp->status);
+
+       return status;
 err:
        spin_unlock_bh(&adapter->mcc_lock);
        return status;
@@ -2679,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:
@@ -2723,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;
@@ -2761,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;
@@ -2814,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)
@@ -2843,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;
@@ -2904,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);
 
@@ -2984,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);
@@ -3015,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;
 
@@ -3047,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;
@@ -3057,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);
@@ -3072,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)
 {
@@ -3596,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)
 {