Skip to content

Commit

Permalink
Merge branch 'wireless'
Browse files Browse the repository at this point in the history
John W. Linville says:

====================
This batch of fixes is intended for 3.8...

Included is a Bluetooth pull.  Gustavo says:

"A few fixes for 3.8. Five of them are just new devices ids addition.
Apart from the that there is fix to a kernel memory leak to userspace from
Anderson Lizardo, two interoperability fixes from Jaganath Kanakkassery and
Szymon Janc. And a crash fix by me."

Along with that, Amitkumar Karwar brings a pair of mwifiex fixes for
problems related to handling of band information within the driver.
These problems can lead to association failures.

Sujith Manoharan fixes a memory leak in the ath9k_htc code (originally
reported by Larry Finger).

The big hero this round is Felix Fietkau.  Felix gives us seven
ath9k fixes, including a fix for a race condition, the removal of a
double-free, and a fix for a deadlock, among others.

These have all been in linux-next for at least a couple of days,
with no complaints so far.  Please let me know if there are problems!
====================

Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
davem330 committed Jan 17, 2013
2 parents fa1e492 + 811477d commit be05e45
Show file tree
Hide file tree
Showing 17 changed files with 73 additions and 88 deletions.
10 changes: 10 additions & 0 deletions drivers/bluetooth/ath3k.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,15 @@ static struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x0CF3, 0x311D) },
{ USB_DEVICE(0x13d3, 0x3375) },
{ USB_DEVICE(0x04CA, 0x3005) },
{ USB_DEVICE(0x04CA, 0x3006) },
{ USB_DEVICE(0x04CA, 0x3008) },
{ USB_DEVICE(0x13d3, 0x3362) },
{ USB_DEVICE(0x0CF3, 0xE004) },
{ USB_DEVICE(0x0930, 0x0219) },
{ USB_DEVICE(0x0489, 0xe057) },
{ USB_DEVICE(0x13d3, 0x3393) },
{ USB_DEVICE(0x0489, 0xe04e) },
{ USB_DEVICE(0x0489, 0xe056) },

/* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xE02C) },
Expand All @@ -104,10 +109,15 @@ static struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },

/* Atheros AR5BBU22 with sflash firmware */
{ USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
Expand Down
5 changes: 5 additions & 0 deletions drivers/bluetooth/btusb.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,15 @@ static struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },

/* Atheros AR5BBU12 with sflash firmware */
{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
Expand Down
3 changes: 0 additions & 3 deletions drivers/net/wireless/ath/ath9k/ath9k.h
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,6 @@ struct ath_rx {
u32 *rxlink;
u32 num_pkts;
unsigned int rxfilter;
spinlock_t rxbuflock;
struct list_head rxbuf;
struct ath_descdma rxdma;
struct ath_buf *rx_bufptr;
Expand All @@ -328,7 +327,6 @@ struct ath_rx {

int ath_startrecv(struct ath_softc *sc);
bool ath_stoprecv(struct ath_softc *sc);
void ath_flushrecv(struct ath_softc *sc);
u32 ath_calcrxfilter(struct ath_softc *sc);
int ath_rx_init(struct ath_softc *sc, int nbufs);
void ath_rx_cleanup(struct ath_softc *sc);
Expand Down Expand Up @@ -646,7 +644,6 @@ void ath_ant_comb_update(struct ath_softc *sc);
enum sc_op_flags {
SC_OP_INVALID,
SC_OP_BEACONS,
SC_OP_RXFLUSH,
SC_OP_ANI_RUN,
SC_OP_PRIM_STA_VIF,
SC_OP_HW_RESET,
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/ath/ath9k/beacon.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw,
skb->len, DMA_TO_DEVICE);
dev_kfree_skb_any(skb);
bf->bf_buf_addr = 0;
bf->bf_mpdu = NULL;
}

skb = ieee80211_beacon_get(hw, vif);
Expand Down Expand Up @@ -359,7 +360,6 @@ void ath9k_beacon_tasklet(unsigned long data)
return;

bf = ath9k_beacon_generate(sc->hw, vif);
WARN_ON(!bf);

if (sc->beacon.bmisscnt != 0) {
ath_dbg(common, BSTUCK, "resume beacon xmit after %u misses\n",
Expand Down
1 change: 0 additions & 1 deletion drivers/net/wireless/ath/ath9k/debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -861,7 +861,6 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
RXS_ERR("RX-LENGTH-ERR", rx_len_err);
RXS_ERR("RX-OOM-ERR", rx_oom_err);
RXS_ERR("RX-RATE-ERR", rx_rate_err);
RXS_ERR("RX-DROP-RXFLUSH", rx_drop_rxflush);
RXS_ERR("RX-TOO-MANY-FRAGS", rx_too_many_frags_err);

PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN);
Expand Down
2 changes: 0 additions & 2 deletions drivers/net/wireless/ath/ath9k/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,6 @@ struct ath_tx_stats {
* @rx_oom_err: No. of frames dropped due to OOM issues.
* @rx_rate_err: No. of frames dropped due to rate errors.
* @rx_too_many_frags_err: Frames dropped due to too-many-frags received.
* @rx_drop_rxflush: No. of frames dropped due to RX-FLUSH.
* @rx_beacons: No. of beacons received.
* @rx_frags: No. of rx-fragements received.
*/
Expand All @@ -235,7 +234,6 @@ struct ath_rx_stats {
u32 rx_oom_err;
u32 rx_rate_err;
u32 rx_too_many_frags_err;
u32 rx_drop_rxflush;
u32 rx_beacons;
u32 rx_frags;
};
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/wireless/ath/ath9k/htc_hst.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,8 @@ void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle,
endpoint->ep_callbacks.tx(endpoint->ep_callbacks.priv,
skb, htc_hdr->endpoint_id,
txok);
} else {
kfree_skb(skb);
}
}

Expand Down
19 changes: 6 additions & 13 deletions drivers/net/wireless/ath/ath9k/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ static void ath_restart_work(struct ath_softc *sc)
ath_start_ani(sc);
}

static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush)
static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx)
{
struct ath_hw *ah = sc->sc_ah;
bool ret = true;
Expand All @@ -202,14 +202,6 @@ static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush)
if (!ath_drain_all_txq(sc, retry_tx))
ret = false;

