root/drivers/net/wireless/intel/iwlwifi/pcie/ctxt-info-gen3.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. iwl_pcie_ctxt_info_gen3_init
  2. iwl_pcie_ctxt_info_gen3_free

   1 /******************************************************************************
   2  *
   3  * This file is provided under a dual BSD/GPLv2 license.  When using or
   4  * redistributing this file, you may do so under either license.
   5  *
   6  * GPL LICENSE SUMMARY
   7  *
   8  * Copyright(c) 2018 - 2019 Intel Corporation
   9  *
  10  * This program is free software; you can redistribute it and/or modify
  11  * it under the terms of version 2 of the GNU General Public License as
  12  * published by the Free Software Foundation.
  13  *
  14  * This program is distributed in the hope that it will be useful, but
  15  * WITHOUT ANY WARRANTY; without even the implied warranty of
  16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17  * General Public License for more details.
  18  *
  19  * BSD LICENSE
  20  *
  21  * Copyright(c) 2018 - 2019 Intel Corporation
  22  * All rights reserved.
  23  *
  24  * Redistribution and use in source and binary forms, with or without
  25  * modification, are permitted provided that the following conditions
  26  * are met:
  27  *
  28  *  * Redistributions of source code must retain the above copyright
  29  *    notice, this list of conditions and the following disclaimer.
  30  *  * Redistributions in binary form must reproduce the above copyright
  31  *    notice, this list of conditions and the following disclaimer in
  32  *    the documentation and/or other materials provided with the
  33  *    distribution.
  34  *  * Neither the name Intel Corporation nor the names of its
  35  *    contributors may be used to endorse or promote products derived
  36  *    from this software without specific prior written permission.
  37  *
  38  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  39  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  40  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  41  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  42  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  43  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  44  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  45  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  46  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  47  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  48  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  49  *
  50  *****************************************************************************/
  51 
  52 #include "iwl-trans.h"
  53 #include "iwl-fh.h"
  54 #include "iwl-context-info-gen3.h"
  55 #include "internal.h"
  56 #include "iwl-prph.h"
  57 
  58 int iwl_pcie_ctxt_info_gen3_init(struct iwl_trans *trans,
  59                                  const struct fw_img *fw)
  60 {
  61         struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
  62         struct iwl_context_info_gen3 *ctxt_info_gen3;
  63         struct iwl_prph_scratch *prph_scratch;
  64         struct iwl_prph_scratch_ctrl_cfg *prph_sc_ctrl;
  65         struct iwl_prph_info *prph_info;
  66         void *iml_img;
  67         u32 control_flags = 0;
  68         int ret;
  69         int cmdq_size = max_t(u32, IWL_CMD_QUEUE_SIZE,
  70                               trans->cfg->min_txq_size);
  71 
  72         /* Allocate prph scratch */
  73         prph_scratch = dma_alloc_coherent(trans->dev, sizeof(*prph_scratch),
  74                                           &trans_pcie->prph_scratch_dma_addr,
  75                                           GFP_KERNEL);
  76         if (!prph_scratch)
  77                 return -ENOMEM;
  78 
  79         prph_sc_ctrl = &prph_scratch->ctrl_cfg;
  80 
  81         prph_sc_ctrl->version.version = 0;
  82         prph_sc_ctrl->version.mac_id =
  83                 cpu_to_le16((u16)iwl_read32(trans, CSR_HW_REV));
  84         prph_sc_ctrl->version.size = cpu_to_le16(sizeof(*prph_scratch) / 4);
  85 
  86         control_flags = IWL_PRPH_SCRATCH_RB_SIZE_4K |
  87                         IWL_PRPH_SCRATCH_MTR_MODE |
  88                         (IWL_PRPH_MTR_FORMAT_256B &
  89                          IWL_PRPH_SCRATCH_MTR_FORMAT) |
  90                         IWL_PRPH_SCRATCH_EARLY_DEBUG_EN |
  91                         IWL_PRPH_SCRATCH_EDBG_DEST_DRAM;
  92         prph_sc_ctrl->control.control_flags = cpu_to_le32(control_flags);
  93 
  94         /* initialize RX default queue */
  95         prph_sc_ctrl->rbd_cfg.free_rbd_addr =
  96                 cpu_to_le64(trans_pcie->rxq->bd_dma);
  97 
  98         /* Configure debug, for integration */
  99         if (!iwl_trans_dbg_ini_valid(trans))
 100                 iwl_pcie_alloc_fw_monitor(trans, 0);
 101         if (trans->dbg.num_blocks) {
 102                 prph_sc_ctrl->hwm_cfg.hwm_base_addr =
 103                         cpu_to_le64(trans->dbg.fw_mon[0].physical);
 104                 prph_sc_ctrl->hwm_cfg.hwm_size =
 105                         cpu_to_le32(trans->dbg.fw_mon[0].size);
 106         }
 107 
 108         /* allocate ucode sections in dram and set addresses */
 109         ret = iwl_pcie_init_fw_sec(trans, fw, &prph_scratch->dram);
 110         if (ret)
 111                 goto err_free_prph_scratch;
 112 
 113 
 114         /* Allocate prph information
 115          * currently we don't assign to the prph info anything, but it would get
 116          * assigned later */
 117         prph_info = dma_alloc_coherent(trans->dev, sizeof(*prph_info),
 118                                        &trans_pcie->prph_info_dma_addr,
 119                                        GFP_KERNEL);
 120         if (!prph_info) {
 121                 ret = -ENOMEM;
 122                 goto err_free_prph_scratch;
 123         }
 124 
 125         /* Allocate context info */
 126         ctxt_info_gen3 = dma_alloc_coherent(trans->dev,
 127                                             sizeof(*ctxt_info_gen3),
 128                                             &trans_pcie->ctxt_info_dma_addr,
 129                                             GFP_KERNEL);
 130         if (!ctxt_info_gen3) {
 131                 ret = -ENOMEM;
 132                 goto err_free_prph_info;
 133         }
 134 
 135         ctxt_info_gen3->prph_info_base_addr =
 136                 cpu_to_le64(trans_pcie->prph_info_dma_addr);
 137         ctxt_info_gen3->prph_scratch_base_addr =
 138                 cpu_to_le64(trans_pcie->prph_scratch_dma_addr);
 139         ctxt_info_gen3->prph_scratch_size =
 140                 cpu_to_le32(sizeof(*prph_scratch));
 141         ctxt_info_gen3->cr_head_idx_arr_base_addr =
 142                 cpu_to_le64(trans_pcie->rxq->rb_stts_dma);
 143         ctxt_info_gen3->tr_tail_idx_arr_base_addr =
 144                 cpu_to_le64(trans_pcie->rxq->tr_tail_dma);
 145         ctxt_info_gen3->cr_tail_idx_arr_base_addr =
 146                 cpu_to_le64(trans_pcie->rxq->cr_tail_dma);
 147         ctxt_info_gen3->cr_idx_arr_size =
 148                 cpu_to_le16(IWL_NUM_OF_COMPLETION_RINGS);
 149         ctxt_info_gen3->tr_idx_arr_size =
 150                 cpu_to_le16(IWL_NUM_OF_TRANSFER_RINGS);
 151         ctxt_info_gen3->mtr_base_addr =
 152                 cpu_to_le64(trans_pcie->txq[trans_pcie->cmd_queue]->dma_addr);
 153         ctxt_info_gen3->mcr_base_addr =
 154                 cpu_to_le64(trans_pcie->rxq->used_bd_dma);
 155         ctxt_info_gen3->mtr_size =
 156                 cpu_to_le16(TFD_QUEUE_CB_SIZE(cmdq_size));
 157         ctxt_info_gen3->mcr_size =
 158                 cpu_to_le16(RX_QUEUE_CB_SIZE(MQ_RX_TABLE_SIZE));
 159 
 160         trans_pcie->ctxt_info_gen3 = ctxt_info_gen3;
 161         trans_pcie->prph_info = prph_info;
 162         trans_pcie->prph_scratch = prph_scratch;
 163 
 164         /* Allocate IML */
 165         iml_img = dma_alloc_coherent(trans->dev, trans->iml_len,
 166                                      &trans_pcie->iml_dma_addr, GFP_KERNEL);
 167         if (!iml_img)
 168                 return -ENOMEM;
 169 
 170         memcpy(iml_img, trans->iml, trans->iml_len);
 171 
 172         iwl_enable_fw_load_int_ctx_info(trans);
 173 
 174         /* kick FW self load */
 175         iwl_write64(trans, CSR_CTXT_INFO_ADDR,
 176                     trans_pcie->ctxt_info_dma_addr);
 177         iwl_write64(trans, CSR_IML_DATA_ADDR,
 178                     trans_pcie->iml_dma_addr);
 179         iwl_write32(trans, CSR_IML_SIZE_ADDR, trans->iml_len);
 180 
 181         iwl_set_bit(trans, CSR_CTXT_INFO_BOOT_CTRL,
 182                     CSR_AUTO_FUNC_BOOT_ENA);
 183         if (trans->trans_cfg->device_family >= IWL_DEVICE_FAMILY_AX210)
 184                 iwl_write_umac_prph(trans, UREG_CPU_INIT_RUN, 1);
 185         else
 186                 iwl_set_bit(trans, CSR_GP_CNTRL, CSR_AUTO_FUNC_INIT);
 187 
 188         return 0;
 189 
 190 err_free_prph_info:
 191         dma_free_coherent(trans->dev,
 192                           sizeof(*prph_info),
 193                         prph_info,
 194                         trans_pcie->prph_info_dma_addr);
 195 
 196 err_free_prph_scratch:
 197         dma_free_coherent(trans->dev,
 198                           sizeof(*prph_scratch),
 199                         prph_scratch,
 200                         trans_pcie->prph_scratch_dma_addr);
 201         return ret;
 202 
 203 }
 204 
 205 void iwl_pcie_ctxt_info_gen3_free(struct iwl_trans *trans)
 206 {
 207         struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
 208 
 209         if (!trans_pcie->ctxt_info_gen3)
 210                 return;
 211 
 212         dma_free_coherent(trans->dev, sizeof(*trans_pcie->ctxt_info_gen3),
 213                           trans_pcie->ctxt_info_gen3,
 214                           trans_pcie->ctxt_info_dma_addr);
 215         trans_pcie->ctxt_info_dma_addr = 0;
 216         trans_pcie->ctxt_info_gen3 = NULL;
 217 
 218         iwl_pcie_ctxt_info_free_fw_img(trans);
 219 
 220         dma_free_coherent(trans->dev, sizeof(*trans_pcie->prph_scratch),
 221                           trans_pcie->prph_scratch,
 222                           trans_pcie->prph_scratch_dma_addr);
 223         trans_pcie->prph_scratch_dma_addr = 0;
 224         trans_pcie->prph_scratch = NULL;
 225 
 226         dma_free_coherent(trans->dev, sizeof(*trans_pcie->prph_info),
 227                           trans_pcie->prph_info,
 228                           trans_pcie->prph_info_dma_addr);
 229         trans_pcie->prph_info_dma_addr = 0;
 230         trans_pcie->prph_info = NULL;
 231 }

/* [<][>][^][v][top][bottom][index][help] */