]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/net/ethernet/emulex/benet/be_cmds.c
be2net: reduce arguments passed to FW-cmd routines
[karo-tx-linux.git] / drivers / net / ethernet / emulex / benet / be_cmds.c
index f4ea3490f44657f3e90974065fea9a0eee649cd0..791094c33535d845bd68c09cf1ac4e651ec4b8a6 100644 (file)
@@ -1749,8 +1749,7 @@ err:
 }
 
 /* Uses synchronous mcc */
-int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver,
-                     char *fw_on_flash)
+int be_cmd_get_fw_ver(struct be_adapter *adapter)
 {
        struct be_mcc_wrb *wrb;
        struct be_cmd_req_get_fw_version *req;
@@ -1772,9 +1771,8 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver,
        status = be_mcc_notify_wait(adapter);
        if (!status) {
                struct be_cmd_resp_get_fw_version *resp = embedded_payload(wrb);
-               strcpy(fw_ver, resp->firmware_version_string);
-               if (fw_on_flash)
-                       strcpy(fw_on_flash, resp->fw_on_flash_version_string);
+               strcpy(adapter->fw_ver, resp->firmware_version_string);
+               strcpy(adapter->fw_on_flash, resp->fw_on_flash_version_string);
        }
 err:
        spin_unlock_bh(&adapter->mcc_lock);
@@ -1997,8 +1995,7 @@ err:
 }
 
 /* Uses mbox */
-int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num,
-                       u32 *mode, u32 *caps, u16 *asic_rev)
+int be_cmd_query_fw_cfg(struct be_adapter *adapter)
 {
        struct be_mcc_wrb *wrb;
        struct be_cmd_req_query_fw_cfg *req;
@@ -2017,10 +2014,10 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num,
        status = be_mbox_notify_wait(adapter);
        if (!status) {
                struct be_cmd_resp_query_fw_cfg *resp = embedded_payload(wrb);
-               *port_num = le32_to_cpu(resp->phys_port);
-               *mode = le32_to_cpu(resp->function_mode);
-               *caps = le32_to_cpu(resp->function_caps);
-               *asic_rev = le32_to_cpu(resp->asic_revision) & 0xFF;
+               adapter->port_num = le32_to_cpu(resp->phys_port);
+               adapter->function_mode = le32_to_cpu(resp->function_mode);
+               adapter->function_caps = le32_to_cpu(resp->function_caps);
+               adapter->asic_rev = le32_to_cpu(resp->asic_revision) & 0xFF;
        }
 
        mutex_unlock(&adapter->mbox_lock);
@@ -2224,7 +2221,7 @@ int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
 
        if (!wait_for_completion_timeout(&adapter->et_cmd_compl,
                                         msecs_to_jiffies(60000)))
-               status = -1;
+               status = -ETIMEDOUT;
        else
                status = adapter->flash_status;
 
@@ -2320,7 +2317,7 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
 
        if (!wait_for_completion_timeout(&adapter->et_cmd_compl,
                                         msecs_to_jiffies(40000)))
-               status = -1;
+               status = -ETIMEDOUT;
        else
                status = adapter->flash_status;
 
@@ -3313,15 +3310,28 @@ err:
        return status;
 }
 
-static struct be_nic_res_desc *be_get_nic_desc(u8 *buf, u32 desc_count)
+/* Descriptor type */
+enum {
+       FUNC_DESC = 1,
+       VFT_DESC = 2
+};
+
+static struct be_nic_res_desc *be_get_nic_desc(u8 *buf, u32 desc_count,
+                                              int desc_type)
 {
        struct be_res_desc_hdr *hdr = (struct be_res_desc_hdr *)buf;
+       struct be_nic_res_desc *nic;
        int i;
 
        for (i = 0; i < desc_count; i++) {
                if (hdr->desc_type == NIC_RESOURCE_DESC_TYPE_V0 ||
-                   hdr->desc_type == NIC_RESOURCE_DESC_TYPE_V1)
-                       return (struct be_nic_res_desc *)hdr;
+                   hdr->desc_type == NIC_RESOURCE_DESC_TYPE_V1) {
+                       nic = (struct be_nic_res_desc *)hdr;
+                       if (desc_type == FUNC_DESC ||
+                           (desc_type == VFT_DESC &&
+                            nic->flags & (1 << VFT_SHIFT)))
+                               return nic;
+               }
 
                hdr->desc_len = hdr->desc_len ? : RESOURCE_DESC_SIZE_V0;
                hdr = (void *)hdr + hdr->desc_len;
@@ -3329,6 +3339,16 @@ static struct be_nic_res_desc *be_get_nic_desc(u8 *buf, u32 desc_count)
        return NULL;
 }
 
