Search Linux Wireless

Re: kernel BUG at drivers/net/wireless/iwlwifi/iwl3945-base.c:3127!

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Reinette,

This patch never made it to wireless-testing.

Jason

On Tue, Mar 31, 2009 at 6:22 PM, reinette chatre
<reinette.chatre@xxxxxxxxx> wrote:
> I addressed these issues as well as a few more that I uncovered while
> digging into this.
>
> Could you please try this patch?
>
>
> >From c152258435c047dfd7423e0279781c3fcb2f4e71 Mon Sep 17 00:00:00 2001
> From: Reinette Chatre <reinette.chatre@xxxxxxxxx>
> Date: Tue, 31 Mar 2009 14:16:05 -0700
> Subject: [PATCH] iwlwifi: DMA fixes
>
> A few issues wrt DMA were uncovered when using the driver with swiotlb.
> - driver should not use memory after it has been mapped
> - iwl3945's RX queue management cannot use all of iwlagn because
>  the size of the RX buffer is different. Revert back to using
>  iwl3945 specific routines that map/unmap memory.
> - no need to "dma_syn_single_range_for_cpu" followed by pci_unmap_single,
>  we can just call pci_unmap_single initially
> - only map the memory area that will be used by device. this is especially
>  relevant to the mapping of iwl_cmd. we should not map the entire
>  structure because the meta data at the beginning of structure contains
>  the address to be used later for unmapping. If the address to be used for
>  unmapping is stored in mapped data it creates a problem.
> - ensure that _if_ memory needs to be modified after it is mapped that we
>  call _sync_single_for_cpu first, and then release it back to device with
>  _sync_single_for_device
> - we mapped the wrong length of data for host commands, with mapped length
>  differing with length provided to device, fix that.
>
> Thanks to Jason Andryuk <jandryuk@xxxxxxxxx> for significant bisecting
> help to find these issues.
>
> Signed-off-by: Reinette Chatre <reinette.chatre@xxxxxxxxx>
> CC: Jason Andryuk <jandryuk@xxxxxxxxx>
> ---
>  drivers/net/wireless/iwlwifi/iwl-3945.c     |    2 +-
>  drivers/net/wireless/iwlwifi/iwl-3945.h     |    1 +
>  drivers/net/wireless/iwlwifi/iwl-agn.c      |   11 +--
>  drivers/net/wireless/iwlwifi/iwl-dev.h      |    4 +
>  drivers/net/wireless/iwlwifi/iwl-tx.c       |   93 ++++++++++--------
>  drivers/net/wireless/iwlwifi/iwl3945-base.c |  144 +++++++++++++++++++--------
>  6 files changed, 161 insertions(+), 94 deletions(-)
>
> diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
> index d03f553..05cd499 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-3945.c
> +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
> @@ -1192,7 +1192,7 @@ int iwl3945_hw_nic_init(struct iwl_priv *priv)
>                        return -ENOMEM;
>                }
>        } else
> -               iwl_rx_queue_reset(priv, rxq);
> +               iwl3945_rx_queue_reset(priv, rxq);
>
>        iwl3945_rx_replenish(priv);
>
> diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
> index 29bc0d2..3213a63 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-3945.h
> +++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
> @@ -214,6 +214,7 @@ extern int iwl3945_calc_sig_qual(int rssi_dbm, int noise_dbm);
>  extern int iwl3945_tx_queue_init(struct iwl_priv *priv,
>                             struct iwl_tx_queue *txq, int count, u32 id);
>  extern void iwl3945_rx_replenish(void *data);
> +extern void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq);
>  extern void iwl3945_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq);
>  extern int iwl3945_send_cmd_pdu(struct iwl_priv *priv, u8 id, u16 len,
>                            const void *data);
> diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
> index 51f6a01..ea859f6 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-agn.c
> +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
> @@ -976,11 +976,9 @@ void iwl_rx_handle(struct iwl_priv *priv)
>
>                rxq->queue[i] = NULL;
>
> -               dma_sync_single_range_for_cpu(
> -                               &priv->pci_dev->dev, rxb->real_dma_addr,
> -                               rxb->aligned_dma_addr - rxb->real_dma_addr,
> -                               priv->hw_params.rx_buf_size,
> -                               PCI_DMA_FROMDEVICE);
> +               pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
> +                                priv->hw_params.rx_buf_size + 256,
> +                                PCI_DMA_FROMDEVICE);
>                pkt = (struct iwl_rx_packet *)rxb->skb->data;
>
>                /* Reclaim a command buffer only if this packet is a response
> @@ -1031,9 +1029,6 @@ void iwl_rx_handle(struct iwl_priv *priv)
>                        rxb->skb = NULL;
>                }
>
> -               pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
> -                                priv->hw_params.rx_buf_size + 256,
> -                                PCI_DMA_FROMDEVICE);
>                spin_lock_irqsave(&rxq->lock, flags);
>                list_add_tail(&rxb->list, &priv->rxq.rx_used);
>                spin_unlock_irqrestore(&rxq->lock, flags);
> diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
> index 0baae80..721c80f 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-dev.h
> +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
> @@ -360,12 +360,16 @@ struct iwl_host_cmd {
>
>  /**
>  * struct iwl_rx_queue - Rx queue
> + * @bd: driver's pointer to buffer of receive buffer descriptors (rbd)
> + * @dma_addr: bus address of buffer of receive buffer descriptors (rbd)
>  * @read: Shared index to newest available Rx buffer
>  * @write: Shared index to oldest written Rx packet
>  * @free_count: Number of pre-allocated buffers in rx_free
>  * @rx_free: list of free SKBs for use
>  * @rx_used: List of Rx buffers with no SKB
>  * @need_update: flag to indicate we need to update read/write index
> + * @rb_stts: driver's pointer to receive buffer status
> + * @rb_stts_dma: bus address of receive buffer status
>  *
>  * NOTE:  rx_free and rx_used are used as a FIFO for iwl_rx_mem_buffers
>  */
> diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
> index 57ea320..f85b47f 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-tx.c
> +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
> @@ -797,6 +797,22 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
>        /* Copy MAC header from skb into command buffer */
>        memcpy(tx_cmd->hdr, hdr, hdr_len);
>
> +
> +       /* Total # bytes to be transmitted */
> +       len = (u16)skb->len;
> +       tx_cmd->len = cpu_to_le16(len);
> +
> +       if (info->control.hw_key)
> +               iwl_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id);
> +
> +       /* TODO need this for burst mode later on */
> +       iwl_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id);
> +
> +       /* set is_hcca to 0; it probably will never be implemented */
> +       iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0);
> +
> +       iwl_update_tx_stats(priv, le16_to_cpu(fc), len);
> +
>        /*
>         * Use the first empty entry in this queue's command buffer array
>         * to contain the Tx command and MAC header concatenated together
> @@ -817,21 +833,30 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
>        else
>                len_org = 0;
>
> +       /* Tell NIC about any 2-byte padding after MAC header */
> +       if (len_org)
> +               tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
> +
>        /* Physical address of this Tx command's header (not MAC header!),
>         * within command buffer array. */
>        txcmd_phys = pci_map_single(priv->pci_dev,
> -                                   out_cmd, sizeof(struct iwl_cmd),
> +                                   &out_cmd->hdr, len,
>                                    PCI_DMA_BIDIRECTIONAL);
>        pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys);
> -       pci_unmap_len_set(&out_cmd->meta, len, sizeof(struct iwl_cmd));
> +       pci_unmap_len_set(&out_cmd->meta, len, len);
>        /* Add buffer containing Tx command and MAC(!) header to TFD's
>         * first entry */
> -       txcmd_phys += offsetof(struct iwl_cmd, hdr);
>        priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
>                                                   txcmd_phys, len, 1, 0);
>
> -       if (info->control.hw_key)
> -               iwl_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id);
> +       if (!ieee80211_has_morefrags(hdr->frame_control)) {
> +               txq->need_update = 1;
> +               if (qc)
> +                       priv->stations[sta_id].tid[tid].seq_number = seq_number;
> +       } else {
> +               wait_write_ptr = 1;
> +               txq->need_update = 0;
> +       }
>
>        /* Set up TFD's 2nd entry to point directly to remainder of skb,
>         * if any (802.11 null frames have no payload). */
> @@ -844,42 +869,26 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
>                                                           0, 0);
>        }
>
> -       /* Tell NIC about any 2-byte padding after MAC header */
> -       if (len_org)
> -               tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
> -
> -       /* Total # bytes to be transmitted */
> -       len = (u16)skb->len;
> -       tx_cmd->len = cpu_to_le16(len);
> -       /* TODO need this for burst mode later on */
> -       iwl_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id);
> -
> -       /* set is_hcca to 0; it probably will never be implemented */
> -       iwl_tx_cmd_build_rate(priv, tx_cmd, info, fc, sta_id, 0);
> -
> -       iwl_update_tx_stats(priv, le16_to_cpu(fc), len);
> -
>        scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) +
> -               offsetof(struct iwl_tx_cmd, scratch);
> +                               offsetof(struct iwl_tx_cmd, scratch);
> +
> +       len = sizeof(struct iwl_tx_cmd) +
> +               sizeof(struct iwl_cmd_header) + hdr_len;
> +       /* take back ownership of DMA buffer to enable update */
> +       pci_dma_sync_single_for_cpu(priv->pci_dev, txcmd_phys,
> +                                   len, PCI_DMA_BIDIRECTIONAL);
>        tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
>        tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys);
>
> -       if (!ieee80211_has_morefrags(hdr->frame_control)) {
> -               txq->need_update = 1;
> -               if (qc)
> -                       priv->stations[sta_id].tid[tid].seq_number = seq_number;
> -       } else {
> -               wait_write_ptr = 1;
> -               txq->need_update = 0;
> -       }
> -
>        iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd));
> -
>        iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len);
>
>        /* Set up entry for this TFD in Tx byte-count array */
>        priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, len);
>
> +       pci_dma_sync_single_for_device(priv->pci_dev, txcmd_phys,
> +                                      len, PCI_DMA_BIDIRECTIONAL);
> +
>        /* Tell device the write index *just past* this latest filled TFD */
>        q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
>        ret = iwl_txq_update_write_ptr(priv, txq);
> @@ -966,18 +975,9 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
>                        INDEX_TO_SEQ(q->write_ptr));
>        if (out_cmd->meta.flags & CMD_SIZE_HUGE)
>                out_cmd->hdr.sequence |= SEQ_HUGE_FRAME;
> -       len = (idx == TFD_CMD_SLOTS) ?
> -                       IWL_MAX_SCAN_SIZE : sizeof(struct iwl_cmd);
> -
> -       phys_addr = pci_map_single(priv->pci_dev, out_cmd,
> -                                  len, PCI_DMA_BIDIRECTIONAL);
> -       pci_unmap_addr_set(&out_cmd->meta, mapping, phys_addr);
> -       pci_unmap_len_set(&out_cmd->meta, len, len);
> -       phys_addr += offsetof(struct iwl_cmd, hdr);
> +       len = sizeof(struct iwl_cmd) - sizeof(struct iwl_cmd_meta);
> +       len += (idx == TFD_CMD_SLOTS) ?  IWL_MAX_SCAN_SIZE : 0;
>
> -       priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
> -                                                  phys_addr, fix_size, 1,
> -                                                  U32_PAD(cmd->len));
>
>  #ifdef CONFIG_IWLWIFI_DEBUG
>        switch (out_cmd->hdr.cmd) {
> @@ -1005,6 +1005,15 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
>                /* Set up entry in queue's byte count circular buffer */
>                priv->cfg->ops->lib->txq_update_byte_cnt_tbl(priv, txq, 0);
>
> +       phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr,
> +                                  fix_size, PCI_DMA_BIDIRECTIONAL);
> +       pci_unmap_addr_set(&out_cmd->meta, mapping, phys_addr);
> +       pci_unmap_len_set(&out_cmd->meta, len, fix_size);
> +
> +       priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
> +                                                  phys_addr, fix_size, 1,
> +                                                  U32_PAD(cmd->len));
> +
>        /* Increment and update queue's write index */
>        q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
>        ret = iwl_txq_update_write_ptr(priv, txq);
> diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
> index c29189b..c4c8943 100644
> --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
> +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
> @@ -972,7 +972,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
>        dma_addr_t phys_addr;
>        dma_addr_t txcmd_phys;
>        int txq_id = skb_get_queue_mapping(skb);
> -       u16 len, idx, len_org, hdr_len;
> +       u16 len, idx, len_org, hdr_len; /* TODO: len_org is not used */
>        u8 id;
>        u8 unicast;
>        u8 sta_id;
> @@ -1074,6 +1074,38 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
>        /* Copy MAC header from skb into command buffer */
>        memcpy(tx->hdr, hdr, hdr_len);
>
> +
> +       if (info->control.hw_key)
> +               iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, sta_id);
> +
> +       /* TODO need this for burst mode later on */
> +       iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, sta_id);
> +
> +       /* set is_hcca to 0; it probably will never be implemented */
> +       iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, info, hdr, sta_id, 0);
> +
> +       /* Total # bytes to be transmitted */
> +       len = (u16)skb->len;
> +       tx->len = cpu_to_le16(len);
> +
> +
> +       tx->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
> +       tx->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
> +
> +       if (!ieee80211_has_morefrags(hdr->frame_control)) {
> +               txq->need_update = 1;
> +               if (qc)
> +                       priv->stations_39[sta_id].tid[tid].seq_number = seq_number;
> +       } else {
> +               wait_write_ptr = 1;
> +               txq->need_update = 0;
> +       }
> +
> +       iwl_print_hex_dump(priv, IWL_DL_TX, tx, sizeof(*tx));
> +
> +       iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx->hdr,
> +                          ieee80211_hdrlen(fc));
> +
>        /*
>         * Use the first empty entry in this queue's command buffer array
>         * to contain the Tx command and MAC header concatenated together
> @@ -1096,22 +1128,18 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
>
>        /* Physical address of this Tx command's header (not MAC header!),
>         * within command buffer array. */
> -       txcmd_phys = pci_map_single(priv->pci_dev,
> -                                   out_cmd, sizeof(struct iwl_cmd),
> -                                   PCI_DMA_TODEVICE);
> +       txcmd_phys = pci_map_single(priv->pci_dev, &out_cmd->hdr,
> +                                   len, PCI_DMA_TODEVICE);
> +       /* we do not map meta data ... so we can safely access address to
> +        * provide to unmap command*/
>        pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys);
> -       pci_unmap_len_set(&out_cmd->meta, len, sizeof(struct iwl_cmd));
> -       /* Add buffer containing Tx command and MAC(!) header to TFD's
> -        * first entry */
> -       txcmd_phys += offsetof(struct iwl_cmd, hdr);
> +       pci_unmap_len_set(&out_cmd->meta, len, len);
>
>        /* Add buffer containing Tx command and MAC(!) header to TFD's
>         * first entry */
>        priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
>                                                   txcmd_phys, len, 1, 0);
>
> -       if (info->control.hw_key)
> -               iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, sta_id);
>
>        /* Set up TFD's 2nd entry to point directly to remainder of skb,
>         * if any (802.11 null frames have no payload). */
> @@ -1124,32 +1152,6 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
>                                                           0, U32_PAD(len));
>        }
>
> -       /* Total # bytes to be transmitted */
> -       len = (u16)skb->len;
> -       tx->len = cpu_to_le16(len);
> -
> -       /* TODO need this for burst mode later on */
> -       iwl3945_build_tx_cmd_basic(priv, out_cmd, info, hdr, sta_id);
> -
> -       /* set is_hcca to 0; it probably will never be implemented */
> -       iwl3945_hw_build_tx_cmd_rate(priv, out_cmd, info, hdr, sta_id, 0);
> -
> -       tx->tx_flags &= ~TX_CMD_FLG_ANT_A_MSK;
> -       tx->tx_flags &= ~TX_CMD_FLG_ANT_B_MSK;
> -
> -       if (!ieee80211_has_morefrags(hdr->frame_control)) {
> -               txq->need_update = 1;
> -               if (qc)
> -                       priv->stations_39[sta_id].tid[tid].seq_number = seq_number;
> -       } else {
> -               wait_write_ptr = 1;
> -               txq->need_update = 0;
> -       }
> -
> -       iwl_print_hex_dump(priv, IWL_DL_TX, tx, sizeof(*tx));
> -
> -       iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx->hdr,
> -                          ieee80211_hdrlen(fc));
>
>        /* Tell device the write index *just past* this latest filled TFD */
>        q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);
> @@ -1661,6 +1663,37 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv)
>        spin_unlock_irqrestore(&rxq->lock, flags);
>  }
>
> +void iwl3945_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
> +{
> +       unsigned long flags;
> +       int i;
> +       spin_lock_irqsave(&rxq->lock, flags);
> +       INIT_LIST_HEAD(&rxq->rx_free);
> +       INIT_LIST_HEAD(&rxq->rx_used);
> +       /* Fill the rx_used queue with _all_ of the Rx buffers */
> +       for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
> +               /* In the reset function, these buffers may have been allocated
> +                * to an SKB, so we need to unmap and free potential storage */
> +               if (rxq->pool[i].skb != NULL) {
> +                       pci_unmap_single(priv->pci_dev,
> +                                        rxq->pool[i].real_dma_addr,
> +                                        priv->hw_params.rx_buf_size,
> +                                        PCI_DMA_FROMDEVICE);
> +                       priv->alloc_rxb_skb--;
> +                       dev_kfree_skb(rxq->pool[i].skb);
> +                       rxq->pool[i].skb = NULL;
> +               }
> +               list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
> +       }
> +
> +       /* Set us so that we have processed and used all buffers, but have
> +        * not restocked the Rx queue with fresh buffers */
> +       rxq->read = rxq->write = 0;
> +       rxq->free_count = 0;
> +       spin_unlock_irqrestore(&rxq->lock, flags);
> +}
> +EXPORT_SYMBOL(iwl3945_rx_queue_reset);
> +
>  /*
>  * this should be called while priv->lock is locked
>  */
> @@ -1685,6 +1718,34 @@ void iwl3945_rx_replenish(void *data)
>        spin_unlock_irqrestore(&priv->lock, flags);
>  }
>
> +/* Assumes that the skb field of the buffers in 'pool' is kept accurate.
> + * If an SKB has been detached, the POOL needs to have its SKB set to NULL
> + * This free routine walks the list of POOL entries and if SKB is set to
> + * non NULL it is unmapped and freed
> + */
> +void iwl3945_rx_queue_free(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
> +{
> +       int i;
> +       for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {
> +               if (rxq->pool[i].skb != NULL) {
> +                       pci_unmap_single(priv->pci_dev,
> +                                        rxq->pool[i].real_dma_addr,
> +                                        priv->hw_params.rx_buf_size,
> +                                        PCI_DMA_FROMDEVICE);
> +                       dev_kfree_skb(rxq->pool[i].skb);
> +               }
> +       }
> +
> +       pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd,
> +                           rxq->dma_addr);
> +       pci_free_consistent(priv->pci_dev, sizeof(struct iwl_rb_status),
> +                           rxq->rb_stts, rxq->rb_stts_dma);
> +       rxq->bd = NULL;
> +       rxq->rb_stts  = NULL;
> +}
> +EXPORT_SYMBOL(iwl3945_rx_queue_free);
> +
> +
>  /* Convert linear signal-to-noise ratio into dB */
>  static u8 ratio2dB[100] = {
>  /*      0   1   2   3   4   5   6   7   8   9 */
> @@ -1802,9 +1863,9 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
>
>                rxq->queue[i] = NULL;
>
> -               pci_dma_sync_single_for_cpu(priv->pci_dev, rxb->real_dma_addr,
> -                                           priv->hw_params.rx_buf_size,
> -                                           PCI_DMA_FROMDEVICE);
> +               pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
> +                               priv->hw_params.rx_buf_size,
> +                               PCI_DMA_FROMDEVICE);
>                pkt = (struct iwl_rx_packet *)rxb->skb->data;
>
>                /* Reclaim a command buffer only if this packet is a response
> @@ -1852,9 +1913,6 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
>                        rxb->skb = NULL;
>                }
>
> -               pci_unmap_single(priv->pci_dev, rxb->real_dma_addr,
> -                               priv->hw_params.rx_buf_size,
> -                               PCI_DMA_FROMDEVICE);
>                spin_lock_irqsave(&rxq->lock, flags);
>                list_add_tail(&rxb->list, &priv->rxq.rx_used);
>                spin_unlock_irqrestore(&rxq->lock, flags);
> @@ -5144,7 +5202,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
>        iwl3945_dealloc_ucode_pci(priv);
>
>        if (priv->rxq.bd)
> -               iwl_rx_queue_free(priv, &priv->rxq);
> +               iwl3945_rx_queue_free(priv, &priv->rxq);
>        iwl3945_hw_txq_ctx_free(priv);
>
>        iwl3945_unset_hw_params(priv);
> --
> 1.5.6.3
>
>
>
>
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux