aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging
diff options
context:
space:
mode:
authorRoland Vossen <rvossen@broadcom.com>2011-03-10 05:35:06 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2011-03-14 14:44:02 -0400
commit0bf97bb1cff7204111c479c899dae30823314761 (patch)
tree377f4588342d49b0ef533827e7ae8fa9d10eab48 /drivers/staging
parent0789b0033112e301f086f99bd15c7d67c051a51e (diff)
staging: brcm80211: bugfix for NULL scb ptr dereference
The driver uses a struct called 'scb', this struct is primarily used for AMPDU functionality and is embedded in struct ieee80211_sta. To increase driver robustness, the case in which this scb pointer is NULL is now handled graceful. This paves the way for the next patch in this series. Signed-off-by: Roland Vossen <rvossen@broadcom.com> Reviewed-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c
index 7f8790d9b81..26dd9b6a875 100644
--- a/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c
+++ b/drivers/staging/brcm80211/brcmsmac/wlc_ampdu.c
@@ -900,13 +900,7 @@ wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
900 900
901 tx_info = IEEE80211_SKB_CB(p); 901 tx_info = IEEE80211_SKB_CB(p);
902 ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); 902 ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU);
903 ASSERT(scb);
904 ASSERT(scb->magic == SCB_MAGIC);
905 ASSERT(txs->status & TX_STATUS_AMPDU); 903 ASSERT(txs->status & TX_STATUS_AMPDU);
906 scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
907 ASSERT(scb_ampdu);
908 ini = SCB_AMPDU_INI(scb_ampdu, p->priority);
909 ASSERT(ini->scb == scb);
910 904
911 /* BMAC_NOTE: For the split driver, second level txstatus comes later 905 /* BMAC_NOTE: For the split driver, second level txstatus comes later
912 * So if the ACK was received then wait for the second level else just 906 * So if the ACK was received then wait for the second level else just
@@ -930,7 +924,33 @@ wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
930 s2 = R_REG(&wlc->regs->frmtxstatus2); 924 s2 = R_REG(&wlc->regs->frmtxstatus2);
931 } 925 }
932 926
933 wlc_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2); 927 if (likely(scb)) {
928 ASSERT(scb->magic == SCB_MAGIC);
929 scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
930 ASSERT(scb_ampdu);
931 ini = SCB_AMPDU_INI(scb_ampdu, p->priority);
932 ASSERT(ini->scb == scb);
933 wlc_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2);
934 } else {
935 /* loop through all pkts and free */
936 u8 queue = txs->frameid & TXFID_QUEUE_MASK;
937 d11txh_t *txh;
938 u16 mcl;
939 while (p) {
940 tx_info = IEEE80211_SKB_CB(p);
941 txh = (d11txh_t *) p->data;
942 mcl = le16_to_cpu(txh->MacTxControlLow);
943 ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU);
944 pkt_buf_free_skb(p);
945 /* break out if last packet of ampdu */
946 if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) ==
947 TXC_AMPDU_LAST)
948 break;
949 p = GETNEXTTXP(wlc, queue);
950 ASSERT(p != NULL);
951 }
952 wlc_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
953 }
934 wlc_ampdu_txflowcontrol(wlc, scb_ampdu, ini); 954 wlc_ampdu_txflowcontrol(wlc, scb_ampdu, ini);
935} 955}
936 956