Commit 202630b4 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-05-15

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

For the mac80211 bits, Johannes says:

"One fix is to get better VHT performance and the other fixes tracing
garbage or other potential issues with the interface name tracing."

And...

"This has a fix from Emmanuel for a problem I failed to fix - when
association is in progress then it needs to be cancelled while
suspending (I had fixed the same for authentication). Also included a
fix from myself for a userspace API problem that hit the iw tool and a
fix to the remain-on-channel framework."

For the iwlwifi bits, Emmanuel says:

"Alex fixes the scan by disabling the fragmented scan. David prevents
scan offload while associated, the firmware seems not to like it. I
fix a stupid bug I made in BT Coex, and fix a bad #ifdef clause in rate
scaling.  Along with that there is a fix for a NULL pointer exception
that can happen if we load the driver and our ISR gets called because
the interrupt line is shared. The fix has been tested by the reporter."

And...

"We have here a fix from David Spinadel that makes a previous fix more
complete, and an off-by-one issue fixed by Eliad in the same area.
I fix the monitor that broke on the way."

Beyond that...

Daniel Kim's one-liner fixes a brcmfmac regression caused by a typo
in an earlier commit..

Rajkumar Manoharan fixes an ath9k oops reported by David Herrmann.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents fde0133b 025a58fd
...@@ -95,8 +95,10 @@ static void ath9k_htc_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) ...@@ -95,8 +95,10 @@ static void ath9k_htc_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
if ((vif->type == NL80211_IFTYPE_AP || if ((vif->type == NL80211_IFTYPE_AP ||
vif->type == NL80211_IFTYPE_MESH_POINT) && vif->type == NL80211_IFTYPE_MESH_POINT) &&
bss_conf->enable_beacon) bss_conf->enable_beacon) {
priv->reconfig_beacon = true; priv->reconfig_beacon = true;
priv->rearm_ani = true;
}
if (bss_conf->assoc) { if (bss_conf->assoc) {
priv->rearm_ani = true; priv->rearm_ani = true;
...@@ -257,6 +259,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, ...@@ -257,6 +259,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
ath9k_htc_ps_wakeup(priv); ath9k_htc_ps_wakeup(priv);
ath9k_htc_stop_ani(priv);
del_timer_sync(&priv->tx.cleanup_timer); del_timer_sync(&priv->tx.cleanup_timer);
ath9k_htc_tx_drain(priv); ath9k_htc_tx_drain(priv);
......
...@@ -4948,7 +4948,7 @@ static int brcmf_enable_bw40_2g(struct brcmf_if *ifp) ...@@ -4948,7 +4948,7 @@ static int brcmf_enable_bw40_2g(struct brcmf_if *ifp)
if (!err) { if (!err) {
/* only set 2G bandwidth using bw_cap command */ /* only set 2G bandwidth using bw_cap command */
band_bwcap.band = cpu_to_le32(WLC_BAND_2G); band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
band_bwcap.bw_cap = cpu_to_le32(WLC_BW_40MHZ_BIT); band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap, err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
sizeof(band_bwcap)); sizeof(band_bwcap));
} else { } else {
......
...@@ -611,14 +611,14 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm) ...@@ -611,14 +611,14 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
bt_cmd->flags |= cpu_to_le32(BT_COEX_SYNC2SCO); bt_cmd->flags |= cpu_to_le32(BT_COEX_SYNC2SCO);
if (IWL_MVM_BT_COEX_CORUNNING) { if (IWL_MVM_BT_COEX_CORUNNING) {
bt_cmd->valid_bit_msk = cpu_to_le32(BT_VALID_CORUN_LUT_20 | bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_CORUN_LUT_20 |
BT_VALID_CORUN_LUT_40); BT_VALID_CORUN_LUT_40);
bt_cmd->flags |= cpu_to_le32(BT_COEX_CORUNNING); bt_cmd->flags |= cpu_to_le32(BT_COEX_CORUNNING);
} }
if (IWL_MVM_BT_COEX_MPLUT) { if (IWL_MVM_BT_COEX_MPLUT) {
bt_cmd->flags |= cpu_to_le32(BT_COEX_MPLUT); bt_cmd->flags |= cpu_to_le32(BT_COEX_MPLUT);
bt_cmd->valid_bit_msk = cpu_to_le32(BT_VALID_MULTI_PRIO_LUT); bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_MULTI_PRIO_LUT);
} }
if (mvm->cfg->bt_shared_single_ant) if (mvm->cfg->bt_shared_single_ant)
......
...@@ -183,9 +183,9 @@ enum iwl_scan_type { ...@@ -183,9 +183,9 @@ enum iwl_scan_type {
* this number of packets were received (typically 1) * this number of packets were received (typically 1)
* @passive2active: is auto switching from passive to active during scan allowed * @passive2active: is auto switching from passive to active during scan allowed
* @rxchain_sel_flags: RXON_RX_CHAIN_* * @rxchain_sel_flags: RXON_RX_CHAIN_*
* @max_out_time: in usecs, max out of serving channel time * @max_out_time: in TUs, max out of serving channel time
* @suspend_time: how long to pause scan when returning to service channel: * @suspend_time: how long to pause scan when returning to service channel:
* bits 0-19: beacon interal in usecs (suspend before executing) * bits 0-19: beacon interal in TUs (suspend before executing)
* bits 20-23: reserved * bits 20-23: reserved
* bits 24-31: number of beacons (suspend between channels) * bits 24-31: number of beacons (suspend between channels)
* @rxon_flags: RXON_FLG_* * @rxon_flags: RXON_FLG_*
...@@ -383,8 +383,8 @@ enum scan_framework_client { ...@@ -383,8 +383,8 @@ enum scan_framework_client {
* @quiet_plcp_th: quiet channel num of packets threshold * @quiet_plcp_th: quiet channel num of packets threshold
* @good_CRC_th: passive to active promotion threshold * @good_CRC_th: passive to active promotion threshold
* @rx_chain: RXON rx chain. * @rx_chain: RXON rx chain.
* @max_out_time: max uSec to be out of assoceated channel * @max_out_time: max TUs to be out of assoceated channel
* @suspend_time: pause scan this long when returning to service channel * @suspend_time: pause scan this TUs when returning to service channel
* @flags: RXON flags * @flags: RXON flags
* @filter_flags: RXONfilter * @filter_flags: RXONfilter
* @tx_cmd: tx command for active scan; for 2GHz and for 5GHz. * @tx_cmd: tx command for active scan; for 2GHz and for 5GHz.
......
...@@ -1007,7 +1007,7 @@ static void iwl_mvm_mc_iface_iterator(void *_data, u8 *mac, ...@@ -1007,7 +1007,7 @@ static void iwl_mvm_mc_iface_iterator(void *_data, u8 *mac,
memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN); memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN);
len = roundup(sizeof(*cmd) + cmd->count * ETH_ALEN, 4); len = roundup(sizeof(*cmd) + cmd->count * ETH_ALEN, 4);
ret = iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_SYNC, len, cmd); ret = iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_ASYNC, len, cmd);
if (ret) if (ret)
IWL_ERR(mvm, "mcast filter cmd error. ret=%d\n", ret); IWL_ERR(mvm, "mcast filter cmd error. ret=%d\n", ret);
} }
...@@ -1023,7 +1023,7 @@ static void iwl_mvm_recalc_multicast(struct iwl_mvm *mvm) ...@@ -1023,7 +1023,7 @@ static void iwl_mvm_recalc_multicast(struct iwl_mvm *mvm)
if (WARN_ON_ONCE(!mvm->mcast_filter_cmd)) if (WARN_ON_ONCE(!mvm->mcast_filter_cmd))
return; return;
ieee80211_iterate_active_interfaces( ieee80211_iterate_active_interfaces_atomic(
mvm->hw, IEEE80211_IFACE_ITER_NORMAL, mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
iwl_mvm_mc_iface_iterator, &iter_data); iwl_mvm_mc_iface_iterator, &iter_data);
} }
...@@ -1807,6 +1807,11 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw, ...@@ -1807,6 +1807,11 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
mutex_lock(&mvm->mutex); mutex_lock(&mvm->mutex);
if (!iwl_mvm_is_idle(mvm)) {
ret = -EBUSY;
goto out;
}
switch (mvm->scan_status) { switch (mvm->scan_status) {
case IWL_MVM_SCAN_OS: case IWL_MVM_SCAN_OS:
IWL_DEBUG_SCAN(mvm, "Stopping previous scan for sched_scan\n"); IWL_DEBUG_SCAN(mvm, "Stopping previous scan for sched_scan\n");
......
...@@ -1003,6 +1003,9 @@ static inline bool iwl_mvm_vif_low_latency(struct iwl_mvm_vif *mvmvif) ...@@ -1003,6 +1003,9 @@ static inline bool iwl_mvm_vif_low_latency(struct iwl_mvm_vif *mvmvif)
return mvmvif->low_latency; return mvmvif->low_latency;
} }
/* Assoc status */
bool iwl_mvm_is_idle(struct iwl_mvm *mvm);
/* Thermal management and CT-kill */ /* Thermal management and CT-kill */
void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff); void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff);
void iwl_mvm_tt_handler(struct iwl_mvm *mvm); void iwl_mvm_tt_handler(struct iwl_mvm *mvm);
......
...@@ -1010,7 +1010,7 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband, ...@@ -1010,7 +1010,7 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
return; return;
} }
#ifdef CPTCFG_MAC80211_DEBUGFS #ifdef CONFIG_MAC80211_DEBUGFS
/* Disable last tx check if we are debugging with fixed rate */ /* Disable last tx check if we are debugging with fixed rate */
if (lq_sta->dbg_fixed_rate) { if (lq_sta->dbg_fixed_rate) {
IWL_DEBUG_RATE(mvm, "Fixed rate. avoid rate scaling\n"); IWL_DEBUG_RATE(mvm, "Fixed rate. avoid rate scaling\n");
......
...@@ -277,51 +277,22 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm, ...@@ -277,51 +277,22 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
IEEE80211_IFACE_ITER_NORMAL, IEEE80211_IFACE_ITER_NORMAL,
iwl_mvm_scan_condition_iterator, iwl_mvm_scan_condition_iterator,
&global_bound); &global_bound);
/*
* Under low latency traffic passive scan is fragmented meaning
* that dwell on a particular channel will be fragmented. Each fragment
* dwell time is 20ms and fragments period is 105ms. Skipping to next
* channel will be delayed by the same period - 105ms. So suspend_time
* parameter describing both fragments and channels skipping periods is
* set to 105ms. This value is chosen so that overall passive scan
* duration will not be too long. Max_out_time in this case is set to
* 70ms, so for active scanning operating channel will be left for 70ms
* while for passive still for 20ms (fragment dwell).
*/
if (global_bound) {
if (!iwl_mvm_low_latency(mvm)) {
params->suspend_time = ieee80211_tu_to_usec(100);
params->max_out_time = ieee80211_tu_to_usec(600);
} else {
params->suspend_time = ieee80211_tu_to_usec(105);
/* P2P doesn't support fragmented passive scan, so
* configure max_out_time to be at least longest dwell
* time for passive scan.
*/
if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p) {
params->max_out_time = ieee80211_tu_to_usec(70);
params->passive_fragmented = true;
} else {
u32 passive_dwell;
/* if (!global_bound)
* Use band G so that passive channel dwell time goto not_bound;
* will be assigned with maximum value.
*/ params->suspend_time = 100;
band = IEEE80211_BAND_2GHZ; params->max_out_time = 600;
passive_dwell = iwl_mvm_get_passive_dwell(band);
params->max_out_time = if (iwl_mvm_low_latency(mvm)) {
ieee80211_tu_to_usec(passive_dwell); params->suspend_time = 250;
} params->max_out_time = 250;
}
} }
not_bound:
for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) { for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) {
if (params->passive_fragmented) params->dwell[band].passive = iwl_mvm_get_passive_dwell(band);
params->dwell[band].passive = 20;
else
params->dwell[band].passive =
iwl_mvm_get_passive_dwell(band);
params->dwell[band].active = iwl_mvm_get_active_dwell(band, params->dwell[band].active = iwl_mvm_get_active_dwell(band,
n_ssids); n_ssids);
} }
...@@ -761,7 +732,7 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm, ...@@ -761,7 +732,7 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
int band_2ghz = mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels; int band_2ghz = mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels;
int band_5ghz = mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels; int band_5ghz = mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels;
int head = 0; int head = 0;
int tail = band_2ghz + band_5ghz; int tail = band_2ghz + band_5ghz - 1;
u32 ssid_bitmap; u32 ssid_bitmap;
int cmd_len; int cmd_len;
int ret; int ret;
......
...@@ -644,3 +644,22 @@ bool iwl_mvm_low_latency(struct iwl_mvm *mvm) ...@@ -644,3 +644,22 @@ bool iwl_mvm_low_latency(struct iwl_mvm *mvm)
return result; return result;
} }
static void iwl_mvm_idle_iter(void *_data, u8 *mac, struct ieee80211_vif *vif)
{
bool *idle = _data;
if (!vif->bss_conf.idle)
*idle = false;
}
bool iwl_mvm_is_idle(struct iwl_mvm *mvm)
{
bool idle = true;
ieee80211_iterate_active_interfaces_atomic(
mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
iwl_mvm_idle_iter, &idle);
return idle;
}
...@@ -1749,6 +1749,10 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, ...@@ -1749,6 +1749,10 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
* PCI Tx retries from interfering with C3 CPU state */ * PCI Tx retries from interfering with C3 CPU state */
pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
trans->dev = &pdev->dev;
trans_pcie->pci_dev = pdev;
iwl_disable_interrupts(trans);
err = pci_enable_msi(pdev); err = pci_enable_msi(pdev);
if (err) { if (err) {
dev_err(&pdev->dev, "pci_enable_msi failed(0X%x)\n", err); dev_err(&pdev->dev, "pci_enable_msi failed(0X%x)\n", err);
...@@ -1760,8 +1764,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, ...@@ -1760,8 +1764,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
} }
} }
trans->dev = &pdev->dev;
trans_pcie->pci_dev = pdev;
trans->hw_rev = iwl_read32(trans, CSR_HW_REV); trans->hw_rev = iwl_read32(trans, CSR_HW_REV);
trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; trans->hw_id = (pdev->device << 16) + pdev->subsystem_device;
snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), snprintf(trans->hw_id_str, sizeof(trans->hw_id_str),
...@@ -1787,8 +1789,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, ...@@ -1787,8 +1789,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
goto out_pci_disable_msi; goto out_pci_disable_msi;
} }
trans_pcie->inta_mask = CSR_INI_SET_MASK;
if (iwl_pcie_alloc_ict(trans)) if (iwl_pcie_alloc_ict(trans))
goto out_free_cmd_pool; goto out_free_cmd_pool;
...@@ -1800,6 +1800,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, ...@@ -1800,6 +1800,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
goto out_free_ict; goto out_free_ict;
} }
trans_pcie->inta_mask = CSR_INI_SET_MASK;
return trans; return trans;
out_free_ict: out_free_ict:
......
...@@ -3856,6 +3856,8 @@ enum nl80211_ap_sme_features { ...@@ -3856,6 +3856,8 @@ enum nl80211_ap_sme_features {
* @NL80211_FEATURE_CELL_BASE_REG_HINTS: This driver has been tested * @NL80211_FEATURE_CELL_BASE_REG_HINTS: This driver has been tested
* to work properly to suppport receiving regulatory hints from * to work properly to suppport receiving regulatory hints from
* cellular base stations. * cellular base stations.
* @NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL: (no longer available, only
* here to reserve the value for API/ABI compatibility)
* @NL80211_FEATURE_SAE: This driver supports simultaneous authentication of * @NL80211_FEATURE_SAE: This driver supports simultaneous authentication of
* equals (SAE) with user space SME (NL80211_CMD_AUTHENTICATE) in station * equals (SAE) with user space SME (NL80211_CMD_AUTHENTICATE) in station
* mode * mode
...@@ -3897,7 +3899,7 @@ enum nl80211_feature_flags { ...@@ -3897,7 +3899,7 @@ enum nl80211_feature_flags {
NL80211_FEATURE_HT_IBSS = 1 << 1, NL80211_FEATURE_HT_IBSS = 1 << 1,
NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2, NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2,
NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3, NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3,
/* bit 4 is reserved - don't use */ NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL = 1 << 4,
NL80211_FEATURE_SAE = 1 << 5, NL80211_FEATURE_SAE = 1 << 5,
NL80211_FEATURE_LOW_PRIORITY_SCAN = 1 << 6, NL80211_FEATURE_LOW_PRIORITY_SCAN = 1 << 6,
NL80211_FEATURE_SCAN_FLUSH = 1 << 7, NL80211_FEATURE_SCAN_FLUSH = 1 << 7,
......
...@@ -317,6 +317,7 @@ struct ieee80211_roc_work { ...@@ -317,6 +317,7 @@ struct ieee80211_roc_work {
bool started, abort, hw_begun, notified; bool started, abort, hw_begun, notified;
bool to_be_freed; bool to_be_freed;
bool on_channel;
unsigned long hw_start_time; unsigned long hw_start_time;
......
...@@ -3598,18 +3598,24 @@ void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata) ...@@ -3598,18 +3598,24 @@ void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata)
sdata_lock(sdata); sdata_lock(sdata);
if (ifmgd->auth_data) { if (ifmgd->auth_data || ifmgd->assoc_data) {
const u8 *bssid = ifmgd->auth_data ?
ifmgd->auth_data->bss->bssid :
ifmgd->assoc_data->bss->bssid;
/* /*
* If we are trying to authenticate while suspending, cfg80211 * If we are trying to authenticate / associate while suspending,
* won't know and won't actually abort those attempts, thus we * cfg80211 won't know and won't actually abort those attempts,
* need to do that ourselves. * thus we need to do that ourselves.
*/ */
ieee80211_send_deauth_disassoc(sdata, ieee80211_send_deauth_disassoc(sdata, bssid,
ifmgd->auth_data->bss->bssid,
IEEE80211_STYPE_DEAUTH, IEEE80211_STYPE_DEAUTH,
WLAN_REASON_DEAUTH_LEAVING, WLAN_REASON_DEAUTH_LEAVING,
false, frame_buf); false, frame_buf);
ieee80211_destroy_auth_data(sdata, false); if (ifmgd->assoc_data)
ieee80211_destroy_assoc_data(sdata, false);
if (ifmgd->auth_data)
ieee80211_destroy_auth_data(sdata, false);
cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
IEEE80211_DEAUTH_FRAME_LEN); IEEE80211_DEAUTH_FRAME_LEN);
} }
......
...@@ -333,7 +333,7 @@ void ieee80211_sw_roc_work(struct work_struct *work) ...@@ -333,7 +333,7 @@ void ieee80211_sw_roc_work(struct work_struct *work)
container_of(work, struct ieee80211_roc_work, work.work); container_of(work, struct ieee80211_roc_work, work.work);
struct ieee80211_sub_if_data *sdata = roc->sdata; struct ieee80211_sub_if_data *sdata = roc->sdata;
struct ieee80211_local *local = sdata->local; struct ieee80211_local *local = sdata->local;
bool started; bool started, on_channel;
mutex_lock(&local->mtx); mutex_lock(&local->mtx);
...@@ -354,14 +354,26 @@ void ieee80211_sw_roc_work(struct work_struct *work) ...@@ -354,14 +354,26 @@ void ieee80211_sw_roc_work(struct work_struct *work)
if (!roc->started) { if (!roc->started) {
struct ieee80211_roc_work *dep; struct ieee80211_roc_work *dep;
/* start this ROC */ WARN_ON(local->use_chanctx);
ieee80211_offchannel_stop_vifs(local);
/* If actually operating on the desired channel (with at least
* 20 MHz channel width) don't stop all the operations but still
* treat it as though the ROC operation started properly, so
* other ROC operations won't interfere with this one.
*/
roc->on_channel = roc->chan == local->_oper_chandef.chan &&
local->_oper_chandef.width != NL80211_CHAN_WIDTH_5 &&
local->_oper_chandef.width != NL80211_CHAN_WIDTH_10;
/* switch channel etc */ /* start this ROC */
ieee80211_recalc_idle(local); ieee80211_recalc_idle(local);
local->tmp_channel = roc->chan; if (!roc->on_channel) {
ieee80211_hw_config(local, 0); ieee80211_offchannel_stop_vifs(local);
local->tmp_channel = roc->chan;
ieee80211_hw_config(local, 0);
}
/* tell userspace or send frame */ /* tell userspace or send frame */
ieee80211_handle_roc_started(roc); ieee80211_handle_roc_started(roc);
...@@ -380,9 +392,10 @@ void ieee80211_sw_roc_work(struct work_struct *work) ...@@ -380,9 +392,10 @@ void ieee80211_sw_roc_work(struct work_struct *work)
finish: finish:
list_del(&roc->list); list_del(&roc->list);
started = roc->started; started = roc->started;
on_channel = roc->on_channel;
ieee80211_roc_notify_destroy(roc, !roc->abort); ieee80211_roc_notify_destroy(roc, !roc->abort);
if (started) { if (started && !on_channel) {
ieee80211_flush_queues(local, NULL); ieee80211_flush_queues(local, NULL);
local->tmp_channel = NULL; local->tmp_channel = NULL;
......
...@@ -21,10 +21,10 @@ ...@@ -21,10 +21,10 @@
#define VIF_ENTRY __field(enum nl80211_iftype, vif_type) __field(void *, sdata) \ #define VIF_ENTRY __field(enum nl80211_iftype, vif_type) __field(void *, sdata) \
__field(bool, p2p) \ __field(bool, p2p) \
__string(vif_name, sdata->dev ? sdata->dev->name : "<nodev>") __string(vif_name, sdata->name)
#define VIF_ASSIGN __entry->vif_type = sdata->vif.type; __entry->sdata = sdata; \ #define VIF_ASSIGN __entry->vif_type = sdata->vif.type; __entry->sdata = sdata; \
__entry->p2p = sdata->vif.p2p; \ __entry->p2p = sdata->vif.p2p; \
__assign_str(vif_name, sdata->dev ? sdata->dev->name : sdata->name) __assign_str(vif_name, sdata->name)
#define VIF_PR_FMT " vif:%s(%d%s)" #define VIF_PR_FMT " vif:%s(%d%s)"
#define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : "" #define VIF_PR_ARG __get_str(vif_name), __entry->vif_type, __entry->p2p ? "/p2p" : ""
......
...@@ -129,9 +129,12 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata, ...@@ -129,9 +129,12 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
if (!vht_cap_ie || !sband->vht_cap.vht_supported) if (!vht_cap_ie || !sband->vht_cap.vht_supported)
return; return;
/* A VHT STA must support 40 MHz */ /*
if (!(sta->sta.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) * A VHT STA must support 40 MHz, but if we verify that here
return; * then we break a few things - some APs (e.g. Netgear R6300v2
* and others based on the BCM4360 chipset) will unset this
* capability bit when operating in 20 MHz.
*/
vht_cap->vht_supported = true; vht_cap->vht_supported = true;
......
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