if (!flush) {
if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
ath_rx_tasklet(sc, 1, true);
ath_rx_tasklet(sc, 1, false);
} else {
ath_flushrecv(sc);
}

return ret;
}

Expand Down Expand Up @@ -262,11 +254,11 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_hw_cal_data *caldata = NULL;
bool fastcc = true;
bool flush = false;
int r;

__ath_cancel_work(sc);

tasklet_disable(&sc->intr_tq);
spin_lock_bh(&sc->sc_pcu_lock);

if (!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)) {
Expand All @@ -276,11 +268,10 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,

if (!hchan) {
fastcc = false;
flush = true;
hchan = ah->curchan;
}

if (!ath_prepare_reset(sc, retry_tx, flush))
if (!ath_prepare_reset(sc, retry_tx))
fastcc = false;

ath_dbg(common, CONFIG, "Reset to %u MHz, HT40: %d fastcc: %d\n",
Expand All @@ -302,6 +293,8 @@ static int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan,

out:
spin_unlock_bh(&sc->sc_pcu_lock);
tasklet_enable(&sc->intr_tq);

return r;
}

Expand Down Expand Up @@ -804,7 +797,7 @@ static void ath9k_stop(struct ieee80211_hw *hw)
ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
}

ath_prepare_reset(sc, false, true);
ath_prepare_reset(sc, false);

if (sc->rx.frag) {
dev_kfree_skb_any(sc->rx.frag);
Expand Down
54 changes: 15 additions & 39 deletions drivers/net/wireless/ath/ath9k/recv.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,8 +254,6 @@ static int ath_rx_edma_init(struct ath_softc *sc, int nbufs)

static void ath_edma_start_recv(struct ath_softc *sc)
{
spin_lock_bh(&sc->rx.rxbuflock);

ath9k_hw_rxena(sc->sc_ah);

ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP,
Expand All @@ -267,8 +265,6 @@ static void ath_edma_start_recv(struct ath_softc *sc)
ath_opmode_init(sc);

ath9k_hw_startpcureceive(sc->sc_ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL));

spin_unlock_bh(&sc->rx.rxbuflock);
}

static void ath_edma_stop_recv(struct ath_softc *sc)
Expand All @@ -285,8 +281,6 @@ int ath_rx_init(struct ath_softc *sc, int nbufs)
int error = 0;

spin_lock_init(&sc->sc_pcu_lock);
spin_lock_init(&sc->rx.rxbuflock);
clear_bit(SC_OP_RXFLUSH, &sc->sc_flags);

common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 +
sc->sc_ah->caps.rx_status_len;
Expand Down Expand Up @@ -447,7 +441,6 @@ int ath_startrecv(struct ath_softc *sc)
return 0;
}

spin_lock_bh(&sc->rx.rxbuflock);
if (list_empty(&sc->rx.rxbuf))
goto start_recv;

Expand All @@ -468,26 +461,31 @@ int ath_startrecv(struct ath_softc *sc)
ath_opmode_init(sc);
ath9k_hw_startpcureceive(ah, !!(sc->hw->conf.flags & IEEE80211_CONF_OFFCHANNEL));

spin_unlock_bh(&sc->rx.rxbuflock);

return 0;
}

static void ath_flushrecv(struct ath_softc *sc)
{
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
ath_rx_tasklet(sc, 1, true);
ath_rx_tasklet(sc, 1, false);
}