+static struct be_nic_res_desc *be_get_vft_desc(u8 *buf, u32 desc_count)
+{
+       return be_get_nic_desc(buf, desc_count, VFT_DESC);
+}
+
+static struct be_nic_res_desc *be_get_func_nic_desc(u8 *buf, u32 desc_count)
+{
+       return be_get_nic_desc(buf, desc_count, FUNC_DESC);
+}
+
 static struct be_pcie_res_desc *be_get_pcie_desc(u8 devfn, u8 *buf,
                                                 u32 desc_count)
 {
@@ -3424,7 +3444,7 @@ int be_cmd_get_func_config(struct be_adapter *adapter, struct be_resources *res)
                u32 desc_count = le32_to_cpu(resp->desc_count);
                struct be_nic_res_desc *desc;
 
-               desc = be_get_nic_desc(resp->func_param, desc_count);
+               desc = be_get_func_nic_desc(resp->func_param, desc_count);
                if (!desc) {
                        status = -EINVAL;
                        goto err;
@@ -3440,76 +3460,17 @@ err:
        return status;
 }
 
-/* Uses mbox */
-static int be_cmd_get_profile_config_mbox(struct be_adapter *adapter,
-                                         u8 domain, struct be_dma_mem *cmd)
-{
-       struct be_mcc_wrb *wrb;
-       struct be_cmd_req_get_profile_config *req;
-       int status;
-
-       if (mutex_lock_interruptible(&adapter->mbox_lock))
-               return -1;
-       wrb = wrb_from_mbox(adapter);
-
-       req = cmd->va;
-       be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
-                              OPCODE_COMMON_GET_PROFILE_CONFIG,
-                              cmd->size, wrb, cmd);
-
-       req->type = ACTIVE_PROFILE_TYPE;
-       req->hdr.domain = domain;
-       if (!lancer_chip(adapter))
-               req->hdr.version = 1;
-
-       status = be_mbox_notify_wait(adapter);
-
-       mutex_unlock(&adapter->mbox_lock);
-       return status;
-}
-
-/* Uses sync mcc */
-static int be_cmd_get_profile_config_mccq(struct be_adapter *adapter,
-                                         u8 domain, struct be_dma_mem *cmd)
-{
-       struct be_mcc_wrb *wrb;
-       struct be_cmd_req_get_profile_config *req;
-       int status;
-
-       spin_lock_bh(&adapter->mcc_lock);
-
-       wrb = wrb_from_mccq(adapter);
-       if (!wrb) {
-               status = -EBUSY;
-               goto err;
-       }
-
-       req = cmd->va;
-       be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
-                              OPCODE_COMMON_GET_PROFILE_CONFIG,
-                              cmd->size, wrb, cmd);
-
-       req->type = ACTIVE_PROFILE_TYPE;
-       req->hdr.domain = domain;
-       if (!lancer_chip(adapter))
-               req->hdr.version = 1;
-
-       status = be_mcc_notify_wait(adapter);
-
-err:
-       spin_unlock_bh(&adapter->mcc_lock);
-       return status;
-}
-
-/* Uses sync mcc, if MCCQ is already created otherwise mbox */
+/* Will use MBOX only if MCCQ has not been created */
 int be_cmd_get_profile_config(struct be_adapter *adapter,
                              struct be_resources *res, u8 domain)
 {
        struct be_cmd_resp_get_profile_config *resp;
+       struct be_cmd_req_get_profile_config *req;
+       struct be_nic_res_desc *vf_res;
        struct be_pcie_res_desc *pcie;
        struct be_port_res_desc *port;
        struct be_nic_res_desc *nic;
-       struct be_queue_info *mccq = &adapter->mcc_obj.q;
+       struct be_mcc_wrb wrb = {0};
        struct be_dma_mem cmd;
        u32 desc_count;
        int status;
@@ -3520,10 +3481,17 @@ int be_cmd_get_profile_config(struct be_adapter *adapter,
        if (!cmd.va)
                return -ENOMEM;
 
-       if (!mccq->created)
-               status = be_cmd_get_profile_config_mbox(adapter, domain, &cmd);
-       else
-               status = be_cmd_get_profile_config_mccq(adapter, domain, &cmd);
+       req = cmd.va;
+       be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
+                              OPCODE_COMMON_GET_PROFILE_CONFIG,
+                              cmd.size, &wrb, &cmd);
+
+       req->hdr.domain = domain;
+       if (!lancer_chip(adapter))
+               req->hdr.version = 1;
+       req->type = ACTIVE_PROFILE_TYPE;
+
+       status = be_cmd_notify_wait(adapter, &wrb);
        if (status)
                goto err;
 
@@ -3539,48 +3507,52 @@ int be_cmd_get_profile_config(struct be_adapter *adapter,
        if (port)
                adapter->mc_type = port->mc_type;
 
-       nic = be_get_nic_desc(resp->func_param, desc_count);
+       nic = be_get_func_nic_desc(resp->func_param, desc_count);
        if (nic)
                be_copy_nic_desc(res, nic);
 
+       vf_res = be_get_vft_desc(resp->func_param, desc_count);
+       if (vf_res)
+               res->vf_if_cap_flags = vf_res->cap_flags;
 err:
        if (cmd.va)
                pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
        return status;
 }
 
-int be_cmd_set_profile_config(struct be_adapter *adapter, void *desc,
-                             int size, u8 version, u8 domain)
+/* Will use MBOX only if MCCQ has not been created */
+static int be_cmd_set_profile_config(struct be_adapter *adapter, void *desc,
+                                    int size, int count, u8 version, u8 domain)
 {
        struct be_cmd_req_set_profile_config *req;
-       struct be_mcc_wrb *wrb;
+       struct be_mcc_wrb wrb = {0};
+       struct be_dma_mem cmd;
        int status;
 
-       spin_lock_bh(&adapter->mcc_lock);
-
-       wrb = wrb_from_mccq(adapter);
-       if (!wrb) {
-               status = -EBUSY;
-               goto err;
-       }
+       memset(&cmd, 0, sizeof(struct be_dma_mem));
+       cmd.size = sizeof(struct be_cmd_req_set_profile_config);
+       cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size, &cmd.dma);
+       if (!cmd.va)
+               return -ENOMEM;
 
-       req = embedded_payload(wrb);
+       req = cmd.va;
        be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
-                              OPCODE_COMMON_SET_PROFILE_CONFIG, sizeof(*req),
-                              wrb, NULL);
+                              OPCODE_COMMON_SET_PROFILE_CONFIG, cmd.size,
+                              &wrb, &cmd);
        req->hdr.version = version;
        req->hdr.domain = domain;
