Commit 5a292f7b authored by David S. Miller's avatar David S. Miller

Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless

John W. Linville says:

====================
pull request: wireless 2014-04-17

Please pull this batch of fixes intended for the 3.15 stream...

For the mac80211 bits, Johannes says:

"We have a fix from Chun-Yeow to not look at management frame bitrates
that are typically really low, two fixes from Felix for AP_VLAN
interfaces, a fix from Ido to disable SMPS settings when a monitor
interface is enabled, a radar detection fix from Michał and a fix from
myself for a very old remain-on-channel bug."

For the iwlwifi bits, Emmanuel says:

"I have new device IDs and a new firmware API. These are the trivial
ones. The less trivial ones are Johannes's fix that delays the
enablement of an interrupt coalescing hardware until after association
- this fixes a few connection problems seen in the field. Eyal has a
bunch of rate control fixes. I decided to add these for 3.15 because
they fix some disconnection and packet loss scenarios which were
reported by the field. I also have a fix for a memory leak that
happens only with a very new NIC."

Along with those...

Amitkumar Karwar fixes a couple of problems relating to driver/firmware
interactions in mwifiex.

Christian Engelmayer avoids a couple of potential memory leaks in
the new rsi driver.

Eliad Peller provides a wl18xx mailbox alignment fix for problems
when using new firmware.

Frederic Danis adds a couple of missing debugging strings to the
cw1200 driver.

Geert Uytterhoeven adds a variable initialization inside of the
rsi driver.

