Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless into for-davem
This commit is contained in:
commit
025a58fd9d
|
@ -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,
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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 {
|
||||||
* 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 {
|
||||||
* @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,
|
||||||
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)
|
||||||
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,
|
||||||
|
|
||||||
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)
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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)
|
||||||
|
|
||||||
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,
|
||||||
* 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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
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 {
|
||||||
* @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 {
|
||||||
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 {
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
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);
|
|
||||||
|
|
||||||
/* switch channel etc */
|
/* 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;
|
||||||
|
|
||||||
|
/* 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)
|
||||||
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 @@
|
||||||
|
|
||||||
#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,
|
||||||
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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue