Merge branch 'wireless'

John W. Linville says:

====================
This is a small batch of fixes intended for the 3.8 stream...

There are two pulls from Johannes.  Regarding mac80211, Johannes says:

"One fix from Dan for a possible memory overrun."

Regarding iwlwifi,  Johannes says:

"I have one fix from Emmanuel reverting a previous fix that caused
more trouble than it's worth."

Along with those:

Arend van Spriel fixes a fatal error in brcsmac related to tx status processing.

Bing Zhao corrects a problem where mwifiex would fail to complete a scan
in the event of an IE processing error.

Larry Finger fixes a thinko in rtlwifi in which the wrong skb variable
was being used in some cases.

Rafał Miłecki fixes a thinko in an ID check in the bcma flash code.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2013-02-01 14:50:16 -05:00
commit 9165bf273e
6 changed files with 25 additions and 41 deletions

View File

@ -21,7 +21,7 @@ int bcma_nflash_init(struct bcma_drv_cc *cc)
struct bcma_bus *bus = cc->core->bus; struct bcma_bus *bus = cc->core->bus;
if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4706 && if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4706 &&
cc->core->id.rev != 0x38) { cc->core->id.rev != 38) {
bcma_err(bus, "NAND flash on unsupported board!\n"); bcma_err(bus, "NAND flash on unsupported board!\n");
return -ENOTSUPP; return -ENOTSUPP;
} }

View File

@ -1027,7 +1027,6 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs)
static bool static bool
brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
{ {
bool morepending = false;
struct bcma_device *core; struct bcma_device *core;
struct tx_status txstatus, *txs; struct tx_status txstatus, *txs;
u32 s1, s2; u32 s1, s2;
@ -1041,23 +1040,20 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
txs = &txstatus; txs = &txstatus;
core = wlc_hw->d11core; core = wlc_hw->d11core;
*fatal = false; *fatal = false;
s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
while (!(*fatal)
&& (s1 & TXS_V)) {
/* !give others some time to run! */
if (n >= max_tx_num) {
morepending = true;
break;
}
while (n < max_tx_num) {
s1 = bcma_read32(core, D11REGOFFS(frmtxstatus));
if (s1 == 0xffffffff) { if (s1 == 0xffffffff) {
brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit, brcms_err(core, "wl%d: %s: dead chip\n", wlc_hw->unit,
__func__); __func__);
*fatal = true; *fatal = true;
return false; return false;
} }
s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2)); /* only process when valid */
if (!(s1 & TXS_V))
break;
s2 = bcma_read32(core, D11REGOFFS(frmtxstatus2));
txs->status = s1 & TXS_STATUS_MASK; txs->status = s1 & TXS_STATUS_MASK;
txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT; txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT;
txs->sequence = s2 & TXS_SEQ_MASK; txs->sequence = s2 & TXS_SEQ_MASK;
@ -1065,15 +1061,12 @@ brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal)
txs->lasttxtime = 0; txs->lasttxtime = 0;
*fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs); *fatal = brcms_c_dotxstatus(wlc_hw->wlc, txs);
if (*fatal == true)
s1 = bcma_read32(core, D11REGOFFS(frmtxstatus)); return false;
n++; n++;
} }
if (*fatal) return n >= max_tx_num;
return false;
return morepending;
} }
static void brcms_c_tbtt(struct brcms_c_info *wlc) static void brcms_c_tbtt(struct brcms_c_info *wlc)

View File