Luciano Coelho patches the wlcore code to ignore dummy packet events
in PLT mode in order to work around a firmware bug.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ba67b510 4a0c3d9f
...@@ -41,6 +41,8 @@ static const char * const cw1200_debug_link_id[] = { ...@@ -41,6 +41,8 @@ static const char * const cw1200_debug_link_id[] = {
"REQ", "REQ",
"SOFT", "SOFT",
"HARD", "HARD",
"RESET",
"RESET_REMAP",
}; };
static const char *cw1200_debug_mode(int mode) static const char *cw1200_debug_mode(int mode)
......
...@@ -67,8 +67,8 @@ ...@@ -67,8 +67,8 @@
#include "iwl-agn-hw.h" #include "iwl-agn-hw.h"
/* Highest firmware API version supported */ /* Highest firmware API version supported */
#define IWL7260_UCODE_API_MAX 8 #define IWL7260_UCODE_API_MAX 9
#define IWL3160_UCODE_API_MAX 8 #define IWL3160_UCODE_API_MAX 9
/* Oldest version we won't warn about */ /* Oldest version we won't warn about */
#define IWL7260_UCODE_API_OK 8 #define IWL7260_UCODE_API_OK 8
...@@ -244,3 +244,4 @@ const struct iwl_cfg iwl7265_n_cfg = { ...@@ -244,3 +244,4 @@ const struct iwl_cfg iwl7265_n_cfg = {
MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK)); MODULE_FIRMWARE(IWL7260_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK)); MODULE_FIRMWARE(IWL3160_MODULE_FIRMWARE(IWL3160_UCODE_API_OK));
MODULE_FIRMWARE(IWL7265_MODULE_FIRMWARE(IWL7260_UCODE_API_OK));
...@@ -190,7 +190,7 @@ static const __le32 iwl_combined_lookup[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE] = { ...@@ -190,7 +190,7 @@ static const __le32 iwl_combined_lookup[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE] = {
cpu_to_le32(0xcc00aaaa), cpu_to_le32(0xcc00aaaa),
cpu_to_le32(0x0000aaaa), cpu_to_le32(0x0000aaaa),
cpu_to_le32(0xc0004000), cpu_to_le32(0xc0004000),
cpu_to_le32(0x00000000), cpu_to_le32(0x00004000),
cpu_to_le32(0xf0005000), cpu_to_le32(0xf0005000),
cpu_to_le32(0xf0005000), cpu_to_le32(0xf0005000),
}, },
...@@ -213,16 +213,16 @@ static const __le32 iwl_combined_lookup[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE] = { ...@@ -213,16 +213,16 @@ static const __le32 iwl_combined_lookup[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE] = {
/* Tx Tx disabled */ /* Tx Tx disabled */
cpu_to_le32(0xaaaaaaaa), cpu_to_le32(0xaaaaaaaa),
cpu_to_le32(0xaaaaaaaa), cpu_to_le32(0xaaaaaaaa),
cpu_to_le32(0xaaaaaaaa), cpu_to_le32(0xeeaaaaaa),
cpu_to_le32(0xaaaaaaaa), cpu_to_le32(0xaaaaaaaa),
cpu_to_le32(0xcc00ff28), cpu_to_le32(0xcc00ff28),
cpu_to_le32(0x0000aaaa), cpu_to_le32(0x0000aaaa),
cpu_to_le32(0xcc00aaaa), cpu_to_le32(0xcc00aaaa),
cpu_to_le32(0x0000aaaa), cpu_to_le32(0x0000aaaa),
cpu_to_le32(0xC0004000), cpu_to_le32(0xc0004000),
cpu_to_le32(0xC0004000), cpu_to_le32(0xc0004000),
cpu_to_le32(0xF0005000), cpu_to_le32(0xf0005000),
cpu_to_le32(0xF0005000), cpu_to_le32(0xf0005000),
}, },
}; };
...@@ -1262,6 +1262,7 @@ int iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm, ...@@ -1262,6 +1262,7 @@ int iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
struct iwl_rx_packet *pkt = rxb_addr(rxb); struct iwl_rx_packet *pkt = rxb_addr(rxb);
u32 ant_isolation = le32_to_cpup((void *)pkt->data); u32 ant_isolation = le32_to_cpup((void *)pkt->data);
u8 __maybe_unused lower_bound, upper_bound; u8 __maybe_unused lower_bound, upper_bound;
int ret;
u8 lut; u8 lut;
struct iwl_bt_coex_cmd *bt_cmd; struct iwl_bt_coex_cmd *bt_cmd;
...@@ -1318,5 +1319,8 @@ int iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm, ...@@ -1318,5 +1319,8 @@ int iwl_mvm_rx_ant_coupling_notif(struct iwl_mvm *mvm,
memcpy(bt_cmd->bt4_corun_lut40, antenna_coupling_ranges[lut].lut20, memcpy(bt_cmd->bt4_corun_lut40, antenna_coupling_ranges[lut].lut20,
sizeof(bt_cmd->bt4_corun_lut40)); sizeof(bt_cmd->bt4_corun_lut40));
return 0; ret = iwl_mvm_send_cmd(mvm, &cmd);
kfree(bt_cmd);
return ret;
} }
...@@ -1332,6 +1332,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, ...@@ -1332,6 +1332,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
*/ */
iwl_mvm_remove_time_event(mvm, mvmvif, iwl_mvm_remove_time_event(mvm, mvmvif,
&mvmvif->time_event_data); &mvmvif->time_event_data);
iwl_mvm_sf_update(mvm, vif, false);
WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, CMD_SYNC)); WARN_ON(iwl_mvm_enable_beacon_filter(mvm, vif, CMD_SYNC));
} else if (changes & (BSS_CHANGED_PS | BSS_CHANGED_P2P_PS | } else if (changes & (BSS_CHANGED_PS | BSS_CHANGED_P2P_PS |
BSS_CHANGED_QOS)) { BSS_CHANGED_QOS)) {
......
This diff is collapsed.
...@@ -156,6 +156,7 @@ enum { ...@@ -156,6 +156,7 @@ enum {
#define IWL_RATE_HIGH_TH 10880 /* 85% */ #define IWL_RATE_HIGH_TH 10880 /* 85% */
#define IWL_RATE_INCREASE_TH 6400 /* 50% */ #define IWL_RATE_INCREASE_TH 6400 /* 50% */
#define RS_SR_FORCE_DECREASE 1920 /* 15% */ #define RS_SR_FORCE_DECREASE 1920 /* 15% */
#define RS_SR_NO_DECREASE 10880 /* 85% */
#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */ #define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) /* 4 milliseconds */
#define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000) #define LINK_QUAL_AGG_TIME_LIMIT_MAX (8000)
...@@ -310,13 +311,20 @@ struct iwl_lq_sta { ...@@ -310,13 +311,20 @@ struct iwl_lq_sta {
u32 visited_columns; /* Bitmask marking which Tx columns were u32 visited_columns; /* Bitmask marking which Tx columns were
* explored during a search cycle * explored during a search cycle
*/ */
u64 last_tx;
bool is_vht; bool is_vht;
enum ieee80211_band band; enum ieee80211_band band;
/* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
u16 active_legacy_rate; unsigned long active_legacy_rate;
u16 active_siso_rate; unsigned long active_siso_rate;
u16 active_mimo2_rate; unsigned long active_mimo2_rate;
/* Highest rate per Tx mode */
u8 max_legacy_rate_idx;
u8 max_siso_rate_idx;
u8 max_mimo2_rate_idx;
s8 max_rate_idx; /* Max rate set by user */ s8 max_rate_idx; /* Max rate set by user */
u8 missed_rate_counter; u8 missed_rate_counter;
......
...@@ -274,7 +274,8 @@ int iwl_mvm_sf_update(struct iwl_mvm *mvm, struct ieee80211_vif *changed_vif, ...@@ -274,7 +274,8 @@ int iwl_mvm_sf_update(struct iwl_mvm *mvm, struct ieee80211_vif *changed_vif,
return -EINVAL; return -EINVAL;
if (changed_vif->type != NL80211_IFTYPE_STATION) { if (changed_vif->type != NL80211_IFTYPE_STATION) {
new_state = SF_UNINIT; new_state = SF_UNINIT;
} else if (changed_vif->bss_conf.assoc) { } else if (changed_vif->bss_conf.assoc &&
changed_vif->bss_conf.dtim_period) {
mvmvif = iwl_mvm_vif_from_mac80211(changed_vif); mvmvif = iwl_mvm_vif_from_mac80211(changed_vif);
sta_id = mvmvif->ap_sta_id; sta_id = mvmvif->ap_sta_id;
new_state = SF_FULL_ON; new_state = SF_FULL_ON;
......
...@@ -373,12 +373,14 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = { ...@@ -373,12 +373,14 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
{IWL_PCI_DEVICE(0x095A, 0x500A, iwl7265_2n_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x500A, iwl7265_2n_cfg)},
{IWL_PCI_DEVICE(0x095B, 0x5200, iwl7265_2n_cfg)}, {IWL_PCI_DEVICE(0x095B, 0x5200, iwl7265_2n_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x5002, iwl7265_n_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x5002, iwl7265_n_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x5102, iwl7265_n_cfg)},
{IWL_PCI_DEVICE(0x095B, 0x5202, iwl7265_n_cfg)}, {IWL_PCI_DEVICE(0x095B, 0x5202, iwl7265_n_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9010, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x9010, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9012, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x9012, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x9110, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9112, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x9112, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x9210, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9200, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x9510, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9310, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x9310, iwl7265_2ac_cfg)},
{IWL_PCI_DEVICE(0x095A, 0x9410, iwl7265_2ac_cfg)}, {IWL_PCI_DEVICE(0x095A, 0x9410, iwl7265_2ac_cfg)},
......
...@@ -292,6 +292,12 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter) ...@@ -292,6 +292,12 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
while ((skb = skb_dequeue(&adapter->usb_rx_data_q))) while ((skb = skb_dequeue(&adapter->usb_rx_data_q)))
mwifiex_handle_rx_packet(adapter, skb); mwifiex_handle_rx_packet(adapter, skb);
/* Check for event */
if (adapter->event_received) {
adapter->event_received = false;
mwifiex_process_event(adapter);
}
/* Check for Cmd Resp */ /* Check for Cmd Resp */
if (adapter->cmd_resp_received) { if (adapter->cmd_resp_received) {
adapter->cmd_resp_received = false; adapter->cmd_resp_received = false;
...@@ -304,12 +310,6 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter) ...@@ -304,12 +310,6 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
} }
} }
/* Check for event */
if (adapter->event_received) {
adapter->event_received = false;
mwifiex_process_event(adapter);
}
/* Check if we need to confirm Sleep Request /* Check if we need to confirm Sleep Request
received previously */ received previously */
if (adapter->ps_state == PS_STATE_PRE_SLEEP) { if (adapter->ps_state == PS_STATE_PRE_SLEEP) {
......
...@@ -60,9 +60,10 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter, ...@@ -60,9 +60,10 @@ int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter,
int status; int status;
/* Wait for completion */ /* Wait for completion */
status = wait_event_interruptible(adapter->cmd_wait_q.wait, status = wait_event_interruptible_timeout(adapter->cmd_wait_q.wait,
*(cmd_queued->condition)); *(cmd_queued->condition),
if (status) { (12 * HZ));
if (status <= 0) {
dev_err(adapter->dev, "cmd_wait_q terminated: %d\n", status); dev_err(adapter->dev, "cmd_wait_q terminated: %d\n", status);
mwifiex_cancel_all_pending_cmd(adapter); mwifiex_cancel_all_pending_cmd(adapter);
return status; return status;
......
...@@ -88,7 +88,7 @@ static u8 rsi_core_determine_hal_queue(struct rsi_common *common) ...@@ -88,7 +88,7 @@ static u8 rsi_core_determine_hal_queue(struct rsi_common *common)
bool recontend_queue = false; bool recontend_queue = false;
u32 q_len = 0; u32 q_len = 0;
u8 q_num = INVALID_QUEUE; u8 q_num = INVALID_QUEUE;
u8 ii, min = 0; u8 ii = 0, min = 0;
if (skb_queue_len(&common->tx_queue[MGMT_SOFT_Q])) { if (skb_queue_len(&common->tx_queue[MGMT_SOFT_Q])) {
if (!common->mgmt_q_block) if (!common->mgmt_q_block)
......
...@@ -841,16 +841,6 @@ int rsi_set_channel(struct rsi_common *common, u16 channel) ...@@ -841,16 +841,6 @@ int rsi_set_channel(struct rsi_common *common, u16 channel)
rsi_dbg(MGMT_TX_ZONE, rsi_dbg(MGMT_TX_ZONE,
"%s: Sending scan req frame\n", __func__); "%s: Sending scan req frame\n", __func__);
skb = dev_alloc_skb(FRAME_DESC_SZ);
if (!skb) {
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
__func__);
return -ENOMEM;
}
memset(skb->data, 0, FRAME_DESC_SZ);
mgmt_frame = (struct rsi_mac_frame *)skb->data;
if (common->band == IEEE80211_BAND_5GHZ) { if (common->band == IEEE80211_BAND_5GHZ) {
if ((channel >= 36) && (channel <= 64)) if ((channel >= 36) && (channel <= 64))
channel = ((channel - 32) / 4); channel = ((channel - 32) / 4);
...@@ -868,6 +858,16 @@ int rsi_set_channel(struct rsi_common *common, u16 channel) ...@@ -868,6 +858,16 @@ int rsi_set_channel(struct rsi_common *common, u16 channel)
} }
} }
skb = dev_alloc_skb(FRAME_DESC_SZ);
if (!skb) {
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of skb\n",
__func__);
return -ENOMEM;
}
memset(skb->data, 0, FRAME_DESC_SZ);
mgmt_frame = (struct rsi_mac_frame *)skb->data;
mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12); mgmt_frame->desc_word[0] = cpu_to_le16(RSI_WIFI_MGMT_Q << 12);
mgmt_frame->desc_word[1] = cpu_to_le16(SCAN_REQUEST); mgmt_frame->desc_word[1] = cpu_to_le16(SCAN_REQUEST);
mgmt_frame->desc_word[4] = cpu_to_le16(channel); mgmt_frame->desc_word[4] = cpu_to_le16(channel);
...@@ -966,6 +966,7 @@ static int rsi_send_auto_rate_request(struct rsi_common *common) ...@@ -966,6 +966,7 @@ static int rsi_send_auto_rate_request(struct rsi_common *common)
if (!selected_rates) { if (!selected_rates) {
rsi_dbg(ERR_ZONE, "%s: Failed in allocation of mem\n", rsi_dbg(ERR_ZONE, "%s: Failed in allocation of mem\n",
__func__); __func__);
dev_kfree_skb(skb);
return -ENOMEM; return -ENOMEM;
} }
......
...@@ -68,6 +68,26 @@ struct wl18xx_event_mailbox { ...@@ -68,6 +68,26 @@ struct wl18xx_event_mailbox {
/* bitmap of inactive stations (by HLID) */ /* bitmap of inactive stations (by HLID) */
__le32 inactive_sta_bitmap; __le32 inactive_sta_bitmap;
/* rx BA win size indicated by RX_BA_WIN_SIZE_CHANGE_EVENT_ID */
u8 rx_ba_role_id;
u8 rx_ba_link_id;
u8 rx_ba_win_size;
u8 padding;
/* smart config */
u8 sc_ssid_len;
u8 sc_pwd_len;
u8 sc_token_len;
u8 padding1;
u8 sc_ssid[32];
u8 sc_pwd[32];
u8 sc_token[32];
/* smart config sync channel */
u8 sc_sync_channel;
u8 sc_sync_band;
u8 padding2[2];
} __packed; } __packed;
int wl18xx_wait_for_event(struct wl1271 *wl, enum wlcore_wait_event event, int wl18xx_wait_for_event(struct wl1271 *wl, enum wlcore_wait_event event,
......
...@@ -158,6 +158,11 @@ EXPORT_SYMBOL_GPL(wlcore_event_channel_switch); ...@@ -158,6 +158,11 @@ EXPORT_SYMBOL_GPL(wlcore_event_channel_switch);
void wlcore_event_dummy_packet(struct wl1271 *wl) void wlcore_event_dummy_packet(struct wl1271 *wl)
{ {
if (wl->plt) {
wl1271_info("Got DUMMY_PACKET event in PLT mode. FW bug, ignoring.");
return;
}
wl1271_debug(DEBUG_EVENT, "DUMMY_PACKET_ID_EVENT_ID"); wl1271_debug(DEBUG_EVENT, "DUMMY_PACKET_ID_EVENT_ID");
wl1271_tx_dummy_packet(wl); wl1271_tx_dummy_packet(wl);
} }
......
...@@ -249,7 +249,7 @@ ieee80211_new_chanctx(struct ieee80211_local *local, ...@@ -249,7 +249,7 @@ ieee80211_new_chanctx(struct ieee80211_local *local,
if (!local->use_chanctx) { if (!local->use_chanctx) {
local->_oper_chandef = *chandef; local->_oper_chandef = *chandef;
ieee80211_hw_config(local, 0); ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
} else { } else {
err = drv_add_chanctx(local, ctx); err = drv_add_chanctx(local, ctx);
if (err) { if (err) {
...@@ -286,7 +286,7 @@ static void ieee80211_free_chanctx(struct ieee80211_local *local, ...@@ -286,7 +286,7 @@ static void ieee80211_free_chanctx(struct ieee80211_local *local,
check_single_channel = true; check_single_channel = true;
local->hw.conf.radar_enabled = false; local->hw.conf.radar_enabled = false;
ieee80211_hw_config(local, 0); ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
} else { } else {
drv_remove_chanctx(local, ctx); drv_remove_chanctx(local, ctx);
} }
...@@ -492,6 +492,13 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, ...@@ -492,6 +492,13 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
rx_chains_static = max(rx_chains_static, needed_static); rx_chains_static = max(rx_chains_static, needed_static);
rx_chains_dynamic = max(rx_chains_dynamic, needed_dynamic); rx_chains_dynamic = max(rx_chains_dynamic, needed_dynamic);
} }
/* Disable SMPS for the monitor interface */
sdata = rcu_dereference(local->monitor_sdata);
if (sdata &&
rcu_access_pointer(sdata->vif.chanctx_conf) == &chanctx->conf)
rx_chains_dynamic = rx_chains_static = local->rx_chains;
rcu_read_unlock(); rcu_read_unlock();
if (!local->use_chanctx) { if (!local->use_chanctx) {
......
...@@ -148,6 +148,8 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local) ...@@ -148,6 +148,8 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
list_for_each_entry_rcu(sdata, &local->interfaces, list) { list_for_each_entry_rcu(sdata, &local->interfaces, list) {
if (!rcu_access_pointer(sdata->vif.chanctx_conf)) if (!rcu_access_pointer(sdata->vif.chanctx_conf))
continue; continue;
if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
continue;
power = min(power, sdata->vif.bss_conf.txpower); power = min(power, sdata->vif.bss_conf.txpower);
} }
rcu_read_unlock(); rcu_read_unlock();
...@@ -199,7 +201,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, ...@@ -199,7 +201,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
{ {
struct ieee80211_local *local = sdata->local; struct ieee80211_local *local = sdata->local;
if (!changed) if (!changed || sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
return; return;
drv_bss_info_changed(local, sdata, &sdata->vif.bss_conf, changed); drv_bss_info_changed(local, sdata, &sdata->vif.bss_conf, changed);
......
...@@ -355,6 +355,7 @@ void ieee80211_sw_roc_work(struct work_struct *work) ...@@ -355,6 +355,7 @@ void ieee80211_sw_roc_work(struct work_struct *work)
struct ieee80211_roc_work *dep; struct ieee80211_roc_work *dep;
/* start this ROC */ /* start this ROC */
ieee80211_offchannel_stop_vifs(local);
/* switch channel etc */ /* switch channel etc */
ieee80211_recalc_idle(local); ieee80211_recalc_idle(local);
......
...@@ -618,6 +618,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) ...@@ -618,6 +618,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
sta, true, acked); sta, true, acked);
if ((local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) && if ((local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) &&
(ieee80211_is_data(hdr->frame_control)) &&
(rates_idx != -1)) (rates_idx != -1))
sta->last_tx_rate = info->status.rates[rates_idx]; sta->last_tx_rate = info->status.rates[rates_idx];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment