aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2012-09-24 14:37:36 -0400
committerJohn W. Linville <linville@tuxdriver.com>2012-09-24 14:37:36 -0400
commite5a876250d05d9708895da3d5408bdf67f1180f3 (patch)
tree92f2c844912ebd4d91741980a2cd56544c2906d7 /drivers
parent9b4e9e756541fd5d1223b323ed5a8a8545dd11cd (diff)
parent83f84d7bd49f9e4deea0a77a76c9882673ee1f3c (diff)
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-next
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/ucode.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c26
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h3
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c13
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h2
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c75
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c84
7 files changed, 117 insertions, 90 deletions
diff --git a/drivers/net/wireless/iwlwifi/dvm/ucode.c b/drivers/net/wireless/iwlwifi/dvm/ucode.c
index 6d8d6dd7943f..2cb1efbc5ed1 100644
--- a/drivers/net/wireless/iwlwifi/dvm/ucode.c
+++ b/drivers/net/wireless/iwlwifi/dvm/ucode.c
@@ -295,7 +295,7 @@ static int iwl_alive_notify(struct iwl_priv *priv)
295static int iwl_verify_sec_sparse(struct iwl_priv *priv, 295static int iwl_verify_sec_sparse(struct iwl_priv *priv,
296 const struct fw_desc *fw_desc) 296 const struct fw_desc *fw_desc)
297{ 297{
298 __le32 *image = (__le32 *)fw_desc->v_addr; 298 __le32 *image = (__le32 *)fw_desc->data;
299 u32 len = fw_desc->len; 299 u32 len = fw_desc->len;
300 u32 val; 300 u32 val;
301 u32 i; 301 u32 i;
@@ -319,7 +319,7 @@ static int iwl_verify_sec_sparse(struct iwl_priv *priv,
319static void iwl_print_mismatch_sec(struct iwl_priv *priv, 319static void iwl_print_mismatch_sec(struct iwl_priv *priv,
320 const struct fw_desc *fw_desc) 320 const struct fw_desc *fw_desc)
321{ 321{
322 __le32 *image = (__le32 *)fw_desc->v_addr; 322 __le32 *image = (__le32 *)fw_desc->data;
323 u32 len = fw_desc->len; 323 u32 len = fw_desc->len;
324 u32 val; 324 u32 val;
325 u32 offs; 325 u32 offs;
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index 48d6d44c16d0..198634b75ed0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -64,6 +64,7 @@
64#include <linux/dma-mapping.h> 64#include <linux/dma-mapping.h>
65#include <linux/firmware.h> 65#include <linux/firmware.h>
66#include <linux/module.h> 66#include <linux/module.h>
67#include <linux/vmalloc.h>
67 68
68#include "iwl-drv.h" 69#include "iwl-drv.h"
69#include "iwl-debug.h" 70#include "iwl-debug.h"
@@ -164,10 +165,8 @@ struct fw_sec {
164 165
165static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc) 166static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc)
166{ 167{
167 if (desc->v_addr) 168 vfree(desc->data);
168 dma_free_coherent(drv->trans->dev, desc->len, 169 desc->data = NULL;
169 desc->v_addr, desc->p_addr);
170 desc->v_addr = NULL;
171 desc->len = 0; 170 desc->len = 0;
172} 171}
173 172
@@ -186,21 +185,24 @@ static void iwl_dealloc_ucode(struct iwl_drv *drv)
186} 185}
187 186
188static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc, 187static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc,
189 struct fw_sec *sec) 188 struct fw_sec *sec)
190{ 189{
191 if (!sec || !sec->size) { 190 void *data;
192 desc->v_addr = NULL; 191
192 desc->data = NULL;
193
194 if (!sec || !sec->size)
193 return -EINVAL; 195 return -EINVAL;
194 }
195 196
196 desc->v_addr = dma_alloc_coherent(drv->trans->dev, sec->size, 197 data = vmalloc(sec->size);
197 &desc->p_addr, GFP_KERNEL); 198 if (!data)
198 if (!desc->v_addr)
199 return -ENOMEM; 199 return -ENOMEM;
200 200
201 desc->len = sec->size; 201 desc->len = sec->size;
202 desc->offset = sec->offset; 202 desc->offset = sec->offset;
203 memcpy(desc->v_addr, sec->data, sec->size); 203 memcpy(data, sec->data, desc->len);
204 desc->data = data;
205
204 return 0; 206 return 0;
205} 207}
206 208
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index 2153e4cc5572..d1a86b66bc51 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -124,8 +124,7 @@ struct iwl_ucode_capabilities {
124 124
125/* one for each uCode image (inst/data, init/runtime/wowlan) */ 125/* one for each uCode image (inst/data, init/runtime/wowlan) */
126struct fw_desc { 126struct fw_desc {
127 dma_addr_t p_addr; /* hardware address */ 127 const void *data; /* vmalloc'ed data */
128 void *v_addr; /* software address */
129 u32 len; /* size in bytes */ 128 u32 len; /* size in bytes */
130 u32 offset; /* offset in the device */ 129 u32 offset; /* offset in the device */
131}; 130};
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index 89bfb43f4946..2a4675396707 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -263,8 +263,6 @@ MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids);
263/* PCI registers */ 263/* PCI registers */
264#define PCI_CFG_RETRY_TIMEOUT 0x041 264#define PCI_CFG_RETRY_TIMEOUT 0x041
265 265
266#ifndef CONFIG_IWLWIFI_IDI
267
268static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 266static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
269{ 267{
270 const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); 268 const struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
@@ -307,8 +305,6 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
307 pci_set_drvdata(pdev, NULL); 305 pci_set_drvdata(pdev, NULL);
308} 306}
309 307
310#endif /* CONFIG_IWLWIFI_IDI */
311
312#ifdef CONFIG_PM_SLEEP 308#ifdef CONFIG_PM_SLEEP
313 309
314static int iwl_pci_suspend(struct device *device) 310static int iwl_pci_suspend(struct device *device)
@@ -353,15 +349,6 @@ static SIMPLE_DEV_PM_OPS(iwl_dev_pm_ops, iwl_pci_suspend, iwl_pci_resume);
353 349
354#endif 350#endif
355 351
356#ifdef CONFIG_IWLWIFI_IDI
357/*
358 * Defined externally in iwl-idi.c
359 */
360int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
361void __devexit iwl_pci_remove(struct pci_dev *pdev);
362
363#endif /* CONFIG_IWLWIFI_IDI */
364
365static struct pci_driver iwl_pci_driver = { 352static struct pci_driver iwl_pci_driver = {
366 .name = DRV_NAME, 353 .name = DRV_NAME,
367 .id_table = iwl_hw_card_ids, 354 .id_table = iwl_hw_card_ids,
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index 71c79943e633..401178f44a3b 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -311,7 +311,7 @@ void iwl_trans_pcie_free(struct iwl_trans *trans);
311******************************************************/ 311******************************************************/
312void iwl_bg_rx_replenish(struct work_struct *data); 312void iwl_bg_rx_replenish(struct work_struct *data);
313void iwl_irq_tasklet(struct iwl_trans *trans); 313void iwl_irq_tasklet(struct iwl_trans *trans);
314void iwlagn_rx_replenish(struct iwl_trans *trans); 314void iwl_rx_replenish(struct iwl_trans *trans);
315void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans, 315void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans,
316 struct iwl_rx_queue *q); 316 struct iwl_rx_queue *q);
317 317
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index 498372008810..17c8e5d82681 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -35,10 +35,6 @@
35#include "internal.h" 35#include "internal.h"
36#include "iwl-op-mode.h" 36#include "iwl-op-mode.h"
37 37
38#ifdef CONFIG_IWLWIFI_IDI
39#include "iwl-amfh.h"
40#endif
41
42/****************************************************************************** 38/******************************************************************************
43 * 39 *
44 * RX path functions 40 * RX path functions
@@ -181,15 +177,15 @@ void iwl_rx_queue_update_write_ptr(struct iwl_trans *trans,
181} 177}
182 178
183/** 179/**
184 * iwlagn_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr 180 * iwl_dma_addr2rbd_ptr - convert a DMA address to a uCode read buffer ptr
185 */ 181 */
186static inline __le32 iwlagn_dma_addr2rbd_ptr(dma_addr_t dma_addr) 182static inline __le32 iwl_dma_addr2rbd_ptr(dma_addr_t dma_addr)
187{ 183{
188 return cpu_to_le32((u32)(dma_addr >> 8)); 184 return cpu_to_le32((u32)(dma_addr >> 8));
189} 185}
190 186
191/** 187/**
192 * iwlagn_rx_queue_restock - refill RX queue from pre-allocated pool 188 * iwl_rx_queue_restock - refill RX queue from pre-allocated pool
193 * 189 *
194 * If there are slots in the RX queue that need to be restocked, 190 * If there are slots in the RX queue that need to be restocked,
195 * and we have free pre-allocated buffers, fill the ranks as much 191 * and we have free pre-allocated buffers, fill the ranks as much
@@ -199,7 +195,7 @@ static inline __le32 iwlagn_dma_addr2rbd_ptr(dma_addr_t dma_addr)
199 * also updates the memory address in the firmware to reference the new 195 * also updates the memory address in the firmware to reference the new
200 * target buffer. 196 * target buffer.
201 */ 197 */
202static void iwlagn_rx_queue_restock(struct iwl_trans *trans) 198static void iwl_rx_queue_restock(struct iwl_trans *trans)
203{ 199{
204 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 200 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
205 struct iwl_rx_queue *rxq = &trans_pcie->rxq; 201 struct iwl_rx_queue *rxq = &trans_pcie->rxq;
@@ -207,6 +203,17 @@ static void iwlagn_rx_queue_restock(struct iwl_trans *trans)
207 struct iwl_rx_mem_buffer *rxb; 203 struct iwl_rx_mem_buffer *rxb;
208 unsigned long flags; 204 unsigned long flags;
209 205
206 /*
207 * If the device isn't enabled - not need to try to add buffers...
208 * This can happen when we stop the device and still have an interrupt
209 * pending. We stop the APM before we sync the interrupts / tasklets
210 * because we have to (see comment there). On the other hand, since
211 * the APM is stopped, we cannot access the HW (in particular not prph).
212 * So don't try to restock if the APM has been already stopped.
213 */
214 if (!test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status))
215 return;
216
210 spin_lock_irqsave(&rxq->lock, flags); 217 spin_lock_irqsave(&rxq->lock, flags);
211 while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) { 218 while ((iwl_rx_queue_space(rxq) > 0) && (rxq->free_count)) {
212 /* The overwritten rxb must be a used one */ 219 /* The overwritten rxb must be a used one */
@@ -219,7 +226,7 @@ static void iwlagn_rx_queue_restock(struct iwl_trans *trans)
219 list_del(element); 226 list_del(element);
220 227
221 /* Point to Rx buffer via next RBD in circular buffer */ 228 /* Point to Rx buffer via next RBD in circular buffer */
222 rxq->bd[rxq->write] = iwlagn_dma_addr2rbd_ptr(rxb->page_dma); 229 rxq->bd[rxq->write] = iwl_dma_addr2rbd_ptr(rxb->page_dma);
223 rxq->queue[rxq->write] = rxb; 230 rxq->queue[rxq->write] = rxb;
224 rxq->write = (rxq->write + 1) & RX_QUEUE_MASK; 231 rxq->write = (rxq->write + 1) & RX_QUEUE_MASK;
225 rxq->free_count--; 232 rxq->free_count--;
@@ -230,7 +237,6 @@ static void iwlagn_rx_queue_restock(struct iwl_trans *trans)
230 if (rxq->free_count <= RX_LOW_WATERMARK) 237 if (rxq->free_count <= RX_LOW_WATERMARK)
231 schedule_work(&trans_pcie->rx_replenish); 238 schedule_work(&trans_pcie->rx_replenish);
232 239
233
234 /* If we've added more space for the firmware to place data, tell it. 240 /* If we've added more space for the firmware to place data, tell it.
235 * Increment device's write pointer in multiples of 8. */ 241 * Increment device's write pointer in multiples of 8. */
236 if (rxq->write_actual != (rxq->write & ~0x7)) { 242 if (rxq->write_actual != (rxq->write & ~0x7)) {
@@ -241,15 +247,16 @@ static void iwlagn_rx_queue_restock(struct iwl_trans *trans)
241 } 247 }
242} 248}
243 249
244/** 250/*
245 * iwlagn_rx_replenish - Move all used packet from rx_used to rx_free 251 * iwl_rx_allocate - allocate a page for each used RBD
246 *
247 * When moving to rx_free an SKB is allocated for the slot.
248 * 252 *
249 * Also restock the Rx queue via iwl_rx_queue_restock. 253 * A used RBD is an Rx buffer that has been given to the stack. To use it again
250 * This is called as a scheduled work item (except for during initialization) 254 * a page must be allocated and the RBD must point to the page. This function
255 * doesn't change the HW pointer but handles the list of pages that is used by
256 * iwl_rx_queue_restock. The latter function will update the HW to use the newly
257 * allocated buffers.
251 */ 258 */
252static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority) 259static void iwl_rx_allocate(struct iwl_trans *trans, gfp_t priority)
253{ 260{
254 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 261 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
255 struct iwl_rx_queue *rxq = &trans_pcie->rxq; 262 struct iwl_rx_queue *rxq = &trans_pcie->rxq;
@@ -328,23 +335,31 @@ static void iwlagn_rx_allocate(struct iwl_trans *trans, gfp_t priority)
328 } 335 }
329} 336}
330 337
331void iwlagn_rx_replenish(struct iwl_trans *trans) 338/*
339 * iwl_rx_replenish - Move all used buffers from rx_used to rx_free
340 *
341 * When moving to rx_free an page is allocated for the slot.
342 *
343 * Also restock the Rx queue via iwl_rx_queue_restock.
344 * This is called as a scheduled work item (except for during initialization)
345 */
346void iwl_rx_replenish(struct iwl_trans *trans)
332{ 347{
333 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 348 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
334 unsigned long flags; 349 unsigned long flags;
335 350
336 iwlagn_rx_allocate(trans, GFP_KERNEL); 351 iwl_rx_allocate(trans, GFP_KERNEL);
337 352
338 spin_lock_irqsave(&trans_pcie->irq_lock, flags); 353 spin_lock_irqsave(&trans_pcie->irq_lock, flags);
339 iwlagn_rx_queue_restock(trans); 354 iwl_rx_queue_restock(trans);
340 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 355 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
341} 356}
342 357
343static void iwlagn_rx_replenish_now(struct iwl_trans *trans) 358static void iwl_rx_replenish_now(struct iwl_trans *trans)
344{ 359{
345 iwlagn_rx_allocate(trans, GFP_ATOMIC); 360 iwl_rx_allocate(trans, GFP_ATOMIC);
346 361
347 iwlagn_rx_queue_restock(trans); 362 iwl_rx_queue_restock(trans);
348} 363}
349 364
350void iwl_bg_rx_replenish(struct work_struct *data) 365void iwl_bg_rx_replenish(struct work_struct *data)
@@ -352,7 +367,7 @@ void iwl_bg_rx_replenish(struct work_struct *data)
352 struct iwl_trans_pcie *trans_pcie = 367 struct iwl_trans_pcie *trans_pcie =
353 container_of(data, struct iwl_trans_pcie, rx_replenish); 368 container_of(data, struct iwl_trans_pcie, rx_replenish);
354 369
355 iwlagn_rx_replenish(trans_pcie->trans); 370 iwl_rx_replenish(trans_pcie->trans);
356} 371}
357 372
358static void iwl_rx_handle_rxbuf(struct iwl_trans *trans, 373static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,
@@ -530,7 +545,7 @@ static void iwl_rx_handle(struct iwl_trans *trans)
530 count++; 545 count++;
531 if (count >= 8) { 546 if (count >= 8) {
532 rxq->read = i; 547 rxq->read = i;
533 iwlagn_rx_replenish_now(trans); 548 iwl_rx_replenish_now(trans);
534 count = 0; 549 count = 0;
535 } 550 }
536 } 551 }
@@ -539,9 +554,9 @@ static void iwl_rx_handle(struct iwl_trans *trans)
539 /* Backtrack one entry */ 554 /* Backtrack one entry */
540 rxq->read = i; 555 rxq->read = i;
541 if (fill_rx) 556 if (fill_rx)
542 iwlagn_rx_replenish_now(trans); 557 iwl_rx_replenish_now(trans);
543 else 558 else
544 iwlagn_rx_queue_restock(trans); 559 iwl_rx_queue_restock(trans);
545} 560}
546 561
547/** 562/**
@@ -723,11 +738,9 @@ void iwl_irq_tasklet(struct iwl_trans *trans)
723 /* Disable periodic interrupt; we use it as just a one-shot. */ 738 /* Disable periodic interrupt; we use it as just a one-shot. */
724 iwl_write8(trans, CSR_INT_PERIODIC_REG, 739 iwl_write8(trans, CSR_INT_PERIODIC_REG,
725 CSR_INT_PERIODIC_DIS); 740 CSR_INT_PERIODIC_DIS);
726#ifdef CONFIG_IWLWIFI_IDI 741
727 iwl_amfh_rx_handler();
728#else
729 iwl_rx_handle(trans); 742 iwl_rx_handle(trans);
730#endif 743
731 /* 744 /*
732 * Enable periodic interrupt in 8 msec only if we received 745 * Enable periodic interrupt in 8 msec only if we received
733 * real RX interrupt (instead of just periodic int), to catch 746 * real RX interrupt (instead of just periodic int), to catch
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 848851177e7e..d0c0fe7edc2f 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -216,7 +216,7 @@ static int iwl_rx_init(struct iwl_trans *trans)
216 rxq->free_count = 0; 216 rxq->free_count = 0;
217 spin_unlock_irqrestore(&rxq->lock, flags); 217 spin_unlock_irqrestore(&rxq->lock, flags);
218 218
219 iwlagn_rx_replenish(trans); 219 iwl_rx_replenish(trans);
220 220
221 iwl_trans_rx_hw_init(trans, rxq); 221 iwl_trans_rx_hw_init(trans, rxq);
222 222
@@ -855,10 +855,8 @@ static int iwl_nic_init(struct iwl_trans *trans)
855 855
856 iwl_op_mode_nic_config(trans->op_mode); 856 iwl_op_mode_nic_config(trans->op_mode);
857 857
858#ifndef CONFIG_IWLWIFI_IDI
859 /* Allocate the RX queue, or reset if it is already allocated */ 858 /* Allocate the RX queue, or reset if it is already allocated */
860 iwl_rx_init(trans); 859 iwl_rx_init(trans);
861#endif
862 860
863 /* Allocate or reset and init all Tx and Command queues */ 861 /* Allocate or reset and init all Tx and Command queues */
864 if (iwl_tx_init(trans)) 862 if (iwl_tx_init(trans))
@@ -925,13 +923,10 @@ static int iwl_prepare_card_hw(struct iwl_trans *trans)
925/* 923/*
926 * ucode 924 * ucode
927 */ 925 */
928static int iwl_load_section(struct iwl_trans *trans, u8 section_num, 926static int iwl_load_firmware_chunk(struct iwl_trans *trans, u32 dst_addr,
929 const struct fw_desc *section) 927 dma_addr_t phy_addr, u32 byte_cnt)
930{ 928{
931 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 929 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
932 dma_addr_t phy_addr = section->p_addr;
933 u32 byte_cnt = section->len;
934 u32 dst_addr = section->offset;
935 int ret; 930 int ret;
936 931
937 trans_pcie->ucode_write_complete = false; 932 trans_pcie->ucode_write_complete = false;
@@ -945,8 +940,8 @@ static int iwl_load_section(struct iwl_trans *trans, u8 section_num,
945 dst_addr); 940 dst_addr);
946 941
947 iwl_write_direct32(trans, 942 iwl_write_direct32(trans,
948 FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL), 943 FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL),
949 phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK); 944 phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);
950 945
951 iwl_write_direct32(trans, 946 iwl_write_direct32(trans,
952 FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), 947 FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL),
@@ -965,33 +960,64 @@ static int iwl_load_section(struct iwl_trans *trans, u8 section_num,
965 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE | 960 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE |
966 FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD); 961 FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
967 962
968 IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n",
969 section_num);
970 ret = wait_event_timeout(trans_pcie->ucode_write_waitq, 963 ret = wait_event_timeout(trans_pcie->ucode_write_waitq,
971 trans_pcie->ucode_write_complete, 5 * HZ); 964 trans_pcie->ucode_write_complete, 5 * HZ);
972 if (!ret) { 965 if (!ret) {
973 IWL_ERR(trans, "Could not load the [%d] uCode section\n", 966 IWL_ERR(trans, "Failed to load firmware chunk!\n");
974 section_num);
975 return -ETIMEDOUT; 967 return -ETIMEDOUT;
976 } 968 }
977 969
978 return 0; 970 return 0;
979} 971}
980 972
981static int iwl_load_given_ucode(struct iwl_trans *trans, 973static int iwl_load_section(struct iwl_trans *trans, u8 section_num,
982 const struct fw_img *image) 974 const struct fw_desc *section)
983{ 975{
976 u8 *v_addr;
977 dma_addr_t p_addr;
978 u32 offset;
984 int ret = 0; 979 int ret = 0;
985 int i;
986 980
987 for (i = 0; i < IWL_UCODE_SECTION_MAX; i++) { 981 IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n",
988 if (!image->sec[i].p_addr) 982 section_num);
989 break;
990 983
991 ret = iwl_load_section(trans, i, &image->sec[i]); 984 v_addr = dma_alloc_coherent(trans->dev, PAGE_SIZE, &p_addr, GFP_KERNEL);
992 if (ret) 985 if (!v_addr)
993 return ret; 986 return -ENOMEM;
987
988 for (offset = 0; offset < section->len; offset += PAGE_SIZE) {
989 u32 copy_size;
990
991 copy_size = min_t(u32, PAGE_SIZE, section->len - offset);
992
993 memcpy(v_addr, (u8 *)section->data + offset, copy_size);
994 ret = iwl_load_firmware_chunk(trans, section->offset + offset,
995 p_addr, copy_size);
996 if (ret) {
997 IWL_ERR(trans,
998 "Could not load the [%d] uCode section\n",
999 section_num);
1000 break;
994 } 1001 }
1002 }
1003
1004 dma_free_coherent(trans->dev, PAGE_SIZE, v_addr, p_addr);
1005 return ret;
1006}
1007
1008static int iwl_load_given_ucode(struct iwl_trans *trans,
1009 const struct fw_img *image)
1010{
1011 int i, ret = 0;
1012
1013 for (i = 0; i < IWL_UCODE_SECTION_MAX; i++) {
1014 if (!image->sec[i].data)
1015 break;
1016
1017 ret = iwl_load_section(trans, i, &image->sec[i]);
1018 if (ret)
1019 return ret;
1020 }
995 1021
996 /* Remove all resets to allow NIC to operate */ 1022 /* Remove all resets to allow NIC to operate */
997 iwl_write32(trans, CSR_RESET, 0); 1023 iwl_write32(trans, CSR_RESET, 0);
@@ -1184,9 +1210,8 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
1184 */ 1210 */
1185 if (test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status)) { 1211 if (test_bit(STATUS_DEVICE_ENABLED, &trans_pcie->status)) {
1186 iwl_trans_tx_stop(trans); 1212 iwl_trans_tx_stop(trans);
1187#ifndef CONFIG_IWLWIFI_IDI
1188 iwl_trans_rx_stop(trans); 1213 iwl_trans_rx_stop(trans);
1189#endif 1214
1190 /* Power-down device's busmaster DMA clocks */ 1215 /* Power-down device's busmaster DMA clocks */
1191 iwl_write_prph(trans, APMG_CLK_DIS_REG, 1216 iwl_write_prph(trans, APMG_CLK_DIS_REG,
1192 APMG_CLK_VAL_DMA_CLK_RQT); 1217 APMG_CLK_VAL_DMA_CLK_RQT);
@@ -1456,14 +1481,16 @@ static void iwl_trans_pcie_stop_hw(struct iwl_trans *trans,
1456 bool hw_rfkill; 1481 bool hw_rfkill;
1457 unsigned long flags; 1482 unsigned long flags;
1458 1483
1484 spin_lock_irqsave(&trans_pcie->irq_lock, flags);
1485 iwl_disable_interrupts(trans);
1486 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
1487
1459 iwl_apm_stop(trans); 1488 iwl_apm_stop(trans);
1460 1489
1461 spin_lock_irqsave(&trans_pcie->irq_lock, flags); 1490 spin_lock_irqsave(&trans_pcie->irq_lock, flags);
1462 iwl_disable_interrupts(trans); 1491 iwl_disable_interrupts(trans);
1463 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags); 1492 spin_unlock_irqrestore(&trans_pcie->irq_lock, flags);
1464 1493
1465 iwl_write32(trans, CSR_INT, 0xFFFFFFFF);
1466
1467 if (!op_mode_leaving) { 1494 if (!op_mode_leaving) {
1468 /* 1495 /*
1469 * Even if we stop the HW, we still want the RF kill 1496 * Even if we stop the HW, we still want the RF kill
@@ -1551,9 +1578,8 @@ void iwl_trans_pcie_free(struct iwl_trans *trans)
1551 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 1578 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1552 1579
1553 iwl_trans_pcie_tx_free(trans); 1580 iwl_trans_pcie_tx_free(trans);
1554#ifndef CONFIG_IWLWIFI_IDI
1555 iwl_trans_pcie_rx_free(trans); 1581 iwl_trans_pcie_rx_free(trans);
1556#endif 1582
1557 if (trans_pcie->irq_requested == true) { 1583 if (trans_pcie->irq_requested == true) {
1558 free_irq(trans_pcie->irq, trans); 1584 free_irq(trans_pcie->irq, trans);
1559 iwl_free_isr_ict(trans); 1585 iwl_free_isr_ict(trans);