Skip to content

Commit

Permalink
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/linville/wireless

John W. Linville says:

====================
Please pull this batch of fixes intended for the 3.14 stream...

For the mac80211 bits, Johannes says:

"This time I have a fix to get out of an 'infinite error state' in case
regulatory domain updates failed and two fixes for VHT associations: one
to not disconnect immediately when the AP uses more bandwidth than the
new regdomain would allow after a change due to association country
information getting used, and one for an issue in the code where
mac80211 doesn't correctly ignore a reserved field and then uses an HT
instead of VHT association."

For the iwlwifi bits, Emmanuel says:

"Johannes fixes a long standing bug in the AMPDU status reporting.
Max fixes the listen time which was way too long and causes trouble
to several APs."

Along with those, Bing Zhao marks the mwifiex_usb driver as _not_
supporting USB autosuspend after a number of problems with that have
been reported.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Mar 3, 2014
2 parents ec0223e + 0c6a481 commit 4823551
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 24 deletions.
14 changes: 9 additions & 5 deletions drivers/net/wireless/iwlwifi/dvm/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1291,8 +1291,6 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
struct iwl_compressed_ba_resp *ba_resp = (void *)pkt->data;
struct iwl_ht_agg *agg;
struct sk_buff_head reclaimed_skbs;
struct ieee80211_tx_info *info;
struct ieee80211_hdr *hdr;
struct sk_buff *skb;
int sta_id;
int tid;
Expand Down Expand Up @@ -1379,22 +1377,28 @@ int iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
freed = 0;

skb_queue_walk(&reclaimed_skbs, skb) {
hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_hdr *hdr = (void *)skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);

if (ieee80211_is_data_qos(hdr->frame_control))
freed++;
else
WARN_ON_ONCE(1);

info = IEEE80211_SKB_CB(skb);
iwl_trans_free_tx_cmd(priv->trans, info->driver_data[1]);

memset(&info->status, 0, sizeof(info->status));
/* Packet was transmitted successfully, failures come as single
* frames because before failing a frame the firmware transmits
* it without aggregation at least once.
*/
info->flags |= IEEE80211_TX_STAT_ACK;

if (freed == 1) {
/* this is the first skb we deliver in this batch */
/* put the rate scaling data there */
info = IEEE80211_SKB_CB(skb);
memset(&info->status, 0, sizeof(info->status));
info->flags |= IEEE80211_TX_STAT_ACK;
info->flags |= IEEE80211_TX_STAT_AMPDU;
info->status.ampdu_ack_len = ba_resp->txed_2_done;
info->status.ampdu_len = ba_resp->txed;
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlwifi/mvm/mvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ enum iwl_power_scheme {
IWL_POWER_SCHEME_LP
};

#define IWL_CONN_MAX_LISTEN_INTERVAL 70
#define IWL_CONN_MAX_LISTEN_INTERVAL 10
#define IWL_UAPSD_AC_INFO (IEEE80211_WMM_IE_STA_QOSINFO_AC_VO |\
IEEE80211_WMM_IE_STA_QOSINFO_AC_VI |\
IEEE80211_WMM_IE_STA_QOSINFO_AC_BK |\
Expand Down
18 changes: 9 additions & 9 deletions drivers/net/wireless/iwlwifi/mvm/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -822,16 +822,12 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
struct iwl_mvm_ba_notif *ba_notif = (void *)pkt->data;
struct sk_buff_head reclaimed_skbs;
struct iwl_mvm_tid_data *tid_data;
struct ieee80211_tx_info *info;
struct ieee80211_sta *sta;
struct iwl_mvm_sta *mvmsta;
struct ieee80211_hdr *hdr;
struct sk_buff *skb;
int sta_id, tid, freed;

/* "flow" corresponds to Tx queue */
u16 scd_flow = le16_to_cpu(ba_notif->scd_flow);

/* "ssn" is start of block-ack Tx window, corresponds to index
* (in Tx queue's circular buffer) of first TFD/frame in window */
u16 ba_resp_scd_ssn = le16_to_cpu(ba_notif->scd_ssn);
Expand Down Expand Up @@ -888,22 +884,26 @@ int iwl_mvm_rx_ba_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
freed = 0;

skb_queue_walk(&reclaimed_skbs, skb) {
hdr = (struct ieee80211_hdr *)skb->data;
struct ieee80211_hdr *hdr = (void *)skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);

if (ieee80211_is_data_qos(hdr->frame_control))
freed++;
else
WARN_ON_ONCE(1);

info = IEEE80211_SKB_CB(skb);
iwl_trans_free_tx_cmd(mvm->trans, info->driver_data[1]);

memset(&info->status, 0, sizeof(info->status));
/* Packet was transmitted successfully, failures come as single
* frames because before failing a frame the firmware transmits
* it without aggregation at least once.
*/
info->flags |= IEEE80211_TX_STAT_ACK;

if (freed == 1) {
/* this is the first skb we deliver in this batch */
/* put the rate scaling data there */
info = IEEE80211_SKB_CB(skb);
memset(&info->status, 0, sizeof(info->status));
info->flags |= IEEE80211_TX_STAT_ACK;
info->flags |= IEEE80211_TX_STAT_AMPDU;
info->status.ampdu_ack_len = ba_notif->txed_2_done;
info->status.ampdu_len = ba_notif->txed;
Expand Down
8 changes: 0 additions & 8 deletions drivers/net/wireless/mwifiex/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -525,13 +525,6 @@ static int mwifiex_usb_resume(struct usb_interface *intf)
MWIFIEX_BSS_ROLE_ANY),
MWIFIEX_ASYNC_CMD);