-       req->desc_count = cpu_to_le32(1);
+       req->desc_count = cpu_to_le32(count);
        memcpy(req->desc, desc, size);
 
-       status = be_mcc_notify_wait(adapter);
-err:
-       spin_unlock_bh(&adapter->mcc_lock);
+       status = be_cmd_notify_wait(adapter, &wrb);
+
+       if (cmd.va)
+               pci_free_consistent(adapter->pdev, cmd.size, cmd.va, cmd.dma);
        return status;
 }
 
 /* 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;
@@ -3601,9 +3573,20 @@ void be_reset_nic_desc(struct be_nic_res_desc *nic)
        nic->wol_param = 0x0F;
        nic->tunnel_iface_count = 0xFFFF;
        nic->direct_tenant_iface_count = 0xFFFF;
+       nic->bw_min = 0xFFFFFFFF;
        nic->bw_max = 0xFFFFFFFF;
 }
 
+/* Mark all fields invalid */
+static void be_reset_pcie_desc(struct be_pcie_res_desc *pcie)
+{
+       memset(pcie, 0, sizeof(*pcie));
+       pcie->sriov_state = 0xFF;
+       pcie->pf_state = 0xFF;
+       pcie->pf_type = 0xFF;
+       pcie->num_vfs = 0xFFFF;
+}
+
 int be_cmd_config_qos(struct be_adapter *adapter, u32 max_rate, u16 link_speed,
                      u8 domain)
 {
@@ -3634,7 +3617,63 @@ int be_cmd_config_qos(struct be_adapter *adapter, u32 max_rate, u16 link_speed,
 
        return be_cmd_set_profile_config(adapter, &nic_desc,
                                         nic_desc.hdr.desc_len,
-                                        version, domain);
+                                        1, version, domain);
+}
+
+int be_cmd_set_sriov_config(struct be_adapter *adapter,
+                           struct be_resources res, u16 num_vfs)
+{
+       struct {
+               struct be_pcie_res_desc pcie;
+               struct be_nic_res_desc nic_vft;
+       } __packed desc;
+       u16 vf_q_count;
+
+       if (BEx_chip(adapter) || lancer_chip(adapter))
+               return 0;
+
+       /* PF PCIE descriptor */
+       be_reset_pcie_desc(&desc.pcie);
+       desc.pcie.hdr.desc_type = PCIE_RESOURCE_DESC_TYPE_V1;
+       desc.pcie.hdr.desc_len = RESOURCE_DESC_SIZE_V1;
+       desc.pcie.flags = (1 << IMM_SHIFT) | (1 << NOSV_SHIFT);
+       desc.pcie.pf_num = adapter->pdev->devfn;
+       desc.pcie.sriov_state = num_vfs ? 1 : 0;
+       desc.pcie.num_vfs = cpu_to_le16(num_vfs);
+
+       /* VF NIC Template descriptor */
+       be_reset_nic_desc(&desc.nic_vft);
+       desc.nic_vft.hdr.desc_type = NIC_RESOURCE_DESC_TYPE_V1;
+       desc.nic_vft.hdr.desc_len = RESOURCE_DESC_SIZE_V1;
+       desc.nic_vft.flags = (1 << VFT_SHIFT) | (1 << IMM_SHIFT) |
+                               (1 << NOSV_SHIFT);
+       desc.nic_vft.pf_num = adapter->pdev->devfn;
+       desc.nic_vft.vf_num = 0;
+
+       if (num_vfs && res.vf_if_cap_flags & BE_IF_FLAGS_RSS) {
+               /* If number of VFs requested is 8 less than max supported,
+                * assign 8 queue pairs to the PF and divide the remaining
+                * resources evenly among the VFs
+                */
+               if (num_vfs < (be_max_vfs(adapter) - 8))
+                       vf_q_count = (res.max_rss_qs - 8) / num_vfs;
+               else
+                       vf_q_count = res.max_rss_qs / num_vfs;
+
+               desc.nic_vft.rq_count = cpu_to_le16(vf_q_count);
+               desc.nic_vft.txq_count = cpu_to_le16(vf_q_count);
+               desc.nic_vft.rssq_count = cpu_to_le16(vf_q_count - 1);
+               desc.nic_vft.cq_count = cpu_to_le16(3 * vf_q_count);
+       } else {
+               desc.nic_vft.txq_count = cpu_to_le16(1);
+               desc.nic_vft.rq_count = cpu_to_le16(1);
+               desc.nic_vft.rssq_count = cpu_to_le16(0);
+               /* One CQ for each TX, RX and MCCQ */
+               desc.nic_vft.cq_count = cpu_to_le16(3);
+       }
+
+       return be_cmd_set_profile_config(adapter, &desc,
+                                        2 * RESOURCE_DESC_SIZE_V1, 2, 1, 0);
 }
 
 int be_cmd_manage_iface(struct be_adapter *adapter, u32 iface, u8 op)
@@ -3686,7 +3725,7 @@ int be_cmd_set_vxlan_port(struct be_adapter *adapter, __be16 port)
        }
 
        return be_cmd_set_profile_config(adapter, &port_desc,
-                                        RESOURCE_DESC_SIZE_V1, 1, 0);
+                                        RESOURCE_DESC_SIZE_V1, 1, 1, 0);
 }
 
 int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg,