aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/intel/iwlwifi/fw
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2017-11-11 08:37:22 -0500
committerDavid S. Miller <davem@davemloft.net>2017-11-11 08:37:22 -0500
commit7c5556decd0a629e9ee02e93653f75ba7b7da03c (patch)
treebc56819788e9226efc04a1d1710b99fa6d4512e4 /drivers/net/wireless/intel/iwlwifi/fw
parent39b175211053c7a6a4d794c42e225994f1c069c2 (diff)
parentfdd0bd88ceaecf729db103ac8836af5805dd2dc1 (diff)
Merge tag 'wireless-drivers-next-for-davem-2017-11-11' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next
Kalle Valo says: ==================== wireless-drivers-next patches for 4.15 Last minute patches before the merge window. Not really anything special standing out, mostly fixes or cleanup and some minor new features. Major changes: iwlwifi * some new PCI IDs ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/fw')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/api/paging.h24
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/file.h2
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/img.h8
-rw-r--r--drivers/net/wireless/intel/iwlwifi/fw/paging.c103
4 files changed, 13 insertions, 124 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/api/paging.h b/drivers/net/wireless/intel/iwlwifi/fw/api/paging.h
index e76f9cd4473d..721b9fed7201 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/api/paging.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/api/paging.h
@@ -81,28 +81,4 @@ struct iwl_fw_paging_cmd {
81 __le32 device_phy_addr[NUM_OF_FW_PAGING_BLOCKS]; 81 __le32 device_phy_addr[NUM_OF_FW_PAGING_BLOCKS];
82} __packed; /* FW_PAGING_BLOCK_CMD_API_S_VER_1 */ 82} __packed; /* FW_PAGING_BLOCK_CMD_API_S_VER_1 */
83 83
84/**
85 * enum iwl_fw_item_id - FW item IDs
86 *
87 * @IWL_FW_ITEM_ID_PAGING: Address of the pages that the FW will upload
88 * download
89 */
90enum iwl_fw_item_id {
91 IWL_FW_ITEM_ID_PAGING = 3,
92};
93
94/**
95 * struct iwl_fw_get_item_cmd - get an item from the fw
96 * @item_id: ID of item to obtain, see &enum iwl_fw_item_id
97 */
98struct iwl_fw_get_item_cmd {
99 __le32 item_id;
100} __packed; /* FW_GET_ITEM_CMD_API_S_VER_1 */
101
102struct iwl_fw_get_item_resp {
103 __le32 item_id;
104 __le32 item_byte_cnt;
105 __le32 item_val;
106} __packed; /* FW_GET_ITEM_RSP_S_VER_1 */
107
108#endif /* __iwl_fw_api_paging_h__ */ 84#endif /* __iwl_fw_api_paging_h__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h
index efd7fb65de8b..740d97093d1c 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/file.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h
@@ -136,7 +136,7 @@ enum iwl_ucode_tlv_type {
136 IWL_UCODE_TLV_N_SCAN_CHANNELS = 31, 136 IWL_UCODE_TLV_N_SCAN_CHANNELS = 31,
137 IWL_UCODE_TLV_PAGING = 32, 137 IWL_UCODE_TLV_PAGING = 32,
138 IWL_UCODE_TLV_SEC_RT_USNIFFER = 34, 138 IWL_UCODE_TLV_SEC_RT_USNIFFER = 34,
139 IWL_UCODE_TLV_SDIO_ADMA_ADDR = 35, 139 /* 35 is unused */
140 IWL_UCODE_TLV_FW_VERSION = 36, 140 IWL_UCODE_TLV_FW_VERSION = 36,
141 IWL_UCODE_TLV_FW_DBG_DEST = 38, 141 IWL_UCODE_TLV_FW_DBG_DEST = 38,
142 IWL_UCODE_TLV_FW_DBG_CONF = 39, 142 IWL_UCODE_TLV_FW_DBG_CONF = 39,
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/img.h b/drivers/net/wireless/intel/iwlwifi/fw/img.h
index e6bc9cb60700..985496cc01d0 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/img.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/img.h
@@ -138,11 +138,6 @@ struct fw_img {
138 u32 paging_mem_size; 138 u32 paging_mem_size;
139}; 139};
140 140
141struct iwl_sf_region {
142 u32 addr;
143 u32 size;
144};
145
146/* 141/*
147 * Block paging calculations 142 * Block paging calculations
148 */ 143 */
@@ -257,7 +252,6 @@ enum iwl_fw_type {
257 * @type: firmware type (&enum iwl_fw_type) 252 * @type: firmware type (&enum iwl_fw_type)
258 * @cipher_scheme: optional external cipher scheme. 253 * @cipher_scheme: optional external cipher scheme.
259 * @human_readable: human readable version 254 * @human_readable: human readable version
260 * @sdio_adma_addr: the default address to set for the ADMA in SDIO mode until
261 * we get the ALIVE from the uCode 255 * we get the ALIVE from the uCode
262 * @dbg_dest_tlv: points to the destination TLV for debug 256 * @dbg_dest_tlv: points to the destination TLV for debug
263 * @dbg_conf_tlv: array of pointers to configuration TLVs for debug 257 * @dbg_conf_tlv: array of pointers to configuration TLVs for debug
@@ -290,8 +284,6 @@ struct iwl_fw {
290 struct iwl_fw_cipher_scheme cs[IWL_UCODE_MAX_CS]; 284 struct iwl_fw_cipher_scheme cs[IWL_UCODE_MAX_CS];
291 u8 human_readable[FW_VER_HUMAN_READABLE_SZ]; 285 u8 human_readable[FW_VER_HUMAN_READABLE_SZ];
292 286
293 u32 sdio_adma_addr;
294
295 struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv; 287 struct iwl_fw_dbg_dest_tlv *dbg_dest_tlv;
296 struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX]; 288 struct iwl_fw_dbg_conf_tlv *dbg_conf_tlv[FW_DBG_CONF_MAX];
297 size_t dbg_conf_tlv_len[FW_DBG_CONF_MAX]; 289 size_t dbg_conf_tlv_len[FW_DBG_CONF_MAX];
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/paging.c b/drivers/net/wireless/intel/iwlwifi/fw/paging.c
index 1610722b8099..1fec8e3a6b35 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/paging.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/paging.c
@@ -87,9 +87,6 @@ void iwl_free_fw_paging(struct iwl_fw_runtime *fwrt)
87 get_order(paging->fw_paging_size)); 87 get_order(paging->fw_paging_size));
88 paging->fw_paging_block = NULL; 88 paging->fw_paging_block = NULL;
89 } 89 }
90 kfree(fwrt->trans->paging_download_buf);
91 fwrt->trans->paging_download_buf = NULL;
92 fwrt->trans->paging_db = NULL;
93 90
94 memset(fwrt->fw_paging_db, 0, sizeof(fwrt->fw_paging_db)); 91 memset(fwrt->fw_paging_db, 0, sizeof(fwrt->fw_paging_db));
95} 92}
@@ -100,13 +97,11 @@ static int iwl_alloc_fw_paging_mem(struct iwl_fw_runtime *fwrt,
100{ 97{
101 struct page *block; 98 struct page *block;
102 dma_addr_t phys = 0; 99 dma_addr_t phys = 0;
103 int blk_idx, order, num_of_pages, size, dma_enabled; 100 int blk_idx, order, num_of_pages, size;
104 101
105 if (fwrt->fw_paging_db[0].fw_paging_block) 102 if (fwrt->fw_paging_db[0].fw_paging_block)
106 return 0; 103 return 0;
107 104
108 dma_enabled = is_device_dma_capable(fwrt->trans->dev);
109
110 /* ensure BLOCK_2_EXP_SIZE is power of 2 of PAGING_BLOCK_SIZE */ 105 /* ensure BLOCK_2_EXP_SIZE is power of 2 of PAGING_BLOCK_SIZE */
111 BUILD_BUG_ON(BIT(BLOCK_2_EXP_SIZE) != PAGING_BLOCK_SIZE); 106 BUILD_BUG_ON(BIT(BLOCK_2_EXP_SIZE) != PAGING_BLOCK_SIZE);
112 107
@@ -139,24 +134,18 @@ static int iwl_alloc_fw_paging_mem(struct iwl_fw_runtime *fwrt,
139 fwrt->fw_paging_db[blk_idx].fw_paging_block = block; 134 fwrt->fw_paging_db[blk_idx].fw_paging_block = block;
140 fwrt->fw_paging_db[blk_idx].fw_paging_size = size; 135 fwrt->fw_paging_db[blk_idx].fw_paging_size = size;
141 136
142 if (dma_enabled) { 137 phys = dma_map_page(fwrt->trans->dev, block, 0,
143 phys = dma_map_page(fwrt->trans->dev, block, 0, 138 PAGE_SIZE << order,
144 PAGE_SIZE << order, 139 DMA_BIDIRECTIONAL);
145 DMA_BIDIRECTIONAL); 140 if (dma_mapping_error(fwrt->trans->dev, phys)) {
146 if (dma_mapping_error(fwrt->trans->dev, phys)) { 141 /*
147 /* 142 * free the previous pages and the current one
148 * free the previous pages and the current one 143 * since we failed to map_page.
149 * since we failed to map_page. 144 */
150 */ 145 iwl_free_fw_paging(fwrt);
151 iwl_free_fw_paging(fwrt); 146 return -ENOMEM;
152 return -ENOMEM;
153 }
154 fwrt->fw_paging_db[blk_idx].fw_paging_phys = phys;
155 } else {
156 fwrt->fw_paging_db[blk_idx].fw_paging_phys =
157 PAGING_ADDR_SIG |
158 blk_idx << BLOCK_2_EXP_SIZE;
159 } 147 }
148 fwrt->fw_paging_db[blk_idx].fw_paging_phys = phys;
160 149
161 if (!blk_idx) 150 if (!blk_idx)
162 IWL_DEBUG_FW(fwrt, 151 IWL_DEBUG_FW(fwrt,
@@ -312,60 +301,6 @@ static int iwl_send_paging_cmd(struct iwl_fw_runtime *fwrt,
312 return iwl_trans_send_cmd(fwrt->trans, &hcmd); 301 return iwl_trans_send_cmd(fwrt->trans, &hcmd);
313} 302}
314 303
315/*
316 * Send paging item cmd to FW in case CPU2 has paging image
317 */
318static int iwl_trans_get_paging_item(struct iwl_fw_runtime *fwrt)
319{
320 int ret;
321 struct iwl_fw_get_item_cmd fw_get_item_cmd = {
322 .item_id = cpu_to_le32(IWL_FW_ITEM_ID_PAGING),
323 };
324 struct iwl_fw_get_item_resp *item_resp;
325 struct iwl_host_cmd cmd = {
326 .id = iwl_cmd_id(FW_GET_ITEM_CMD, IWL_ALWAYS_LONG_GROUP, 0),
327 .flags = CMD_WANT_SKB | CMD_SEND_IN_RFKILL,
328 .data = { &fw_get_item_cmd, },
329 .len = { sizeof(fw_get_item_cmd), },
330 };
331
332 ret = iwl_trans_send_cmd(fwrt->trans, &cmd);
333 if (ret) {
334 IWL_ERR(fwrt,
335 "Paging: Failed to send FW_GET_ITEM_CMD cmd (err = %d)\n",
336 ret);
337 return ret;
338 }
339
340 item_resp = (void *)((struct iwl_rx_packet *)cmd.resp_pkt)->data;
341 if (item_resp->item_id != cpu_to_le32(IWL_FW_ITEM_ID_PAGING)) {
342 IWL_ERR(fwrt,
343 "Paging: got wrong item in FW_GET_ITEM_CMD resp (item_id = %u)\n",
344 le32_to_cpu(item_resp->item_id));
345 ret = -EIO;
346 goto exit;
347 }
348
349 /* Add an extra page for headers */
350 fwrt->trans->paging_download_buf = kzalloc(PAGING_BLOCK_SIZE +
351 FW_PAGING_SIZE,
352 GFP_KERNEL);
353 if (!fwrt->trans->paging_download_buf) {
354 ret = -ENOMEM;
355 goto exit;
356 }
357 fwrt->trans->paging_req_addr = le32_to_cpu(item_resp->item_val);
358 fwrt->trans->paging_db = fwrt->fw_paging_db;
359 IWL_DEBUG_FW(fwrt,
360 "Paging: got paging request address (paging_req_addr 0x%08x)\n",
361 fwrt->trans->paging_req_addr);
362
363exit:
364 iwl_free_resp(&cmd);
365
366 return ret;
367}
368
369int iwl_init_paging(struct iwl_fw_runtime *fwrt, enum iwl_ucode_type type) 304int iwl_init_paging(struct iwl_fw_runtime *fwrt, enum iwl_ucode_type type)
370{ 305{
371 const struct fw_img *fw = &fwrt->fw->img[type]; 306 const struct fw_img *fw = &fwrt->fw->img[type];
@@ -382,20 +317,6 @@ int iwl_init_paging(struct iwl_fw_runtime *fwrt, enum iwl_ucode_type type)
382 if (!fw->paging_mem_size) 317 if (!fw->paging_mem_size)
383 return 0; 318 return 0;
384 319
385 /*
386 * When dma is not enabled, the driver needs to copy / write
387 * the downloaded / uploaded page to / from the smem.
388 * This gets the location of the place were the pages are
389 * stored.
390 */
391 if (!is_device_dma_capable(fwrt->trans->dev)) {
392 ret = iwl_trans_get_paging_item(fwrt);
393 if (ret) {
394 IWL_ERR(fwrt, "failed to get FW paging item\n");
395 return ret;
396 }
397 }
398
399 ret = iwl_save_fw_paging(fwrt, fw); 320 ret = iwl_save_fw_paging(fwrt, fw);
400 if (ret) { 321 if (ret) {
401 IWL_ERR(fwrt, "failed to save the FW paging image\n"); 322 IWL_ERR(fwrt, "failed to save the FW paging image\n");