Skip to content

Commit

Permalink
Merge tag 'master-2012-10-08' of git://git.kernel.org/pub/scm/linux/k…
Browse files Browse the repository at this point in the history
…ernel/git/linville/wireless

John W. Linville says:

====================
Here is a batch of fixes intended for 3.7...

Amitkumar Karwar provides a couple of mwifiex fixes to correctly
report some reason codes for certain connection failures.  He also
provides a fix to cleanup after a scanning failure.  Bing Zhao rounds
that out with another mwifiex scanning fix.

Daniel Golle gives us a fix for a copy/paste error in rt2x00.

Felix Fietkau brings a couple of ath9k fixes related to suspend/resume,
and a couple of fixes to prevent memory leaks in ath9k and mac80211.

Ronald Wahl sends a carl9170 fix for a sleep in softirq context.

Thomas Pedersen reorders some code to prevent drv_get_tsf from being
called while holding a spinlock, now that it can sleep.

Finally, Wei Yongjun prevents a NULL pointer dereference in the
ath5k driver.

Please let me know if there are problems!
====================

Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
davem330 committed Oct 10, 2012
2 parents 2474542 + c3e7724 commit 8545768
Show file tree
Hide file tree
Showing 19 changed files with 151 additions and 106 deletions.
3 changes: 2 additions & 1 deletion drivers/net/wireless/ath/ath5k/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -1804,7 +1804,7 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
{
int ret;
struct ath5k_hw *ah = hw->priv;
struct ath5k_vif *avf = (void *)vif->drv_priv;
struct ath5k_vif *avf;
struct sk_buff *skb;

if (WARN_ON(!vif)) {
Expand All @@ -1819,6 +1819,7 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
goto out;
}

avf = (void *)vif->drv_priv;
ath5k_txbuf_free_skb(ah, avf->bbuf);
avf->bbuf->skb = skb;
ret = ath5k_beacon_setup(ah, avf->bbuf);
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 @@ -120,7 +120,7 @@ static void ath9k_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)

if (ath_tx_start(hw, skb, &txctl) != 0) {
ath_dbg(common, XMIT, "CABQ TX failed\n");
dev_kfree_skb_any(skb);
ieee80211_free_txskb(hw, skb);
}
}

Expand Down
5 changes: 5 additions & 0 deletions drivers/net/wireless/ath/ath9k/hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -1450,9 +1450,14 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
REG_WRITE(ah, AR_RTC_FORCE_WAKE,
AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);

if (!ah->reset_power_on)
type = ATH9K_RESET_POWER_ON;

