diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
| -rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/mac80211.c | 16 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/main.c | 2 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/rxon.c | 12 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/rx.c | 23 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/tx.c | 8 | 
5 files changed, 43 insertions, 18 deletions
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index ff8162d4c45..2d9eee93c74 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -521,7 +521,7 @@ static void iwlagn_mac_tx(struct ieee80211_hw *hw,  		     ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);  	if (iwlagn_tx_skb(priv, control->sta, skb)) -		dev_kfree_skb_any(skb); +		ieee80211_free_txskb(hw, skb);  }  static void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw, @@ -1354,6 +1354,20 @@ static int iwlagn_mac_add_interface(struct ieee80211_hw *hw,  	vif_priv->ctx = ctx;  	ctx->vif = vif; +	/* +	 * In SNIFFER device type, the firmware reports the FCS to +	 * the host, rather than snipping it off. Unfortunately, +	 * mac80211 doesn't (yet) provide a per-packet flag for +	 * this, so that we have to set the hardware flag based +	 * on the interfaces added. As the monitor interface can +	 * only be present by itself, and will be removed before +	 * other interfaces are added, this is safe. +	 */ +	if (vif->type == NL80211_IFTYPE_MONITOR) +		priv->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS; +	else +		priv->hw->flags &= ~IEEE80211_HW_RX_INCLUDES_FCS; +  	err = iwl_setup_interface(priv, ctx);  	if (!err || reset)  		goto out; diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c index 7ff3f143067..408132cf83c 100644 --- a/drivers/net/wireless/iwlwifi/dvm/main.c +++ b/drivers/net/wireless/iwlwifi/dvm/main.c @@ -2114,7 +2114,7 @@ static void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)  	info = IEEE80211_SKB_CB(skb);  	iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]); -	dev_kfree_skb_any(skb); +	ieee80211_free_txskb(priv->hw, skb);  }  static void iwl_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) diff --git a/drivers/net/wireless/iwlwifi/dvm/rxon.c b/drivers/net/wireless/iwlwifi/dvm/rxon.c index 10896393e5a..2830ea29050 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rxon.c +++ b/drivers/net/wireless/iwlwifi/dvm/rxon.c @@ -1012,12 +1012,12 @@ static void iwl_calc_basic_rates(struct iwl_priv *priv,  	 * As a consequence, it's not as complicated as it sounds, just add  	 * any lower rates to the ACK rate bitmap.  	 */ -	if (IWL_RATE_11M_INDEX < lowest_present_ofdm) -		ofdm |= IWL_RATE_11M_MASK >> IWL_FIRST_CCK_RATE; -	if (IWL_RATE_5M_INDEX < lowest_present_ofdm) -		ofdm |= IWL_RATE_5M_MASK >> IWL_FIRST_CCK_RATE; -	if (IWL_RATE_2M_INDEX < lowest_present_ofdm) -		ofdm |= IWL_RATE_2M_MASK >> IWL_FIRST_CCK_RATE; +	if (IWL_RATE_11M_INDEX < lowest_present_cck) +		cck |= IWL_RATE_11M_MASK >> IWL_FIRST_CCK_RATE; +	if (IWL_RATE_5M_INDEX < lowest_present_cck) +		cck |= IWL_RATE_5M_MASK >> IWL_FIRST_CCK_RATE; +	if (IWL_RATE_2M_INDEX < lowest_present_cck) +		cck |= IWL_RATE_2M_MASK >> IWL_FIRST_CCK_RATE;  	/* 1M already there or needed so always add */  	cck |= IWL_RATE_1M_MASK >> IWL_FIRST_CCK_RATE; diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index 17c8e5d8268..bb69f8f90b3 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c @@ -321,6 +321,14 @@ static void iwl_rx_allocate(struct iwl_trans *trans, gfp_t priority)  			dma_map_page(trans->dev, page, 0,  				     PAGE_SIZE << trans_pcie->rx_page_order,  				     DMA_FROM_DEVICE); +		if (dma_mapping_error(trans->dev, rxb->page_dma)) { +			rxb->page = NULL; +			spin_lock_irqsave(&rxq->lock, flags); +			list_add(&rxb->list, &rxq->rx_used); +			spin_unlock_irqrestore(&rxq->lock, flags); +			__free_pages(page, trans_pcie->rx_page_order); +			return; +		}  		/* dma address must be no more than 36 bits */  		BUG_ON(rxb->page_dma & ~DMA_BIT_MASK(36));  		/* and also 256 byte aligned! */ @@ -488,8 +496,19 @@ static void iwl_rx_handle_rxbuf(struct iwl_trans *trans,  			dma_map_page(trans->dev, rxb->page, 0,  				     PAGE_SIZE << trans_pcie->rx_page_order,  				     DMA_FROM_DEVICE); -		list_add_tail(&rxb->list, &rxq->rx_free); -		rxq->free_count++; +		if (dma_mapping_error(trans->dev, rxb->page_dma)) { +			/* +			 * free the page(s) as well to not break +			 * the invariant that the items on the used +			 * list have no page(s) +			 */ +			__free_pages(rxb->page, trans_pcie->rx_page_order); +			rxb->page = NULL; +			list_add_tail(&rxb->list, &rxq->rx_used); +		} else { +			list_add_tail(&rxb->list, &rxq->rx_free); +			rxq->free_count++; +		}  	} else  		list_add_tail(&rxb->list, &rxq->rx_used);  	spin_unlock_irqrestore(&rxq->lock, flags); diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 105e3af3c62..79a4ddc002d 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -480,20 +480,12 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, int fifo,  void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id)  {  	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); -	u16 rd_ptr, wr_ptr; -	int n_bd = trans_pcie->txq[txq_id].q.n_bd;  	if (!test_and_clear_bit(txq_id, trans_pcie->queue_used)) {  		WARN_ONCE(1, "queue %d not used", txq_id);  		return;  	} -	rd_ptr = iwl_read_prph(trans, SCD_QUEUE_RDPTR(txq_id)) & (n_bd - 1); -	wr_ptr = iwl_read_prph(trans, SCD_QUEUE_WRPTR(txq_id)); - -	WARN_ONCE(rd_ptr != wr_ptr, "queue %d isn't empty: [%d,%d]", -		  txq_id, rd_ptr, wr_ptr); -  	iwl_txq_set_inactive(trans, txq_id);  	IWL_DEBUG_TX_QUEUES(trans, "Deactivate queue %d\n", txq_id);  }  |