diff options
author | Samuel Ortiz <samuel.ortiz@intel.com> | 2009-01-19 18:30:26 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-01-29 16:00:56 -0500 |
commit | 7aaa1d79e3a2d573ac469744506f17b1c9386840 (patch) | |
tree | b003f298588e7f6a9f97764387f1c62a17c18b9e /drivers/net/wireless/iwlwifi/iwl-3945.c | |
parent | 4f3602c8a3cf8d31e8b08b82d7ea9b0c30f28965 (diff) |
iwlwifi: Add TFD library operations
The TFD structures for 3945 and agn HWs are fundamentally different. We thus
need to define operations for attaching and freeing them. This will allow us
to share a fair amount of code (cmd and tx queue related) between both
drivers.
Signed-off-by: Samuel Ortiz <samuel.ortiz@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-3945.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index e6d4503cd213..18e0f0e3a74f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -318,7 +318,7 @@ static void iwl3945_tx_queue_reclaim(struct iwl_priv *priv, | |||
318 | tx_info = &txq->txb[txq->q.read_ptr]; | 318 | tx_info = &txq->txb[txq->q.read_ptr]; |
319 | ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0]); | 319 | ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb[0]); |
320 | tx_info->skb[0] = NULL; | 320 | tx_info->skb[0] = NULL; |
321 | iwl3945_hw_txq_free_tfd(priv, txq); | 321 | priv->cfg->ops->lib->txq_free_tfd(priv, txq); |
322 | } | 322 | } |
323 | 323 | ||
324 | if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) && | 324 | if (iwl_queue_space(q) > q->low_mark && (txq_id >= 0) && |
@@ -724,15 +724,21 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv, | |||
724 | iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status); | 724 | iwl3945_pass_packet_to_mac80211(priv, rxb, &rx_status); |
725 | } | 725 | } |
726 | 726 | ||
727 | int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr, | 727 | int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, |
728 | dma_addr_t addr, u16 len) | 728 | struct iwl_tx_queue *txq, |
729 | dma_addr_t addr, u16 len, u8 reset, u8 pad) | ||
729 | { | 730 | { |
730 | int count; | 731 | int count; |
731 | u32 pad; | 732 | struct iwl_queue *q; |
732 | struct iwl3945_tfd *tfd = (struct iwl3945_tfd *)ptr; | 733 | struct iwl3945_tfd *tfd; |
734 | |||
735 | q = &txq->q; | ||
736 | tfd = &txq->tfds39[q->write_ptr]; | ||
737 | |||
738 | if (reset) | ||
739 | memset(tfd, 0, sizeof(*tfd)); | ||
733 | 740 | ||
734 | count = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags)); | 741 | count = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags)); |
735 | pad = TFD_CTL_PAD_GET(le32_to_cpu(tfd->control_flags)); | ||
736 | 742 | ||
737 | if ((count >= NUM_TFD_CHUNKS) || (count < 0)) { | 743 | if ((count >= NUM_TFD_CHUNKS) || (count < 0)) { |
738 | IWL_ERR(priv, "Error can not send more than %d chunks\n", | 744 | IWL_ERR(priv, "Error can not send more than %d chunks\n", |
@@ -756,7 +762,7 @@ int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr, | |||
756 | * | 762 | * |
757 | * Does NOT advance any indexes | 763 | * Does NOT advance any indexes |
758 | */ | 764 | */ |
759 | int iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) | 765 | void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) |
760 | { | 766 | { |
761 | struct iwl3945_tfd *tfd_tmp = (struct iwl3945_tfd *)&txq->tfds39[0]; | 767 | struct iwl3945_tfd *tfd_tmp = (struct iwl3945_tfd *)&txq->tfds39[0]; |
762 | struct iwl3945_tfd *tfd = &tfd_tmp[txq->q.read_ptr]; | 768 | struct iwl3945_tfd *tfd = &tfd_tmp[txq->q.read_ptr]; |
@@ -767,14 +773,14 @@ int iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) | |||
767 | /* classify bd */ | 773 | /* classify bd */ |
768 | if (txq->q.id == IWL_CMD_QUEUE_NUM) | 774 | if (txq->q.id == IWL_CMD_QUEUE_NUM) |
769 | /* nothing to cleanup after for host commands */ | 775 | /* nothing to cleanup after for host commands */ |
770 | return 0; | 776 | return; |
771 | 777 | ||
772 | /* sanity check */ | 778 | /* sanity check */ |
773 | counter = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags)); | 779 | counter = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags)); |
774 | if (counter > NUM_TFD_CHUNKS) { | 780 | if (counter > NUM_TFD_CHUNKS) { |
775 | IWL_ERR(priv, "Too many chunks: %i\n", counter); | 781 | IWL_ERR(priv, "Too many chunks: %i\n", counter); |
776 | /* @todo issue fatal error, it is quite serious situation */ | 782 | /* @todo issue fatal error, it is quite serious situation */ |
777 | return 0; | 783 | return; |
778 | } | 784 | } |
779 | 785 | ||
780 | /* unmap chunks if any */ | 786 | /* unmap chunks if any */ |
@@ -791,7 +797,7 @@ int iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) | |||
791 | } | 797 | } |
792 | } | 798 | } |
793 | } | 799 | } |
794 | return 0; | 800 | return ; |
795 | } | 801 | } |
796 | 802 | ||
797 | u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *addr) | 803 | u8 iwl3945_hw_find_station(struct iwl_priv *priv, const u8 *addr) |
@@ -2697,6 +2703,8 @@ static int iwl3945_load_bsm(struct iwl_priv *priv) | |||
2697 | } | 2703 | } |
2698 | 2704 | ||
2699 | static struct iwl_lib_ops iwl3945_lib = { | 2705 | static struct iwl_lib_ops iwl3945_lib = { |
2706 | .txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd, | ||
2707 | .txq_free_tfd = iwl3945_hw_txq_free_tfd, | ||
2700 | .load_ucode = iwl3945_load_bsm, | 2708 | .load_ucode = iwl3945_load_bsm, |
2701 | .apm_ops = { | 2709 | .apm_ops = { |
2702 | .init = iwl3945_apm_init, | 2710 | .init = iwl3945_apm_init, |