be2net: Provide an alternate way to read pf_num for BEx chips
[cascardo/linux.git] / drivers / net / ethernet / emulex / benet / be_cmds.c
index fa11a5a..45d1742 100644 (file)
@@ -92,6 +92,11 @@ static struct be_cmd_priv_map cmd_priv_map[] = {
                CMD_SUBSYSTEM_COMMON,
                BE_PRIV_DEVCFG | BE_PRIV_VHADM
        },
+       {
+               OPCODE_COMMON_GET_EXT_FAT_CAPABILITIES,
+               CMD_SUBSYSTEM_COMMON,
+               BE_PRIV_DEVCFG
+       }
 };
 
 static bool be_cmd_allowed(struct be_adapter *adapter, u8 opcode, u8 subsystem)
@@ -705,7 +710,7 @@ static int be_mbox_notify_wait(struct be_adapter *adapter)
        return 0;
 }
 
-static u16 be_POST_stage_get(struct be_adapter *adapter)
+u16 be_POST_stage_get(struct be_adapter *adapter)
 {
        u32 sem;
 
@@ -3522,6 +3527,11 @@ int be_cmd_get_cntl_attributes(struct be_adapter *adapter)
                for (i = 0; i < CNTL_SERIAL_NUM_WORDS; i++)
                        adapter->serial_num[i] = le32_to_cpu(serial_num[i]) &
                                (BIT_MASK(16) - 1);
+               /* For BEx, since GET_FUNC_CONFIG command is not
+                * supported, we read funcnum here as a workaround.
+                */
+               if (BEx_chip(adapter))
+                       adapter->pf_num = attribs->hba_attribs.pci_funcnum;
        }
 
 err:
@@ -4127,6 +4137,10 @@ int be_cmd_get_ext_fat_capabilites(struct be_adapter *adapter,
        struct be_cmd_req_get_ext_fat_caps *req;
        int status;
 
+       if (!be_cmd_allowed(adapter, OPCODE_COMMON_GET_EXT_FAT_CAPABILITIES,
+                           CMD_SUBSYSTEM_COMMON))
+               return -EPERM;
+
        if (mutex_lock_interruptible(&adapter->mbox_lock))
                return -1;
 
@@ -4138,7 +4152,7 @@ int be_cmd_get_ext_fat_capabilites(struct be_adapter *adapter,
 
        req = cmd->va;
        be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
-                              OPCODE_COMMON_GET_EXT_FAT_CAPABILITES,
+                              OPCODE_COMMON_GET_EXT_FAT_CAPABILITIES,
                               cmd->size, wrb, cmd);
        req->parameter_type = cpu_to_le32(1);
 
@@ -4167,7 +4181,7 @@ int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter,
        req = cmd->va;
        memcpy(&req->set_params, configs, sizeof(struct be_fat_conf_params));
        be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
-                              OPCODE_COMMON_SET_EXT_FAT_CAPABILITES,
+                              OPCODE_COMMON_SET_EXT_FAT_CAPABILITIES,
                               cmd->size, wrb, cmd);
 
        status = be_mcc_notify_wait(adapter);
@@ -4373,7 +4387,7 @@ err:
 }
 
 /* This routine returns a list of all the NIC PF_nums in the adapter */
-u16 be_get_nic_pf_num_list(u8 *buf, u32 desc_count, u16 *nic_pf_nums)
+static u16 be_get_nic_pf_num_list(u8 *buf, u32 desc_count, u16 *nic_pf_nums)
 {
        struct be_res_desc_hdr *hdr = (struct be_res_desc_hdr *)buf;
        struct be_pcie_res_desc *pcie = NULL;
@@ -4525,7 +4539,7 @@ static int be_cmd_set_profile_config(struct be_adapter *adapter, void *desc,
 }
 
 /* Mark all fields invalid */
-void be_reset_nic_desc(struct be_nic_res_desc *nic)
+static void be_reset_nic_desc(struct be_nic_res_desc *nic)
 {
        memset(nic, 0, sizeof(*nic));
        nic->unicast_mac_count = 0xFFFF;
@@ -4898,8 +4912,9 @@ err:
        return status;
 }
 
-int __be_cmd_set_logical_link_config(struct be_adapter *adapter,
-                                    int link_state, int version, u8 domain)
+static int
+__be_cmd_set_logical_link_config(struct be_adapter *adapter,
+                                int link_state, int version, u8 domain)
 {
        struct be_mcc_wrb *wrb;
        struct be_cmd_req_set_ll_link *req;
@@ -4954,6 +4969,57 @@ int be_cmd_set_logical_link_config(struct be_adapter *adapter,
                                                          1, domain);
        return status;
 }
+
+int be_cmd_set_features(struct be_adapter *adapter)
+{
+       struct be_cmd_resp_set_features *resp;
+       struct be_cmd_req_set_features *req;
+       struct be_mcc_wrb *wrb;
+       int status;
+
+       if (mutex_lock_interruptible(&adapter->mcc_lock))
+               return -1;
+
+       wrb = wrb_from_mccq(adapter);
+       if (!wrb) {
+               status = -EBUSY;
+               goto err;
+       }
+
+       req = embedded_payload(wrb);
+
+       be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+                              OPCODE_COMMON_SET_FEATURES,
+                              sizeof(*req), wrb, NULL);
+
+       req->features = cpu_to_le32(BE_FEATURE_UE_RECOVERY);
+       req->parameter_len = cpu_to_le32(sizeof(struct be_req_ue_recovery));
+       req->parameter.req.uer = cpu_to_le32(BE_UE_RECOVERY_UER_MASK);
+
+       status = be_mcc_notify_wait(adapter);
+       if (status)
+               goto err;
+
+       resp = embedded_payload(wrb);
+
+       adapter->error_recovery.ue_to_poll_time =
+               le16_to_cpu(resp->parameter.resp.ue2rp);
+       adapter->error_recovery.ue_to_reset_time =
+               le16_to_cpu(resp->parameter.resp.ue2sr);
+       adapter->error_recovery.recovery_supported = true;
+err:
+       /* Checking "MCC_STATUS_INVALID_LENGTH" for SKH as FW
+        * returns this error in older firmware versions
+        */
+       if (base_status(status) == MCC_STATUS_ILLEGAL_REQUEST ||
+           base_status(status) == MCC_STATUS_INVALID_LENGTH)
+               dev_info(&adapter->pdev->dev,
+                        "Adapter does not support HW error recovery\n");
+
+       mutex_unlock(&adapter->mcc_lock);
+       return status;
+}
+
 int be_roce_mcc_cmd(void *netdev_handle, void *wrb_payload,
                    int wrb_payload_size, u16 *cmd_status, u16 *ext_status)
 {