iwlwifi: unify iwl_get_ucode_image() implementations
[cascardo/linux.git] / drivers / net / wireless / intel / iwlwifi / mvm / fw.c
index 7e0cdbf..7322c43 100644 (file)
@@ -90,15 +90,6 @@ struct iwl_mvm_alive_data {
        u32 scd_base_addr;
 };
 
-static inline const struct fw_img *
-iwl_get_ucode_image(struct iwl_mvm *mvm, enum iwl_ucode_type ucode_type)
-{
-       if (ucode_type >= IWL_UCODE_TYPE_MAX)
-               return NULL;
-
-       return &mvm->fw->img[ucode_type];
-}
-
 static int iwl_send_tx_ant_cfg(struct iwl_mvm *mvm, u8 valid_tx_ant)
 {
        struct iwl_tx_ant_cfg_cmd tx_ant_cmd = {
@@ -385,9 +376,7 @@ static int iwl_save_fw_paging(struct iwl_mvm *mvm,
 /* send paging cmd to FW in case CPU2 has paging image */
 static int iwl_send_paging_cmd(struct iwl_mvm *mvm, const struct fw_img *fw)
 {
-       int blk_idx;
-       __le32 dev_phy_addr;
-       struct iwl_fw_paging_cmd fw_paging_cmd = {
+       struct iwl_fw_paging_cmd paging_cmd = {
                .flags =
                        cpu_to_le32(PAGING_CMD_IS_SECURED |
                                    PAGING_CMD_IS_ENABLED |
@@ -396,18 +385,32 @@ static int iwl_send_paging_cmd(struct iwl_mvm *mvm, const struct fw_img *fw)
                .block_size = cpu_to_le32(BLOCK_2_EXP_SIZE),
                .block_num = cpu_to_le32(mvm->num_of_paging_blk),
        };
+       int blk_idx, size = sizeof(paging_cmd);
+
+       /* A bit hard coded - but this is the old API and will be deprecated */
+       if (!iwl_mvm_has_new_tx_api(mvm))
+               size -= NUM_OF_FW_PAGING_BLOCKS * 4;
 
        /* loop for for all paging blocks + CSS block */
        for (blk_idx = 0; blk_idx < mvm->num_of_paging_blk + 1; blk_idx++) {
-               dev_phy_addr =
-                       cpu_to_le32(mvm->fw_paging_db[blk_idx].fw_paging_phys >>
-                                   PAGE_2_EXP_SIZE);
-               fw_paging_cmd.device_phy_addr[blk_idx] = dev_phy_addr;
+               dma_addr_t addr = mvm->fw_paging_db[blk_idx].fw_paging_phys;
+
+               addr = addr >> PAGE_2_EXP_SIZE;
+
+               if (iwl_mvm_has_new_tx_api(mvm)) {
+                       __le64 phy_addr = cpu_to_le64(addr);
+
+                       paging_cmd.device_phy_addr.addr64[blk_idx] = phy_addr;
+               } else {
+                       __le32 phy_addr = cpu_to_le32(addr);
+
+                       paging_cmd.device_phy_addr.addr32[blk_idx] = phy_addr;
+               }
        }
 
        return iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(FW_PAGING_BLOCK_CMD,
                                                    IWL_ALWAYS_LONG_GROUP, 0),
-                                   0, sizeof(fw_paging_cmd), &fw_paging_cmd);
+                                   0, size, &paging_cmd);
 }
 
 /*
@@ -580,9 +583,9 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
            iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_START_FROM_ALIVE) &&
            !(fw_has_capa(&mvm->fw->ucode_capa,
                          IWL_UCODE_TLV_CAPA_USNIFFER_UNIFIED)))
-               fw = iwl_get_ucode_image(mvm, IWL_UCODE_REGULAR_USNIFFER);
+               fw = iwl_get_ucode_image(mvm->fw, IWL_UCODE_REGULAR_USNIFFER);
        else
-               fw = iwl_get_ucode_image(mvm, ucode_type);
+               fw = iwl_get_ucode_image(mvm->fw, ucode_type);
        if (WARN_ON(!fw))
                return -EINVAL;
        mvm->cur_ucode = ucode_type;
@@ -826,59 +829,48 @@ out:
        return ret;
 }
 
-static void iwl_mvm_get_shared_mem_conf(struct iwl_mvm *mvm)
+static void iwl_mvm_parse_shared_mem_a000(struct iwl_mvm *mvm,
+                                         struct iwl_rx_packet *pkt)
 {
-       struct iwl_host_cmd cmd = {
-               .flags = CMD_WANT_SKB,
-               .data = { NULL, },
-               .len = { 0, },
-       };
-       struct iwl_shared_mem_cfg *mem_cfg;
-       struct iwl_rx_packet *pkt;
-       u32 i;
+       struct iwl_shared_mem_cfg *mem_cfg = (void *)pkt->data;
+       int i;
 
-       lockdep_assert_held(&mvm->mutex);
+       mvm->shared_mem_cfg.num_txfifo_entries =
+               ARRAY_SIZE(mvm->shared_mem_cfg.txfifo_size);
+       for (i = 0; i < ARRAY_SIZE(mem_cfg->txfifo_size); i++)
+               mvm->shared_mem_cfg.txfifo_size[i] =
+                       le32_to_cpu(mem_cfg->txfifo_size[i]);
+       for (i = 0; i < ARRAY_SIZE(mvm->shared_mem_cfg.rxfifo_size); i++)
+               mvm->shared_mem_cfg.rxfifo_size[i] =
+                       le32_to_cpu(mem_cfg->rxfifo_size[i]);
 
-       if (fw_has_capa(&mvm->fw->ucode_capa,
-                       IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG))
-               cmd.id = iwl_cmd_id(SHARED_MEM_CFG_CMD, SYSTEM_GROUP, 0);
-       else
-               cmd.id = SHARED_MEM_CFG;
+       BUILD_BUG_ON(sizeof(mvm->shared_mem_cfg.internal_txfifo_size) !=
+                    sizeof(mem_cfg->internal_txfifo_size));
 
-       if (WARN_ON(iwl_mvm_send_cmd(mvm, &cmd)))
-               return;
+       for (i = 0; i < ARRAY_SIZE(mvm->shared_mem_cfg.internal_txfifo_size);
+            i++)
+               mvm->shared_mem_cfg.internal_txfifo_size[i] =
+                       le32_to_cpu(mem_cfg->internal_txfifo_size[i]);
+}
 
-       pkt = cmd.resp_pkt;
-       mem_cfg = (void *)pkt->data;
-
-       mvm->shared_mem_cfg.shared_mem_addr =
-               le32_to_cpu(mem_cfg->shared_mem_addr);
-       mvm->shared_mem_cfg.shared_mem_size =
-               le32_to_cpu(mem_cfg->shared_mem_size);
-       mvm->shared_mem_cfg.sample_buff_addr =
-               le32_to_cpu(mem_cfg->sample_buff_addr);
-       mvm->shared_mem_cfg.sample_buff_size =
-               le32_to_cpu(mem_cfg->sample_buff_size);
-       mvm->shared_mem_cfg.txfifo_addr = le32_to_cpu(mem_cfg->txfifo_addr);
-       for (i = 0; i < ARRAY_SIZE(mvm->shared_mem_cfg.txfifo_size); i++)
+static void iwl_mvm_parse_shared_mem(struct iwl_mvm *mvm,
+                                    struct iwl_rx_packet *pkt)
+{
+       struct iwl_shared_mem_cfg_v1 *mem_cfg = (void *)pkt->data;
+       int i;
+
+       mvm->shared_mem_cfg.num_txfifo_entries =
+               ARRAY_SIZE(mvm->shared_mem_cfg.txfifo_size);
+       for (i = 0; i < ARRAY_SIZE(mem_cfg->txfifo_size); i++)
                mvm->shared_mem_cfg.txfifo_size[i] =
                        le32_to_cpu(mem_cfg->txfifo_size[i]);
        for (i = 0; i < ARRAY_SIZE(mvm->shared_mem_cfg.rxfifo_size); i++)
                mvm->shared_mem_cfg.rxfifo_size[i] =
                        le32_to_cpu(mem_cfg->rxfifo_size[i]);
-       mvm->shared_mem_cfg.page_buff_addr =
-               le32_to_cpu(mem_cfg->page_buff_addr);
-       mvm->shared_mem_cfg.page_buff_size =
-               le32_to_cpu(mem_cfg->page_buff_size);
 
-       /* new API has more data */
+       /* new API has more data, from rxfifo_addr field and on */
        if (fw_has_capa(&mvm->fw->ucode_capa,
                        IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG)) {
-               mvm->shared_mem_cfg.rxfifo_addr =
-                       le32_to_cpu(mem_cfg->rxfifo_addr);
-               mvm->shared_mem_cfg.internal_txfifo_addr =
-                       le32_to_cpu(mem_cfg->internal_txfifo_addr);
-
                BUILD_BUG_ON(sizeof(mvm->shared_mem_cfg.internal_txfifo_size) !=
                             sizeof(mem_cfg->internal_txfifo_size));
 
@@ -888,6 +880,33 @@ static void iwl_mvm_get_shared_mem_conf(struct iwl_mvm *mvm)
                        mvm->shared_mem_cfg.internal_txfifo_size[i] =
                                le32_to_cpu(mem_cfg->internal_txfifo_size[i]);
        }
+}
+
+static void iwl_mvm_get_shared_mem_conf(struct iwl_mvm *mvm)
+{
+       struct iwl_host_cmd cmd = {
+               .flags = CMD_WANT_SKB,
+               .data = { NULL, },
+               .len = { 0, },
+       };
+       struct iwl_rx_packet *pkt;
+
+       lockdep_assert_held(&mvm->mutex);
+
+       if (fw_has_capa(&mvm->fw->ucode_capa,
+                       IWL_UCODE_TLV_CAPA_EXTEND_SHARED_MEM_CFG))
+               cmd.id = iwl_cmd_id(SHARED_MEM_CFG_CMD, SYSTEM_GROUP, 0);
+       else
+               cmd.id = SHARED_MEM_CFG;
+
+       if (WARN_ON(iwl_mvm_send_cmd(mvm, &cmd)))
+               return;
+
+       pkt = cmd.resp_pkt;
+       if (iwl_mvm_has_new_tx_api(mvm))
+               iwl_mvm_parse_shared_mem_a000(mvm, pkt);
+       else
+               iwl_mvm_parse_shared_mem(mvm, pkt);
 
        IWL_DEBUG_INFO(mvm, "SHARED MEM CFG: got memory offsets/sizes\n");