Lines Matching +full:block +full:- +full:copy

1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
3 * Copyright (C) 2012-2014, 2018-2019, 2021 Intel Corporation
4 * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
5 * Copyright (C) 2016-2017 Intel Deutschland GmbH
7 #include "iwl-drv.h"
15 if (!fwrt->fw_paging_db[0].fw_paging_block) in iwl_free_fw_paging()
19 struct iwl_fw_paging *paging = &fwrt->fw_paging_db[i]; in iwl_free_fw_paging()
21 if (!paging->fw_paging_block) { in iwl_free_fw_paging()
23 "Paging: block %d already freed, continue to next page\n", in iwl_free_fw_paging()
28 dma_unmap_page(fwrt->trans->dev, paging->fw_paging_phys, in iwl_free_fw_paging()
29 paging->fw_paging_size, DMA_BIDIRECTIONAL); in iwl_free_fw_paging()
31 __free_pages(paging->fw_paging_block, in iwl_free_fw_paging()
32 get_order(paging->fw_paging_size)); in iwl_free_fw_paging()
33 paging->fw_paging_block = NULL; in iwl_free_fw_paging()
36 memset(fwrt->fw_paging_db, 0, sizeof(fwrt->fw_paging_db)); in iwl_free_fw_paging()
43 struct page *block; in iwl_alloc_fw_paging_mem() local
47 if (fwrt->fw_paging_db[0].fw_paging_block) in iwl_alloc_fw_paging_mem()
53 num_of_pages = image->paging_mem_size / FW_PAGING_SIZE; in iwl_alloc_fw_paging_mem()
54 fwrt->num_of_paging_blk = in iwl_alloc_fw_paging_mem()
56 fwrt->num_of_pages_in_last_blk = in iwl_alloc_fw_paging_mem()
57 num_of_pages - in iwl_alloc_fw_paging_mem()
58 NUM_OF_PAGE_PER_GROUP * (fwrt->num_of_paging_blk - 1); in iwl_alloc_fw_paging_mem()
61 …"Paging: allocating mem for %d paging blocks, each block holds 8 pages, last block holds %d pages\… in iwl_alloc_fw_paging_mem()
62 fwrt->num_of_paging_blk, in iwl_alloc_fw_paging_mem()
63 fwrt->num_of_pages_in_last_blk); in iwl_alloc_fw_paging_mem()
68 for (blk_idx = 0; blk_idx < fwrt->num_of_paging_blk + 1; blk_idx++) { in iwl_alloc_fw_paging_mem()
72 block = alloc_pages(GFP_KERNEL, order); in iwl_alloc_fw_paging_mem()
73 if (!block) { in iwl_alloc_fw_paging_mem()
76 return -ENOMEM; in iwl_alloc_fw_paging_mem()
79 fwrt->fw_paging_db[blk_idx].fw_paging_block = block; in iwl_alloc_fw_paging_mem()
80 fwrt->fw_paging_db[blk_idx].fw_paging_size = size; in iwl_alloc_fw_paging_mem()
82 phys = dma_map_page(fwrt->trans->dev, block, 0, in iwl_alloc_fw_paging_mem()
85 if (dma_mapping_error(fwrt->trans->dev, phys)) { in iwl_alloc_fw_paging_mem()
91 return -ENOMEM; in iwl_alloc_fw_paging_mem()
93 fwrt->fw_paging_db[blk_idx].fw_paging_phys = phys; in iwl_alloc_fw_paging_mem()
118 * CPU1_CPU2_SEPARATOR_SECTION delimiter - separate between CPU1 to CPU2 in iwl_fill_paging_mem()
120 * PAGING_SEPARATOR_SECTION delimiter - separate between CPU2 in iwl_fill_paging_mem()
125 for (sec_idx = 0; sec_idx < image->num_sec; sec_idx++) { in iwl_fill_paging_mem()
126 if (image->sec[sec_idx].offset == PAGING_SEPARATOR_SECTION) { in iwl_fill_paging_mem()
136 if (sec_idx >= image->num_sec - 1) { in iwl_fill_paging_mem()
138 ret = -EINVAL; in iwl_fill_paging_mem()
142 /* copy the CSS block to the dram */ in iwl_fill_paging_mem()
146 if (image->sec[sec_idx].len > fwrt->fw_paging_db[0].fw_paging_size) { in iwl_fill_paging_mem()
147 IWL_ERR(fwrt, "CSS block is larger than paging size\n"); in iwl_fill_paging_mem()
148 ret = -EINVAL; in iwl_fill_paging_mem()
152 memcpy(page_address(fwrt->fw_paging_db[0].fw_paging_block), in iwl_fill_paging_mem()
153 image->sec[sec_idx].data, in iwl_fill_paging_mem()
154 image->sec[sec_idx].len); in iwl_fill_paging_mem()
155 fwrt->fw_paging_db[0].fw_offs = image->sec[sec_idx].offset; in iwl_fill_paging_mem()
156 dma_sync_single_for_device(fwrt->trans->dev, in iwl_fill_paging_mem()
157 fwrt->fw_paging_db[0].fw_paging_phys, in iwl_fill_paging_mem()
158 fwrt->fw_paging_db[0].fw_paging_size, in iwl_fill_paging_mem()
162 "Paging: copied %d CSS bytes to first block\n", in iwl_fill_paging_mem()
163 fwrt->fw_paging_db[0].fw_paging_size); in iwl_fill_paging_mem()
168 * Copy the paging blocks to the dram. The loop index starts in iwl_fill_paging_mem()
169 * from 1 since the CSS block (index 0) was already copied to in iwl_fill_paging_mem()
172 for (idx = 1; idx < fwrt->num_of_paging_blk + 1; idx++) { in iwl_fill_paging_mem()
173 struct iwl_fw_paging *block = &fwrt->fw_paging_db[idx]; in iwl_fill_paging_mem() local
174 int remaining = image->sec[sec_idx].len - offset; in iwl_fill_paging_mem()
175 int len = block->fw_paging_size; in iwl_fill_paging_mem()
178 * For the last block, we copy all that is remaining, in iwl_fill_paging_mem()
179 * for all other blocks, we copy fw_paging_size at a in iwl_fill_paging_mem()
181 if (idx == fwrt->num_of_paging_blk) { in iwl_fill_paging_mem()
184 fwrt->num_of_pages_in_last_blk * FW_PAGING_SIZE) { in iwl_fill_paging_mem()
186 "Paging: last block contains more data than expected %d\n", in iwl_fill_paging_mem()
188 ret = -EINVAL; in iwl_fill_paging_mem()
191 } else if (block->fw_paging_size > remaining) { in iwl_fill_paging_mem()
193 "Paging: not enough data in other in block %d (%d)\n", in iwl_fill_paging_mem()
195 ret = -EINVAL; in iwl_fill_paging_mem()
199 memcpy(page_address(block->fw_paging_block), in iwl_fill_paging_mem()
200 (const u8 *)image->sec[sec_idx].data + offset, len); in iwl_fill_paging_mem()
201 block->fw_offs = image->sec[sec_idx].offset + offset; in iwl_fill_paging_mem()
202 dma_sync_single_for_device(fwrt->trans->dev, in iwl_fill_paging_mem()
203 block->fw_paging_phys, in iwl_fill_paging_mem()
204 block->fw_paging_size, in iwl_fill_paging_mem()
208 "Paging: copied %d paging bytes to block %d\n", in iwl_fill_paging_mem()
211 offset += block->fw_paging_size; in iwl_fill_paging_mem()
240 (fwrt->num_of_pages_in_last_blk << in iwl_send_paging_cmd()
243 .block_num = cpu_to_le32(fwrt->num_of_paging_blk), in iwl_send_paging_cmd()
252 /* loop for for all paging blocks + CSS block */ in iwl_send_paging_cmd()
253 for (blk_idx = 0; blk_idx < fwrt->num_of_paging_blk + 1; blk_idx++) { in iwl_send_paging_cmd()
254 dma_addr_t addr = fwrt->fw_paging_db[blk_idx].fw_paging_phys; in iwl_send_paging_cmd()
262 return iwl_trans_send_cmd(fwrt->trans, &hcmd); in iwl_send_paging_cmd()
267 const struct fw_img *fw = &fwrt->fw->img[type]; in iwl_init_paging()
270 if (fwrt->trans->trans_cfg->gen2) in iwl_init_paging()
278 if (!fw->paging_mem_size) in iwl_init_paging()