switch (type) {
case ATH9K_RESET_POWER_ON:
ret = ath9k_hw_set_reset_power_on(ah);
if (!ret)
ah->reset_power_on = true;
break;
case ATH9K_RESET_WARM:
case ATH9K_RESET_COLD:
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/ath/ath9k/hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,7 @@ struct ath_hw {
u32 rfkill_polarity;
u32 ah_flags;

bool reset_power_on;
bool htc_reset_init;

enum nl80211_iftype opmode;
Expand Down
15 changes: 5 additions & 10 deletions drivers/net/wireless/ath/ath9k/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -639,8 +639,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
ath_err(common,
"Unable to reset hardware; reset status %d (freq %u MHz)\n",
r, curchan->center_freq);
spin_unlock_bh(&sc->sc_pcu_lock);
goto mutex_unlock;
ah->reset_power_on = false;
}

/* Setup our intr mask. */
Expand All @@ -665,11 +664,8 @@ static int ath9k_start(struct ieee80211_hw *hw)
clear_bit(SC_OP_INVALID, &sc->sc_flags);
sc->sc_ah->is_monitoring = false;

if (!ath_complete_reset(sc, false)) {
r = -EIO;
spin_unlock_bh(&sc->sc_pcu_lock);
goto mutex_unlock;
}
if (!ath_complete_reset(sc, false))
ah->reset_power_on = false;

if (ah->led_pin >= 0) {
ath9k_hw_cfg_output(ah, ah->led_pin,
Expand All @@ -688,12 +684,11 @@ static int ath9k_start(struct ieee80211_hw *hw)
if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en)
common->bus_ops->extn_synch_en(common);

mutex_unlock:
mutex_unlock(&sc->mutex);

ath9k_ps_restore(sc);

return r;
return 0;
}

static void ath9k_tx(struct ieee80211_hw *hw,
Expand Down Expand Up @@ -770,7 +765,7 @@ static void ath9k_tx(struct ieee80211_hw *hw,

return;
exit:
dev_kfree_skb_any(skb);
ieee80211_free_txskb(hw, skb);
}

static void ath9k_stop(struct ieee80211_hw *hw)
Expand Down
7 changes: 7 additions & 0 deletions drivers/net/wireless/ath/ath9k/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,10 @@ static int ath_pci_suspend(struct device *device)
static int ath_pci_resume(struct device *device)
{
struct pci_dev *pdev = to_pci_dev(device);
struct ieee80211_hw *hw = pci_get_drvdata(pdev);
struct ath_softc *sc = hw->priv;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
u32 val;

/*
Expand All @@ -335,6 +339,9 @@ static int ath_pci_resume(struct device *device)
if ((val & 0x0000ff00) != 0)
pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);

ath_pci_aspm_init(common);
ah->reset_power_on = false;

return 0;
}

Expand Down
53 changes: 29 additions & 24 deletions drivers/net/wireless/ath/ath9k/xmit.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,7 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
struct ath_txq *txq,
struct ath_atx_tid *tid,
struct sk_buff *skb,
bool dequeue);
struct sk_buff *skb);

enum {
MCS_HT20,
Expand Down Expand Up @@ -176,7 +175,15 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
fi = get_frame_info(skb);
bf = fi->bf;

if (bf && fi->retries) {
if (!bf) {
bf = ath_tx_setup_buffer(sc, txq, tid, skb);
if (!bf) {
ieee80211_free_txskb(sc->hw, skb);
continue;
}
}

if (fi->retries) {
list_add_tail(&bf->list, &bf_head);
ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
Expand Down Expand Up @@ -785,10 +792,13 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
fi = get_frame_info(skb);
bf = fi->bf;
if (!fi->bf)
bf = ath_tx_setup_buffer(sc, txq, tid, skb, true);
bf = ath_tx_setup_buffer(sc, txq, tid, skb);

if (!bf)
if (!bf) {
__skb_unlink(skb, &tid->buf_q);
ieee80211_free_txskb(sc->hw, skb);
continue;
}

bf->bf_state.bf_type = BUF_AMPDU | BUF_AGGR;
seqno = bf->bf_state.seqno;
Expand Down Expand Up @@ -1731,9 +1741,11 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
return;
}

bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false);
if (!bf)
bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
if (!bf) {
ieee80211_free_txskb(sc->hw, skb);
return;
}

bf->bf_state.bf_type = BUF_AMPDU;
INIT_LIST_HEAD(&bf_head);
Expand All @@ -1757,11 +1769,6 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
struct ath_buf *bf;

bf = fi->bf;
if (!bf)
bf = ath_tx_setup_buffer(sc, txq, tid, skb, false);

if (!bf)
return;

INIT_LIST_HEAD(&bf_head);
list_add_tail(&bf->list, &bf_head);
Expand Down Expand Up @@ -1839,8 +1846,7 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
struct ath_txq *txq,
struct ath_atx_tid *tid,
struct sk_buff *skb,
bool dequeue)
struct sk_buff *skb)
{
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
struct ath_frame_info *fi = get_frame_info(skb);
Expand All @@ -1852,7 +1858,7 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
bf = ath_tx_get_buffer(sc);
if (!bf) {
ath_dbg(common, XMIT, "TX buffers are full\n");
goto error;
return NULL;
}

ATH_TXBUF_RESET(bf);
Expand Down Expand Up @@ -1881,18 +1887,12 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
ath_err(ath9k_hw_common(sc->sc_ah),
"dma_mapping_error() on TX\n");
ath_tx_return_buffer(sc, bf);
goto error;
return NULL;
}

fi->bf = bf;

return bf;

error:
if (dequeue)
__skb_unlink(skb, &tid->buf_q);
dev_kfree_skb_any(skb);
return NULL;
}

/* FIXME: tx power */
Expand Down Expand Up @@ -1921,9 +1921,14 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
*/
ath_tx_send_ampdu(sc, tid, skb, txctl);
} else {
bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false);
if (!bf)
bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
if (!bf) {
if (txctl->paprd)
dev_kfree_skb_any(skb);
else
ieee80211_free_txskb(sc->hw, skb);
return;
}

bf->bf_state.bfs_paprd = txctl->paprd;

Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/ath/carl9170/carl9170.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ struct ar9170 {
unsigned long queue_stop_timeout[__AR9170_NUM_TXQ];
unsigned long max_queue_stop_timeout[__AR9170_NUM_TXQ];
bool needs_full_reset;
bool force_usb_reset;
atomic_t pending_restarts;

/* interface mode settings */
Expand Down
29 changes: 14 additions & 15 deletions drivers/net/wireless/ath/carl9170/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -465,27 +465,26 @@ static void carl9170_restart_work(struct work_struct *work)
{
struct ar9170 *ar = container_of(work, struct ar9170,
restart_work);
int err;
int err = -EIO;

ar->usedkeys = 0;
ar->filter_state = 0;
carl9170_cancel_worker(ar);

mutex_lock(&ar->mutex);
err = carl9170_usb_restart(ar);
if (net_ratelimit()) {
if (err) {
dev_err(&ar->udev->dev, "Failed to restart device "
" (%d).\n", err);
} else {
dev_info(&ar->udev->dev, "device restarted "
"successfully.\n");
if (!ar->force_usb_reset) {
err = carl9170_usb_restart(ar);
if (net_ratelimit()) {
if (err)
dev_err(&ar->udev->dev, "Failed to restart device (%d).\n", err);
else
dev_info(&ar->udev->dev, "device restarted successfully.\n");
}
}

carl9170_zap_queues(ar);
mutex_unlock(&ar->mutex);
if (!err) {

if (!err && !ar->force_usb_reset) {
ar->restart_counter++;
atomic_set(&ar->pending_restarts, 0);

Expand Down Expand Up @@ -526,10 +525,10 @@ void carl9170_restart(struct ar9170 *ar, const enum carl9170_restart_reasons r)
if (!ar->registered)
return;

if (IS_ACCEPTING_CMD(ar) && !ar->needs_full_reset)
ieee80211_queue_work(ar->hw, &ar->restart_work);
else
carl9170_usb_reset(ar);
if (!IS_ACCEPTING_CMD(ar) || ar->needs_full_reset)
ar->force_usb_reset = true;

ieee80211_queue_work(ar->hw, &ar->restart_work);

/*
* At this point, the device instance might have vanished/disabled.
Expand Down
27 changes: 21 additions & 6 deletions drivers/net/wireless/mwifiex/cfg80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -1596,8 +1596,9 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
}
}

if (mwifiex_bss_start(priv, bss, &req_ssid))
return -EFAULT;
ret = mwifiex_bss_start(priv, bss, &req_ssid);
if (ret)
return ret;

if (mode == NL80211_IFTYPE_ADHOC) {
/* Inform the BSS information to kernel, otherwise
Expand Down Expand Up @@ -1652,9 +1653,19 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
"info: association to bssid %pM failed\n",
priv->cfg_bssid);
memset(priv->cfg_bssid, 0, ETH_ALEN);

if (ret > 0)
cfg80211_connect_result(priv->netdev, priv->cfg_bssid,
NULL, 0, NULL, 0, ret,
GFP_KERNEL);
else
cfg80211_connect_result(priv->netdev, priv->cfg_bssid,
NULL, 0, NULL, 0,
WLAN_STATUS_UNSPECIFIED_FAILURE,
GFP_KERNEL);
}

return ret;
return 0;
}

/*
Expand Down Expand Up @@ -1802,7 +1813,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
{
struct net_device *dev = request->wdev->netdev;
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
int i, offset;
int i, offset, ret;
struct ieee80211_channel *chan;
struct ieee_types_header *ie;

Expand Down Expand Up @@ -1855,8 +1866,12 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,

priv->user_scan_cfg->chan_list[i].scan_time = 0;
}
if (mwifiex_scan_networks(priv, priv->user_scan_cfg))
return -EFAULT;

ret = mwifiex_scan_networks(priv, priv->user_scan_cfg);
if (ret) {
dev_err(priv->adapter->dev, "scan failed: %d\n", ret);
return ret;
}

if (request->ie && request->ie_len) {
for (i = 0; i < MWIFIEX_MAX_VSIE_NUM; i++) {
Expand Down
6 changes: 4 additions & 2 deletions drivers/net/wireless/mwifiex/join.c
Original file line number Diff line number Diff line change
Expand Up @@ -1180,16 +1180,18 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
struct mwifiex_adapter *adapter = priv->adapter;
struct host_cmd_ds_802_11_ad_hoc_result *adhoc_result;
struct mwifiex_bssdescriptor *bss_desc;
u16 reason_code;

adhoc_result = &resp->params.adhoc_result;

bss_desc = priv->attempted_bss_desc;

/* Join result code 0 --> SUCCESS */
if (le16_to_cpu(resp->result)) {
reason_code = le16_to_cpu(resp->result);
if (reason_code) {
dev_err(priv->adapter->dev, "ADHOC_RESP: failed\n");
if (priv->media_connected)
mwifiex_reset_connect_state(priv);
mwifiex_reset_connect_state(priv, reason_code);

memset(&priv->curr_bss_params.bss_descriptor,
0x00, sizeof(struct mwifiex_bssdescriptor));
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/mwifiex/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,7 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
struct mwifiex_bssdescriptor *bss_desc);
int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
struct host_cmd_ds_command *resp);
void mwifiex_reset_connect_state(struct mwifiex_private *priv);
void mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason);
u8 mwifiex_band_to_radio_type(u8 band);
int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac);
int mwifiex_adhoc_start(struct mwifiex_private *priv,
Expand Down
Loading

0 comments on commit 8545768

Please sign in to comment.