bool ath_stoprecv(struct ath_softc *sc)
{
struct ath_hw *ah = sc->sc_ah;
bool stopped, reset = false;

spin_lock_bh(&sc->rx.rxbuflock);
ath9k_hw_abortpcurecv(ah);
ath9k_hw_setrxfilter(ah, 0);
stopped = ath9k_hw_stopdmarecv(ah, &reset);

ath_flushrecv(sc);

if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
ath_edma_stop_recv(sc);
else
sc->rx.rxlink = NULL;
spin_unlock_bh(&sc->rx.rxbuflock);

if (!(ah->ah_flags & AH_UNPLUGGED) &&
unlikely(!stopped)) {
Expand All @@ -499,15 +497,6 @@ bool ath_stoprecv(struct ath_softc *sc)
return stopped && !reset;
}

void ath_flushrecv(struct ath_softc *sc)
{
set_bit(SC_OP_RXFLUSH, &sc->sc_flags);
if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
ath_rx_tasklet(sc, 1, true);
ath_rx_tasklet(sc, 1, false);
clear_bit(SC_OP_RXFLUSH, &sc->sc_flags);
}

static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb)
{
/* Check whether the Beacon frame has DTIM indicating buffered bc/mc */
Expand Down Expand Up @@ -744,6 +733,7 @@ static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
return NULL;
}

list_del(&bf->list);
if (!bf->bf_mpdu)
return bf;

Expand Down Expand Up @@ -1059,16 +1049,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
dma_type = DMA_FROM_DEVICE;

qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP;
spin_lock_bh(&sc->rx.rxbuflock);

tsf = ath9k_hw_gettsf64(ah);
tsf_lower = tsf & 0xffffffff;

do {
bool decrypt_error = false;
/* If handling rx interrupt and flush is in progress => exit */
if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags) && (flush == 0))
break;

memset(&rs, 0, sizeof(rs));
if (edma)
Expand Down Expand Up @@ -1111,15 +1097,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)

ath_debug_stat_rx(sc, &rs);

/*
* If we're asked to flush receive queue, directly
* chain it back at the queue without processing it.
*/
if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags)) {
RX_STAT_INC(rx_drop_rxflush);
goto requeue_drop_frag;
}

memset(rxs, 0, sizeof(struct ieee80211_rx_status));

rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
Expand Down Expand Up @@ -1254,19 +1231,18 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
sc->rx.frag = NULL;
}
requeue:
list_add_tail(&bf->list, &sc->rx.rxbuf);
if (flush)
continue;

if (edma) {
list_add_tail(&bf->list, &sc->rx.rxbuf);
ath_rx_edma_buf_link(sc, qtype);
} else {
list_move_tail(&bf->list, &sc->rx.rxbuf);
ath_rx_buf_link(sc, bf);
if (!flush)
ath9k_hw_rxena(ah);
ath9k_hw_rxena(ah);
}
} while (1);

spin_unlock_bh(&sc->rx.rxbuflock);

if (!(ah->imask & ATH9K_INT_RXEOL)) {
ah->imask |= (ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
ath9k_hw_set_interrupts(ah);
Expand Down
7 changes: 4 additions & 3 deletions drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -1407,9 +1407,10 @@ void brcms_add_timer(struct brcms_timer *t, uint ms, int periodic)
#endif
t->ms = ms;
t->periodic = (bool) periodic;
t->set = true;

atomic_inc(&t->wl->callbacks);
if (!t->set) {
t->set = true;
atomic_inc(&t->wl->callbacks);
}

ieee80211_queue_delayed_work(hw, &t->dly_wrk, msecs_to_jiffies(ms));
}
Expand Down
17 changes: 2 additions & 15 deletions drivers/net/wireless/mwifiex/cfg80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -1459,7 +1459,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
struct cfg80211_ssid req_ssid;
int ret, auth_type = 0;
struct cfg80211_bss *bss = NULL;
u8 is_scanning_required = 0, config_bands = 0;
u8 is_scanning_required = 0;

memset(&req_ssid, 0, sizeof(struct cfg80211_ssid));

Expand All @@ -1478,19 +1478,6 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
/* disconnect before try to associate */
mwifiex_deauthenticate(priv, NULL);

if (channel) {
if (mode == NL80211_IFTYPE_STATION) {
if (channel->band == IEEE80211_BAND_2GHZ)
config_bands = BAND_B | BAND_G | BAND_GN;
else
config_bands = BAND_A | BAND_AN;

if (!((config_bands | priv->adapter->fw_bands) &
~priv->adapter->fw_bands))
priv->adapter->config_bands = config_bands;
}
}

/* As this is new association, clear locally stored
* keys and security related flags */
priv->sec_info.wpa_enabled = false;
Expand Down Expand Up @@ -1707,7 +1694,7 @@ static int mwifiex_set_ibss_params(struct mwifiex_private *priv,

if (cfg80211_get_chandef_type(&params->chandef) !=
NL80211_CHAN_NO_HT)
config_bands |= BAND_GN;
config_bands |= BAND_G | BAND_GN;
} else {
if (cfg80211_get_chandef_type(&params->chandef) ==
NL80211_CHAN_NO_HT)
Expand Down
Loading

0 comments on commit be05e45

Please sign in to comment.