diff options
author | Ron Rindjunsky <ron.rindjunsky@intel.com> | 2008-05-04 22:22:43 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2008-05-14 16:29:46 -0400 |
commit | 1053d35f4ed6876ad9d3a14cdae363db0a7e9b0a (patch) | |
tree | 64c30d5add3bd5be8857803c06c2aedf71182c72 /drivers/net/wireless | |
parent | 5a676bbeaf9e534b75286f2294ec57a4c544f1d2 (diff) |
iwlwifi: move NIC init and Tx queues init to iwlcore
This patch does the following:
1 - change hw_nic_init from a handler to a function
2 - move hw_nic_init function to iwlcore
3 - open a new file - iwl-tx.c
4 - move all Tx queues initialization (part of NIC init) to iwl-tx.c
5 - move iwl_rx_init, previously as part of the NIC init, to iwl-rx.c
6 - iwl4965_tfd_frame rename to iwl_tfd_frame
Signed-off-by: Ron Rindjunsky <ron.rindjunsky@intel.com>
Signed-off-by: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/iwlwifi/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965-hw.h | 10 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 339 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 95 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 17 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-dev.h | 10 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-rx.c | 52 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-tx.c | 374 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl4965-base.c | 177 |
9 files changed, 550 insertions, 526 deletions
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile index 0211a7f7147d..85c8bf62d595 100644 --- a/drivers/net/wireless/iwlwifi/Makefile +++ b/drivers/net/wireless/iwlwifi/Makefile | |||
@@ -1,6 +1,6 @@ | |||
1 | obj-$(CONFIG_IWLCORE) += iwlcore.o | 1 | obj-$(CONFIG_IWLCORE) += iwlcore.o |
2 | iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o | 2 | iwlcore-objs := iwl-core.o iwl-eeprom.o iwl-hcmd.o iwl-power.o |
3 | iwlcore-objs += iwl-rx.o | 3 | iwlcore-objs += iwl-rx.o iwl-tx.o |
4 | iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o | 4 | iwlcore-$(CONFIG_IWLWIFI_DEBUGFS) += iwl-debugfs.o |
5 | iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o | 5 | iwlcore-$(CONFIG_IWLWIFI_LEDS) += iwl-led.o |
6 | iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o | 6 | iwlcore-$(CONFIG_IWLWIFI_RFKILL) += iwl-rfkill.o |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h index 29749e2a8ff0..ee55b283226b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965-hw.h +++ b/drivers/net/wireless/iwlwifi/iwl-4965-hw.h | |||
@@ -829,7 +829,7 @@ static inline __le32 iwl4965_hw_set_rate_n_flags(u8 rate, u16 flags) | |||
829 | #define IWL49_NUM_QUEUES 16 | 829 | #define IWL49_NUM_QUEUES 16 |
830 | 830 | ||
831 | /** | 831 | /** |
832 | * struct iwl4965_tfd_frame_data | 832 | * struct iwl_tfd_frame_data |
833 | * | 833 | * |
834 | * Describes up to 2 buffers containing (contiguous) portions of a Tx frame. | 834 | * Describes up to 2 buffers containing (contiguous) portions of a Tx frame. |
835 | * Each buffer must be on dword boundary. | 835 | * Each buffer must be on dword boundary. |
@@ -848,7 +848,7 @@ static inline __le32 iwl4965_hw_set_rate_n_flags(u8 rate, u16 flags) | |||
848 | * 31-20: Tx buffer 2 length (bytes) | 848 | * 31-20: Tx buffer 2 length (bytes) |
849 | * 19- 0: Tx buffer 2 address bits [35:16] | 849 | * 19- 0: Tx buffer 2 address bits [35:16] |
850 | */ | 850 | */ |
851 | struct iwl4965_tfd_frame_data { | 851 | struct iwl_tfd_frame_data { |
852 | __le32 tb1_addr; | 852 | __le32 tb1_addr; |
853 | 853 | ||
854 | __le32 val1; | 854 | __le32 val1; |
@@ -878,7 +878,7 @@ struct iwl4965_tfd_frame_data { | |||
878 | 878 | ||
879 | 879 | ||
880 | /** | 880 | /** |
881 | * struct iwl4965_tfd_frame | 881 | * struct iwl_tfd_frame |
882 | * | 882 | * |
883 | * Transmit Frame Descriptor (TFD) | 883 | * Transmit Frame Descriptor (TFD) |
884 | * | 884 | * |
@@ -905,7 +905,7 @@ struct iwl4965_tfd_frame_data { | |||
905 | * | 905 | * |
906 | * A maximum of 255 (not 256!) TFDs may be on a queue waiting for Tx. | 906 | * A maximum of 255 (not 256!) TFDs may be on a queue waiting for Tx. |
907 | */ | 907 | */ |
908 | struct iwl4965_tfd_frame { | 908 | struct iwl_tfd_frame { |
909 | __le32 val0; | 909 | __le32 val0; |
910 | /* __le32 rsvd1:24; */ | 910 | /* __le32 rsvd1:24; */ |
911 | /* __le32 num_tbs:5; */ | 911 | /* __le32 num_tbs:5; */ |
@@ -914,7 +914,7 @@ struct iwl4965_tfd_frame { | |||
914 | #define IWL_num_tbs_SYM val0 | 914 | #define IWL_num_tbs_SYM val0 |
915 | /* __le32 rsvd2:1; */ | 915 | /* __le32 rsvd2:1; */ |
916 | /* __le32 padding:2; */ | 916 | /* __le32 padding:2; */ |
917 | struct iwl4965_tfd_frame_data pa[10]; | 917 | struct iwl_tfd_frame_data pa[10]; |
918 | __le32 reserved; | 918 | __le32 reserved; |
919 | } __attribute__ ((packed)); | 919 | } __attribute__ ((packed)); |
920 | 920 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index 9e6f3e33ab66..319ffe747a70 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -53,8 +53,6 @@ static struct iwl_mod_params iwl4965_mod_params = { | |||
53 | /* the rest are 0 by default */ | 53 | /* the rest are 0 by default */ |
54 | }; | 54 | }; |
55 | 55 | ||
56 | static void iwl4965_hw_card_show_info(struct iwl_priv *priv); | ||
57 | |||
58 | #ifdef CONFIG_IWL4965_HT | 56 | #ifdef CONFIG_IWL4965_HT |
59 | 57 | ||
60 | static const u16 default_tid_to_tx_fifo[] = { | 58 | static const u16 default_tid_to_tx_fifo[] = { |
@@ -372,104 +370,6 @@ int iwl4965_set_pwr_src(struct iwl_priv *priv, enum iwl_pwr_src src) | |||
372 | return ret; | 370 | return ret; |
373 | } | 371 | } |
374 | 372 | ||
375 | static int iwl4965_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | ||
376 | { | ||
377 | int ret; | ||
378 | unsigned long flags; | ||
379 | unsigned int rb_size; | ||
380 | |||
381 | spin_lock_irqsave(&priv->lock, flags); | ||
382 | ret = iwl_grab_nic_access(priv); | ||
383 | if (ret) { | ||
384 | spin_unlock_irqrestore(&priv->lock, flags); | ||
385 | return ret; | ||
386 | } | ||
387 | |||
388 | if (priv->cfg->mod_params->amsdu_size_8K) | ||
389 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; | ||
390 | else | ||
391 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; | ||
392 | |||
393 | /* Stop Rx DMA */ | ||
394 | iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); | ||
395 | |||
396 | /* Reset driver's Rx queue write index */ | ||
397 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); | ||
398 | |||
399 | /* Tell device where to find RBD circular buffer in DRAM */ | ||
400 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG, | ||
401 | rxq->dma_addr >> 8); | ||
402 | |||
403 | /* Tell device where in DRAM to update its Rx status */ | ||
404 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG, | ||
405 | (priv->shared_phys + | ||
406 | offsetof(struct iwl4965_shared, rb_closed)) >> 4); | ||
407 | |||
408 | /* Enable Rx DMA, enable host interrupt, Rx buffer size 4k, 256 RBDs */ | ||
409 | iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, | ||
410 | FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | | ||
411 | FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | | ||
412 | rb_size | | ||
413 | /* 0x10 << 4 | */ | ||
414 | (RX_QUEUE_SIZE_LOG << | ||
415 | FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT)); | ||
416 | |||
417 | /* | ||
418 | * iwl_write32(priv,CSR_INT_COAL_REG,0); | ||
419 | */ | ||
420 | |||
421 | iwl_release_nic_access(priv); | ||
422 | spin_unlock_irqrestore(&priv->lock, flags); | ||
423 | |||
424 | return 0; | ||
425 | } | ||
426 | |||
427 | /* Tell 4965 where to find the "keep warm" buffer */ | ||
428 | static int iwl4965_kw_init(struct iwl_priv *priv) | ||
429 | { | ||
430 | unsigned long flags; | ||
431 | int rc; | ||
432 | |||
433 | spin_lock_irqsave(&priv->lock, flags); | ||
434 | rc = iwl_grab_nic_access(priv); | ||
435 | if (rc) | ||
436 | goto out; | ||
437 | |||
438 | iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, | ||
439 | priv->kw.dma_addr >> 4); | ||
440 | iwl_release_nic_access(priv); | ||
441 | out: | ||
442 | spin_unlock_irqrestore(&priv->lock, flags); | ||
443 | return rc; | ||
444 | } | ||
445 | |||
446 | static int iwl4965_kw_alloc(struct iwl_priv *priv) | ||
447 | { | ||
448 | struct pci_dev *dev = priv->pci_dev; | ||
449 | struct iwl4965_kw *kw = &priv->kw; | ||
450 | |||
451 | kw->size = IWL4965_KW_SIZE; /* TBW need set somewhere else */ | ||
452 | kw->v_addr = pci_alloc_consistent(dev, kw->size, &kw->dma_addr); | ||
453 | if (!kw->v_addr) | ||
454 | return -ENOMEM; | ||
455 | |||
456 | return 0; | ||
457 | } | ||
458 | |||
459 | /** | ||
460 | * iwl4965_kw_free - Free the "keep warm" buffer | ||
461 | */ | ||
462 | static void iwl4965_kw_free(struct iwl_priv *priv) | ||
463 | { | ||
464 | struct pci_dev *dev = priv->pci_dev; | ||
465 | struct iwl4965_kw *kw = &priv->kw; | ||
466 | |||
467 | if (kw->v_addr) { | ||
468 | pci_free_consistent(dev, kw->size, kw->v_addr, kw->dma_addr); | ||
469 | memset(kw, 0, sizeof(*kw)); | ||
470 | } | ||
471 | } | ||
472 | |||
473 | static int iwl4965_disable_tx_fifo(struct iwl_priv *priv) | 373 | static int iwl4965_disable_tx_fifo(struct iwl_priv *priv) |
474 | { | 374 | { |
475 | unsigned long flags; | 375 | unsigned long flags; |
@@ -491,65 +391,6 @@ static int iwl4965_disable_tx_fifo(struct iwl_priv *priv) | |||
491 | return 0; | 391 | return 0; |
492 | } | 392 | } |
493 | 393 | ||
494 | /** | ||
495 | * iwl4965_txq_ctx_reset - Reset TX queue context | ||
496 | * Destroys all DMA structures and initialise them again | ||
497 | * | ||
498 | * @param priv | ||
499 | * @return error code | ||
500 | */ | ||
501 | static int iwl4965_txq_ctx_reset(struct iwl_priv *priv) | ||
502 | { | ||
503 | int rc = 0; | ||
504 | int txq_id, slots_num; | ||
505 | |||
506 | iwl4965_kw_free(priv); | ||
507 | |||
508 | /* Free all tx/cmd queues and keep-warm buffer */ | ||
509 | iwl4965_hw_txq_ctx_free(priv); | ||
510 | |||
511 | /* Alloc keep-warm buffer */ | ||
512 | rc = iwl4965_kw_alloc(priv); | ||
513 | if (rc) { | ||
514 | IWL_ERROR("Keep Warm allocation failed"); | ||
515 | goto error_kw; | ||
516 | } | ||
517 | |||
518 | /* Turn off all Tx DMA fifos */ | ||
519 | rc = priv->cfg->ops->lib->disable_tx_fifo(priv); | ||
520 | if (unlikely(rc)) | ||
521 | goto error_reset; | ||
522 | |||
523 | /* Tell 4965 where to find the keep-warm buffer */ | ||
524 | rc = iwl4965_kw_init(priv); | ||
525 | if (rc) { | ||
526 | IWL_ERROR("kw_init failed\n"); | ||
527 | goto error_reset; | ||
528 | } | ||
529 | |||
530 | /* Alloc and init all (default 16) Tx queues, | ||
531 | * including the command queue (#4) */ | ||
532 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { | ||
533 | slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ? | ||
534 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; | ||
535 | rc = iwl4965_tx_queue_init(priv, &priv->txq[txq_id], slots_num, | ||
536 | txq_id); | ||
537 | if (rc) { | ||
538 | IWL_ERROR("Tx %d queue init failed\n", txq_id); | ||
539 | goto error; | ||
540 | } | ||
541 | } | ||
542 | |||
543 | return rc; | ||
544 | |||
545 | error: | ||
546 | iwl4965_hw_txq_ctx_free(priv); | ||
547 | error_reset: | ||
548 | iwl4965_kw_free(priv); | ||
549 | error_kw: | ||
550 | return rc; | ||
551 | } | ||
552 | |||
553 | static int iwl4965_apm_init(struct iwl_priv *priv) | 394 | static int iwl4965_apm_init(struct iwl_priv *priv) |
554 | { | 395 | { |
555 | unsigned long flags; | 396 | unsigned long flags; |
@@ -633,58 +474,6 @@ static void iwl4965_nic_config(struct iwl_priv *priv) | |||
633 | spin_unlock_irqrestore(&priv->lock, flags); | 474 | spin_unlock_irqrestore(&priv->lock, flags); |
634 | } | 475 | } |
635 | 476 | ||
636 | int iwl4965_hw_nic_init(struct iwl_priv *priv) | ||
637 | { | ||
638 | unsigned long flags; | ||
639 | struct iwl_rx_queue *rxq = &priv->rxq; | ||
640 | int ret; | ||
641 | |||
642 | /* nic_init */ | ||
643 | priv->cfg->ops->lib->apm_ops.init(priv); | ||
644 | |||
645 | spin_lock_irqsave(&priv->lock, flags); | ||
646 | iwl_write32(priv, CSR_INT_COALESCING, 512 / 32); | ||
647 | spin_unlock_irqrestore(&priv->lock, flags); | ||
648 | |||
649 | ret = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN); | ||
650 | |||
651 | priv->cfg->ops->lib->apm_ops.config(priv); | ||
652 | |||
653 | iwl4965_hw_card_show_info(priv); | ||
654 | |||
655 | /* end nic_init */ | ||
656 | |||
657 | /* Allocate the RX queue, or reset if it is already allocated */ | ||
658 | if (!rxq->bd) { | ||
659 | ret = iwl_rx_queue_alloc(priv); | ||
660 | if (ret) { | ||
661 | IWL_ERROR("Unable to initialize Rx queue\n"); | ||
662 | return -ENOMEM; | ||
663 | } | ||
664 | } else | ||
665 | iwl_rx_queue_reset(priv, rxq); | ||
666 | |||
667 | iwl_rx_replenish(priv); | ||
668 | |||
669 | iwl4965_rx_init(priv, rxq); | ||
670 | |||
671 | spin_lock_irqsave(&priv->lock, flags); | ||
672 | |||
673 | rxq->need_update = 1; | ||
674 | iwl_rx_queue_update_write_ptr(priv, rxq); | ||
675 | |||
676 | spin_unlock_irqrestore(&priv->lock, flags); | ||
677 | |||
678 | /* Allocate and init all Tx and Command queues */ | ||
679 | ret = iwl4965_txq_ctx_reset(priv); | ||
680 | if (ret) | ||
681 | return ret; | ||
682 | |||
683 | set_bit(STATUS_INIT, &priv->status); | ||
684 | |||
685 | return 0; | ||
686 | } | ||
687 | |||
688 | int iwl4965_hw_nic_stop_master(struct iwl_priv *priv) | 477 | int iwl4965_hw_nic_stop_master(struct iwl_priv *priv) |
689 | { | 478 | { |
690 | int rc = 0; | 479 | int rc = 0; |
@@ -745,7 +534,7 @@ void iwl4965_hw_txq_ctx_stop(struct iwl_priv *priv) | |||
745 | } | 534 | } |
746 | 535 | ||
747 | /* Deallocate memory for all Tx queues */ | 536 | /* Deallocate memory for all Tx queues */ |
748 | iwl4965_hw_txq_ctx_free(priv); | 537 | iwl_hw_txq_ctx_free(priv); |
749 | } | 538 | } |
750 | 539 | ||
751 | int iwl4965_hw_nic_reset(struct iwl_priv *priv) | 540 | int iwl4965_hw_nic_reset(struct iwl_priv *priv) |
@@ -1199,82 +988,6 @@ int iwl4965_hw_set_hw_params(struct iwl_priv *priv) | |||
1199 | return 0; | 988 | return 0; |
1200 | } | 989 | } |
1201 | 990 | ||
1202 | /** | ||
1203 | * iwl4965_hw_txq_ctx_free - Free TXQ Context | ||
1204 | * | ||
1205 | * Destroy all TX DMA queues and structures | ||
1206 | */ | ||
1207 | void iwl4965_hw_txq_ctx_free(struct iwl_priv *priv) | ||
1208 | { | ||
1209 | int txq_id; | ||
1210 | |||
1211 | /* Tx queues */ | ||
1212 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) | ||
1213 | iwl4965_tx_queue_free(priv, &priv->txq[txq_id]); | ||
1214 | |||
1215 | /* Keep-warm buffer */ | ||
1216 | iwl4965_kw_free(priv); | ||
1217 | } | ||
1218 | |||
1219 | /** | ||
1220 | * iwl4965_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] | ||
1221 | * | ||
1222 | * Does NOT advance any TFD circular buffer read/write indexes | ||
1223 | * Does NOT free the TFD itself (which is within circular buffer) | ||
1224 | */ | ||
1225 | int iwl4965_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl4965_tx_queue *txq) | ||
1226 | { | ||
1227 | struct iwl4965_tfd_frame *bd_tmp = (struct iwl4965_tfd_frame *)&txq->bd[0]; | ||
1228 | struct iwl4965_tfd_frame *bd = &bd_tmp[txq->q.read_ptr]; | ||
1229 | struct pci_dev *dev = priv->pci_dev; | ||
1230 | int i; | ||
1231 | int counter = 0; | ||
1232 | int index, is_odd; | ||
1233 | |||
1234 | /* Host command buffers stay mapped in memory, nothing to clean */ | ||
1235 | if (txq->q.id == IWL_CMD_QUEUE_NUM) | ||
1236 | return 0; | ||
1237 | |||
1238 | /* Sanity check on number of chunks */ | ||
1239 | counter = IWL_GET_BITS(*bd, num_tbs); | ||
1240 | if (counter > MAX_NUM_OF_TBS) { | ||
1241 | IWL_ERROR("Too many chunks: %i\n", counter); | ||
1242 | /* @todo issue fatal error, it is quite serious situation */ | ||
1243 | return 0; | ||
1244 | } | ||
1245 | |||
1246 | /* Unmap chunks, if any. | ||
1247 | * TFD info for odd chunks is different format than for even chunks. */ | ||
1248 | for (i = 0; i < counter; i++) { | ||
1249 | index = i / 2; | ||
1250 | is_odd = i & 0x1; | ||
1251 | |||
1252 | if (is_odd) | ||
1253 | pci_unmap_single( | ||
1254 | dev, | ||
1255 | IWL_GET_BITS(bd->pa[index], tb2_addr_lo16) | | ||
1256 | (IWL_GET_BITS(bd->pa[index], | ||
1257 | tb2_addr_hi20) << 16), | ||
1258 | IWL_GET_BITS(bd->pa[index], tb2_len), | ||
1259 | PCI_DMA_TODEVICE); | ||
1260 | |||
1261 | else if (i > 0) | ||
1262 | pci_unmap_single(dev, | ||
1263 | le32_to_cpu(bd->pa[index].tb1_addr), | ||
1264 | IWL_GET_BITS(bd->pa[index], tb1_len), | ||
1265 | PCI_DMA_TODEVICE); | ||
1266 | |||
1267 | /* Free SKB, if any, for this chunk */ | ||
1268 | if (txq->txb[txq->q.read_ptr].skb[i]) { | ||
1269 | struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[i]; | ||
1270 | |||
1271 | dev_kfree_skb(skb); | ||
1272 | txq->txb[txq->q.read_ptr].skb[i] = NULL; | ||
1273 | } | ||
1274 | } | ||
1275 | return 0; | ||
1276 | } | ||
1277 | |||
1278 | /* set card power command */ | 991 | /* set card power command */ |
1279 | static int iwl4965_set_power(struct iwl_priv *priv, | 992 | static int iwl4965_set_power(struct iwl_priv *priv, |
1280 | void *cmd) | 993 | void *cmd) |
@@ -2240,46 +1953,11 @@ unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, | |||
2240 | return (sizeof(*tx_beacon_cmd) + frame_size); | 1953 | return (sizeof(*tx_beacon_cmd) + frame_size); |
2241 | } | 1954 | } |
2242 | 1955 | ||
2243 | /* | ||
2244 | * Tell 4965 where to find circular buffer of Tx Frame Descriptors for | ||
2245 | * given Tx queue, and enable the DMA channel used for that queue. | ||
2246 | * | ||
2247 | * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA | ||
2248 | * channels supported in hardware. | ||
2249 | */ | ||
2250 | int iwl4965_hw_tx_queue_init(struct iwl_priv *priv, struct iwl4965_tx_queue *txq) | ||
2251 | { | ||
2252 | int rc; | ||
2253 | unsigned long flags; | ||
2254 | int txq_id = txq->q.id; | ||
2255 | |||
2256 | spin_lock_irqsave(&priv->lock, flags); | ||
2257 | rc = iwl_grab_nic_access(priv); | ||
2258 | if (rc) { | ||
2259 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2260 | return rc; | ||
2261 | } | ||
2262 | |||
2263 | /* Circular buffer (TFD queue in DRAM) physical base address */ | ||
2264 | iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id), | ||
2265 | txq->q.dma_addr >> 8); | ||
2266 | |||
2267 | /* Enable DMA channel, using same id as for TFD queue */ | ||
2268 | iwl_write_direct32( | ||
2269 | priv, FH_TCSR_CHNL_TX_CONFIG_REG(txq_id), | ||
2270 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | | ||
2271 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL); | ||
2272 | iwl_release_nic_access(priv); | ||
2273 | spin_unlock_irqrestore(&priv->lock, flags); | ||
2274 | |||
2275 | return 0; | ||
2276 | } | ||
2277 | |||
2278 | int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr, | 1956 | int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr, |
2279 | dma_addr_t addr, u16 len) | 1957 | dma_addr_t addr, u16 len) |
2280 | { | 1958 | { |
2281 | int index, is_odd; | 1959 | int index, is_odd; |
2282 | struct iwl4965_tfd_frame *tfd = ptr; | 1960 | struct iwl_tfd_frame *tfd = ptr; |
2283 | u32 num_tbs = IWL_GET_BITS(*tfd, num_tbs); | 1961 | u32 num_tbs = IWL_GET_BITS(*tfd, num_tbs); |
2284 | 1962 | ||
2285 | /* Each TFD can point to a maximum 20 Tx buffers */ | 1963 | /* Each TFD can point to a maximum 20 Tx buffers */ |
@@ -2309,18 +1987,6 @@ int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr, | |||
2309 | return 0; | 1987 | return 0; |
2310 | } | 1988 | } |
2311 | 1989 | ||
2312 | static void iwl4965_hw_card_show_info(struct iwl_priv *priv) | ||
2313 | { | ||
2314 | u16 hw_version = iwl_eeprom_query16(priv, EEPROM_4965_BOARD_REVISION); | ||
2315 | |||
2316 | IWL_DEBUG_INFO("4965ABGN HW Version %u.%u.%u\n", | ||
2317 | ((hw_version >> 8) & 0x0F), | ||
2318 | ((hw_version >> 8) >> 4), (hw_version & 0x00FF)); | ||
2319 | |||
2320 | IWL_DEBUG_INFO("4965ABGN PBA Number %.16s\n", | ||
2321 | &priv->eeprom[EEPROM_4965_BOARD_PBA]); | ||
2322 | } | ||
2323 | |||
2324 | static int iwl4965_alloc_shared_mem(struct iwl_priv *priv) | 1990 | static int iwl4965_alloc_shared_mem(struct iwl_priv *priv) |
2325 | { | 1991 | { |
2326 | priv->shared_virt = pci_alloc_consistent(priv->pci_dev, | 1992 | priv->shared_virt = pci_alloc_consistent(priv->pci_dev, |
@@ -4054,7 +3720,6 @@ static struct iwl_lib_ops iwl4965_lib = { | |||
4054 | .alloc_shared_mem = iwl4965_alloc_shared_mem, | 3720 | .alloc_shared_mem = iwl4965_alloc_shared_mem, |
4055 | .free_shared_mem = iwl4965_free_shared_mem, | 3721 | .free_shared_mem = iwl4965_free_shared_mem, |
4056 | .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl, | 3722 | .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl, |
4057 | .hw_nic_init = iwl4965_hw_nic_init, | ||
4058 | .disable_tx_fifo = iwl4965_disable_tx_fifo, | 3723 | .disable_tx_fifo = iwl4965_disable_tx_fifo, |
4059 | .rx_handler_setup = iwl4965_rx_handler_setup, | 3724 | .rx_handler_setup = iwl4965_rx_handler_setup, |
4060 | .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr, | 3725 | .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 2ff27a01cf66..4ba860741f81 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -121,6 +121,101 @@ void iwl_hw_detect(struct iwl_priv *priv) | |||
121 | } | 121 | } |
122 | EXPORT_SYMBOL(iwl_hw_detect); | 122 | EXPORT_SYMBOL(iwl_hw_detect); |
123 | 123 | ||
124 | /* Tell nic where to find the "keep warm" buffer */ | ||
125 | int iwl_kw_init(struct iwl_priv *priv) | ||
126 | { | ||
127 | unsigned long flags; | ||
128 | int ret; | ||
129 | |||
130 | spin_lock_irqsave(&priv->lock, flags); | ||
131 | ret = iwl_grab_nic_access(priv); | ||
132 | if (ret) | ||
133 | goto out; | ||
134 | |||
135 | iwl_write_direct32(priv, FH_KW_MEM_ADDR_REG, | ||
136 | priv->kw.dma_addr >> 4); | ||
137 | iwl_release_nic_access(priv); | ||
138 | out: | ||
139 | spin_unlock_irqrestore(&priv->lock, flags); | ||
140 | return ret; | ||
141 | } | ||
142 | |||
143 | int iwl_kw_alloc(struct iwl_priv *priv) | ||
144 | { | ||
145 | struct pci_dev *dev = priv->pci_dev; | ||
146 | struct iwl4965_kw *kw = &priv->kw; | ||
147 | |||
148 | kw->size = IWL4965_KW_SIZE; /* TBW need set somewhere else */ | ||
149 | kw->v_addr = pci_alloc_consistent(dev, kw->size, &kw->dma_addr); | ||
150 | if (!kw->v_addr) | ||
151 | return -ENOMEM; | ||
152 | |||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | /** | ||
157 | * iwl_kw_free - Free the "keep warm" buffer | ||
158 | */ | ||
159 | void iwl_kw_free(struct iwl_priv *priv) | ||
160 | { | ||
161 | struct pci_dev *dev = priv->pci_dev; | ||
162 | struct iwl4965_kw *kw = &priv->kw; | ||
163 | |||
164 | if (kw->v_addr) { | ||
165 | pci_free_consistent(dev, kw->size, kw->v_addr, kw->dma_addr); | ||
166 | memset(kw, 0, sizeof(*kw)); | ||
167 | } | ||
168 | } | ||
169 | |||
170 | int iwl_hw_nic_init(struct iwl_priv *priv) | ||
171 | { | ||
172 | unsigned long flags; | ||
173 | struct iwl_rx_queue *rxq = &priv->rxq; | ||
174 | int ret; | ||
175 | |||
176 | /* nic_init */ | ||
177 | priv->cfg->ops->lib->apm_ops.init(priv); | ||
178 | |||
179 | spin_lock_irqsave(&priv->lock, flags); | ||
180 | iwl_write32(priv, CSR_INT_COALESCING, 512 / 32); | ||
181 | spin_unlock_irqrestore(&priv->lock, flags); | ||
182 | |||
183 | ret = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN); | ||
184 | |||
185 | priv->cfg->ops->lib->apm_ops.config(priv); | ||
186 | |||
187 | /* Allocate the RX queue, or reset if it is already allocated */ | ||
188 | if (!rxq->bd) { | ||
189 | ret = iwl_rx_queue_alloc(priv); | ||
190 | if (ret) { | ||
191 | IWL_ERROR("Unable to initialize Rx queue\n"); | ||
192 | return -ENOMEM; | ||
193 | } | ||
194 | } else | ||
195 | iwl_rx_queue_reset(priv, rxq); | ||
196 | |||
197 | iwl_rx_replenish(priv); | ||
198 | |||
199 | iwl_rx_init(priv, rxq); | ||
200 | |||
201 | spin_lock_irqsave(&priv->lock, flags); | ||
202 | |||
203 | rxq->need_update = 1; | ||
204 | iwl_rx_queue_update_write_ptr(priv, rxq); | ||
205 | |||
206 | spin_unlock_irqrestore(&priv->lock, flags); | ||
207 | |||
208 | /* Allocate and init all Tx and Command queues */ | ||
209 | ret = iwl_txq_ctx_reset(priv); | ||
210 | if (ret) | ||
211 | return ret; | ||
212 | |||
213 | set_bit(STATUS_INIT, &priv->status); | ||
214 | |||
215 | return 0; | ||
216 | } | ||
217 | EXPORT_SYMBOL(iwl_hw_nic_init); | ||
218 | |||
124 | /** | 219 | /** |
125 | * iwlcore_clear_stations_table - Clear the driver's station table | 220 | * iwlcore_clear_stations_table - Clear the driver's station table |
126 | * | 221 | * |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index c29f8b347129..3a75dc6e35a2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -108,8 +108,6 @@ struct iwl_lib_ops { | |||
108 | u16 byte_cnt); | 108 | u16 byte_cnt); |
109 | /* setup Rx handler */ | 109 | /* setup Rx handler */ |
110 | void (*rx_handler_setup)(struct iwl_priv *priv); | 110 | void (*rx_handler_setup)(struct iwl_priv *priv); |
111 | /* nic init */ | ||
112 | int (*hw_nic_init)(struct iwl_priv *priv); | ||
113 | /* nic Tx fifo handling */ | 111 | /* nic Tx fifo handling */ |
114 | int (*disable_tx_fifo)(struct iwl_priv *priv); | 112 | int (*disable_tx_fifo)(struct iwl_priv *priv); |
115 | /* alive notification */ | 113 | /* alive notification */ |
@@ -178,6 +176,12 @@ int iwl_setup(struct iwl_priv *priv); | |||
178 | void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info); | 176 | void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_info *ht_info); |
179 | u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv, | 177 | u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv, |
180 | struct ieee80211_ht_info *sta_ht_inf); | 178 | struct ieee80211_ht_info *sta_ht_inf); |
179 | int iwl_hw_nic_init(struct iwl_priv *priv); | ||
180 | |||
181 | /* "keep warm" functions */ | ||
182 | int iwl_kw_init(struct iwl_priv *priv); | ||
183 | int iwl_kw_alloc(struct iwl_priv *priv); | ||
184 | void iwl_kw_free(struct iwl_priv *priv); | ||
181 | 185 | ||
182 | /***************************************************** | 186 | /***************************************************** |
183 | * RX | 187 | * RX |
@@ -189,12 +193,21 @@ int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, | |||
189 | struct iwl_rx_queue *q); | 193 | struct iwl_rx_queue *q); |
190 | void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); | 194 | void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq); |
191 | void iwl_rx_replenish(struct iwl_priv *priv); | 195 | void iwl_rx_replenish(struct iwl_priv *priv); |
196 | int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq); | ||
192 | /* FIXME: remove when TX is moved to iwl core */ | 197 | /* FIXME: remove when TX is moved to iwl core */ |
193 | int iwl_rx_queue_restock(struct iwl_priv *priv); | 198 | int iwl_rx_queue_restock(struct iwl_priv *priv); |
194 | int iwl_rx_queue_space(const struct iwl_rx_queue *q); | 199 | int iwl_rx_queue_space(const struct iwl_rx_queue *q); |
195 | void iwl_rx_allocate(struct iwl_priv *priv); | 200 | void iwl_rx_allocate(struct iwl_priv *priv); |
196 | 201 | ||
197 | /***************************************************** | 202 | /***************************************************** |
203 | * TX | ||
204 | ******************************************************/ | ||
205 | int iwl_txq_ctx_reset(struct iwl_priv *priv); | ||
206 | /* FIXME: remove when free Tx is fully merged into iwlcore */ | ||
207 | int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl4965_tx_queue *txq); | ||
208 | void iwl_hw_txq_ctx_free(struct iwl_priv *priv); | ||
209 | |||
210 | /***************************************************** | ||
198 | * S e n d i n g H o s t C o m m a n d s * | 211 | * S e n d i n g H o s t C o m m a n d s * |
199 | *****************************************************/ | 212 | *****************************************************/ |
200 | 213 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h index 23cae4c13459..e730583d88cc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-dev.h +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h | |||
@@ -138,7 +138,7 @@ struct iwl4965_tx_info { | |||
138 | */ | 138 | */ |
139 | struct iwl4965_tx_queue { | 139 | struct iwl4965_tx_queue { |
140 | struct iwl4965_queue q; | 140 | struct iwl4965_queue q; |
141 | struct iwl4965_tfd_frame *bd; | 141 | struct iwl_tfd_frame *bd; |
142 | struct iwl_cmd *cmd; | 142 | struct iwl_cmd *cmd; |
143 | dma_addr_t dma_addr_cmd; | 143 | dma_addr_t dma_addr_cmd; |
144 | struct iwl4965_tx_info *txb; | 144 | struct iwl4965_tx_info *txb; |
@@ -649,9 +649,6 @@ extern int iwl4965_is_duplicate_packet(struct iwl_priv *priv, | |||
649 | struct ieee80211_hdr *header); | 649 | struct ieee80211_hdr *header); |
650 | extern int iwl4965_calc_db_from_ratio(int sig_ratio); | 650 | extern int iwl4965_calc_db_from_ratio(int sig_ratio); |
651 | extern int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm); | 651 | extern int iwl4965_calc_sig_qual(int rssi_dbm, int noise_dbm); |
652 | extern int iwl4965_tx_queue_init(struct iwl_priv *priv, | ||
653 | struct iwl4965_tx_queue *txq, int count, u32 id); | ||
654 | extern void iwl4965_tx_queue_free(struct iwl_priv *priv, struct iwl4965_tx_queue *txq); | ||
655 | extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv, | 652 | extern unsigned int iwl4965_fill_beacon_frame(struct iwl_priv *priv, |
656 | struct ieee80211_hdr *hdr, | 653 | struct ieee80211_hdr *hdr, |
657 | const u8 *dest, int left); | 654 | const u8 *dest, int left); |
@@ -692,17 +689,12 @@ extern void iwl4965_hw_setup_deferred_work(struct iwl_priv *priv); | |||
692 | extern void iwl4965_hw_cancel_deferred_work(struct iwl_priv *priv); | 689 | extern void iwl4965_hw_cancel_deferred_work(struct iwl_priv *priv); |
693 | extern int iwl4965_hw_rxq_stop(struct iwl_priv *priv); | 690 | extern int iwl4965_hw_rxq_stop(struct iwl_priv *priv); |
694 | extern int iwl4965_hw_set_hw_params(struct iwl_priv *priv); | 691 | extern int iwl4965_hw_set_hw_params(struct iwl_priv *priv); |
695 | extern int iwl4965_hw_nic_init(struct iwl_priv *priv); | ||
696 | extern int iwl4965_hw_nic_stop_master(struct iwl_priv *priv); | 692 | extern int iwl4965_hw_nic_stop_master(struct iwl_priv *priv); |
697 | extern void iwl4965_hw_txq_ctx_free(struct iwl_priv *priv); | ||
698 | extern void iwl4965_hw_txq_ctx_stop(struct iwl_priv *priv); | 693 | extern void iwl4965_hw_txq_ctx_stop(struct iwl_priv *priv); |
699 | extern int iwl4965_hw_nic_reset(struct iwl_priv *priv); | 694 | extern int iwl4965_hw_nic_reset(struct iwl_priv *priv); |
700 | extern int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *tfd, | 695 | extern int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *tfd, |
701 | dma_addr_t addr, u16 len); | 696 | dma_addr_t addr, u16 len); |
702 | extern int iwl4965_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl4965_tx_queue *txq); | ||
703 | extern int iwl4965_hw_get_temperature(struct iwl_priv *priv); | 697 | extern int iwl4965_hw_get_temperature(struct iwl_priv *priv); |
704 | extern int iwl4965_hw_tx_queue_init(struct iwl_priv *priv, | ||
705 | struct iwl4965_tx_queue *txq); | ||
706 | extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, | 698 | extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv, |
707 | struct iwl4965_frame *frame, u8 rate); | 699 | struct iwl4965_frame *frame, u8 rate); |
708 | extern int iwl4965_hw_get_rx_read(struct iwl_priv *priv); | 700 | extern int iwl4965_hw_get_rx_read(struct iwl_priv *priv); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c index 667b592e6ade..171751e417d5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c | |||
@@ -369,3 +369,55 @@ void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | |||
369 | } | 369 | } |
370 | EXPORT_SYMBOL(iwl_rx_queue_reset); | 370 | EXPORT_SYMBOL(iwl_rx_queue_reset); |
371 | 371 | ||
372 | int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | ||
373 | { | ||
374 | int ret; | ||
375 | unsigned long flags; | ||
376 | unsigned int rb_size; | ||
377 | |||
378 | spin_lock_irqsave(&priv->lock, flags); | ||
379 | ret = iwl_grab_nic_access(priv); | ||
380 | if (ret) { | ||
381 | spin_unlock_irqrestore(&priv->lock, flags); | ||
382 | return ret; | ||
383 | } | ||
384 | |||
385 | if (priv->cfg->mod_params->amsdu_size_8K) | ||
386 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K; | ||
387 | else | ||
388 | rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K; | ||
389 | |||
390 | /* Stop Rx DMA */ | ||
391 | iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0); | ||
392 | |||
393 | /* Reset driver's Rx queue write index */ | ||
394 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0); | ||
395 | |||
396 | /* Tell device where to find RBD circular buffer in DRAM */ | ||
397 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG, | ||
398 | rxq->dma_addr >> 8); | ||
399 | |||
400 | /* Tell device where in DRAM to update its Rx status */ | ||
401 | iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG, | ||
402 | (priv->shared_phys + | ||
403 | offsetof(struct iwl4965_shared, rb_closed)) >> 4); | ||
404 | |||
405 | /* Enable Rx DMA, enable host interrupt, Rx buffer size 4k, 256 RBDs */ | ||
406 | iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, | ||
407 | FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL | | ||
408 | FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL | | ||
409 | rb_size | | ||
410 | /* 0x10 << 4 | */ | ||
411 | (RX_QUEUE_SIZE_LOG << | ||
412 | FH_RCSR_RX_CONFIG_RBDCB_SIZE_BITSHIFT)); | ||
413 | |||
414 | /* | ||
415 | * iwl_write32(priv,CSR_INT_COAL_REG,0); | ||
416 | */ | ||
417 | |||
418 | iwl_release_nic_access(priv); | ||
419 | spin_unlock_irqrestore(&priv->lock, flags); | ||
420 | |||
421 | return 0; | ||
422 | } | ||
423 | |||
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c new file mode 100644 index 000000000000..ade247e63106 --- /dev/null +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -0,0 +1,374 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2003 - 2008 Intel Corporation. All rights reserved. | ||
4 | * | ||
5 | * Portions of this file are derived from the ipw3945 project, as well | ||
6 | * as portions of the ieee80211 subsystem header files. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of version 2 of the GNU General Public License as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
14 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
15 | * more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License along with | ||
18 | * this program; if not, write to the Free Software Foundation, Inc., | ||
19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
20 | * | ||
21 | * The full GNU General Public License is included in this distribution in the | ||
22 | * file called LICENSE. | ||
23 | * | ||
24 | * Contact Information: | ||
25 | * James P. Ketrenos <ipw2100-admin@linux.intel.com> | ||
26 | * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | #include <net/mac80211.h> | ||
31 | #include "iwl-eeprom.h" | ||
32 | #include "iwl-dev.h" | ||
33 | #include "iwl-core.h" | ||
34 | #include "iwl-sta.h" | ||
35 | #include "iwl-io.h" | ||
36 | #include "iwl-helpers.h" | ||
37 | |||
38 | /** | ||
39 | * iwl_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr] | ||
40 | * | ||
41 | * Does NOT advance any TFD circular buffer read/write indexes | ||
42 | * Does NOT free the TFD itself (which is within circular buffer) | ||
43 | */ | ||
44 | int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl4965_tx_queue *txq) | ||
45 | { | ||
46 | struct iwl_tfd_frame *bd_tmp = (struct iwl_tfd_frame *)&txq->bd[0]; | ||
47 | struct iwl_tfd_frame *bd = &bd_tmp[txq->q.read_ptr]; | ||
48 | struct pci_dev *dev = priv->pci_dev; | ||
49 | int i; | ||
50 | int counter = 0; | ||
51 | int index, is_odd; | ||
52 | |||
53 | /* Host command buffers stay mapped in memory, nothing to clean */ | ||
54 | if (txq->q.id == IWL_CMD_QUEUE_NUM) | ||
55 | return 0; | ||
56 | |||
57 | /* Sanity check on number of chunks */ | ||
58 | counter = IWL_GET_BITS(*bd, num_tbs); | ||
59 | if (counter > MAX_NUM_OF_TBS) { | ||
60 | IWL_ERROR("Too many chunks: %i\n", counter); | ||
61 | /* @todo issue fatal error, it is quite serious situation */ | ||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | /* Unmap chunks, if any. | ||
66 | * TFD info for odd chunks is different format than for even chunks. */ | ||
67 | for (i = 0; i < counter; i++) { | ||
68 | index = i / 2; | ||
69 | is_odd = i & 0x1; | ||
70 | |||
71 | if (is_odd) | ||
72 | pci_unmap_single( | ||
73 | dev, | ||
74 | IWL_GET_BITS(bd->pa[index], tb2_addr_lo16) | | ||
75 | (IWL_GET_BITS(bd->pa[index], | ||
76 | tb2_addr_hi20) << 16), | ||
77 | IWL_GET_BITS(bd->pa[index], tb2_len), | ||
78 | PCI_DMA_TODEVICE); | ||
79 | |||
80 | else if (i > 0) | ||
81 | pci_unmap_single(dev, | ||
82 | le32_to_cpu(bd->pa[index].tb1_addr), | ||
83 | IWL_GET_BITS(bd->pa[index], tb1_len), | ||
84 | PCI_DMA_TODEVICE); | ||
85 | |||
86 | /* Free SKB, if any, for this chunk */ | ||
87 | if (txq->txb[txq->q.read_ptr].skb[i]) { | ||
88 | struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[i]; | ||
89 | |||
90 | dev_kfree_skb(skb); | ||
91 | txq->txb[txq->q.read_ptr].skb[i] = NULL; | ||
92 | } | ||
93 | } | ||
94 | return 0; | ||
95 | } | ||
96 | EXPORT_SYMBOL(iwl_hw_txq_free_tfd); | ||
97 | |||
98 | /** | ||
99 | * iwl_tx_queue_free - Deallocate DMA queue. | ||
100 | * @txq: Transmit queue to deallocate. | ||
101 | * | ||
102 | * Empty queue by removing and destroying all BD's. | ||
103 | * Free all buffers. | ||
104 | * 0-fill, but do not free "txq" descriptor structure. | ||
105 | */ | ||
106 | static void iwl_tx_queue_free(struct iwl_priv *priv, | ||
107 | struct iwl4965_tx_queue *txq) | ||
108 | { | ||
109 | struct iwl4965_queue *q = &txq->q; | ||
110 | struct pci_dev *dev = priv->pci_dev; | ||
111 | int len; | ||
112 | |||
113 | if (q->n_bd == 0) | ||
114 | return; | ||
115 | |||
116 | /* first, empty all BD's */ | ||
117 | for (; q->write_ptr != q->read_ptr; | ||
118 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) | ||
119 | iwl_hw_txq_free_tfd(priv, txq); | ||
120 | |||
121 | len = sizeof(struct iwl_cmd) * q->n_window; | ||
122 | if (q->id == IWL_CMD_QUEUE_NUM) | ||
123 | len += IWL_MAX_SCAN_SIZE; | ||
124 | |||
125 | /* De-alloc array of command/tx buffers */ | ||
126 | pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); | ||
127 | |||
128 | /* De-alloc circular buffer of TFDs */ | ||
129 | if (txq->q.n_bd) | ||
130 | pci_free_consistent(dev, sizeof(struct iwl_tfd_frame) * | ||
131 | txq->q.n_bd, txq->bd, txq->q.dma_addr); | ||
132 | |||
133 | /* De-alloc array of per-TFD driver data */ | ||
134 | kfree(txq->txb); | ||
135 | txq->txb = NULL; | ||
136 | |||
137 | /* 0-fill queue descriptor structure */ | ||
138 | memset(txq, 0, sizeof(*txq)); | ||
139 | } | ||
140 | |||
141 | /** | ||
142 | * iwl_hw_txq_ctx_free - Free TXQ Context | ||
143 | * | ||
144 | * Destroy all TX DMA queues and structures | ||
145 | */ | ||
146 | void iwl_hw_txq_ctx_free(struct iwl_priv *priv) | ||
147 | { | ||
148 | int txq_id; | ||
149 | |||
150 | /* Tx queues */ | ||
151 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) | ||
152 | iwl_tx_queue_free(priv, &priv->txq[txq_id]); | ||
153 | |||
154 | /* Keep-warm buffer */ | ||
155 | iwl_kw_free(priv); | ||
156 | } | ||
157 | EXPORT_SYMBOL(iwl_hw_txq_ctx_free); | ||
158 | |||
159 | /** | ||
160 | * iwl_queue_init - Initialize queue's high/low-water and read/write indexes | ||
161 | */ | ||
162 | static int iwl_queue_init(struct iwl_priv *priv, struct iwl4965_queue *q, | ||
163 | int count, int slots_num, u32 id) | ||
164 | { | ||
165 | q->n_bd = count; | ||
166 | q->n_window = slots_num; | ||
167 | q->id = id; | ||
168 | |||
169 | /* count must be power-of-two size, otherwise iwl_queue_inc_wrap | ||
170 | * and iwl_queue_dec_wrap are broken. */ | ||
171 | BUG_ON(!is_power_of_2(count)); | ||
172 | |||
173 | /* slots_num must be power-of-two size, otherwise | ||
174 | * get_cmd_index is broken. */ | ||
175 | BUG_ON(!is_power_of_2(slots_num)); | ||
176 | |||
177 | q->low_mark = q->n_window / 4; | ||
178 | if (q->low_mark < 4) | ||
179 | q->low_mark = 4; | ||
180 | |||
181 | q->high_mark = q->n_window / 8; | ||
182 | if (q->high_mark < 2) | ||
183 | q->high_mark = 2; | ||
184 | |||
185 | q->write_ptr = q->read_ptr = 0; | ||
186 | |||
187 | return 0; | ||
188 | } | ||
189 | |||
190 | /** | ||
191 | * iwl_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue | ||
192 | */ | ||
193 | static int iwl_tx_queue_alloc(struct iwl_priv *priv, | ||
194 | struct iwl4965_tx_queue *txq, u32 id) | ||
195 | { | ||
196 | struct pci_dev *dev = priv->pci_dev; | ||
197 | |||
198 | /* Driver private data, only for Tx (not command) queues, | ||
199 | * not shared with device. */ | ||
200 | if (id != IWL_CMD_QUEUE_NUM) { | ||
201 | txq->txb = kmalloc(sizeof(txq->txb[0]) * | ||
202 | TFD_QUEUE_SIZE_MAX, GFP_KERNEL); | ||
203 | if (!txq->txb) { | ||
204 | IWL_ERROR("kmalloc for auxiliary BD " | ||
205 | "structures failed\n"); | ||
206 | goto error; | ||
207 | } | ||
208 | } else | ||
209 | txq->txb = NULL; | ||
210 | |||
211 | /* Circular buffer of transmit frame descriptors (TFDs), | ||
212 | * shared with device */ | ||
213 | txq->bd = pci_alloc_consistent(dev, | ||
214 | sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX, | ||
215 | &txq->q.dma_addr); | ||
216 | |||
217 | if (!txq->bd) { | ||
218 | IWL_ERROR("pci_alloc_consistent(%zd) failed\n", | ||
219 | sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX); | ||
220 | goto error; | ||
221 | } | ||
222 | txq->q.id = id; | ||
223 | |||
224 | return 0; | ||
225 | |||
226 | error: | ||
227 | kfree(txq->txb); | ||
228 | txq->txb = NULL; | ||
229 | |||
230 | return -ENOMEM; | ||
231 | } | ||
232 | |||
233 | /* | ||
234 | * Tell nic where to find circular buffer of Tx Frame Descriptors for | ||
235 | * given Tx queue, and enable the DMA channel used for that queue. | ||
236 | * | ||
237 | * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA | ||
238 | * channels supported in hardware. | ||
239 | */ | ||
240 | static int iwl_hw_tx_queue_init(struct iwl_priv *priv, | ||
241 | struct iwl4965_tx_queue *txq) | ||
242 | { | ||
243 | int rc; | ||
244 | unsigned long flags; | ||
245 | int txq_id = txq->q.id; | ||
246 | |||
247 | spin_lock_irqsave(&priv->lock, flags); | ||
248 | rc = iwl_grab_nic_access(priv); | ||
249 | if (rc) { | ||
250 | spin_unlock_irqrestore(&priv->lock, flags); | ||
251 | return rc; | ||
252 | } | ||
253 | |||
254 | /* Circular buffer (TFD queue in DRAM) physical base address */ | ||
255 | iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id), | ||
256 | txq->q.dma_addr >> 8); | ||
257 | |||
258 | /* Enable DMA channel, using same id as for TFD queue */ | ||
259 | iwl_write_direct32( | ||
260 | priv, FH_TCSR_CHNL_TX_CONFIG_REG(txq_id), | ||
261 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE | | ||
262 | FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL); | ||
263 | iwl_release_nic_access(priv); | ||
264 | spin_unlock_irqrestore(&priv->lock, flags); | ||
265 | |||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | /** | ||
270 | * iwl_tx_queue_init - Allocate and initialize one tx/cmd queue | ||
271 | */ | ||
272 | static int iwl_tx_queue_init(struct iwl_priv *priv, | ||
273 | struct iwl4965_tx_queue *txq, | ||
274 | int slots_num, u32 txq_id) | ||
275 | { | ||
276 | struct pci_dev *dev = priv->pci_dev; | ||
277 | int len; | ||
278 | int rc = 0; | ||
279 | |||
280 | /* | ||
281 | * Alloc buffer array for commands (Tx or other types of commands). | ||
282 | * For the command queue (#4), allocate command space + one big | ||
283 | * command for scan, since scan command is very huge; the system will | ||
284 | * not have two scans at the same time, so only one is needed. | ||
285 | * For normal Tx queues (all other queues), no super-size command | ||
286 | * space is needed. | ||
287 | */ | ||
288 | len = sizeof(struct iwl_cmd) * slots_num; | ||
289 | if (txq_id == IWL_CMD_QUEUE_NUM) | ||
290 | len += IWL_MAX_SCAN_SIZE; | ||
291 | txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd); | ||
292 | if (!txq->cmd) | ||
293 | return -ENOMEM; | ||
294 | |||
295 | /* Alloc driver data array and TFD circular buffer */ | ||
296 | rc = iwl_tx_queue_alloc(priv, txq, txq_id); | ||
297 | if (rc) { | ||
298 | pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); | ||
299 | |||
300 | return -ENOMEM; | ||
301 | } | ||
302 | txq->need_update = 0; | ||
303 | |||
304 | /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise | ||
305 | * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */ | ||
306 | BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); | ||
307 | |||
308 | /* Initialize queue's high/low-water marks, and head/tail indexes */ | ||
309 | iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); | ||
310 | |||
311 | /* Tell device where to find queue */ | ||
312 | iwl_hw_tx_queue_init(priv, txq); | ||
313 | |||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | /** | ||
318 | * iwl_txq_ctx_reset - Reset TX queue context | ||
319 | * Destroys all DMA structures and initialise them again | ||
320 | * | ||
321 | * @param priv | ||
322 | * @return error code | ||
323 | */ | ||
324 | int iwl_txq_ctx_reset(struct iwl_priv *priv) | ||
325 | { | ||
326 | int ret = 0; | ||
327 | int txq_id, slots_num; | ||
328 | |||
329 | iwl_kw_free(priv); | ||
330 | |||
331 | /* Free all tx/cmd queues and keep-warm buffer */ | ||
332 | iwl_hw_txq_ctx_free(priv); | ||
333 | |||
334 | /* Alloc keep-warm buffer */ | ||
335 | ret = iwl_kw_alloc(priv); | ||
336 | if (ret) { | ||
337 | IWL_ERROR("Keep Warm allocation failed"); | ||
338 | goto error_kw; | ||
339 | } | ||
340 | |||
341 | /* Turn off all Tx DMA fifos */ | ||
342 | ret = priv->cfg->ops->lib->disable_tx_fifo(priv); | ||
343 | if (unlikely(ret)) | ||
344 | goto error_reset; | ||
345 | |||
346 | /* Tell nic where to find the keep-warm buffer */ | ||
347 | ret = iwl_kw_init(priv); | ||
348 | if (ret) { | ||
349 | IWL_ERROR("kw_init failed\n"); | ||
350 | goto error_reset; | ||
351 | } | ||
352 | |||
353 | /* Alloc and init all (default 16) Tx queues, | ||
354 | * including the command queue (#4) */ | ||
355 | for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { | ||
356 | slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ? | ||
357 | TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; | ||
358 | ret = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num, | ||
359 | txq_id); | ||
360 | if (ret) { | ||
361 | IWL_ERROR("Tx %d queue init failed\n", txq_id); | ||
362 | goto error; | ||
363 | } | ||
364 | } | ||
365 | |||
366 | return ret; | ||
367 | |||
368 | error: | ||
369 | iwl_hw_txq_ctx_free(priv); | ||
370 | error_reset: | ||
371 | iwl_kw_free(priv); | ||
372 | error_kw: | ||
373 | return ret; | ||
374 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl4965-base.c b/drivers/net/wireless/iwlwifi/iwl4965-base.c index ad45249454f0..8d06cf1a3193 100644 --- a/drivers/net/wireless/iwlwifi/iwl4965-base.c +++ b/drivers/net/wireless/iwlwifi/iwl4965-base.c | |||
@@ -207,173 +207,6 @@ static inline u8 get_cmd_index(struct iwl4965_queue *q, u32 index, int is_huge) | |||
207 | return index & (q->n_window - 1); | 207 | return index & (q->n_window - 1); |
208 | } | 208 | } |
209 | 209 | ||
210 | /** | ||
211 | * iwl4965_queue_init - Initialize queue's high/low-water and read/write indexes | ||
212 | */ | ||
213 | static int iwl4965_queue_init(struct iwl_priv *priv, struct iwl4965_queue *q, | ||
214 | int count, int slots_num, u32 id) | ||
215 | { | ||
216 | q->n_bd = count; | ||
217 | q->n_window = slots_num; | ||
218 | q->id = id; | ||
219 | |||
220 | /* count must be power-of-two size, otherwise iwl_queue_inc_wrap | ||
221 | * and iwl_queue_dec_wrap are broken. */ | ||
222 | BUG_ON(!is_power_of_2(count)); | ||
223 | |||
224 | /* slots_num must be power-of-two size, otherwise | ||
225 | * get_cmd_index is broken. */ | ||
226 | BUG_ON(!is_power_of_2(slots_num)); | ||
227 | |||
228 | q->low_mark = q->n_window / 4; | ||
229 | if (q->low_mark < 4) | ||
230 | q->low_mark = 4; | ||
231 | |||
232 | q->high_mark = q->n_window / 8; | ||
233 | if (q->high_mark < 2) | ||
234 | q->high_mark = 2; | ||
235 | |||
236 | q->write_ptr = q->read_ptr = 0; | ||
237 | |||
238 | return 0; | ||
239 | } | ||
240 | |||
241 | /** | ||
242 | * iwl4965_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue | ||
243 | */ | ||
244 | static int iwl4965_tx_queue_alloc(struct iwl_priv *priv, | ||
245 | struct iwl4965_tx_queue *txq, u32 id) | ||
246 | { | ||
247 | struct pci_dev *dev = priv->pci_dev; | ||
248 | |||
249 | /* Driver private data, only for Tx (not command) queues, | ||
250 | * not shared with device. */ | ||
251 | if (id != IWL_CMD_QUEUE_NUM) { | ||
252 | txq->txb = kmalloc(sizeof(txq->txb[0]) * | ||
253 | TFD_QUEUE_SIZE_MAX, GFP_KERNEL); | ||
254 | if (!txq->txb) { | ||
255 | IWL_ERROR("kmalloc for auxiliary BD " | ||
256 | "structures failed\n"); | ||
257 | goto error; | ||
258 | } | ||
259 | } else | ||
260 | txq->txb = NULL; | ||
261 | |||
262 | /* Circular buffer of transmit frame descriptors (TFDs), | ||
263 | * shared with device */ | ||
264 | txq->bd = pci_alloc_consistent(dev, | ||
265 | sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX, | ||
266 | &txq->q.dma_addr); | ||
267 | |||
268 | if (!txq->bd) { | ||
269 | IWL_ERROR("pci_alloc_consistent(%zd) failed\n", | ||
270 | sizeof(txq->bd[0]) * TFD_QUEUE_SIZE_MAX); | ||
271 | goto error; | ||
272 | } | ||
273 | txq->q.id = id; | ||
274 | |||
275 | return 0; | ||
276 | |||
277 | error: | ||
278 | if (txq->txb) { | ||
279 | kfree(txq->txb); | ||
280 | txq->txb = NULL; | ||
281 | } | ||
282 | |||
283 | return -ENOMEM; | ||
284 | } | ||
285 | |||
286 | /** | ||
287 | * iwl4965_tx_queue_init - Allocate and initialize one tx/cmd queue | ||
288 | */ | ||
289 | int iwl4965_tx_queue_init(struct iwl_priv *priv, | ||
290 | struct iwl4965_tx_queue *txq, int slots_num, u32 txq_id) | ||
291 | { | ||
292 | struct pci_dev *dev = priv->pci_dev; | ||
293 | int len; | ||
294 | int rc = 0; | ||
295 | |||
296 | /* | ||
297 | * Alloc buffer array for commands (Tx or other types of commands). | ||
298 | * For the command queue (#4), allocate command space + one big | ||
299 | * command for scan, since scan command is very huge; the system will | ||
300 | * not have two scans at the same time, so only one is needed. | ||
301 | * For normal Tx queues (all other queues), no super-size command | ||
302 | * space is needed. | ||
303 | */ | ||
304 | len = sizeof(struct iwl_cmd) * slots_num; | ||
305 | if (txq_id == IWL_CMD_QUEUE_NUM) | ||
306 | len += IWL_MAX_SCAN_SIZE; | ||
307 | txq->cmd = pci_alloc_consistent(dev, len, &txq->dma_addr_cmd); | ||
308 | if (!txq->cmd) | ||
309 | return -ENOMEM; | ||
310 | |||
311 | /* Alloc driver data array and TFD circular buffer */ | ||
312 | rc = iwl4965_tx_queue_alloc(priv, txq, txq_id); | ||
313 | if (rc) { | ||
314 | pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); | ||
315 | |||
316 | return -ENOMEM; | ||
317 | } | ||
318 | txq->need_update = 0; | ||
319 | |||
320 | /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise | ||
321 | * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */ | ||
322 | BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); | ||
323 | |||
324 | /* Initialize queue's high/low-water marks, and head/tail indexes */ | ||
325 | iwl4965_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id); | ||
326 | |||
327 | /* Tell device where to find queue */ | ||
328 | iwl4965_hw_tx_queue_init(priv, txq); | ||
329 | |||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | /** | ||
334 | * iwl4965_tx_queue_free - Deallocate DMA queue. | ||
335 | * @txq: Transmit queue to deallocate. | ||
336 | * | ||
337 | * Empty queue by removing and destroying all BD's. | ||
338 | * Free all buffers. | ||
339 | * 0-fill, but do not free "txq" descriptor structure. | ||
340 | */ | ||
341 | void iwl4965_tx_queue_free(struct iwl_priv *priv, struct iwl4965_tx_queue *txq) | ||
342 | { | ||
343 | struct iwl4965_queue *q = &txq->q; | ||
344 | struct pci_dev *dev = priv->pci_dev; | ||
345 | int len; | ||
346 | |||
347 | if (q->n_bd == 0) | ||
348 | return; | ||
349 | |||
350 | /* first, empty all BD's */ | ||
351 | for (; q->write_ptr != q->read_ptr; | ||
352 | q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) | ||
353 | iwl4965_hw_txq_free_tfd(priv, txq); | ||
354 | |||
355 | len = sizeof(struct iwl_cmd) * q->n_window; | ||
356 | if (q->id == IWL_CMD_QUEUE_NUM) | ||
357 | len += IWL_MAX_SCAN_SIZE; | ||
358 | |||
359 | /* De-alloc array of command/tx buffers */ | ||
360 | pci_free_consistent(dev, len, txq->cmd, txq->dma_addr_cmd); | ||
361 | |||
362 | /* De-alloc circular buffer of TFDs */ | ||
363 | if (txq->q.n_bd) | ||
364 | pci_free_consistent(dev, sizeof(struct iwl4965_tfd_frame) * | ||
365 | txq->q.n_bd, txq->bd, txq->q.dma_addr); | ||
366 | |||
367 | /* De-alloc array of per-TFD driver data */ | ||
368 | if (txq->txb) { | ||
369 | kfree(txq->txb); | ||
370 | txq->txb = NULL; | ||
371 | } | ||
372 | |||
373 | /* 0-fill queue descriptor structure */ | ||
374 | memset(txq, 0, sizeof(*txq)); | ||
375 | } | ||
376 | |||
377 | const u8 iwl4965_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | 210 | const u8 iwl4965_broadcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
378 | 211 | ||
379 | /*************** STATION TABLE MANAGEMENT **** | 212 | /*************** STATION TABLE MANAGEMENT **** |
@@ -516,7 +349,7 @@ int iwl4965_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
516 | { | 349 | { |
517 | struct iwl4965_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; | 350 | struct iwl4965_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; |
518 | struct iwl4965_queue *q = &txq->q; | 351 | struct iwl4965_queue *q = &txq->q; |
519 | struct iwl4965_tfd_frame *tfd; | 352 | struct iwl_tfd_frame *tfd; |
520 | u32 *control_flags; | 353 | u32 *control_flags; |
521 | struct iwl_cmd *out_cmd; | 354 | struct iwl_cmd *out_cmd; |
522 | u32 idx; | 355 | u32 idx; |
@@ -1931,7 +1764,7 @@ static int iwl4965_tx_skb(struct iwl_priv *priv, | |||
1931 | struct sk_buff *skb, struct ieee80211_tx_control *ctl) | 1764 | struct sk_buff *skb, struct ieee80211_tx_control *ctl) |
1932 | { | 1765 | { |
1933 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1766 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1934 | struct iwl4965_tfd_frame *tfd; | 1767 | struct iwl_tfd_frame *tfd; |
1935 | u32 *control_flags; | 1768 | u32 *control_flags; |
1936 | int txq_id = ctl->queue; | 1769 | int txq_id = ctl->queue; |
1937 | struct iwl4965_tx_queue *txq = NULL; | 1770 | struct iwl4965_tx_queue *txq = NULL; |
@@ -2515,7 +2348,7 @@ int iwl4965_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) | |||
2515 | if (txq_id != IWL_CMD_QUEUE_NUM) { | 2348 | if (txq_id != IWL_CMD_QUEUE_NUM) { |
2516 | iwl4965_txstatus_to_ieee(priv, | 2349 | iwl4965_txstatus_to_ieee(priv, |
2517 | &(txq->txb[txq->q.read_ptr])); | 2350 | &(txq->txb[txq->q.read_ptr])); |
2518 | iwl4965_hw_txq_free_tfd(priv, txq); | 2351 | iwl_hw_txq_free_tfd(priv, txq); |
2519 | } else if (nfreed > 1) { | 2352 | } else if (nfreed > 1) { |
2520 | IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index, | 2353 | IWL_ERROR("HCMD skipped: index (%d) %d %d\n", index, |
2521 | q->write_ptr, q->read_ptr); | 2354 | q->write_ptr, q->read_ptr); |
@@ -4677,7 +4510,7 @@ static int __iwl4965_up(struct iwl_priv *priv) | |||
4677 | return ret; | 4510 | return ret; |
4678 | } | 4511 | } |
4679 | 4512 | ||
4680 | ret = priv->cfg->ops->lib->hw_nic_init(priv); | 4513 | ret = iwl_hw_nic_init(priv); |
4681 | if (ret) { | 4514 | if (ret) { |
4682 | IWL_ERROR("Unable to init nic\n"); | 4515 | IWL_ERROR("Unable to init nic\n"); |
4683 | return ret; | 4516 | return ret; |
@@ -6940,7 +6773,7 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) | |||
6940 | 6773 | ||
6941 | if (priv->rxq.bd) | 6774 | if (priv->rxq.bd) |
6942 | iwl_rx_queue_free(priv, &priv->rxq); | 6775 | iwl_rx_queue_free(priv, &priv->rxq); |
6943 | iwl4965_hw_txq_ctx_free(priv); | 6776 | iwl_hw_txq_ctx_free(priv); |
6944 | 6777 | ||
6945 | iwlcore_clear_stations_table(priv); | 6778 | iwlcore_clear_stations_table(priv); |
6946 | iwl_eeprom_free(priv); | 6779 | iwl_eeprom_free(priv); |