@ -1153,6 +1153,13 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
next_reclaimed = ssn; next_reclaimed = ssn;
} }
if (tid != IWL_TID_NON_QOS) {
priv->tid_data[sta_id][tid].next_reclaimed =
next_reclaimed;
IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d\n",
next_reclaimed);
}
iwl_trans_reclaim(priv->trans, txq_id, ssn, &skbs); iwl_trans_reclaim(priv->trans, txq_id, ssn, &skbs);
iwlagn_check_ratid_empty(priv, sta_id, tid); iwlagn_check_ratid_empty(priv, sta_id, tid);
@ -1203,28 +1210,11 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb,
if (!is_agg) if (!is_agg)
iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1); iwlagn_non_agg_tx_status(priv, ctx, hdr->addr1);
/*
* W/A for FW bug - the seq_ctl isn't updated when the
* queues are flushed. Fetch it from the packet itself
*/
if (!is_agg && status == TX_STATUS_FAIL_FIFO_FLUSHED) {
next_reclaimed = le16_to_cpu(hdr->seq_ctrl);
next_reclaimed =
SEQ_TO_SN(next_reclaimed + 0x10);
}
is_offchannel_skb = is_offchannel_skb =
(info->flags & IEEE80211_TX_CTL_TX_OFFCHAN); (info->flags & IEEE80211_TX_CTL_TX_OFFCHAN);
freed++; freed++;
} }
if (tid != IWL_TID_NON_QOS) {
priv->tid_data[sta_id][tid].next_reclaimed =
next_reclaimed;
IWL_DEBUG_TX_REPLY(priv, "Next reclaimed packet:%d\n",
next_reclaimed);
}
WARN_ON(!is_agg && freed != 1); WARN_ON(!is_agg && freed != 1);
/* /*

View File

@ -1563,7 +1563,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n", dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n",
scan_rsp->number_of_sets); scan_rsp->number_of_sets);
ret = -1; ret = -1;
goto done; goto check_next_scan;
} }
bytes_left = le16_to_cpu(scan_rsp->bss_descript_size); bytes_left = le16_to_cpu(scan_rsp->bss_descript_size);
@ -1634,7 +1634,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
if (!beacon_size || beacon_size > bytes_left) { if (!beacon_size || beacon_size > bytes_left) {
bss_info += bytes_left; bss_info += bytes_left;
bytes_left = 0; bytes_left = 0;
return -1; ret = -1;
goto check_next_scan;
} }
/* Initialize the current working beacon pointer for this BSS /* Initialize the current working beacon pointer for this BSS
@ -1690,7 +1691,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
dev_err(priv->adapter->dev, dev_err(priv->adapter->dev,
"%s: bytes left < IE length\n", "%s: bytes left < IE length\n",
__func__); __func__);
goto done; goto check_next_scan;
} }
if (element_id == WLAN_EID_DS_PARAMS) { if (element_id == WLAN_EID_DS_PARAMS) {
channel = *(current_ptr + sizeof(struct ieee_types_header)); channel = *(current_ptr + sizeof(struct ieee_types_header));
@ -1753,6 +1754,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
} }
} }
check_next_scan:
spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
if (list_empty(&adapter->scan_pending_q)) { if (list_empty(&adapter->scan_pending_q)) {
spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
@ -1813,7 +1815,6 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
} }
} }
done:
return ret; return ret;
} }

View File

@ -542,8 +542,8 @@ static void _rtl_rx_pre_process(struct ieee80211_hw *hw, struct sk_buff *skb)
WARN_ON(skb_queue_empty(&rx_queue)); WARN_ON(skb_queue_empty(&rx_queue));
while (!skb_queue_empty(&rx_queue)) { while (!skb_queue_empty(&rx_queue)) {
_skb = skb_dequeue(&rx_queue); _skb = skb_dequeue(&rx_queue);
_rtl_usb_rx_process_agg(hw, skb); _rtl_usb_rx_process_agg(hw, _skb);
ieee80211_rx_irqsafe(hw, skb); ieee80211_rx_irqsafe(hw, _skb);
} }
} }

View File

@ -1358,7 +1358,7 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
&iwe, IW_EV_UINT_LEN); &iwe, IW_EV_UINT_LEN);
} }
buf = kmalloc(30, GFP_ATOMIC); buf = kmalloc(31, GFP_ATOMIC);
if (buf) { if (buf) {
memset(&iwe, 0, sizeof(iwe)); memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVCUSTOM; iwe.cmd = IWEVCUSTOM;