aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
diff options
context:
space:
mode:
authorWey-Yi Guy <wey-yi.w.guy@intel.com>2010-03-17 16:34:34 -0400
committerReinette Chatre <reinette.chatre@intel.com>2010-03-25 14:19:27 -0400
commit74bcdb33e99f49ef5202dd2f8109945b4570edc2 (patch)
tree0c1be859e04b0c460abd9cbf1f40571362c82956 /drivers/net/wireless/iwlwifi/iwl-agn-lib.c
parent348ee7cd57831c47373dd157f138c558daaf129d (diff)
iwlwifi: move agn only tx functions from iwlcore to iwlagn
Identify the tx functions only used by agn driver and move those from iwlcore to iwlagn. Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-lib.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c136
1 files changed, 133 insertions, 3 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index c826b7f54256..6f9d52d04464 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -208,7 +208,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
208 "scd_ssn=%d idx=%d txq=%d swq=%d\n", 208 "scd_ssn=%d idx=%d txq=%d swq=%d\n",
209 scd_ssn , index, txq_id, txq->swq_id); 209 scd_ssn , index, txq_id, txq->swq_id);
210 210
211 freed = iwl_tx_queue_reclaim(priv, txq_id, index); 211 freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
212 iwl_free_tfds_in_queue(priv, sta_id, tid, freed); 212 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
213 213
214 if (priv->mac80211_registered && 214 if (priv->mac80211_registered &&
@@ -236,7 +236,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
236 le32_to_cpu(tx_resp->rate_n_flags), 236 le32_to_cpu(tx_resp->rate_n_flags),
237 tx_resp->failure_frame); 237 tx_resp->failure_frame);
238 238
239 freed = iwl_tx_queue_reclaim(priv, txq_id, index); 239 freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
240 iwl_free_tfds_in_queue(priv, sta_id, tid, freed); 240 iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
241 241
242 if (priv->mac80211_registered && 242 if (priv->mac80211_registered &&
@@ -244,7 +244,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
244 iwl_wake_queue(priv, txq_id); 244 iwl_wake_queue(priv, txq_id);
245 } 245 }
246 246
247 iwl_txq_check_empty(priv, sta_id, tid, txq_id); 247 iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
248 248
249 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK)) 249 if (iwl_check_bits(status, TX_ABORT_REQUIRED_MSK))
250 IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n"); 250 IWL_ERR(priv, "TODO: Implement Tx ABORT REQUIRED!!!\n");
@@ -381,3 +381,133 @@ struct iwl_mod_params iwlagn_mod_params = {
381 .restart_fw = 1, 381 .restart_fw = 1,
382 /* the rest are 0 by default */ 382 /* the rest are 0 by default */
383}; 383};
384
385void iwlagn_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
386{
387 unsigned long flags;
388 int i;
389 spin_lock_irqsave(&rxq->lock, flags);
390 INIT_LIST_HEAD(&rxq->rx_free);
391 INIT_LIST_HEAD(&rxq->rx_used);
392 /* Fill the rx_used queue with _all_ of the Rx buffers */
393 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
394 /* In the reset function, these buffers may have been allocated
395 * to an SKB, so we need to unmap and free potential storage */
396 if (rxq->pool[i].page != NULL) {
397 pci_unmap_page(priv->pci_dev, rxq->pool[i].page_dma,
398 PAGE_SIZE << priv->hw_params.rx_page_order,
399 PCI_DMA_FROMDEVICE);
400 __iwl_free_pages(priv, rxq->pool[i].page);
401 rxq->pool[i].page = NULL;
402 }
403 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
404 }
405
406 /* Set us so that we have processed and used all buffers, but have
407 * not restocked the Rx queue with fresh buffers */
408 rxq->read = rxq->write = 0;
409 rxq->write_actual = 0;
410 rxq->free_count = 0;
411 spin_unlock_irqrestore(&rxq->lock, flags);
412}
413
414int iwlagn_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
415{
416 u32 rb_size;
417 const u32 rfdnlog = RX_QUEUE_SIZE_LOG; /* 256 RBDs */
418 u32 rb_timeout = 0; /* FIXME: RX_RB_TIMEOUT for all devices? */
419
420 if (!priv->cfg->use_isr_legacy)
421 rb_timeout = RX_RB_TIMEOUT;
422
423 if (priv->cfg->mod_params->amsdu_size_8K)
424 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_8K;
425 else
426 rb_size = FH_RCSR_RX_CONFIG_REG_VAL_RB_SIZE_4K;
427
428 /* Stop Rx DMA */
429 iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG, 0);
430
431 /* Reset driver's Rx queue write index */
432 iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_WPTR_REG, 0);
433
434 /* Tell device where to find RBD circular buffer in DRAM */
435 iwl_write_direct32(priv, FH_RSCSR_CHNL0_RBDCB_BASE_REG,
436 (u32)(rxq->dma_addr >> 8));
437
438 /* Tell device where in DRAM to update its Rx status */
439 iwl_write_direct32(priv, FH_RSCSR_CHNL0_STTS_WPTR_REG,
440 rxq->rb_stts_dma >> 4);
441
442 /* Enable Rx DMA
443 * FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY is set because of HW bug in
444 * the credit mechanism in 5000 HW RX FIFO
445 * Direct rx interrupts to hosts
446 * Rx buffer size 4 or 8k
447 * RB timeout 0x10
448 * 256 RBDs
449 */
450 iwl_write_direct32(priv, FH_MEM_RCSR_CHNL0_CONFIG_REG,
451 FH_RCSR_RX_CONFIG_CHNL_EN_ENABLE_VAL |
452 FH_RCSR_CHNL0_RX_IGNORE_RXF_EMPTY |
453 FH_RCSR_CHNL0_RX_CONFIG_IRQ_DEST_INT_HOST_VAL |
454 FH_RCSR_CHNL0_RX_CONFIG_SINGLE_FRAME_MSK |
455 rb_size|
456 (rb_timeout << FH_RCSR_RX_CONFIG_REG_IRQ_RBTH_POS)|
457 (rfdnlog << FH_RCSR_RX_CONFIG_RBDCB_SIZE_POS));
458
459 /* Set interrupt coalescing timer to default (2048 usecs) */
460 iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
461
462 return 0;
463}
464
465int iwlagn_hw_nic_init(struct iwl_priv *priv)
466{
467 unsigned long flags;
468 struct iwl_rx_queue *rxq = &priv->rxq;
469 int ret;
470
471 /* nic_init */
472 spin_lock_irqsave(&priv->lock, flags);
473 priv->cfg->ops->lib->apm_ops.init(priv);
474
475 /* Set interrupt coalescing calibration timer to default (512 usecs) */
476 iwl_write8(priv, CSR_INT_COALESCING, IWL_HOST_INT_CALIB_TIMEOUT_DEF);
477
478 spin_unlock_irqrestore(&priv->lock, flags);
479
480 ret = priv->cfg->ops->lib->apm_ops.set_pwr_src(priv, IWL_PWR_SRC_VMAIN);
481
482 priv->cfg->ops->lib->apm_ops.config(priv);
483
484 /* Allocate the RX queue, or reset if it is already allocated */
485 if (!rxq->bd) {
486 ret = iwl_rx_queue_alloc(priv);
487 if (ret) {
488 IWL_ERR(priv, "Unable to initialize Rx queue\n");
489 return -ENOMEM;
490 }
491 } else
492 iwlagn_rx_queue_reset(priv, rxq);
493
494 iwl_rx_replenish(priv);
495
496 iwlagn_rx_init(priv, rxq);
497
498 spin_lock_irqsave(&priv->lock, flags);
499
500 rxq->need_update = 1;
501 iwl_rx_queue_update_write_ptr(priv, rxq);
502
503 spin_unlock_irqrestore(&priv->lock, flags);
504
505 /* Allocate and init all Tx and Command queues */
506 ret = iwlagn_txq_ctx_reset(priv);
507 if (ret)
508 return ret;
509
510 set_bit(STATUS_INIT, &priv->status);
511
512 return 0;
513}