#ifdef CONFIG_PM
/* Resume handler may be called due to remote wakeup,
* force to exit suspend anyway
*/
usb_disable_autosuspend(card->udev);
#endif /* CONFIG_PM */

return 0;
}

Expand Down Expand Up @@ -571,7 +564,6 @@ static struct usb_driver mwifiex_usb_driver = {
.id_table = mwifiex_usb_table,
.suspend = mwifiex_usb_suspend,
.resume = mwifiex_usb_resume,
.supports_autosuspend = 1,
};

static int mwifiex_usb_tx_init(struct mwifiex_adapter *adapter)
Expand Down
23 changes: 23 additions & 0 deletions net/mac80211/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
switch (vht_oper->chan_width) {
case IEEE80211_VHT_CHANWIDTH_USE_HT:
vht_chandef.width = chandef->width;
vht_chandef.center_freq1 = chandef->center_freq1;
break;
case IEEE80211_VHT_CHANWIDTH_80MHZ:
vht_chandef.width = NL80211_CHAN_WIDTH_80;
Expand Down Expand Up @@ -271,6 +272,28 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
ret = 0;

out:
/*
* When tracking the current AP, don't do any further checks if the
* new chandef is identical to the one we're currently using for the
* connection. This keeps us from playing ping-pong with regulatory,
* without it the following can happen (for example):
* - connect to an AP with 80 MHz, world regdom allows 80 MHz
* - AP advertises regdom US
* - CRDA loads regdom US with 80 MHz prohibited (old database)
* - the code below detects an unsupported channel, downgrades, and
* we disconnect from the AP in the caller
* - disconnect causes CRDA to reload world regdomain and the game
* starts anew.
* (see https://bugzilla.kernel.org/show_bug.cgi?id=70881)
*
* It seems possible that there are still scenarios with CSA or real
* bandwidth changes where a this could happen, but those cases are
* less common and wouldn't completely prevent using the AP.
*/
if (tracking &&
cfg80211_chandef_identical(chandef, &sdata->vif.bss_conf.chandef))
return ret;

/* don't print the message below for VHT mismatch if VHT is disabled */
if (ret & IEEE80211_STA_DISABLE_VHT)
vht_chandef = *chandef;
Expand Down
10 changes: 9 additions & 1 deletion net/wireless/reg.c
Original file line number Diff line number Diff line change
Expand Up @@ -2373,6 +2373,7 @@ static int reg_set_rd_country_ie(const struct ieee80211_regdomain *rd,
int set_regdom(const struct ieee80211_regdomain *rd)
{
struct regulatory_request *lr;
bool user_reset = false;
int r;

if (!reg_is_valid_request(rd->alpha2)) {
Expand All @@ -2389,6 +2390,7 @@ int set_regdom(const struct ieee80211_regdomain *rd)
break;
case NL80211_REGDOM_SET_BY_USER:
r = reg_set_rd_user(rd, lr);
user_reset = true;
break;
case NL80211_REGDOM_SET_BY_DRIVER:
r = reg_set_rd_driver(rd, lr);
Expand All @@ -2402,8 +2404,14 @@ int set_regdom(const struct ieee80211_regdomain *rd)
}

if (r) {
if (r == -EALREADY)
switch (r) {
case -EALREADY:
reg_set_request_processed();
break;
default:
/* Back to world regulatory in case of errors */
restore_regulatory_settings(user_reset);
}

kfree(rd);
return r;
Expand Down

0 comments on commit 4823551

Please sign in to comment.