forked from Minki/linux
Another set of patches for -next:
* API support for concurrent scheduled scan requests * API changes for roaming reporting * BSS max idle support in mac80211 * API changes for TX status reporting in mac80211 * API changes for RX rate reporting in mac80211 * rewrite monitor logic to prepare for BPF filters * bugfix for rare devices without 2.4 GHz support * a bugfix for recent DFS changes * some further cleanups The API changes are actually at a nice time, since it's typically quiet just before the merge window, and trees can be synchronized easily during it. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEExu3sM/nZ1eRSfR9Ha3t4Rpy0AB0FAlkDggoACgkQa3t4Rpy0 AB2kpQ/+PUTNPKklYvV2TVRyT71oGoE4WNzPe4v5cgpbBkk48qCOD1ncAHCo6q2s L90gh9yOXnjht3pobvjd0PlYHy5faq4VyDohBdyId3YlR78FYyk41KSMkp4BAKn0 aeTI3QeA0FOsXECiagqG6pwYpMJM1nQFhFbL1AvVIf1MxBGYNgh+iVLzk2tyTGXB OYdJBHTjgKW3nuIRYgtUoLQaWNUlUhK+5wpypb3wkgn41DEq4sL4ay5VgNKSd0AE 5AkCrhLbiZlR4xrxivqOuS3nNPPIDOq5imuRvMMbQDChZ/4p60l0f1VIo6MR6UAQ N5Cn2ReD0bV+GFVaWmpDnmdQJIoLLYHWdlX362XdVbQCFOWOfsaD9zM2j5wXMeNV YBCMYa7Lt52ewjz4BABsAtH4/ZFReKCDmkFOMyakA2LnWzUxxqjWourcAM7XV2Kc RZIcM36Xx6yhsSReOzzd/HV9CUjqF8xuKrMKd/vWxBwWiaWdywtWqhEksxi0aOvq LUnCqgvcIxCh9dd8ygcfNdGbpZVqPVxmPdixRQbNL50M7gXtqUwZgnHHUdExgs8E 8sP+ua8H9RlXVGItuBFURShaV4hToJrxKw0xVjtVkpVXkqibgOIjxRv2mh+nkKXr tq8VWxnrKOH4nAVIyZJonoXp0Hi0vYLyt7bAwAj01CoGyZZdqUw= =dYTw -----END PGP SIGNATURE----- Merge tag 'mac80211-next-for-davem-2017-04-28' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next Johannes Berg says: ==================== Another set of patches for -next: * API support for concurrent scheduled scan requests * API changes for roaming reporting * BSS max idle support in mac80211 * API changes for TX status reporting in mac80211 * API changes for RX rate reporting in mac80211 * rewrite monitor logic to prepare for BPF filters * bugfix for rare devices without 2.4 GHz support * a bugfix for recent DFS changes * some further cleanups The API changes are actually at a nice time, since it's typically quiet just before the merge window, and trees can be synchronized easily during it. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
cec3819198
@ -632,11 +632,11 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar,
|
||||
sgi = (info3 >> 7) & 1;
|
||||
|
||||
status->rate_idx = mcs;
|
||||
status->flag |= RX_FLAG_HT;
|
||||
status->encoding = RX_ENC_HT;
|
||||
if (sgi)
|
||||
status->flag |= RX_FLAG_SHORT_GI;
|
||||
status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
|
||||
if (bw)
|
||||
status->flag |= RX_FLAG_40MHZ;
|
||||
status->bw = RATE_INFO_BW_40;
|
||||
break;
|
||||
case HTT_RX_VHT:
|
||||
case HTT_RX_VHT_WITH_TXBF:
|
||||
@ -689,10 +689,10 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar,
|
||||
}
|
||||
|
||||
status->rate_idx = mcs;
|
||||
status->vht_nss = nss;
|
||||
status->nss = nss;
|
||||
|
||||
if (sgi)
|
||||
status->flag |= RX_FLAG_SHORT_GI;
|
||||
status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
|
||||
|
||||
switch (bw) {
|
||||
/* 20MHZ */
|
||||
@ -700,18 +700,18 @@ static void ath10k_htt_rx_h_rates(struct ath10k *ar,
|
||||
break;
|
||||
/* 40MHZ */
|
||||
case 1:
|
||||
status->flag |= RX_FLAG_40MHZ;
|
||||
status->bw = RATE_INFO_BW_40;
|
||||
break;
|
||||
/* 80MHZ */
|
||||
case 2:
|
||||
status->vht_flag |= RX_VHT_FLAG_80MHZ;
|
||||
status->bw = RATE_INFO_BW_80;
|
||||
break;
|
||||
case 3:
|
||||
status->vht_flag |= RX_VHT_FLAG_160MHZ;
|
||||
status->bw = RATE_INFO_BW_160;
|
||||
break;
|
||||
}
|
||||
|
||||
status->flag |= RX_FLAG_VHT;
|
||||
status->encoding = RX_ENC_VHT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -874,13 +874,10 @@ static void ath10k_htt_rx_h_ppdu(struct ath10k *ar,
|
||||
/* New PPDU starts so clear out the old per-PPDU status. */
|
||||
status->freq = 0;
|
||||
status->rate_idx = 0;
|
||||
status->vht_nss = 0;
|
||||
status->vht_flag &= ~RX_VHT_FLAG_80MHZ;
|
||||
status->flag &= ~(RX_FLAG_HT |
|
||||
RX_FLAG_VHT |
|
||||
RX_FLAG_SHORT_GI |
|
||||
RX_FLAG_40MHZ |
|
||||
RX_FLAG_MACTIME_END);
|
||||
status->nss = 0;
|
||||
status->encoding = RX_ENC_LEGACY;
|
||||
status->bw = RATE_INFO_BW_20;
|
||||
status->flag &= ~RX_FLAG_MACTIME_END;
|
||||
status->flag |= RX_FLAG_NO_SIGNAL_VAL;
|
||||
|
||||
ath10k_htt_rx_h_signal(ar, status, rxd);
|
||||
@ -933,7 +930,7 @@ static void ath10k_process_rx(struct ath10k *ar,
|
||||
*status = *rx_status;
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_DATA,
|
||||
"rx skb %pK len %u peer %pM %s %s sn %u %s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%llx fcs-err %i mic-err %i amsdu-more %i\n",
|
||||
"rx skb %pK len %u peer %pM %s %s sn %u %s%s%s%s%s%s %srate_idx %u vht_nss %u freq %u band %u flag 0x%x fcs-err %i mic-err %i amsdu-more %i\n",
|
||||
skb,
|
||||
skb->len,
|
||||
ieee80211_get_SA(hdr),
|
||||
@ -941,16 +938,15 @@ static void ath10k_process_rx(struct ath10k *ar,
|
||||
is_multicast_ether_addr(ieee80211_get_DA(hdr)) ?
|
||||
"mcast" : "ucast",
|
||||
(__le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_SEQ) >> 4,
|
||||
(status->flag & (RX_FLAG_HT | RX_FLAG_VHT)) == 0 ?
|
||||
"legacy" : "",
|
||||
status->flag & RX_FLAG_HT ? "ht" : "",
|
||||
status->flag & RX_FLAG_VHT ? "vht" : "",
|
||||
status->flag & RX_FLAG_40MHZ ? "40" : "",
|
||||
status->vht_flag & RX_VHT_FLAG_80MHZ ? "80" : "",
|
||||
status->vht_flag & RX_VHT_FLAG_160MHZ ? "160" : "",
|
||||
status->flag & RX_FLAG_SHORT_GI ? "sgi " : "",
|
||||
(status->encoding == RX_ENC_LEGACY) ? "legacy" : "",
|
||||
(status->encoding == RX_ENC_HT) ? "ht" : "",
|
||||
(status->encoding == RX_ENC_VHT) ? "vht" : "",
|
||||
(status->bw == RATE_INFO_BW_40) ? "40" : "",
|
||||
(status->bw == RATE_INFO_BW_80) ? "80" : "",
|
||||
(status->bw == RATE_INFO_BW_160) ? "160" : "",
|
||||
status->enc_flags & RX_ENC_FLAG_SHORT_GI ? "sgi " : "",
|
||||
status->rate_idx,
|
||||
status->vht_nss,
|
||||
status->nss,
|
||||
status->freq,
|
||||
status->band, status->flag,
|
||||
!!(status->flag & RX_FLAG_FAILED_FCS_CRC),
|
||||
|
@ -1414,10 +1414,10 @@ ath5k_receive_frame(struct ath5k_hw *ah, struct sk_buff *skb,
|
||||
rxs->flag |= ath5k_rx_decrypted(ah, skb, rs);
|
||||
switch (ah->ah_bwmode) {
|
||||
case AR5K_BWMODE_5MHZ:
|
||||
rxs->flag |= RX_FLAG_5MHZ;
|
||||
rxs->bw = RATE_INFO_BW_5;
|
||||
break;
|
||||
case AR5K_BWMODE_10MHZ:
|
||||
rxs->flag |= RX_FLAG_10MHZ;
|
||||
rxs->bw = RATE_INFO_BW_10;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1425,7 +1425,7 @@ ath5k_receive_frame(struct ath5k_hw *ah, struct sk_buff *skb,
|
||||
|
||||
if (rs->rs_rate ==
|
||||
ah->sbands[ah->curchan->band].bitrates[rxs->rate_idx].hw_value_short)
|
||||
rxs->flag |= RX_FLAG_SHORTPRE;
|
||||
rxs->enc_flags |= RX_ENC_FLAG_SHORTPRE;
|
||||
|
||||
trace_ath5k_rx(ah, skb);
|
||||
|
||||
|
@ -169,7 +169,7 @@ static void ath6kl_cfg80211_sscan_disable(struct ath6kl_vif *vif)
|
||||
if (!stopped)
|
||||
return;
|
||||
|
||||
cfg80211_sched_scan_stopped(ar->wiphy);
|
||||
cfg80211_sched_scan_stopped(ar->wiphy, 0);
|
||||
}
|
||||
|
||||
static int ath6kl_set_wpa_version(struct ath6kl_vif *vif,
|
||||
@ -806,9 +806,15 @@ void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
|
||||
WLAN_STATUS_SUCCESS, GFP_KERNEL);
|
||||
cfg80211_put_bss(ar->wiphy, bss);
|
||||
} else if (vif->sme_state == SME_CONNECTED) {
|
||||
struct cfg80211_roam_info roam_info = {
|
||||
.bss = bss,
|
||||
.req_ie = assoc_req_ie,
|
||||
.req_ie_len = assoc_req_len,
|
||||
.resp_ie = assoc_resp_ie,
|
||||
.resp_ie_len = assoc_resp_len,
|
||||
};
|
||||
/* inform roam event to cfg80211 */
|
||||
cfg80211_roamed_bss(vif->ndev, bss, assoc_req_ie, assoc_req_len,
|
||||
assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
|
||||
cfg80211_roamed(vif->ndev, &roam_info, GFP_KERNEL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3352,7 +3358,7 @@ static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
|
||||
}
|
||||
|
||||
static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy,
|
||||
struct net_device *dev)
|
||||
struct net_device *dev, u64 reqid)
|
||||
{
|
||||
struct ath6kl_vif *vif = netdev_priv(dev);
|
||||
bool stopped;
|
||||
@ -3973,7 +3979,7 @@ int ath6kl_cfg80211_init(struct ath6kl *ar)
|
||||
WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
|
||||
|
||||
if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, ar->fw_capabilities))
|
||||
ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
|
||||
ar->wiphy->max_sched_scan_reqs = 1;
|
||||
|
||||
if (test_bit(ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT,
|
||||
ar->fw_capabilities))
|
||||
|
@ -1082,7 +1082,7 @@ void ath6kl_wmi_sscan_timer(unsigned long ptr)
|
||||
{
|
||||
struct ath6kl_vif *vif = (struct ath6kl_vif *) ptr;
|
||||
|
||||
cfg80211_sched_scan_results(vif->ar->wiphy);
|
||||
cfg80211_sched_scan_results(vif->ar->wiphy, 0);
|
||||
}
|
||||
|
||||
static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len,
|
||||
|
@ -494,7 +494,8 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
|
||||
|
||||
rxs->rs_status = 0;
|
||||
rxs->rs_flags = 0;
|
||||
rxs->flag = 0;
|
||||
rxs->enc_flags = 0;
|
||||
rxs->bw = RATE_INFO_BW_20;
|
||||
|
||||
rxs->rs_datalen = rxsp->status2 & AR_DataLen;
|
||||
rxs->rs_tstamp = rxsp->status3;
|
||||
@ -520,8 +521,8 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs,
|
||||
rxs->rs_isaggr = (rxsp->status11 & AR_RxAggr) ? 1 : 0;
|
||||
rxs->rs_moreaggr = (rxsp->status11 & AR_RxMoreAggr) ? 1 : 0;
|
||||
rxs->rs_antenna = (MS(rxsp->status4, AR_RxAntenna) & 0x7);
|
||||
rxs->flag |= (rxsp->status4 & AR_GI) ? RX_FLAG_SHORT_GI : 0;
|
||||
rxs->flag |= (rxsp->status4 & AR_2040) ? RX_FLAG_40MHZ : 0;
|
||||
rxs->enc_flags |= (rxsp->status4 & AR_GI) ? RX_ENC_FLAG_SHORT_GI : 0;
|
||||
rxs->enc_flags |= (rxsp->status4 & AR_2040) ? RX_ENC_FLAG_40MHZ : 0;
|
||||
|
||||
rxs->evm0 = rxsp->status6;
|
||||
rxs->evm1 = rxsp->status7;
|
||||
|
@ -181,14 +181,15 @@ int ath9k_cmn_process_rate(struct ath_common *common,
|
||||
sband = hw->wiphy->bands[band];
|
||||
|
||||
if (IS_CHAN_QUARTER_RATE(ah->curchan))
|
||||
rxs->flag |= RX_FLAG_5MHZ;
|
||||
rxs->bw = RATE_INFO_BW_5;
|
||||
else if (IS_CHAN_HALF_RATE(ah->curchan))
|
||||
rxs->flag |= RX_FLAG_10MHZ;
|
||||
rxs->bw = RATE_INFO_BW_10;
|
||||
|
||||
if (rx_stats->rs_rate & 0x80) {
|
||||
/* HT rate */
|
||||
rxs->flag |= RX_FLAG_HT;
|
||||
rxs->flag |= rx_stats->flag;
|
||||
rxs->encoding = RX_ENC_HT;
|
||||
rxs->enc_flags |= rx_stats->enc_flags;
|
||||
rxs->bw = rx_stats->bw;
|
||||
rxs->rate_idx = rx_stats->rs_rate & 0x7f;
|
||||
return 0;
|
||||
}
|
||||
@ -199,7 +200,7 @@ int ath9k_cmn_process_rate(struct ath_common *common,
|
||||
return 0;
|
||||
}
|
||||
if (sband->bitrates[i].hw_value_short == rx_stats->rs_rate) {
|
||||
rxs->flag |= RX_FLAG_SHORTPRE;
|
||||
rxs->enc_flags |= RX_ENC_FLAG_SHORTPRE;
|
||||
rxs->rate_idx = i;
|
||||
return 0;
|
||||
}
|
||||
|
@ -116,12 +116,12 @@ void ath_debug_rate_stats(struct ath_softc *sc,
|
||||
if (rxs->rate_idx >= ARRAY_SIZE(rstats->ht_stats))
|
||||
goto exit;
|
||||
|
||||
if (rxs->flag & RX_FLAG_40MHZ)
|
||||
if ((rxs->bw == RATE_INFO_BW_40))
|
||||
rstats->ht_stats[rxs->rate_idx].ht40_cnt++;
|
||||
else
|
||||
rstats->ht_stats[rxs->rate_idx].ht20_cnt++;
|
||||
|
||||
if (rxs->flag & RX_FLAG_SHORT_GI)
|
||||
if (rxs->enc_flags & RX_ENC_FLAG_SHORT_GI)
|
||||
rstats->ht_stats[rxs->rate_idx].sgi_cnt++;
|
||||
else
|
||||
rstats->ht_stats[rxs->rate_idx].lgi_cnt++;
|
||||
@ -130,7 +130,7 @@ void ath_debug_rate_stats(struct ath_softc *sc,
|
||||
}
|
||||
|
||||
if (IS_CCK_RATE(rs->rs_rate)) {
|
||||
if (rxs->flag & RX_FLAG_SHORTPRE)
|
||||
if (rxs->enc_flags & RX_ENC_FLAG_SHORTPRE)
|
||||
rstats->cck_stats[rxs->rate_idx].cck_sp_cnt++;
|
||||
else
|
||||
rstats->cck_stats[rxs->rate_idx].cck_lp_cnt++;
|
||||
|
@ -929,11 +929,12 @@ void ath9k_host_rx_init(struct ath9k_htc_priv *priv)
|
||||
static inline void convert_htc_flag(struct ath_rx_status *rx_stats,
|
||||
struct ath_htc_rx_status *rxstatus)
|
||||
{
|
||||
rx_stats->flag = 0;
|
||||
rx_stats->enc_flags = 0;
|
||||
rx_stats->bw = RATE_INFO_BW_20;
|
||||
if (rxstatus->rs_flags & ATH9K_RX_2040)
|
||||
rx_stats->flag |= RX_FLAG_40MHZ;
|
||||
rx_stats->bw = RATE_INFO_BW_40;
|
||||
if (rxstatus->rs_flags & ATH9K_RX_GI)
|
||||
rx_stats->flag |= RX_FLAG_SHORT_GI;
|
||||
rx_stats->enc_flags |= RX_ENC_FLAG_SHORT_GI;
|
||||
}
|
||||
|
||||
static void rx_status_htc_to_ath(struct ath_rx_status *rx_stats,
|
||||
|
@ -535,7 +535,8 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
|
||||
|
||||
rs->rs_status = 0;
|
||||
rs->rs_flags = 0;
|
||||
rs->flag = 0;
|
||||
rs->enc_flags = 0;
|
||||
rs->bw = RATE_INFO_BW_20;
|
||||
|
||||
rs->rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
|
||||
rs->rs_tstamp = ads.AR_RcvTimestamp;
|
||||
@ -577,15 +578,15 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
|
||||
rs->rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
|
||||
|
||||
/* directly mapped flags for ieee80211_rx_status */
|
||||
rs->flag |=
|
||||
(ads.ds_rxstatus3 & AR_GI) ? RX_FLAG_SHORT_GI : 0;
|
||||
rs->flag |=
|
||||
(ads.ds_rxstatus3 & AR_2040) ? RX_FLAG_40MHZ : 0;
|
||||
rs->enc_flags |=
|
||||
(ads.ds_rxstatus3 & AR_GI) ? RX_ENC_FLAG_SHORT_GI : 0;
|
||||
rs->enc_flags |=
|
||||
(ads.ds_rxstatus3 & AR_2040) ? RX_ENC_FLAG_40MHZ : 0;
|
||||
if (AR_SREV_9280_20_OR_LATER(ah))
|
||||
rs->flag |=
|
||||
rs->enc_flags |=
|
||||
(ads.ds_rxstatus3 & AR_STBC) ?
|
||||
/* we can only Nss=1 STBC */
|
||||
(1 << RX_FLAG_STBC_SHIFT) : 0;
|
||||
(1 << RX_ENC_FLAG_STBC_SHIFT) : 0;
|
||||
|
||||
if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
|
||||
rs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#ifndef MAC_H
|
||||
#define MAC_H
|
||||
#include <net/cfg80211.h>
|
||||
|
||||
#define set11nTries(_series, _index) \
|
||||
(SM((_series)[_index].Tries, AR_XmitDataTries##_index))
|
||||
@ -143,7 +144,8 @@ struct ath_rx_status {
|
||||
u32 evm2;
|
||||
u32 evm3;
|
||||
u32 evm4;
|
||||
u32 flag; /* see enum mac80211_rx_flags */
|
||||
u16 enc_flags;
|
||||
enum rate_info_bw bw;
|
||||
};
|
||||
|
||||
struct ath_htc_rx_status {
|
||||
|
@ -1037,11 +1037,11 @@ static void ath_rx_count_airtime(struct ath_softc *sc,
|
||||
|
||||
rxs = IEEE80211_SKB_RXCB(skb);
|
||||
|
||||
is_sgi = !!(rxs->flag & RX_FLAG_SHORT_GI);
|
||||
is_40 = !!(rxs->flag & RX_FLAG_40MHZ);
|
||||
is_sp = !!(rxs->flag & RX_FLAG_SHORTPRE);
|
||||
is_sgi = !!(rxs->enc_flags & RX_ENC_FLAG_SHORT_GI);
|
||||
is_40 = !!(rxs->bw == RATE_INFO_BW_40);
|
||||
is_sp = !!(rxs->enc_flags & RX_ENC_FLAG_SHORTPRE);
|
||||
|
||||
if (!!(rxs->flag & RX_FLAG_HT)) {
|
||||
if (!!(rxs->encoding == RX_ENC_HT)) {
|
||||
/* MCS rates */
|
||||
|
||||
airtime += ath_pkt_duration(sc, rxs->rate_idx, len,
|
||||
|
@ -358,7 +358,7 @@ static int carl9170_rx_mac_status(struct ar9170 *ar,
|
||||
switch (mac->status & AR9170_RX_STATUS_MODULATION) {
|
||||
case AR9170_RX_STATUS_MODULATION_CCK:
|
||||
if (mac->status & AR9170_RX_STATUS_SHORT_PREAMBLE)
|
||||
status->flag |= RX_FLAG_SHORTPRE;
|
||||
status->enc_flags |= RX_ENC_FLAG_SHORTPRE;
|
||||
switch (head->plcp[0]) {
|
||||
case AR9170_RX_PHY_RATE_CCK_1M:
|
||||
status->rate_idx = 0;
|
||||
@ -423,12 +423,12 @@ static int carl9170_rx_mac_status(struct ar9170 *ar,
|
||||
|
||||
case AR9170_RX_STATUS_MODULATION_HT:
|
||||
if (head->plcp[3] & 0x80)
|
||||
status->flag |= RX_FLAG_40MHZ;
|
||||
status->bw = RATE_INFO_BW_40;
|
||||
if (head->plcp[6] & 0x80)
|
||||
status->flag |= RX_FLAG_SHORT_GI;
|
||||
status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
|
||||
|
||||
status->rate_idx = clamp(0, 75, head->plcp[3] & 0x7f);
|
||||
status->flag |= RX_FLAG_HT;
|
||||
status->encoding = RX_ENC_HT;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -68,7 +68,7 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb)
|
||||
RX_FLAG_MMIC_STRIPPED |
|
||||
RX_FLAG_DECRYPTED;
|
||||
|
||||
wcn36xx_dbg(WCN36XX_DBG_RX, "status.flags=%llx\n", status.flag);
|
||||
wcn36xx_dbg(WCN36XX_DBG_RX, "status.flags=%x\n", status.flag);
|
||||
|
||||
memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
|
||||
|
||||
|
@ -694,7 +694,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
|
||||
if (unlikely(phystat0 & (B43_RX_PHYST0_PLCPHCF | B43_RX_PHYST0_PLCPFV)))
|
||||
status.flag |= RX_FLAG_FAILED_PLCP_CRC;
|
||||
if (phystat0 & B43_RX_PHYST0_SHORTPRMBL)
|
||||
status.flag |= RX_FLAG_SHORTPRE;
|
||||
status.enc_flags |= RX_ENC_FLAG_SHORTPRE;
|
||||
if (macstat & B43_RX_MAC_DECERR) {
|
||||
/* Decryption with the given key failed.
|
||||
* Drop the packet. We also won't be able to decrypt it with
|
||||
|
@ -762,7 +762,7 @@ s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
|
||||
brcmf_dbg(SCAN, "scheduled scan completed\n");
|
||||
cfg->internal_escan = false;
|
||||
if (!aborted)
|
||||
cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
|
||||
cfg80211_sched_scan_results(cfg_to_wiphy(cfg), 0);
|
||||
} else if (scan_request) {
|
||||
struct cfg80211_scan_info info = {
|
||||
.aborted = aborted,
|
||||
@ -3372,7 +3372,7 @@ brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
|
||||
goto free_req;
|
||||
|
||||
out_err:
|
||||
cfg80211_sched_scan_stopped(wiphy);
|
||||
cfg80211_sched_scan_stopped(wiphy, 0);
|
||||
free_req:
|
||||
kfree(request);
|
||||
return err;
|
||||
@ -3405,7 +3405,7 @@ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
|
||||
}
|
||||
|
||||
static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
|
||||
struct net_device *ndev)
|
||||
struct net_device *ndev, u64 reqid)
|
||||
{
|
||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
@ -3607,7 +3607,7 @@ static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
|
||||
cfg->wowl.pre_pmmode);
|
||||
cfg->wowl.active = false;
|
||||
if (cfg->wowl.nd_enabled) {
|
||||
brcmf_cfg80211_sched_scan_stop(cfg->wiphy, ifp->ndev);
|
||||
brcmf_cfg80211_sched_scan_stop(cfg->wiphy, ifp->ndev, 0);
|
||||
brcmf_fweh_unregister(cfg->pub, BRCMF_E_PFN_NET_FOUND);
|
||||
brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
|
||||
brcmf_notify_sched_scan_results);
|
||||
@ -3691,7 +3691,7 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
|
||||
|
||||
/* Stop scheduled scan */
|
||||
if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO))
|
||||
brcmf_cfg80211_sched_scan_stop(wiphy, ndev);
|
||||
brcmf_cfg80211_sched_scan_stop(wiphy, ndev, 0);
|
||||
|
||||
/* end any scanning */
|
||||
if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
|
||||
@ -5359,6 +5359,7 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
|
||||
struct ieee80211_supported_band *band;
|
||||
struct brcmf_bss_info_le *bi;
|
||||
struct brcmu_chan ch;
|
||||
struct cfg80211_roam_info roam_info = {};
|
||||
u32 freq;
|
||||
s32 err = 0;
|
||||
u8 *buf;
|
||||
@ -5397,9 +5398,15 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
|
||||
|
||||
done:
|
||||
kfree(buf);
|
||||
cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
|
||||
conn_info->req_ie, conn_info->req_ie_len,
|
||||
conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
|
||||
|
||||
roam_info.channel = notify_channel;
|
||||
roam_info.bssid = profile->bssid;
|
||||
roam_info.req_ie = conn_info->req_ie;
|
||||
roam_info.req_ie_len = conn_info->req_ie_len;
|
||||
roam_info.resp_ie = conn_info->resp_ie;
|
||||
roam_info.resp_ie_len = conn_info->resp_ie_len;
|
||||
|
||||
cfg80211_roamed(ndev, &roam_info, GFP_KERNEL);
|
||||
brcmf_dbg(CONN, "Report roaming result\n");
|
||||
|
||||
set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
|
||||
@ -6374,11 +6381,11 @@ err:
|
||||
static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
|
||||
{
|
||||
/* scheduled scan settings */
|
||||
wiphy->max_sched_scan_reqs = 1;
|
||||
wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
|
||||
wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
|
||||
wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
|
||||
wiphy->max_sched_scan_plan_interval = BRCMF_PNO_SCHED_SCAN_MAX_PERIOD;
|
||||
wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
@ -7092,9 +7092,9 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
|
||||
rspec = brcms_c_compute_rspec(rxh, plcp);
|
||||
if (is_mcs_rate(rspec)) {
|
||||
rx_status->rate_idx = rspec & RSPEC_RATE_MASK;
|
||||
rx_status->flag |= RX_FLAG_HT;
|
||||
rx_status->encoding = RX_ENC_HT;
|
||||
if (rspec_is40mhz(rspec))
|
||||
rx_status->flag |= RX_FLAG_40MHZ;
|
||||
rx_status->bw = RATE_INFO_BW_40;
|
||||
} else {
|
||||
switch (rspec2rate(rspec)) {
|
||||
case BRCM_RATE_1M:
|
||||
@ -7149,9 +7149,9 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
|
||||
/* Determine short preamble and rate_idx */
|
||||
if (is_cck_rate(rspec)) {
|
||||
if (rxh->PhyRxStatus_0 & PRXS0_SHORTH)
|
||||
rx_status->flag |= RX_FLAG_SHORTPRE;
|
||||
rx_status->enc_flags |= RX_ENC_FLAG_SHORTPRE;
|
||||
} else if (is_ofdm_rate(rspec)) {
|
||||
rx_status->flag |= RX_FLAG_SHORTPRE;
|
||||
rx_status->enc_flags |= RX_ENC_FLAG_SHORTPRE;
|
||||
} else {
|
||||
brcms_err(wlc->hw->d11core, "%s: Unknown modulation\n",
|
||||
__func__);
|
||||
@ -7159,7 +7159,7 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh,
|
||||
}
|
||||
|
||||
if (plcp3_issgi(plcp[3]))
|
||||
rx_status->flag |= RX_FLAG_SHORT_GI;
|
||||
rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
|
||||
|
||||
if (rxh->RxStatus1 & RXS_DECERR) {
|
||||
rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC;
|
||||
|
@ -570,7 +570,7 @@ il3945_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
|
||||
|
||||
/* set the preamble flag if appropriate */
|
||||
if (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
|
||||
rx_status.flag |= RX_FLAG_SHORTPRE;
|
||||
rx_status.enc_flags |= RX_ENC_FLAG_SHORTPRE;
|
||||
|
||||
if ((unlikely(rx_stats->phy_count > 20))) {
|
||||
D_DROP("dsp size out of range [0,20]: %d\n",
|
||||
|
@ -728,15 +728,15 @@ il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
|
||||
|
||||
/* set the preamble flag if appropriate */
|
||||
if (phy_res->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
|
||||
rx_status.flag |= RX_FLAG_SHORTPRE;
|
||||
rx_status.enc_flags |= RX_ENC_FLAG_SHORTPRE;
|
||||
|
||||
/* Set up the HT phy flags */
|
||||
if (rate_n_flags & RATE_MCS_HT_MSK)
|
||||
rx_status.flag |= RX_FLAG_HT;
|
||||
rx_status.encoding = RX_ENC_HT;
|
||||
if (rate_n_flags & RATE_MCS_HT40_MSK)
|
||||
rx_status.flag |= RX_FLAG_40MHZ;
|
||||
rx_status.enc_flags |= RX_ENC_FLAG_40MHZ;
|
||||
if (rate_n_flags & RATE_MCS_SGI_MSK)
|
||||
rx_status.flag |= RX_FLAG_SHORT_GI;
|
||||
rx_status.enc_flags |= RX_ENC_FLAG_SHORT_GI;
|
||||
|
||||
if (phy_res->phy_flags & RX_RES_PHY_FLAGS_AGG_MSK) {
|
||||
/* We know which subframes of an A-MPDU belong
|
||||
|
@ -873,7 +873,7 @@ static void iwlagn_rx_reply_rx(struct iwl_priv *priv,
|
||||
|
||||
/* set the preamble flag if appropriate */
|
||||
if (phy_res->phy_flags & RX_RES_PHY_FLAGS_SHORT_PREAMBLE_MSK)
|
||||
rx_status.flag |= RX_FLAG_SHORTPRE;
|
||||
rx_status.enc_flags |= RX_ENC_FLAG_SHORTPRE;
|
||||
|
||||
if (phy_res->phy_flags & RX_RES_PHY_FLAGS_AGG_MSK) {
|
||||
/*
|
||||
@ -887,13 +887,13 @@ static void iwlagn_rx_reply_rx(struct iwl_priv *priv,
|
||||
|
||||
/* Set up the HT phy flags */
|
||||
if (rate_n_flags & RATE_MCS_HT_MSK)
|
||||
rx_status.flag |= RX_FLAG_HT;
|
||||
rx_status.encoding = RX_ENC_HT;
|
||||
if (rate_n_flags & RATE_MCS_HT40_MSK)
|
||||
rx_status.flag |= RX_FLAG_40MHZ;
|
||||
rx_status.enc_flags |= RX_ENC_FLAG_40MHZ;
|
||||
if (rate_n_flags & RATE_MCS_SGI_MSK)
|
||||
rx_status.flag |= RX_FLAG_SHORT_GI;
|
||||
rx_status.enc_flags |= RX_ENC_FLAG_SHORT_GI;
|
||||
if (rate_n_flags & RATE_MCS_GF_MSK)
|
||||
rx_status.flag |= RX_FLAG_HT_GF;
|
||||
rx_status.enc_flags |= RX_ENC_FLAG_HT_GF;
|
||||
|
||||
iwlagn_pass_packet_to_mac80211(priv, header, len, ampdu_status,
|
||||
rxb, &rx_status);
|
||||
|
@ -620,7 +620,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
|
||||
else
|
||||
hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
||||
|
||||
hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
|
||||
hw->wiphy->max_sched_scan_reqs = 1;
|
||||
hw->wiphy->max_sched_scan_ssids = PROBE_OPTION_MAX;
|
||||
hw->wiphy->max_match_sets = IWL_SCAN_MAX_PROFILES;
|
||||
/* we create the 802.11 header and zero length SSID IE. */
|
||||
|
@ -410,7 +410,7 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
|
||||
/* set the preamble flag if appropriate */
|
||||
if (phy_info->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_SHORT_PREAMBLE))
|
||||
rx_status->flag |= RX_FLAG_SHORTPRE;
|
||||
rx_status->enc_flags |= RX_ENC_FLAG_SHORTPRE;
|
||||
|
||||
if (phy_info->phy_flags & cpu_to_le16(RX_RES_PHY_FLAGS_AGG)) {
|
||||
/*
|
||||
@ -427,38 +427,38 @@ void iwl_mvm_rx_rx_mpdu(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
case RATE_MCS_CHAN_WIDTH_20:
|
||||
break;
|
||||
case RATE_MCS_CHAN_WIDTH_40:
|
||||
rx_status->flag |= RX_FLAG_40MHZ;
|
||||
rx_status->bw = RATE_INFO_BW_40;
|
||||
break;
|
||||
case RATE_MCS_CHAN_WIDTH_80:
|
||||
rx_status->vht_flag |= RX_VHT_FLAG_80MHZ;
|
||||
rx_status->bw = RATE_INFO_BW_80;
|
||||
break;
|
||||
case RATE_MCS_CHAN_WIDTH_160:
|
||||
rx_status->vht_flag |= RX_VHT_FLAG_160MHZ;
|
||||
rx_status->bw = RATE_INFO_BW_160;
|
||||
break;
|
||||
}
|
||||
if (rate_n_flags & RATE_MCS_SGI_MSK)
|
||||
rx_status->flag |= RX_FLAG_SHORT_GI;
|
||||
rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
|
||||
if (rate_n_flags & RATE_HT_MCS_GF_MSK)
|
||||
rx_status->flag |= RX_FLAG_HT_GF;
|
||||
rx_status->enc_flags |= RX_ENC_FLAG_HT_GF;
|
||||
if (rate_n_flags & RATE_MCS_LDPC_MSK)
|
||||
rx_status->flag |= RX_FLAG_LDPC;
|
||||
rx_status->enc_flags |= RX_ENC_FLAG_LDPC;
|
||||
if (rate_n_flags & RATE_MCS_HT_MSK) {
|
||||
u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >>
|
||||
RATE_MCS_STBC_POS;
|
||||
rx_status->flag |= RX_FLAG_HT;
|
||||
rx_status->encoding = RX_ENC_HT;
|
||||
rx_status->rate_idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK;
|
||||
rx_status->flag |= stbc << RX_FLAG_STBC_SHIFT;
|
||||
rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT;
|
||||
} else if (rate_n_flags & RATE_MCS_VHT_MSK) {
|
||||
u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >>
|
||||
RATE_MCS_STBC_POS;
|
||||
rx_status->vht_nss =
|
||||
rx_status->nss =
|
||||
((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >>
|
||||
RATE_VHT_MCS_NSS_POS) + 1;
|
||||
rx_status->rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK;
|
||||
rx_status->flag |= RX_FLAG_VHT;
|
||||
rx_status->flag |= stbc << RX_FLAG_STBC_SHIFT;
|
||||
rx_status->encoding = RX_ENC_VHT;
|
||||
rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT;
|
||||
if (rate_n_flags & RATE_MCS_BF_MSK)
|
||||
rx_status->vht_flag |= RX_VHT_FLAG_BF;
|
||||
rx_status->enc_flags |= RX_ENC_FLAG_BF;
|
||||
} else {
|
||||
int rate = iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags,
|
||||
rx_status->band);
|
||||
|
@ -824,7 +824,7 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
}
|
||||
/* set the preamble flag if appropriate */
|
||||
if (phy_info & IWL_RX_MPDU_PHY_SHORT_PREAMBLE)
|
||||
rx_status->flag |= RX_FLAG_SHORTPRE;
|
||||
rx_status->enc_flags |= RX_ENC_FLAG_SHORTPRE;
|
||||
|
||||
if (likely(!(phy_info & IWL_RX_MPDU_PHY_TSF_OVERLOAD))) {
|
||||
rx_status->mactime = le64_to_cpu(desc->tsf_on_air_rise);
|
||||
@ -958,38 +958,38 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi,
|
||||
case RATE_MCS_CHAN_WIDTH_20:
|
||||
break;
|
||||
case RATE_MCS_CHAN_WIDTH_40:
|
||||
rx_status->flag |= RX_FLAG_40MHZ;
|
||||
rx_status->bw = RATE_INFO_BW_40;
|
||||
break;
|
||||
case RATE_MCS_CHAN_WIDTH_80:
|
||||
rx_status->vht_flag |= RX_VHT_FLAG_80MHZ;
|
||||
rx_status->bw = RATE_INFO_BW_80;
|
||||
break;
|
||||
case RATE_MCS_CHAN_WIDTH_160:
|
||||
rx_status->vht_flag |= RX_VHT_FLAG_160MHZ;
|
||||
rx_status->bw = RATE_INFO_BW_160;
|
||||
break;
|
||||
}
|
||||
if (rate_n_flags & RATE_MCS_SGI_MSK)
|
||||
rx_status->flag |= RX_FLAG_SHORT_GI;
|
||||
rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
|
||||
if (rate_n_flags & RATE_HT_MCS_GF_MSK)
|
||||
rx_status->flag |= RX_FLAG_HT_GF;
|
||||
rx_status->enc_flags |= RX_ENC_FLAG_HT_GF;
|
||||
if (rate_n_flags & RATE_MCS_LDPC_MSK)
|
||||
rx_status->flag |= RX_FLAG_LDPC;
|
||||
rx_status->enc_flags |= RX_ENC_FLAG_LDPC;
|
||||
if (rate_n_flags & RATE_MCS_HT_MSK) {
|
||||
u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >>
|
||||
RATE_MCS_STBC_POS;
|
||||
rx_status->flag |= RX_FLAG_HT;
|
||||
rx_status->encoding = RX_ENC_HT;
|
||||
rx_status->rate_idx = rate_n_flags & RATE_HT_MCS_INDEX_MSK;
|
||||
rx_status->flag |= stbc << RX_FLAG_STBC_SHIFT;
|
||||
rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT;
|
||||
} else if (rate_n_flags & RATE_MCS_VHT_MSK) {
|
||||
u8 stbc = (rate_n_flags & RATE_MCS_STBC_MSK) >>
|
||||
RATE_MCS_STBC_POS;
|
||||
rx_status->vht_nss =
|
||||
rx_status->nss =
|
||||
((rate_n_flags & RATE_VHT_MCS_NSS_MSK) >>
|
||||
RATE_VHT_MCS_NSS_POS) + 1;
|
||||
rx_status->rate_idx = rate_n_flags & RATE_VHT_MCS_RATE_CODE_MSK;
|
||||
rx_status->flag |= RX_FLAG_VHT;
|
||||
rx_status->flag |= stbc << RX_FLAG_STBC_SHIFT;
|
||||
rx_status->encoding = RX_ENC_VHT;
|
||||
rx_status->enc_flags |= stbc << RX_ENC_FLAG_STBC_SHIFT;
|
||||
if (rate_n_flags & RATE_MCS_BF_MSK)
|
||||
rx_status->vht_flag |= RX_VHT_FLAG_BF;
|
||||
rx_status->enc_flags |= RX_ENC_FLAG_BF;
|
||||
} else {
|
||||
int rate = iwl_mvm_legacy_rate_to_mac80211_idx(rate_n_flags,
|
||||
rx_status->band);
|
||||
|
@ -352,7 +352,7 @@ static int p54_rx_data(struct p54_common *priv, struct sk_buff *skb)
|
||||
|
||||
rx_status->signal = p54_rssi_to_dbm(priv, hdr->rssi);
|
||||
if (hdr->rate & 0x10)
|
||||
rx_status->flag |= RX_FLAG_SHORTPRE;
|
||||
rx_status->enc_flags |= RX_ENC_FLAG_SHORTPRE;
|
||||
if (priv->hw->conf.chandef.chan->band == NL80211_BAND_5GHZ)
|
||||
rx_status->rate_idx = (rate < 4) ? 0 : rate - 4;
|
||||
else
|
||||
|
@ -1192,18 +1192,18 @@ static bool mac80211_hwsim_tx_frame_no_nl(struct ieee80211_hw *hw,
|
||||
if (info->control.rates[0].flags & IEEE80211_TX_RC_VHT_MCS) {
|
||||
rx_status.rate_idx =
|
||||
ieee80211_rate_get_vht_mcs(&info->control.rates[0]);
|
||||
rx_status.vht_nss =
|
||||
rx_status.nss =
|
||||
ieee80211_rate_get_vht_nss(&info->control.rates[0]);
|
||||
rx_status.flag |= RX_FLAG_VHT;
|
||||
rx_status.encoding = RX_ENC_VHT;
|
||||
} else {
|
||||
rx_status.rate_idx = info->control.rates[0].idx;
|
||||
if (info->control.rates[0].flags & IEEE80211_TX_RC_MCS)
|
||||
rx_status.flag |= RX_FLAG_HT;
|
||||
rx_status.encoding = RX_ENC_HT;
|
||||
}
|
||||
if (info->control.rates[0].flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
|
||||
rx_status.flag |= RX_FLAG_40MHZ;
|
||||
rx_status.enc_flags |= RX_ENC_FLAG_40MHZ;
|
||||
if (info->control.rates[0].flags & IEEE80211_TX_RC_SHORT_GI)
|
||||
rx_status.flag |= RX_FLAG_SHORT_GI;
|
||||
rx_status.enc_flags |= RX_ENC_FLAG_SHORT_GI;
|
||||
/* TODO: simulate real signal strength (and optional packet loss) */
|
||||
rx_status.signal = -50;
|
||||
if (info->control.vif)
|
||||
|
@ -2053,7 +2053,7 @@ mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
|
||||
|
||||
if (!mwifiex_stop_bg_scan(priv))
|
||||
cfg80211_sched_scan_stopped_rtnl(priv->wdev.wiphy);
|
||||
cfg80211_sched_scan_stopped_rtnl(priv->wdev.wiphy, 0);
|
||||
|
||||
if (mwifiex_deauthenticate(priv, NULL))
|
||||
return -EFAULT;
|
||||
@ -2321,7 +2321,7 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
|
||||
(int)sme->ssid_len, (char *)sme->ssid, sme->bssid);
|
||||
|
||||
if (!mwifiex_stop_bg_scan(priv))
|
||||
cfg80211_sched_scan_stopped_rtnl(priv->wdev.wiphy);
|
||||
cfg80211_sched_scan_stopped_rtnl(priv->wdev.wiphy, 0);
|
||||
|
||||
ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid,
|
||||
priv->bss_mode, sme->channel, sme, 0);
|
||||
@ -2530,7 +2530,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
|
||||
priv->scan_block = false;
|
||||
|
||||
if (!mwifiex_stop_bg_scan(priv))
|
||||
cfg80211_sched_scan_stopped_rtnl(priv->wdev.wiphy);
|
||||
cfg80211_sched_scan_stopped_rtnl(priv->wdev.wiphy, 0);
|
||||
|
||||
user_scan_cfg = kzalloc(sizeof(*user_scan_cfg), GFP_KERNEL);
|
||||
if (!user_scan_cfg)
|
||||
@ -2720,7 +2720,7 @@ mwifiex_cfg80211_sched_scan_start(struct wiphy *wiphy,
|
||||
* previous bgscan configuration in the firmware
|
||||
*/
|
||||
static int mwifiex_cfg80211_sched_scan_stop(struct wiphy *wiphy,
|
||||
struct net_device *dev)
|
||||
struct net_device *dev, u64 reqid)
|
||||
{
|
||||
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
|
||||
|
||||
@ -4297,7 +4297,6 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
|
||||
wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
|
||||
WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD |
|
||||
WIPHY_FLAG_AP_UAPSD |
|
||||
WIPHY_FLAG_SUPPORTS_SCHED_SCAN |
|
||||
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
|
||||
WIPHY_FLAG_HAS_CHANNEL_SWITCH |
|
||||
WIPHY_FLAG_PS_ON_BY_DEFAULT;
|
||||
@ -4316,6 +4315,7 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
|
||||
NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
|
||||
NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
|
||||
|
||||
wiphy->max_sched_scan_reqs = 1;
|
||||
wiphy->max_sched_scan_ssids = MWIFIEX_MAX_SSID_LIST_LENGTH;
|
||||
wiphy->max_sched_scan_ie_len = MWIFIEX_MAX_VSIE_LEN;
|
||||
wiphy->max_match_sets = MWIFIEX_MAX_SSID_LIST_LENGTH;
|
||||
|
@ -748,7 +748,7 @@ mwifiex_close(struct net_device *dev)
|
||||
mwifiex_dbg(priv->adapter, INFO,
|
||||
"aborting bgscan on ndo_stop\n");
|
||||
mwifiex_stop_bg_scan(priv);
|
||||
cfg80211_sched_scan_stopped(priv->wdev.wiphy);
|
||||
cfg80211_sched_scan_stopped(priv->wdev.wiphy, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1201,7 +1201,7 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
|
||||
break;
|
||||
case HostCmd_CMD_802_11_BG_SCAN_QUERY:
|
||||
ret = mwifiex_ret_802_11_scan(priv, resp);
|
||||
cfg80211_sched_scan_results(priv->wdev.wiphy);
|
||||
cfg80211_sched_scan_results(priv->wdev.wiphy, 0);
|
||||
mwifiex_dbg(adapter, CMD,
|
||||
"info: CMD_RESP: BG_SCAN result is ready!\n");
|
||||
break;
|
||||
|
@ -793,7 +793,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
|
||||
|
||||
case EVENT_BG_SCAN_STOPPED:
|
||||
dev_dbg(adapter->dev, "event: BGS_STOPPED\n");
|
||||
cfg80211_sched_scan_stopped(priv->wdev.wiphy);
|
||||
cfg80211_sched_scan_stopped(priv->wdev.wiphy, 0);
|
||||
if (priv->sched_scanning)
|
||||
priv->sched_scanning = false;
|
||||
break;
|
||||
|
@ -560,7 +560,7 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter)
|
||||
#endif
|
||||
mwifiex_dbg(adapter, CMD, "aborting bgscan!\n");
|
||||
mwifiex_stop_bg_scan(priv);
|
||||
cfg80211_sched_scan_stopped(priv->wdev.wiphy);
|
||||
cfg80211_sched_scan_stopped(priv->wdev.wiphy, 0);
|
||||
#ifdef CONFIG_PM
|
||||
}
|
||||
#endif
|
||||
|
@ -994,9 +994,9 @@ mwl8k_rxd_ap_process(void *_rxd, struct ieee80211_rx_status *status,
|
||||
*noise = -rxd->noise_floor;
|
||||
|
||||
if (rxd->rate & MWL8K_AP_RATE_INFO_MCS_FORMAT) {
|
||||
status->flag |= RX_FLAG_HT;
|
||||
status->encoding = RX_ENC_HT;
|
||||
if (rxd->rate & MWL8K_AP_RATE_INFO_40MHZ)
|
||||
status->flag |= RX_FLAG_40MHZ;
|
||||
status->bw = RATE_INFO_BW_40;
|
||||
status->rate_idx = MWL8K_AP_RATE_INFO_RATEID(rxd->rate);
|
||||
} else {
|
||||
int i;
|
||||
@ -1011,7 +1011,7 @@ mwl8k_rxd_ap_process(void *_rxd, struct ieee80211_rx_status *status,
|
||||
|
||||
if (rxd->channel > 14) {
|
||||
status->band = NL80211_BAND_5GHZ;
|
||||
if (!(status->flag & RX_FLAG_HT))
|
||||
if (!(status->encoding == RX_ENC_HT))
|
||||
status->rate_idx -= 5;
|
||||
} else {
|
||||
status->band = NL80211_BAND_2GHZ;
|
||||
@ -1109,17 +1109,17 @@ mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status,
|
||||
status->rate_idx = MWL8K_STA_RATE_INFO_RATEID(rate_info);
|
||||
|
||||
if (rate_info & MWL8K_STA_RATE_INFO_SHORTPRE)
|
||||
status->flag |= RX_FLAG_SHORTPRE;
|
||||
status->enc_flags |= RX_ENC_FLAG_SHORTPRE;
|
||||
if (rate_info & MWL8K_STA_RATE_INFO_40MHZ)
|
||||
status->flag |= RX_FLAG_40MHZ;
|
||||
status->bw = RATE_INFO_BW_40;
|
||||
if (rate_info & MWL8K_STA_RATE_INFO_SHORTGI)
|
||||
status->flag |= RX_FLAG_SHORT_GI;
|
||||
status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
|
||||
if (rate_info & MWL8K_STA_RATE_INFO_MCS_FORMAT)
|
||||
status->flag |= RX_FLAG_HT;
|
||||
status->encoding = RX_ENC_HT;
|
||||
|
||||
if (rxd->channel > 14) {
|
||||
status->band = NL80211_BAND_5GHZ;
|
||||
if (!(status->flag & RX_FLAG_HT))
|
||||
if (!(status->encoding == RX_ENC_HT))
|
||||
status->rate_idx -= 5;
|
||||
} else {
|
||||
status->band = NL80211_BAND_2GHZ;
|
||||
|
@ -401,7 +401,7 @@ mt76_mac_process_rate(struct ieee80211_rx_status *status, u16 rate)
|
||||
case MT_PHY_TYPE_CCK:
|
||||
if (idx >= 8) {
|
||||
idx -= 8;
|
||||
status->flag |= RX_FLAG_SHORTPRE;
|
||||
status->enc_flags |= RX_ENC_FLAG_SHORTPRE;
|
||||
}
|
||||
|
||||
if (WARN_ON(idx >= 4))
|
||||
@ -410,10 +410,10 @@ mt76_mac_process_rate(struct ieee80211_rx_status *status, u16 rate)
|
||||
status->rate_idx = idx;
|
||||
return;
|
||||
case MT_PHY_TYPE_HT_GF:
|
||||
status->flag |= RX_FLAG_HT_GF;
|
||||
status->enc_flags |= RX_ENC_FLAG_HT_GF;
|
||||
/* fall through */
|
||||
case MT_PHY_TYPE_HT:
|
||||
status->flag |= RX_FLAG_HT;
|
||||
status->encoding = RX_ENC_HT;
|
||||
status->rate_idx = idx;
|
||||
break;
|
||||
default:
|
||||
@ -422,13 +422,13 @@ mt76_mac_process_rate(struct ieee80211_rx_status *status, u16 rate)
|
||||
}
|
||||
|
||||
if (rate & MT_RXWI_RATE_SGI)
|
||||
status->flag |= RX_FLAG_SHORT_GI;
|
||||
status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
|
||||
|
||||
if (rate & MT_RXWI_RATE_STBC)
|
||||
status->flag |= 1 << RX_FLAG_STBC_SHIFT;
|
||||
status->enc_flags |= 1 << RX_ENC_FLAG_STBC_SHIFT;
|
||||
|
||||
if (rate & MT_RXWI_RATE_BW)
|
||||
status->flag |= RX_FLAG_40MHZ;
|
||||
status->bw = RATE_INFO_BW_40;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -889,10 +889,10 @@ void rt2800_process_rxwi(struct queue_entry *entry,
|
||||
rt2x00_desc_read(rxwi, 1, &word);
|
||||
|
||||
if (rt2x00_get_field32(word, RXWI_W1_SHORT_GI))
|
||||
rxdesc->flags |= RX_FLAG_SHORT_GI;
|
||||
rxdesc->enc_flags |= RX_ENC_FLAG_SHORT_GI;
|
||||
|
||||
if (rt2x00_get_field32(word, RXWI_W1_BW))
|
||||
rxdesc->flags |= RX_FLAG_40MHZ;
|
||||
rxdesc->bw = RATE_INFO_BW_40;
|
||||
|
||||
/*
|
||||
* Detect RX rate, always use MCS as signal type.
|
||||
|
@ -825,7 +825,7 @@ void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp)
|
||||
rate_idx = rt2x00lib_rxdone_read_signal(rt2x00dev, &rxdesc);
|
||||
if (rxdesc.rate_mode == RATE_MODE_HT_MIX ||
|
||||
rxdesc.rate_mode == RATE_MODE_HT_GREENFIELD)
|
||||
rxdesc.flags |= RX_FLAG_HT;
|
||||
rxdesc.encoding = RX_ENC_HT;
|
||||
|
||||
/*
|
||||
* Check if this is a beacon, and more frames have been
|
||||
@ -865,6 +865,9 @@ void rt2x00lib_rxdone(struct queue_entry *entry, gfp_t gfp)
|
||||
rx_status->rate_idx = rate_idx;
|
||||
rx_status->signal = rxdesc.rssi;
|
||||
rx_status->flag = rxdesc.flags;
|
||||
rx_status->enc_flags = rxdesc.enc_flags;
|
||||
rx_status->encoding = rxdesc.encoding;
|
||||
rx_status->bw = rxdesc.bw;
|
||||
rx_status->antenna = rt2x00dev->link.ant.active.rx;
|
||||
|
||||
ieee80211_rx_ni(rt2x00dev->hw, entry->skb);
|
||||
|
@ -184,6 +184,9 @@ struct rxdone_entry_desc {
|
||||
int flags;
|
||||
int dev_flags;
|
||||
u16 rate_mode;
|
||||
u16 enc_flags;
|
||||
enum mac80211_rx_encoding encoding;
|
||||
enum rate_info_bw bw;
|
||||
u8 cipher;
|
||||
u8 cipher_status;
|
||||
|
||||
|
@ -315,7 +315,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
|
||||
rx_status.mactime = tsft;
|
||||
rx_status.flag |= RX_FLAG_MACTIME_START;
|
||||
if (flags & RTL818X_RX_DESC_FLAG_SPLCP)
|
||||
rx_status.flag |= RX_FLAG_SHORTPRE;
|
||||
rx_status.enc_flags |= RX_ENC_FLAG_SHORTPRE;
|
||||
if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
|
||||
rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
|
||||
|
||||
|
@ -389,7 +389,7 @@ static void rtl8187_rx_cb(struct urb *urb)
|
||||
rx_status.band = dev->conf.chandef.chan->band;
|
||||
rx_status.flag |= RX_FLAG_MACTIME_START;
|
||||
if (flags & RTL818X_RX_DESC_FLAG_SPLCP)
|
||||
rx_status.flag |= RX_FLAG_SHORTPRE;
|
||||
rx_status.enc_flags |= RX_ENC_FLAG_SHORTPRE;
|
||||
if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
|
||||
rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
|
||||
memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
|
||||
|
@ -5041,7 +5041,7 @@ static void rtl8xxxu_rx_parse_phystats(struct rtl8xxxu_priv *priv,
|
||||
u32 rxmcs)
|
||||
{
|
||||
if (phy_stats->sgi_en)
|
||||
rx_status->flag |= RX_FLAG_SHORT_GI;
|
||||
rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
|
||||
|
||||
if (rxmcs < DESC_RATE_6M) {
|
||||
/*
|
||||
@ -5267,10 +5267,10 @@ int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb)
|
||||
if (rx_desc->crc32)
|
||||
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
|
||||
if (rx_desc->bw)
|
||||
rx_status->flag |= RX_FLAG_40MHZ;
|
||||
rx_status->bw = RATE_INFO_BW_40;
|
||||
|
||||
if (rx_desc->rxht) {
|
||||
rx_status->flag |= RX_FLAG_HT;
|
||||
rx_status->encoding = RX_ENC_HT;
|
||||
rx_status->rate_idx = rx_desc->rxmcs - DESC_RATE_MCS0;
|
||||
} else {
|
||||
rx_status->rate_idx = rx_desc->rxmcs;
|
||||
@ -5337,10 +5337,10 @@ int rtl8xxxu_parse_rxdesc24(struct rtl8xxxu_priv *priv, struct sk_buff *skb)
|
||||
if (rx_desc->crc32)
|
||||
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
|
||||
if (rx_desc->bw)
|
||||
rx_status->flag |= RX_FLAG_40MHZ;
|
||||
rx_status->bw = RATE_INFO_BW_40;
|
||||
|
||||
if (rx_desc->rxmcs >= DESC_RATE_MCS0) {
|
||||
rx_status->flag |= RX_FLAG_HT;
|
||||
rx_status->encoding = RX_ENC_HT;
|
||||
rx_status->rate_idx = rx_desc->rxmcs - DESC_RATE_MCS0;
|
||||
} else {
|
||||
rx_status->rate_idx = rx_desc->rxmcs;
|
||||
|
@ -444,10 +444,10 @@ bool rtl88ee_rx_query_desc(struct ieee80211_hw *hw,
|
||||
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
|
||||
|
||||
if (status->rx_is40Mhzpacket)
|
||||
rx_status->flag |= RX_FLAG_40MHZ;
|
||||
rx_status->bw = RATE_INFO_BW_40;
|
||||
|
||||
if (status->is_ht)
|
||||
rx_status->flag |= RX_FLAG_HT;
|
||||
rx_status->encoding = RX_ENC_HT;
|
||||
|
||||
rx_status->flag |= RX_FLAG_MACTIME_START;
|
||||
|
||||
|
@ -369,10 +369,10 @@ bool rtl92ce_rx_query_desc(struct ieee80211_hw *hw,
|
||||
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
|
||||
|
||||
if (stats->rx_is40Mhzpacket)
|
||||
rx_status->flag |= RX_FLAG_40MHZ;
|
||||
rx_status->bw = RATE_INFO_BW_40;
|
||||
|
||||
if (stats->is_ht)
|
||||
rx_status->flag |= RX_FLAG_HT;
|
||||
rx_status->encoding = RX_ENC_HT;
|
||||
|
||||
rx_status->flag |= RX_FLAG_MACTIME_START;
|
||||
|
||||
|
@ -329,9 +329,9 @@ bool rtl92cu_rx_query_desc(struct ieee80211_hw *hw,
|
||||
if (!GET_RX_DESC_SWDEC(pdesc))
|
||||
rx_status->flag |= RX_FLAG_DECRYPTED;
|
||||
if (GET_RX_DESC_BW(pdesc))
|
||||
rx_status->flag |= RX_FLAG_40MHZ;
|
||||
rx_status->bw = RATE_INFO_BW_40;
|
||||
if (GET_RX_DESC_RX_HT(pdesc))
|
||||
rx_status->flag |= RX_FLAG_HT;
|
||||
rx_status->encoding = RX_ENC_HT;
|
||||
rx_status->flag |= RX_FLAG_MACTIME_START;
|
||||
if (stats->decrypted)
|
||||
rx_status->flag |= RX_FLAG_DECRYPTED;
|
||||
@ -398,9 +398,9 @@ static void _rtl_rx_process(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
if (!GET_RX_DESC_SWDEC(rxdesc))
|
||||
rx_status->flag |= RX_FLAG_DECRYPTED;
|
||||
if (GET_RX_DESC_BW(rxdesc))
|
||||
rx_status->flag |= RX_FLAG_40MHZ;
|
||||
rx_status->bw = RATE_INFO_BW_40;
|
||||
if (GET_RX_DESC_RX_HT(rxdesc))
|
||||
rx_status->flag |= RX_FLAG_HT;
|
||||
rx_status->encoding = RX_ENC_HT;
|
||||
/* Data rate */
|
||||
rx_status->rate_idx = rtlwifi_rate_mapping(hw, stats.is_ht,
|
||||
false, stats.rate);
|
||||
|
@ -503,9 +503,9 @@ bool rtl92de_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
|
||||
if (!GET_RX_DESC_SWDEC(pdesc))
|
||||
rx_status->flag |= RX_FLAG_DECRYPTED;
|
||||
if (GET_RX_DESC_BW(pdesc))
|
||||
rx_status->flag |= RX_FLAG_40MHZ;
|
||||
rx_status->bw = RATE_INFO_BW_40;
|
||||
if (GET_RX_DESC_RXHT(pdesc))
|
||||
rx_status->flag |= RX_FLAG_HT;
|
||||
rx_status->encoding = RX_ENC_HT;
|
||||
rx_status->flag |= RX_FLAG_MACTIME_START;
|
||||
if (stats->decrypted)
|
||||
rx_status->flag |= RX_FLAG_DECRYPTED;
|
||||
|
@ -394,10 +394,10 @@ bool rtl92ee_rx_query_desc(struct ieee80211_hw *hw,
|
||||
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
|
||||
|
||||
if (status->rx_is40Mhzpacket)
|
||||
rx_status->flag |= RX_FLAG_40MHZ;
|
||||
rx_status->bw = RATE_INFO_BW_40;
|
||||
|
||||
if (status->is_ht)
|
||||
rx_status->flag |= RX_FLAG_HT;
|
||||
rx_status->encoding = RX_ENC_HT;
|
||||
|
||||
rx_status->flag |= RX_FLAG_MACTIME_START;
|
||||
|
||||
|
@ -289,10 +289,10 @@ bool rtl92se_rx_query_desc(struct ieee80211_hw *hw, struct rtl_stats *stats,
|
||||
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
|
||||
|
||||
if (stats->rx_is40Mhzpacket)
|
||||
rx_status->flag |= RX_FLAG_40MHZ;
|
||||
rx_status->bw = RATE_INFO_BW_40;
|
||||
|
||||
if (stats->is_ht)
|
||||
rx_status->flag |= RX_FLAG_HT;
|
||||
rx_status->encoding = RX_ENC_HT;
|
||||
|
||||
rx_status->flag |= RX_FLAG_MACTIME_START;
|
||||
|
||||
|
@ -317,10 +317,10 @@ bool rtl8723e_rx_query_desc(struct ieee80211_hw *hw,
|
||||
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
|
||||
|
||||
if (status->rx_is40Mhzpacket)
|
||||
rx_status->flag |= RX_FLAG_40MHZ;
|
||||
rx_status->bw = RATE_INFO_BW_40;
|
||||
|
||||
if (status->is_ht)
|
||||
rx_status->flag |= RX_FLAG_HT;
|
||||
rx_status->encoding = RX_ENC_HT;
|
||||
|
||||
rx_status->flag |= RX_FLAG_MACTIME_START;
|
||||
|
||||
|
@ -373,10 +373,10 @@ bool rtl8723be_rx_query_desc(struct ieee80211_hw *hw,
|
||||
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
|
||||
|
||||
if (status->rx_is40Mhzpacket)
|
||||
rx_status->flag |= RX_FLAG_40MHZ;
|
||||
rx_status->bw = RATE_INFO_BW_40;
|
||||
|
||||
if (status->is_ht)
|
||||
rx_status->flag |= RX_FLAG_HT;
|
||||
rx_status->encoding = RX_ENC_HT;
|
||||
|
||||
rx_status->flag |= RX_FLAG_MACTIME_START;
|
||||
|
||||
|
@ -520,18 +520,18 @@ bool rtl8821ae_rx_query_desc(struct ieee80211_hw *hw,
|
||||
rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
|
||||
|
||||
if (status->rx_packet_bw == HT_CHANNEL_WIDTH_20_40)
|
||||
rx_status->flag |= RX_FLAG_40MHZ;
|
||||
rx_status->bw = RATE_INFO_BW_40;
|
||||
else if (status->rx_packet_bw == HT_CHANNEL_WIDTH_80)
|
||||
rx_status->vht_flag |= RX_VHT_FLAG_80MHZ;
|
||||
rx_status->bw = RATE_INFO_BW_80;
|
||||
if (status->is_ht)
|
||||
rx_status->flag |= RX_FLAG_HT;
|
||||
rx_status->encoding = RX_ENC_HT;
|
||||
if (status->is_vht)
|
||||
rx_status->flag |= RX_FLAG_VHT;
|
||||
rx_status->encoding = RX_ENC_VHT;
|
||||
|
||||
if (status->is_short_gi)
|
||||
rx_status->flag |= RX_FLAG_SHORT_GI;
|
||||
rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
|
||||
|
||||
rx_status->vht_nss = status->vht_nss;
|
||||
rx_status->nss = status->vht_nss;
|
||||
rx_status->flag |= RX_FLAG_MACTIME_START;
|
||||
|
||||
/* hw will set status->decrypted true, if it finds the
|
||||
|
@ -2830,15 +2830,22 @@ static void rndis_wlan_do_link_up_work(struct usbnet *usbdev)
|
||||
}
|
||||
|
||||
if (priv->infra_mode == NDIS_80211_INFRA_INFRA) {
|
||||
if (!roamed)
|
||||
if (!roamed) {
|
||||
cfg80211_connect_result(usbdev->net, bssid, req_ie,
|
||||
req_ie_len, resp_ie,
|
||||
resp_ie_len, 0, GFP_KERNEL);
|
||||
else
|
||||
cfg80211_roamed(usbdev->net,
|
||||
get_current_channel(usbdev, NULL),
|
||||
bssid, req_ie, req_ie_len,
|
||||
resp_ie, resp_ie_len, GFP_KERNEL);
|
||||
} else {
|
||||
struct cfg80211_roam_info roam_info = {
|
||||
.channel = get_current_channel(usbdev, NULL),
|
||||
.bssid = bssid,
|
||||
.req_ie = req_ie,
|
||||
.req_ie_len = req_ie_len,
|
||||
.resp_ie = resp_ie,
|
||||
.resp_ie_len = resp_ie_len,
|
||||
};
|
||||
|
||||
cfg80211_roamed(usbdev->net, &roam_info, GFP_KERNEL);
|
||||
}
|
||||
} else if (priv->infra_mode == NDIS_80211_INFRA_ADHOC)
|
||||
cfg80211_ibss_joined(usbdev->net, bssid,
|
||||
get_current_channel(usbdev, NULL),
|
||||
|
@ -1085,7 +1085,7 @@ void cw1200_rx_cb(struct cw1200_common *priv,
|
||||
hdr->band);
|
||||
|
||||
if (arg->rx_rate >= 14) {
|
||||
hdr->flag |= RX_FLAG_HT;
|
||||
hdr->encoding = RX_ENC_HT;
|
||||
hdr->rate_idx = arg->rx_rate - 14;
|
||||
} else if (arg->rx_rate >= 4) {
|
||||
hdr->rate_idx = arg->rx_rate - 2;
|
||||
|
@ -141,7 +141,7 @@ static void wl1251_rx_status(struct wl1251 *wl,
|
||||
}
|
||||
|
||||
if (desc->mod_pre & SHORT_PREAMBLE_BIT)
|
||||
status->flag |= RX_FLAG_SHORTPRE;
|
||||
status->enc_flags |= RX_ENC_FLAG_SHORTPRE;
|
||||
}
|
||||
|
||||
static void wl1251_rx_body(struct wl1251 *wl,
|
||||
|
@ -6128,6 +6128,7 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
|
||||
wl->hw->wiphy->max_scan_ie_len = WL1271_CMD_TEMPL_MAX_SIZE -
|
||||
sizeof(struct ieee80211_header);
|
||||
|
||||
wl->hw->wiphy->max_sched_scan_reqs = 1;
|
||||
wl->hw->wiphy->max_sched_scan_ie_len = WL1271_CMD_TEMPL_MAX_SIZE -
|
||||
sizeof(struct ieee80211_header);
|
||||
|
||||
@ -6135,7 +6136,6 @@ static int wl1271_init_ieee80211(struct wl1271 *wl)
|
||||
|
||||
wl->hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD |
|
||||
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
|
||||
WIPHY_FLAG_SUPPORTS_SCHED_SCAN |
|
||||
WIPHY_FLAG_HAS_CHANNEL_SWITCH;
|
||||
|
||||
wl->hw->wiphy->features |= NL80211_FEATURE_AP_SCAN;
|
||||
|
@ -72,7 +72,7 @@ static void wl1271_rx_status(struct wl1271 *wl,
|
||||
|
||||
/* 11n support */
|
||||
if (desc->rate <= wl->hw_min_ht_rate)
|
||||
status->flag |= RX_FLAG_HT;
|
||||
status->encoding = RX_ENC_HT;
|
||||
|
||||
/*
|
||||
* Read the signal level and antenna diversity indication.
|
||||
|
@ -666,8 +666,11 @@ void prism2_disconnected(struct wlandevice *wlandev)
|
||||
|
||||
void prism2_roamed(struct wlandevice *wlandev)
|
||||
{
|
||||
cfg80211_roamed(wlandev->netdev, NULL, wlandev->bssid,
|
||||
NULL, 0, NULL, 0, GFP_KERNEL);
|
||||
struct cfg80211_roam_info roam_info = {
|
||||
.bssid = wlandev->bssid,
|
||||
};
|
||||
|
||||
cfg80211_roamed(wlandev->netdev, &roam_info, GFP_KERNEL);
|
||||
}
|
||||
|
||||
/* Structures for declaring wiphy interface */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* Copyright (c) 2005, Devicescape Software, Inc.
|
||||
* Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
|
||||
* Copyright (c) 2013 - 2014 Intel Mobile Communications GmbH
|
||||
* Copyright (c) 2016 Intel Deutschland GmbH
|
||||
* Copyright (c) 2016 - 2017 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@ -2177,37 +2177,37 @@ enum ieee80211_tdls_actioncode {
|
||||
#define WLAN_BSS_COEX_INFORMATION_REQUEST BIT(0)
|
||||
|
||||
/**
|
||||
* enum - mesh synchronization method identifier
|
||||
* enum ieee80211_mesh_sync_method - mesh synchronization method identifier
|
||||
*
|
||||
* @IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET: the default synchronization method
|
||||
* @IEEE80211_SYNC_METHOD_VENDOR: a vendor specific synchronization method
|
||||
* that will be specified in a vendor specific information element
|
||||
*/
|
||||
enum {
|
||||
enum ieee80211_mesh_sync_method {
|
||||
IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET = 1,
|
||||
IEEE80211_SYNC_METHOD_VENDOR = 255,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum - mesh path selection protocol identifier
|
||||
* enum ieee80211_mesh_path_protocol - mesh path selection protocol identifier
|
||||
*
|
||||
* @IEEE80211_PATH_PROTOCOL_HWMP: the default path selection protocol
|
||||
* @IEEE80211_PATH_PROTOCOL_VENDOR: a vendor specific protocol that will
|
||||
* be specified in a vendor specific information element
|
||||
*/
|
||||
enum {
|
||||
enum ieee80211_mesh_path_protocol {
|
||||
IEEE80211_PATH_PROTOCOL_HWMP = 1,
|
||||
IEEE80211_PATH_PROTOCOL_VENDOR = 255,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum - mesh path selection metric identifier
|
||||
* enum ieee80211_mesh_path_metric - mesh path selection metric identifier
|
||||
*
|
||||
* @IEEE80211_PATH_METRIC_AIRTIME: the default path selection metric
|
||||
* @IEEE80211_PATH_METRIC_VENDOR: a vendor specific metric that will be
|
||||
* specified in a vendor specific information element
|
||||
*/
|
||||
enum {
|
||||
enum ieee80211_mesh_path_metric {
|
||||
IEEE80211_PATH_METRIC_AIRTIME = 1,
|
||||
IEEE80211_PATH_METRIC_VENDOR = 255,
|
||||
};
|
||||
@ -2316,6 +2316,32 @@ struct ieee80211_timeout_interval_ie {
|
||||
__le32 value;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* enum ieee80211_idle_options - BSS idle options
|
||||
* @WLAN_IDLE_OPTIONS_PROTECTED_KEEP_ALIVE: the station should send an RSN
|
||||
* protected frame to the AP to reset the idle timer at the AP for
|
||||
* the station.
|
||||
*/
|
||||
enum ieee80211_idle_options {
|
||||
WLAN_IDLE_OPTIONS_PROTECTED_KEEP_ALIVE = BIT(0),
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ieee80211_bss_max_idle_period_ie
|
||||
*
|
||||
* This structure refers to "BSS Max idle period element"
|
||||
*
|
||||
* @max_idle_period: indicates the time period during which a station can
|
||||
* refrain from transmitting frames to its associated AP without being
|
||||
* disassociated. In units of 1000 TUs.
|
||||
* @idle_options: indicates the options associated with the BSS idle capability
|
||||
* as specified in &enum ieee80211_idle_options.
|
||||
*/
|
||||
struct ieee80211_bss_max_idle_period_ie {
|
||||
__le16 max_idle_period;
|
||||
u8 idle_options;
|
||||
} __packed;
|
||||
|
||||
/* BACK action code */
|
||||
enum ieee80211_back_actioncode {
|
||||
WLAN_ACTION_ADDBA_REQ = 0,
|
||||
@ -2356,18 +2382,21 @@ enum ieee80211_sa_query_action {
|
||||
#define WLAN_CIPHER_SUITE_SMS4 SUITE(0x001472, 1)
|
||||
|
||||
/* AKM suite selectors */
|
||||
#define WLAN_AKM_SUITE_8021X SUITE(0x000FAC, 1)
|
||||
#define WLAN_AKM_SUITE_PSK SUITE(0x000FAC, 2)
|
||||
#define WLAN_AKM_SUITE_FT_PSK SUITE(0x000FAC, 4)
|
||||
#define WLAN_AKM_SUITE_8021X_SHA256 SUITE(0x000FAC, 5)
|
||||
#define WLAN_AKM_SUITE_PSK_SHA256 SUITE(0x000FAC, 6)
|
||||
#define WLAN_AKM_SUITE_TDLS SUITE(0x000FAC, 7)
|
||||
#define WLAN_AKM_SUITE_SAE SUITE(0x000FAC, 8)
|
||||
#define WLAN_AKM_SUITE_FT_OVER_SAE SUITE(0x000FAC, 9)
|
||||
#define WLAN_AKM_SUITE_FILS_SHA256 SUITE(0x000FAC, 14)
|
||||
#define WLAN_AKM_SUITE_FILS_SHA384 SUITE(0x000FAC, 15)
|
||||
#define WLAN_AKM_SUITE_FT_FILS_SHA256 SUITE(0x000FAC, 16)
|
||||
#define WLAN_AKM_SUITE_FT_FILS_SHA384 SUITE(0x000FAC, 17)
|
||||
#define WLAN_AKM_SUITE_8021X SUITE(0x000FAC, 1)
|
||||
#define WLAN_AKM_SUITE_PSK SUITE(0x000FAC, 2)
|
||||
#define WLAN_AKM_SUITE_FT_8021X SUITE(0x000FAC, 3)
|
||||
#define WLAN_AKM_SUITE_FT_PSK SUITE(0x000FAC, 4)
|
||||
#define WLAN_AKM_SUITE_8021X_SHA256 SUITE(0x000FAC, 5)
|
||||
#define WLAN_AKM_SUITE_PSK_SHA256 SUITE(0x000FAC, 6)
|
||||
#define WLAN_AKM_SUITE_TDLS SUITE(0x000FAC, 7)
|
||||
#define WLAN_AKM_SUITE_SAE SUITE(0x000FAC, 8)
|
||||
#define WLAN_AKM_SUITE_FT_OVER_SAE SUITE(0x000FAC, 9)
|
||||
#define WLAN_AKM_SUITE_8021X_SUITE_B SUITE(0x000FAC, 11)
|
||||
#define WLAN_AKM_SUITE_8021X_SUITE_B_192 SUITE(0x000FAC, 12)
|
||||
#define WLAN_AKM_SUITE_FILS_SHA256 SUITE(0x000FAC, 14)
|
||||
#define WLAN_AKM_SUITE_FILS_SHA384 SUITE(0x000FAC, 15)
|
||||
#define WLAN_AKM_SUITE_FT_FILS_SHA256 SUITE(0x000FAC, 16)
|
||||
#define WLAN_AKM_SUITE_FT_FILS_SHA384 SUITE(0x000FAC, 17)
|
||||
|
||||
#define WLAN_MAX_KEY_LEN 32
|
||||
|
||||
|
@ -1613,11 +1613,15 @@ static inline void get_random_mask_addr(u8 *buf, const u8 *addr, const u8 *mask)
|
||||
/**
|
||||
* struct cfg80211_match_set - sets of attributes to match
|
||||
*
|
||||
* @ssid: SSID to be matched; may be zero-length for no match (RSSI only)
|
||||
* @ssid: SSID to be matched; may be zero-length in case of BSSID match
|
||||
* or no match (RSSI only)
|
||||
* @bssid: BSSID to be matched; may be all-zero BSSID in case of SSID match
|
||||
* or no match (RSSI only)
|
||||
* @rssi_thold: don't report scan results below this threshold (in s32 dBm)
|
||||
*/
|
||||
struct cfg80211_match_set {
|
||||
struct cfg80211_ssid ssid;
|
||||
u8 bssid[ETH_ALEN];
|
||||
s32 rssi_thold;
|
||||
};
|
||||
|
||||
@ -1662,6 +1666,7 @@ struct cfg80211_bss_select_adjust {
|
||||
* (others are filtered out).
|
||||
* If ommited, all results are passed.
|
||||
* @n_match_sets: number of match sets
|
||||
* @results_wk: worker for processing results notification.
|
||||
* @wiphy: the wiphy this was for
|
||||
* @dev: the interface
|
||||
* @scan_start: start time of the scheduled scan
|
||||
@ -1678,6 +1683,8 @@ struct cfg80211_bss_select_adjust {
|
||||
* @rcu_head: RCU callback used to free the struct
|
||||
* @owner_nlportid: netlink portid of owner (if this should is a request
|
||||
* owned by a particular socket)
|
||||
* @nl_owner_dead: netlink owner socket was closed - this request be freed
|
||||
* @list: for keeping list of requests.
|
||||
* @delay: delay in seconds to use before starting the first scan
|
||||
* cycle. The driver may ignore this parameter and start
|
||||
* immediately (or at any other time), if this feature is not
|
||||
@ -1720,8 +1727,11 @@ struct cfg80211_sched_scan_request {
|
||||
struct wiphy *wiphy;
|
||||
struct net_device *dev;
|
||||
unsigned long scan_start;
|
||||
bool report_results;
|
||||
struct rcu_head rcu_head;
|
||||
u32 owner_nlportid;
|
||||
bool nl_owner_dead;
|
||||
struct list_head list;
|
||||
|
||||
/* keep last */
|
||||
struct ieee80211_channel *channels[0];
|
||||
@ -2678,8 +2688,7 @@ struct cfg80211_nan_func {
|
||||
* indication of requesting reassociation.
|
||||
* In both the driver-initiated and new connect() call initiated roaming
|
||||
* cases, the result of roaming is indicated with a call to
|
||||
* cfg80211_roamed() or cfg80211_roamed_bss().
|
||||
* (invoked with the wireless_dev mutex held)
|
||||
* cfg80211_roamed(). (invoked with the wireless_dev mutex held)
|
||||
* @update_connect_params: Update the connect parameters while connected to a
|
||||
* BSS. The updated parameters can be used by driver/firmware for
|
||||
* subsequent BSS selection (roaming) decisions and to form the
|
||||
@ -2765,12 +2774,12 @@ struct cfg80211_nan_func {
|
||||
* @set_cqm_txe_config: Configure connection quality monitor TX error
|
||||
* thresholds.
|
||||
* @sched_scan_start: Tell the driver to start a scheduled scan.
|
||||
* @sched_scan_stop: Tell the driver to stop an ongoing scheduled scan. This
|
||||
* call must stop the scheduled scan and be ready for starting a new one
|
||||
* before it returns, i.e. @sched_scan_start may be called immediately
|
||||
* after that again and should not fail in that case. The driver should
|
||||
* not call cfg80211_sched_scan_stopped() for a requested stop (when this
|
||||
* method returns 0.)
|
||||
* @sched_scan_stop: Tell the driver to stop an ongoing scheduled scan with
|
||||
* given request id. This call must stop the scheduled scan and be ready
|
||||
* for starting a new one before it returns, i.e. @sched_scan_start may be
|
||||
* called immediately after that again and should not fail in that case.
|
||||
* The driver should not call cfg80211_sched_scan_stopped() for a requested
|
||||
* stop (when this method returns 0).
|
||||
*
|
||||
* @mgmt_frame_register: Notify driver that a management frame type was
|
||||
* registered. The callback is allowed to sleep.
|
||||
@ -3068,7 +3077,8 @@ struct cfg80211_ops {
|
||||
int (*sched_scan_start)(struct wiphy *wiphy,
|
||||
struct net_device *dev,
|
||||
struct cfg80211_sched_scan_request *request);
|
||||
int (*sched_scan_stop)(struct wiphy *wiphy, struct net_device *dev);
|
||||
int (*sched_scan_stop)(struct wiphy *wiphy, struct net_device *dev,
|
||||
u64 reqid);
|
||||
|
||||
int (*set_rekey_data)(struct wiphy *wiphy, struct net_device *dev,
|
||||
struct cfg80211_gtk_rekey_data *data);
|
||||
@ -3213,7 +3223,7 @@ enum wiphy_flags {
|
||||
WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7),
|
||||
WIPHY_FLAG_IBSS_RSN = BIT(8),
|
||||
WIPHY_FLAG_MESH_AUTH = BIT(10),
|
||||
WIPHY_FLAG_SUPPORTS_SCHED_SCAN = BIT(11),
|
||||
/* use hole at 11 */
|
||||
/* use hole at 12 */
|
||||
WIPHY_FLAG_SUPPORTS_FW_ROAM = BIT(13),
|
||||
WIPHY_FLAG_AP_UAPSD = BIT(14),
|
||||
@ -3551,6 +3561,8 @@ struct wiphy_iftype_ext_capab {
|
||||
* this variable determines its size
|
||||
* @max_scan_ssids: maximum number of SSIDs the device can scan for in
|
||||
* any given scan
|
||||
* @max_sched_scan_reqs: maximum number of scheduled scan requests that
|
||||
* the device can run concurrently.
|
||||
* @max_sched_scan_ssids: maximum number of SSIDs the device can scan
|
||||
* for in any given scheduled scan
|
||||
* @max_match_sets: maximum number of match sets the device can handle
|
||||
@ -3687,6 +3699,7 @@ struct wiphy {
|
||||
|
||||
int bss_priv_size;
|
||||
u8 max_scan_ssids;
|
||||
u8 max_sched_scan_reqs;
|
||||
u8 max_sched_scan_ssids;
|
||||
u8 max_match_sets;
|
||||
u16 max_scan_ie_len;
|
||||
@ -3988,6 +4001,7 @@ struct cfg80211_cqm_config;
|
||||
* @event_list: (private) list for internal event processing
|
||||
* @event_lock: (private) lock for event list
|
||||
* @owner_nlportid: (private) owner socket port ID
|
||||
* @nl_owner_dead: (private) owner socket went away
|
||||
* @cqm_config: (private) nl80211 RSSI monitor state
|
||||
*/
|
||||
struct wireless_dev {
|
||||
@ -4037,12 +4051,13 @@ struct wireless_dev {
|
||||
|
||||
u32 ap_unexpected_nlportid;
|
||||
|
||||
u32 owner_nlportid;
|
||||
bool nl_owner_dead;
|
||||
|
||||
bool cac_started;
|
||||
unsigned long cac_start_time;
|
||||
unsigned int cac_time_ms;
|
||||
|
||||
u32 owner_nlportid;
|
||||
|
||||
#ifdef CONFIG_CFG80211_WEXT
|
||||
/* wext data */
|
||||
struct {
|
||||
@ -4551,31 +4566,34 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request,
|
||||
* cfg80211_sched_scan_results - notify that new scan results are available
|
||||
*
|
||||
* @wiphy: the wiphy which got scheduled scan results
|
||||
* @reqid: identifier for the related scheduled scan request
|
||||
*/
|
||||
void cfg80211_sched_scan_results(struct wiphy *wiphy);
|
||||
void cfg80211_sched_scan_results(struct wiphy *wiphy, u64 reqid);
|
||||
|
||||
/**
|
||||
* cfg80211_sched_scan_stopped - notify that the scheduled scan has stopped
|
||||
*
|
||||
* @wiphy: the wiphy on which the scheduled scan stopped
|
||||
* @reqid: identifier for the related scheduled scan request
|
||||
*
|
||||
* The driver can call this function to inform cfg80211 that the
|
||||
* scheduled scan had to be stopped, for whatever reason. The driver
|
||||
* is then called back via the sched_scan_stop operation when done.
|
||||
*/
|
||||
void cfg80211_sched_scan_stopped(struct wiphy *wiphy);
|
||||
void cfg80211_sched_scan_stopped(struct wiphy *wiphy, u64 reqid);
|
||||
|
||||
/**
|
||||
* cfg80211_sched_scan_stopped_rtnl - notify that the scheduled scan has stopped
|
||||
*
|
||||
* @wiphy: the wiphy on which the scheduled scan stopped
|
||||
* @reqid: identifier for the related scheduled scan request
|
||||
*
|
||||
* The driver can call this function to inform cfg80211 that the
|
||||
* scheduled scan had to be stopped, for whatever reason. The driver
|
||||
* is then called back via the sched_scan_stop operation when done.
|
||||
* This function should be called with rtnl locked.
|
||||
*/
|
||||
void cfg80211_sched_scan_stopped_rtnl(struct wiphy *wiphy);
|
||||
void cfg80211_sched_scan_stopped_rtnl(struct wiphy *wiphy, u64 reqid);
|
||||
|
||||
/**
|
||||
* cfg80211_inform_bss_frame_data - inform cfg80211 of a received BSS frame
|
||||
@ -5375,52 +5393,47 @@ cfg80211_connect_timeout(struct net_device *dev, const u8 *bssid,
|
||||
gfp, timeout_reason);
|
||||
}
|
||||
|
||||
/**
|
||||
* struct cfg80211_roam_info - driver initiated roaming information
|
||||
*
|
||||
* @channel: the channel of the new AP
|
||||
* @bss: entry of bss to which STA got roamed (may be %NULL if %bssid is set)
|
||||
* @bssid: the BSSID of the new AP (may be %NULL if %bss is set)
|
||||
* @req_ie: association request IEs (maybe be %NULL)
|
||||
* @req_ie_len: association request IEs length
|
||||
* @resp_ie: association response IEs (may be %NULL)
|
||||
* @resp_ie_len: assoc response IEs length
|
||||
*/
|
||||
struct cfg80211_roam_info {
|
||||
struct ieee80211_channel *channel;
|
||||
struct cfg80211_bss *bss;
|
||||
const u8 *bssid;
|
||||
const u8 *req_ie;
|
||||
size_t req_ie_len;
|
||||
const u8 *resp_ie;
|
||||
size_t resp_ie_len;
|
||||
};
|
||||
|
||||
/**
|
||||
* cfg80211_roamed - notify cfg80211 of roaming
|
||||
*
|
||||
* @dev: network device
|
||||
* @channel: the channel of the new AP
|
||||
* @bssid: the BSSID of the new AP
|
||||
* @req_ie: association request IEs (maybe be %NULL)
|
||||
* @req_ie_len: association request IEs length
|
||||
* @resp_ie: association response IEs (may be %NULL)
|
||||
* @resp_ie_len: assoc response IEs length
|
||||
* @info: information about the new BSS. struct &cfg80211_roam_info.
|
||||
* @gfp: allocation flags
|
||||
*
|
||||
* It should be called by the underlying driver whenever it roamed
|
||||
* from one AP to another while connected.
|
||||
*/
|
||||
void cfg80211_roamed(struct net_device *dev,
|
||||
struct ieee80211_channel *channel,
|
||||
const u8 *bssid,
|
||||
const u8 *req_ie, size_t req_ie_len,
|
||||
const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp);
|
||||
|
||||
/**
|
||||
* cfg80211_roamed_bss - notify cfg80211 of roaming
|
||||
*
|
||||
* @dev: network device
|
||||
* @bss: entry of bss to which STA got roamed
|
||||
* @req_ie: association request IEs (maybe be %NULL)
|
||||
* @req_ie_len: association request IEs length
|
||||
* @resp_ie: association response IEs (may be %NULL)
|
||||
* @resp_ie_len: assoc response IEs length
|
||||
* @gfp: allocation flags
|
||||
*
|
||||
* This is just a wrapper to notify cfg80211 of roaming event with driver
|
||||
* passing bss to avoid a race in timeout of the bss entry. It should be
|
||||
* called by the underlying driver whenever it roamed from one AP to another
|
||||
* while connected. Drivers which have roaming implemented in firmware
|
||||
* may use this function to avoid a race in bss entry timeout where the bss
|
||||
* entry of the new AP is seen in the driver, but gets timed out by the time
|
||||
* it is accessed in __cfg80211_roamed() due to delay in scheduling
|
||||
* This function may be called with the driver passing either the BSSID of the
|
||||
* new AP or passing the bss entry to avoid a race in timeout of the bss entry.
|
||||
* It should be called by the underlying driver whenever it roamed from one AP
|
||||
* to another while connected. Drivers which have roaming implemented in
|
||||
* firmware should pass the bss entry to avoid a race in bss entry timeout where
|
||||
* the bss entry of the new AP is seen in the driver, but gets timed out by the
|
||||
* time it is accessed in __cfg80211_roamed() due to delay in scheduling
|
||||
* rdev->event_work. In case of any failures, the reference is released
|
||||
* either in cfg80211_roamed_bss() or in __cfg80211_romed(), Otherwise,
|
||||
* it will be released while diconneting from the current bss.
|
||||
* either in cfg80211_roamed() or in __cfg80211_romed(), Otherwise, it will be
|
||||
* released while diconneting from the current bss.
|
||||
*/
|
||||
void cfg80211_roamed_bss(struct net_device *dev, struct cfg80211_bss *bss,
|
||||
const u8 *req_ie, size_t req_ie_len,
|
||||
const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp);
|
||||
void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info,
|
||||
gfp_t gfp);
|
||||
|
||||
/**
|
||||
* cfg80211_disconnected - notify cfg80211 that connection was dropped
|
||||
|
@ -5,7 +5,7 @@
|
||||
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
|
||||
* Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2015 - 2016 Intel Deutschland GmbH
|
||||
* Copyright (C) 2015 - 2017 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@ -299,6 +299,8 @@ struct ieee80211_vif_chanctx_switch {
|
||||
* context had been assigned.
|
||||
* @BSS_CHANGED_OCB: OCB join status changed
|
||||
* @BSS_CHANGED_MU_GROUPS: VHT MU-MIMO group id or user position changed
|
||||
* @BSS_CHANGED_KEEP_ALIVE: keep alive options (idle period or protected
|
||||
* keep alive) changed.
|
||||
*/
|
||||
enum ieee80211_bss_change {
|
||||
BSS_CHANGED_ASSOC = 1<<0,
|
||||
@ -325,6 +327,7 @@ enum ieee80211_bss_change {
|
||||
BSS_CHANGED_BANDWIDTH = 1<<21,
|
||||
BSS_CHANGED_OCB = 1<<22,
|
||||
BSS_CHANGED_MU_GROUPS = 1<<23,
|
||||
BSS_CHANGED_KEEP_ALIVE = 1<<24,
|
||||
|
||||
/* when adding here, make sure to change ieee80211_reconfig */
|
||||
};
|
||||
@ -533,6 +536,13 @@ struct ieee80211_mu_group_data {
|
||||
* @allow_p2p_go_ps: indication for AP or P2P GO interface, whether it's allowed
|
||||
* to use P2P PS mechanism or not. AP/P2P GO is not allowed to use P2P PS
|
||||
* if it has associated clients without P2P PS support.
|
||||
* @max_idle_period: the time period during which the station can refrain from
|
||||
* transmitting frames to its associated AP without being disassociated.
|
||||
* In units of 1000 TUs. Zero value indicates that the AP did not include
|
||||
* a (valid) BSS Max Idle Period Element.
|
||||
* @protected_keep_alive: if set, indicates that the station should send an RSN
|
||||
* protected frame to the AP to reset the idle timer at the AP for the
|
||||
* station.
|
||||
*/
|
||||
struct ieee80211_bss_conf {
|
||||
const u8 *bssid;
|
||||
@ -573,6 +583,8 @@ struct ieee80211_bss_conf {
|
||||
enum nl80211_tx_power_setting txpower_type;
|
||||
struct ieee80211_p2p_noa_attr p2p_noa_attr;
|
||||
bool allow_p2p_go_ps;
|
||||
u16 max_idle_period;
|
||||
bool protected_keep_alive;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -948,6 +960,19 @@ struct ieee80211_tx_info {
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ieee80211_tx_status - extended tx staus info for rate control
|
||||
*
|
||||
* @sta: Station that the packet was transmitted for
|
||||
* @info: Basic tx status information
|
||||
* @skb: Packet skb (can be NULL if not provided by the driver)
|
||||
*/
|
||||
struct ieee80211_tx_status {
|
||||
struct ieee80211_sta *sta;
|
||||
struct ieee80211_tx_info *info;
|
||||
struct sk_buff *skb;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ieee80211_scan_ies - descriptors for different blocks of IEs
|
||||
*
|
||||
@ -1045,16 +1070,8 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
|
||||
* (including FCS) was received.
|
||||
* @RX_FLAG_MACTIME_PLCP_START: The timestamp passed in the RX status (@mactime
|
||||
* field) is valid and contains the time the SYNC preamble was received.
|
||||
* @RX_FLAG_SHORTPRE: Short preamble was used for this frame
|
||||
* @RX_FLAG_HT: HT MCS was used and rate_idx is MCS index
|
||||
* @RX_FLAG_VHT: VHT MCS was used and rate_index is MCS index
|
||||
* @RX_FLAG_40MHZ: HT40 (40 MHz) was used
|
||||
* @RX_FLAG_SHORT_GI: Short guard interval was used
|
||||
* @RX_FLAG_NO_SIGNAL_VAL: The signal strength value is not present.
|
||||
* Valid only for data frames (mainly A-MPDU)
|
||||
* @RX_FLAG_HT_GF: This frame was received in a HT-greenfield transmission, if
|
||||
* the driver fills this value it should add %IEEE80211_RADIOTAP_MCS_HAVE_FMT
|
||||
* to hw.radiotap_mcs_details to advertise that fact
|
||||
* @RX_FLAG_AMPDU_DETAILS: A-MPDU details are known, in particular the reference
|
||||
* number (@ampdu_reference) must be populated and be a distinct number for
|
||||
* each A-MPDU
|
||||
@ -1067,7 +1084,6 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
|
||||
* is stored in the @ampdu_delimiter_crc field)
|
||||
* @RX_FLAG_MIC_STRIPPED: The mic was stripped of this packet. Decryption was
|
||||
* done by the hardware
|
||||
* @RX_FLAG_LDPC: LDPC was used
|
||||
* @RX_FLAG_ONLY_MONITOR: Report frame only to monitor interfaces without
|
||||
* processing it in any regular way.
|
||||
* This is useful if drivers offload some frames but still want to report
|
||||
@ -1076,9 +1092,6 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
|
||||
* monitor interfaces.
|
||||
* This is useful if drivers offload some frames but still want to report
|
||||
* them for sniffing purposes.
|
||||
* @RX_FLAG_STBC_MASK: STBC 2 bit bitmask. 1 - Nss=1, 2 - Nss=2, 3 - Nss=3
|
||||
* @RX_FLAG_10MHZ: 10 MHz (half channel) was used
|
||||
* @RX_FLAG_5MHZ: 5 MHz (quarter channel) was used
|
||||
* @RX_FLAG_AMSDU_MORE: Some drivers may prefer to report separate A-MSDU
|
||||
* subframes instead of a one huge frame for performance reasons.
|
||||
* All, but the last MSDU from an A-MSDU should have this flag set. E.g.
|
||||
@ -1106,50 +1119,54 @@ enum mac80211_rx_flags {
|
||||
RX_FLAG_FAILED_FCS_CRC = BIT(5),
|
||||
RX_FLAG_FAILED_PLCP_CRC = BIT(6),
|
||||
RX_FLAG_MACTIME_START = BIT(7),
|
||||
RX_FLAG_SHORTPRE = BIT(8),
|
||||
RX_FLAG_HT = BIT(9),
|
||||
RX_FLAG_40MHZ = BIT(10),
|
||||
RX_FLAG_SHORT_GI = BIT(11),
|
||||
RX_FLAG_NO_SIGNAL_VAL = BIT(12),
|
||||
RX_FLAG_HT_GF = BIT(13),
|
||||
RX_FLAG_AMPDU_DETAILS = BIT(14),
|
||||
RX_FLAG_PN_VALIDATED = BIT(15),
|
||||
RX_FLAG_DUP_VALIDATED = BIT(16),
|
||||
RX_FLAG_AMPDU_LAST_KNOWN = BIT(17),
|
||||
RX_FLAG_AMPDU_IS_LAST = BIT(18),
|
||||
RX_FLAG_AMPDU_DELIM_CRC_ERROR = BIT(19),
|
||||
RX_FLAG_AMPDU_DELIM_CRC_KNOWN = BIT(20),
|
||||
RX_FLAG_MACTIME_END = BIT(21),
|
||||
RX_FLAG_VHT = BIT(22),
|
||||
RX_FLAG_LDPC = BIT(23),
|
||||
RX_FLAG_ONLY_MONITOR = BIT(24),
|
||||
RX_FLAG_SKIP_MONITOR = BIT(25),
|
||||
RX_FLAG_STBC_MASK = BIT(26) | BIT(27),
|
||||
RX_FLAG_10MHZ = BIT(28),
|
||||
RX_FLAG_5MHZ = BIT(29),
|
||||
RX_FLAG_AMSDU_MORE = BIT(30),
|
||||
RX_FLAG_RADIOTAP_VENDOR_DATA = BIT(31),
|
||||
RX_FLAG_MIC_STRIPPED = BIT_ULL(32),
|
||||
RX_FLAG_ALLOW_SAME_PN = BIT_ULL(33),
|
||||
RX_FLAG_ICV_STRIPPED = BIT_ULL(34),
|
||||
RX_FLAG_NO_SIGNAL_VAL = BIT(8),
|
||||
RX_FLAG_AMPDU_DETAILS = BIT(9),
|
||||
RX_FLAG_PN_VALIDATED = BIT(10),
|
||||
RX_FLAG_DUP_VALIDATED = BIT(11),
|
||||
RX_FLAG_AMPDU_LAST_KNOWN = BIT(12),
|
||||
RX_FLAG_AMPDU_IS_LAST = BIT(13),
|
||||
RX_FLAG_AMPDU_DELIM_CRC_ERROR = BIT(14),
|
||||
RX_FLAG_AMPDU_DELIM_CRC_KNOWN = BIT(15),
|
||||
RX_FLAG_MACTIME_END = BIT(16),
|
||||
RX_FLAG_ONLY_MONITOR = BIT(17),
|
||||
RX_FLAG_SKIP_MONITOR = BIT(18),
|
||||
RX_FLAG_AMSDU_MORE = BIT(19),
|
||||
RX_FLAG_RADIOTAP_VENDOR_DATA = BIT(20),
|
||||
RX_FLAG_MIC_STRIPPED = BIT(21),
|
||||
RX_FLAG_ALLOW_SAME_PN = BIT(22),
|
||||
RX_FLAG_ICV_STRIPPED = BIT(23),
|
||||
};
|
||||
|
||||
#define RX_FLAG_STBC_SHIFT 26
|
||||
|
||||
/**
|
||||
* enum mac80211_rx_vht_flags - receive VHT flags
|
||||
* enum mac80211_rx_encoding_flags - MCS & bandwidth flags
|
||||
*
|
||||
* These flags are used with the @vht_flag member of
|
||||
* &struct ieee80211_rx_status.
|
||||
* @RX_VHT_FLAG_80MHZ: 80 MHz was used
|
||||
* @RX_VHT_FLAG_160MHZ: 160 MHz was used
|
||||
* @RX_VHT_FLAG_BF: packet was beamformed
|
||||
* @RX_ENC_FLAG_SHORTPRE: Short preamble was used for this frame
|
||||
* @RX_ENC_FLAG_40MHZ: HT40 (40 MHz) was used
|
||||
* @RX_ENC_FLAG_SHORT_GI: Short guard interval was used
|
||||
* @RX_ENC_FLAG_HT_GF: This frame was received in a HT-greenfield transmission,
|
||||
* if the driver fills this value it should add
|
||||
* %IEEE80211_RADIOTAP_MCS_HAVE_FMT
|
||||
* to hw.radiotap_mcs_details to advertise that fact
|
||||
* @RX_ENC_FLAG_LDPC: LDPC was used
|
||||
* @RX_ENC_FLAG_STBC_MASK: STBC 2 bit bitmask. 1 - Nss=1, 2 - Nss=2, 3 - Nss=3
|
||||
* @RX_ENC_FLAG_BF: packet was beamformed
|
||||
*/
|
||||
enum mac80211_rx_encoding_flags {
|
||||
RX_ENC_FLAG_SHORTPRE = BIT(0),
|
||||
RX_ENC_FLAG_40MHZ = BIT(1),
|
||||
RX_ENC_FLAG_SHORT_GI = BIT(2),
|
||||
RX_ENC_FLAG_HT_GF = BIT(3),
|
||||
RX_ENC_FLAG_STBC_MASK = BIT(4) | BIT(5),
|
||||
RX_ENC_FLAG_LDPC = BIT(6),
|
||||
RX_ENC_FLAG_BF = BIT(7),
|
||||
};
|
||||
|
||||
enum mac80211_rx_vht_flags {
|
||||
RX_VHT_FLAG_80MHZ = BIT(0),
|
||||
RX_VHT_FLAG_160MHZ = BIT(1),
|
||||
RX_VHT_FLAG_BF = BIT(2),
|
||||
#define RX_ENC_FLAG_STBC_SHIFT 4
|
||||
|
||||
enum mac80211_rx_encoding {
|
||||
RX_ENC_LEGACY = 0,
|
||||
RX_ENC_HT,
|
||||
RX_ENC_VHT,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1179,9 +1196,11 @@ enum mac80211_rx_vht_flags {
|
||||
* @antenna: antenna used
|
||||
* @rate_idx: index of data rate into band's supported rates or MCS index if
|
||||
* HT or VHT is used (%RX_FLAG_HT/%RX_FLAG_VHT)
|
||||
* @vht_nss: number of streams (VHT only)
|
||||
* @nss: number of streams (VHT and HE only)
|
||||
* @flag: %RX_FLAG_\*
|
||||
* @vht_flag: %RX_VHT_FLAG_\*
|
||||
* @encoding: &enum mac80211_rx_encoding
|
||||
* @bw: &enum rate_info_bw
|
||||
* @enc_flags: uses bits from &enum mac80211_rx_encoding_flags
|
||||
* @rx_flags: internal RX flags for mac80211
|
||||
* @ampdu_reference: A-MPDU reference number, must be a different value for
|
||||
* each A-MPDU but the same for each subframe within one A-MPDU
|
||||
@ -1192,11 +1211,12 @@ struct ieee80211_rx_status {
|
||||
u64 boottime_ns;
|
||||
u32 device_timestamp;
|
||||
u32 ampdu_reference;
|
||||
u64 flag;
|
||||
u32 flag;
|
||||
u16 freq;
|
||||
u8 vht_flag;
|
||||
u8 enc_flags;
|
||||
u8 encoding:2, bw:3;
|
||||
u8 rate_idx;
|
||||
u8 vht_nss;
|
||||
u8 nss;
|
||||
u8 rx_flags;
|
||||
u8 band;
|
||||
u8 antenna;
|
||||
@ -4205,6 +4225,23 @@ void ieee80211_get_tx_rates(struct ieee80211_vif *vif,
|
||||
void ieee80211_tx_status(struct ieee80211_hw *hw,
|
||||
struct sk_buff *skb);
|
||||
|
||||
/**
|
||||
* ieee80211_tx_status_ext - extended transmit status callback
|
||||
*
|
||||
* This function can be used as a replacement for ieee80211_tx_status
|
||||
* in drivers that may want to provide extra information that does not
|
||||
* fit into &struct ieee80211_tx_info.
|
||||
*
|
||||
* Calls to this function for a single hardware must be synchronized
|
||||
* against each other. Calls to this function, ieee80211_tx_status_ni()
|
||||
* and ieee80211_tx_status_irqsafe() may not be mixed for a single hardware.
|
||||
*
|
||||
* @hw: the hardware the frame was transmitted by
|
||||
* @status: tx status information
|
||||
*/
|
||||
void ieee80211_tx_status_ext(struct ieee80211_hw *hw,
|
||||
struct ieee80211_tx_status *status);
|
||||
|
||||
/**
|
||||
* ieee80211_tx_status_noskb - transmit status callback without skb
|
||||
*
|
||||
@ -4221,9 +4258,17 @@ void ieee80211_tx_status(struct ieee80211_hw *hw,
|
||||
* (NULL for multicast packets)
|
||||
* @info: tx status information
|
||||
*/
|
||||
void ieee80211_tx_status_noskb(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_tx_info *info);
|
||||
static inline void ieee80211_tx_status_noskb(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_tx_info *info)
|
||||
{
|
||||
struct ieee80211_tx_status status = {
|
||||
.sta = sta,
|
||||
.info = info,
|
||||
};
|
||||
|
||||
ieee80211_tx_status_ext(hw, &status);
|
||||
}
|
||||
|
||||
/**
|
||||
* ieee80211_tx_status_ni - transmit status callback (in process context)
|
||||
@ -5476,10 +5521,9 @@ struct rate_control_ops {
|
||||
void (*free_sta)(void *priv, struct ieee80211_sta *sta,
|
||||
void *priv_sta);
|
||||
|
||||
void (*tx_status_noskb)(void *priv,
|
||||
struct ieee80211_supported_band *sband,
|
||||
struct ieee80211_sta *sta, void *priv_sta,
|
||||
struct ieee80211_tx_info *info);
|
||||
void (*tx_status_ext)(void *priv,
|
||||
struct ieee80211_supported_band *sband,
|
||||
void *priv_sta, struct ieee80211_tx_status *st);
|
||||
void (*tx_status)(void *priv, struct ieee80211_supported_band *sband,
|
||||
struct ieee80211_sta *sta, void *priv_sta,
|
||||
struct sk_buff *skb);
|
||||
|
@ -387,7 +387,9 @@
|
||||
* are used. Extra IEs can also be passed from the userspace by
|
||||
* using the %NL80211_ATTR_IE attribute. The first cycle of the
|
||||
* scheduled scan can be delayed by %NL80211_ATTR_SCHED_SCAN_DELAY
|
||||
* is supplied.
|
||||
* is supplied. If the device supports multiple concurrent scheduled
|
||||
* scans, it will allow such when the caller provides the flag attribute
|
||||
* %NL80211_ATTR_SCHED_SCAN_MULTI to indicate user-space support for it.
|
||||
* @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan. Returns -ENOENT if
|
||||
* scheduled scan is not running. The caller may assume that as soon
|
||||
* as the call returns, it is safe to start a new scheduled scan again.
|
||||
@ -2081,6 +2083,11 @@ enum nl80211_commands {
|
||||
* @NL80211_ATTR_PMK: PMK for the PMKSA identified by %NL80211_ATTR_PMKID.
|
||||
* This is used with @NL80211_CMD_SET_PMKSA.
|
||||
*
|
||||
* @NL80211_ATTR_SCHED_SCAN_MULTI: flag attribute which user-space shall use to
|
||||
* indicate that it supports multiple active scheduled scan requests.
|
||||
* @NL80211_ATTR_SCHED_SCAN_MAX_REQS: indicates maximum number of scheduled
|
||||
* scan request that may be active for the device (u32).
|
||||
*
|
||||
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
|
||||
* @NL80211_ATTR_MAX: highest attribute number currently defined
|
||||
* @__NL80211_ATTR_AFTER_LAST: internal use
|
||||
@ -2500,6 +2507,9 @@ enum nl80211_attrs {
|
||||
|
||||
NL80211_ATTR_PMK,
|
||||
|
||||
NL80211_ATTR_SCHED_SCAN_MULTI,
|
||||
NL80211_ATTR_SCHED_SCAN_MAX_REQS,
|
||||
|
||||
/* add attributes here, update the policy in nl80211.c */
|
||||
|
||||
__NL80211_ATTR_AFTER_LAST,
|
||||
@ -3184,6 +3194,7 @@ enum nl80211_reg_rule_attr {
|
||||
* @__NL80211_SCHED_SCAN_MATCH_ATTR_INVALID: attribute number 0 is reserved
|
||||
* @NL80211_SCHED_SCAN_MATCH_ATTR_SSID: SSID to be used for matching,
|
||||
* only report BSS with matching SSID.
|
||||
* (This cannot be used together with BSSID.)
|
||||
* @NL80211_SCHED_SCAN_MATCH_ATTR_RSSI: RSSI threshold (in dBm) for reporting a
|
||||
* BSS in scan results. Filtering is turned off if not specified. Note that
|
||||
* if this attribute is in a match set of its own, then it is treated as
|
||||
@ -3199,6 +3210,8 @@ enum nl80211_reg_rule_attr {
|
||||
* BSS-es in the specified band is to be adjusted before doing
|
||||
* RSSI-based BSS selection. The attribute value is a packed structure
|
||||
* value as specified by &struct nl80211_bss_select_rssi_adjust.
|
||||
* @NL80211_SCHED_SCAN_MATCH_ATTR_BSSID: BSSID to be used for matching
|
||||
* (this cannot be used together with SSID).
|
||||
* @NL80211_SCHED_SCAN_MATCH_ATTR_MAX: highest scheduled scan filter
|
||||
* attribute number currently defined
|
||||
* @__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: internal use
|
||||
@ -3210,6 +3223,7 @@ enum nl80211_sched_scan_match_attr {
|
||||
NL80211_SCHED_SCAN_MATCH_ATTR_RSSI,
|
||||
NL80211_SCHED_SCAN_MATCH_ATTR_RELATIVE_RSSI,
|
||||
NL80211_SCHED_SCAN_MATCH_ATTR_RSSI_ADJUST,
|
||||
NL80211_SCHED_SCAN_MATCH_ATTR_BSSID,
|
||||
|
||||
/* keep last */
|
||||
__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST,
|
||||
|
@ -660,10 +660,11 @@ void sta_set_rate_info_tx(struct sta_info *sta,
|
||||
int shift = ieee80211_vif_get_shift(&sta->sdata->vif);
|
||||
u16 brate;
|
||||
|
||||
sband = sta->local->hw.wiphy->bands[
|
||||
ieee80211_get_sdata_band(sta->sdata)];
|
||||
brate = sband->bitrates[rate->idx].bitrate;
|
||||
rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift);
|
||||
sband = ieee80211_get_sband(sta->sdata);
|
||||
if (sband) {
|
||||
brate = sband->bitrates[rate->idx].bitrate;
|
||||
rinfo->legacy = DIV_ROUND_UP(brate, 1 << shift);
|
||||
}
|
||||
}
|
||||
if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
|
||||
rinfo->bw = RATE_INFO_BW_40;
|
||||
@ -739,11 +740,8 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
|
||||
return 0;
|
||||
|
||||
mutex_lock(&local->mtx);
|
||||
mutex_lock(&local->iflist_mtx);
|
||||
if (local->use_chanctx) {
|
||||
sdata = rcu_dereference_protected(
|
||||
local->monitor_sdata,
|
||||
lockdep_is_held(&local->iflist_mtx));
|
||||
sdata = rtnl_dereference(local->monitor_sdata);
|
||||
if (sdata) {
|
||||
ieee80211_vif_release_channel(sdata);
|
||||
ret = ieee80211_vif_use_channel(sdata, chandef,
|
||||
@ -756,7 +754,6 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
|
||||
|
||||
if (ret == 0)
|
||||
local->monitor_chandef = *chandef;
|
||||
mutex_unlock(&local->iflist_mtx);
|
||||
mutex_unlock(&local->mtx);
|
||||
|
||||
return ret;
|
||||
@ -1257,10 +1254,11 @@ static int sta_apply_parameters(struct ieee80211_local *local,
|
||||
int ret = 0;
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_sub_if_data *sdata = sta->sdata;
|
||||
enum nl80211_band band = ieee80211_get_sdata_band(sdata);
|
||||
u32 mask, set;
|
||||
|
||||
sband = local->hw.wiphy->bands[band];
|
||||
sband = ieee80211_get_sband(sdata);
|
||||
if (!sband)
|
||||
return -EINVAL;
|
||||
|
||||
mask = params->sta_flags_mask;
|
||||
set = params->sta_flags_set;
|
||||
@ -1393,7 +1391,7 @@ static int sta_apply_parameters(struct ieee80211_local *local,
|
||||
ieee80211_parse_bitrates(&sdata->vif.bss_conf.chandef,
|
||||
sband, params->supported_rates,
|
||||
params->supported_rates_len,
|
||||
&sta->sta.supp_rates[band]);
|
||||
&sta->sta.supp_rates[sband->band]);
|
||||
}
|
||||
|
||||
if (params->ht_capa)
|
||||
@ -1409,8 +1407,8 @@ static int sta_apply_parameters(struct ieee80211_local *local,
|
||||
/* returned value is only needed for rc update, but the
|
||||
* rc isn't initialized here yet, so ignore it
|
||||
*/
|
||||
__ieee80211_vht_handle_opmode(sdata, sta,
|
||||
params->opmode_notif, band);
|
||||
__ieee80211_vht_handle_opmode(sdata, sta, params->opmode_notif,
|
||||
sband->band);
|
||||
}
|
||||
|
||||
if (params->support_p2p_ps >= 0)
|
||||
@ -2048,13 +2046,15 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
|
||||
struct bss_parameters *params)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
enum nl80211_band band;
|
||||
struct ieee80211_supported_band *sband;
|
||||
u32 changed = 0;
|
||||
|
||||
if (!sdata_dereference(sdata->u.ap.beacon, sdata))
|
||||
return -ENOENT;
|
||||
|
||||
band = ieee80211_get_sdata_band(sdata);
|
||||
sband = ieee80211_get_sband(sdata);
|
||||
if (!sband)
|
||||
return -EINVAL;
|
||||
|
||||
if (params->use_cts_prot >= 0) {
|
||||
sdata->vif.bss_conf.use_cts_prot = params->use_cts_prot;
|
||||
@ -2067,7 +2067,7 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
|
||||
}
|
||||
|
||||
if (!sdata->vif.bss_conf.use_short_slot &&
|
||||
band == NL80211_BAND_5GHZ) {
|
||||
sband->band == NL80211_BAND_5GHZ) {
|
||||
sdata->vif.bss_conf.use_short_slot = true;
|
||||
changed |= BSS_CHANGED_ERP_SLOT;
|
||||
}
|
||||
@ -2080,7 +2080,7 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
|
||||
|
||||
if (params->basic_rates) {
|
||||
ieee80211_parse_bitrates(&sdata->vif.bss_conf.chandef,
|
||||
wiphy->bands[band],
|
||||
wiphy->bands[sband->band],
|
||||
params->basic_rates,
|
||||
params->basic_rates_len,
|
||||
&sdata->vif.bss_conf.basic_rates);
|
||||
@ -2242,7 +2242,8 @@ ieee80211_sched_scan_start(struct wiphy *wiphy,
|
||||
}
|
||||
|
||||
static int
|
||||
ieee80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev)
|
||||
ieee80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev,
|
||||
u64 reqid)
|
||||
{
|
||||
struct ieee80211_local *local = wiphy_priv(wiphy);
|
||||
|
||||
|
@ -992,7 +992,7 @@ static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata,
|
||||
enum nl80211_band band = rx_status->band;
|
||||
enum nl80211_bss_scan_width scan_width;
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
|
||||
struct ieee80211_supported_band *sband;
|
||||
bool rates_updated = false;
|
||||
u32 supp_rates = 0;
|
||||
|
||||
@ -1002,6 +1002,10 @@ static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata,
|
||||
if (!ether_addr_equal(mgmt->bssid, sdata->u.ibss.bssid))
|
||||
return;
|
||||
|
||||
sband = local->hw.wiphy->bands[band];
|
||||
if (WARN_ON(!sband))
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
sta = sta_info_get(sdata, mgmt->sa);
|
||||
|
||||
@ -1014,9 +1018,9 @@ static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata,
|
||||
prev_rates = sta->sta.supp_rates[band];
|
||||
/* make sure mandatory rates are always added */
|
||||
scan_width = NL80211_BSS_CHAN_WIDTH_20;
|
||||
if (rx_status->flag & RX_FLAG_5MHZ)
|
||||
if (rx_status->bw == RATE_INFO_BW_5)
|
||||
scan_width = NL80211_BSS_CHAN_WIDTH_5;
|
||||
if (rx_status->flag & RX_FLAG_10MHZ)
|
||||
else if (rx_status->bw == RATE_INFO_BW_10)
|
||||
scan_width = NL80211_BSS_CHAN_WIDTH_10;
|
||||
|
||||
sta->sta.supp_rates[band] = supp_rates |
|
||||
|
@ -1001,21 +1001,6 @@ sdata_assert_lock(struct ieee80211_sub_if_data *sdata)
|
||||
lockdep_assert_held(&sdata->wdev.mtx);
|
||||
}
|
||||
|
||||
static inline enum nl80211_band
|
||||
ieee80211_get_sdata_band(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
enum nl80211_band band = NL80211_BAND_2GHZ;
|
||||
struct ieee80211_chanctx_conf *chanctx_conf;
|
||||
|
||||
rcu_read_lock();
|
||||
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
||||
if (!WARN_ON(!chanctx_conf))
|
||||
band = chanctx_conf->def.chan->band;
|
||||
rcu_read_unlock();
|
||||
|
||||
return band;
|
||||
}
|
||||
|
||||
static inline int
|
||||
ieee80211_chandef_get_shift(struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
@ -1421,6 +1406,27 @@ IEEE80211_WDEV_TO_SUB_IF(struct wireless_dev *wdev)
|
||||
return container_of(wdev, struct ieee80211_sub_if_data, wdev);
|
||||
}
|
||||
|
||||
static inline struct ieee80211_supported_band *
|
||||
ieee80211_get_sband(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_chanctx_conf *chanctx_conf;
|
||||
enum nl80211_band band;
|
||||
|
||||
rcu_read_lock();
|
||||
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
||||
|
||||
if (WARN_ON(!chanctx_conf)) {
|
||||
rcu_read_unlock();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
band = chanctx_conf->def.chan->band;
|
||||
rcu_read_unlock();
|
||||
|
||||
return local->hw.wiphy->bands[band];
|
||||
}
|
||||
|
||||
/* this struct represents 802.11n's RA/TID combination */
|
||||
struct ieee80211_ra_tid {
|
||||
u8 ra[ETH_ALEN];
|
||||
@ -1477,6 +1483,7 @@ struct ieee802_11_elems {
|
||||
const u8 *opmode_notif;
|
||||
const struct ieee80211_sec_chan_offs_ie *sec_chan_offs;
|
||||
const struct ieee80211_mesh_chansw_params_ie *mesh_chansw_params_ie;
|
||||
const struct ieee80211_bss_max_idle_period_ie *max_idle_period_ie;
|
||||
|
||||
/* length of them, respectively */
|
||||
u8 ext_capab_len;
|
||||
@ -1530,9 +1537,9 @@ ieee80211_have_rx_timestamp(struct ieee80211_rx_status *status)
|
||||
status->flag & RX_FLAG_MACTIME_END);
|
||||
if (status->flag & (RX_FLAG_MACTIME_START | RX_FLAG_MACTIME_END))
|
||||
return true;
|
||||
/* can't handle HT/VHT preamble yet */
|
||||
/* can't handle non-legacy preamble yet */
|
||||
if (status->flag & RX_FLAG_MACTIME_PLCP_START &&
|
||||
!(status->flag & (RX_FLAG_HT | RX_FLAG_VHT)))
|
||||
status->encoding != RX_ENC_LEGACY)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
@ -253,6 +253,7 @@ static void ieee80211_restart_work(struct work_struct *work)
|
||||
WARN(test_bit(SCAN_HW_SCANNING, &local->scanning),
|
||||
"%s called with hardware scan in progress\n", __func__);
|
||||
|
||||
flush_work(&local->radar_detected_work);
|
||||
rtnl_lock();
|
||||
list_for_each_entry(sdata, &local->interfaces, list)
|
||||
flush_delayed_work(&sdata->dec_tailroom_needed_wk);
|
||||
@ -1187,6 +1188,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
|
||||
cancel_work_sync(&local->reconfig_filter);
|
||||
cancel_work_sync(&local->tdls_chsw_work);
|
||||
flush_work(&local->sched_scan_stopped_work);
|
||||
flush_work(&local->radar_detected_work);
|
||||
|
||||
ieee80211_clear_tx_pending(local);
|
||||
rate_control_deinitialize(local);
|
||||
|
@ -63,6 +63,7 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
||||
u32 basic_rates = 0;
|
||||
struct cfg80211_chan_def sta_chan_def;
|
||||
struct ieee80211_supported_band *sband;
|
||||
|
||||
/*
|
||||
* As support for each feature is added, check for matching
|
||||
@ -83,7 +84,11 @@ bool mesh_matches_local(struct ieee80211_sub_if_data *sdata,
|
||||
(ifmsh->mesh_auth_id == ie->mesh_config->meshconf_auth)))
|
||||
return false;
|
||||
|
||||
ieee80211_sta_get_rates(sdata, ie, ieee80211_get_sdata_band(sdata),
|
||||
sband = ieee80211_get_sband(sdata);
|
||||
if (!sband)
|
||||
return false;
|
||||
|
||||
ieee80211_sta_get_rates(sdata, ie, sband->band,
|
||||
&basic_rates);
|
||||
|
||||
if (sdata->vif.bss_conf.basic_rates != basic_rates)
|
||||
@ -399,12 +404,13 @@ static int mesh_add_ds_params_ie(struct ieee80211_sub_if_data *sdata,
|
||||
int mesh_add_ht_cap_ie(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
enum nl80211_band band = ieee80211_get_sdata_band(sdata);
|
||||
struct ieee80211_supported_band *sband;
|
||||
u8 *pos;
|
||||
|
||||
sband = local->hw.wiphy->bands[band];
|
||||
sband = ieee80211_get_sband(sdata);
|
||||
if (!sband)
|
||||
return -EINVAL;
|
||||
|
||||
if (!sband->ht_cap.ht_supported ||
|
||||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
|
||||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 ||
|
||||
@ -462,12 +468,13 @@ int mesh_add_ht_oper_ie(struct ieee80211_sub_if_data *sdata,
|
||||
int mesh_add_vht_cap_ie(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
enum nl80211_band band = ieee80211_get_sdata_band(sdata);
|
||||
struct ieee80211_supported_band *sband;
|
||||
u8 *pos;
|
||||
|
||||
sband = local->hw.wiphy->bands[band];
|
||||
sband = ieee80211_get_sband(sdata);
|
||||
if (!sband)
|
||||
return -EINVAL;
|
||||
|
||||
if (!sband->vht_cap.vht_supported ||
|
||||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
|
||||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 ||
|
||||
@ -916,12 +923,16 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata,
|
||||
struct cfg80211_csa_settings params;
|
||||
struct ieee80211_csa_ie csa_ie;
|
||||
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
||||
enum nl80211_band band = ieee80211_get_sdata_band(sdata);
|
||||
struct ieee80211_supported_band *sband;
|
||||
int err;
|
||||
u32 sta_flags;
|
||||
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
sband = ieee80211_get_sband(sdata);
|
||||
if (!sband)
|
||||
return false;
|
||||
|
||||
sta_flags = IEEE80211_STA_DISABLE_VHT;
|
||||
switch (sdata->vif.bss_conf.chandef.width) {
|
||||
case NL80211_CHAN_WIDTH_20_NOHT:
|
||||
@ -935,7 +946,7 @@ ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata,
|
||||
|
||||
memset(¶ms, 0, sizeof(params));
|
||||
memset(&csa_ie, 0, sizeof(csa_ie));
|
||||
err = ieee80211_parse_ch_switch_ie(sdata, elems, band,
|
||||
err = ieee80211_parse_ch_switch_ie(sdata, elems, sband->band,
|
||||
sta_flags, sdata->vif.addr,
|
||||
&csa_ie);
|
||||
if (err < 0)
|
||||
|
@ -95,19 +95,23 @@ static inline void mesh_plink_fsm_restart(struct sta_info *sta)
|
||||
static u32 mesh_set_short_slot_time(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
enum nl80211_band band = ieee80211_get_sdata_band(sdata);
|
||||
struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct sta_info *sta;
|
||||
u32 erp_rates = 0, changed = 0;
|
||||
int i;
|
||||
bool short_slot = false;
|
||||
|
||||
if (band == NL80211_BAND_5GHZ) {
|
||||
sband = ieee80211_get_sband(sdata);
|
||||
if (!sband)
|
||||
return changed;
|
||||
|
||||
if (sband->band == NL80211_BAND_5GHZ) {
|
||||
/* (IEEE 802.11-2012 19.4.5) */
|
||||
short_slot = true;
|
||||
goto out;
|
||||
} else if (band != NL80211_BAND_2GHZ)
|
||||
} else if (sband->band != NL80211_BAND_2GHZ) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i < sband->n_bitrates; i++)
|
||||
if (sband->bitrates[i].flags & IEEE80211_RATE_ERP_G)
|
||||
@ -123,7 +127,7 @@ static u32 mesh_set_short_slot_time(struct ieee80211_sub_if_data *sdata)
|
||||
continue;
|
||||
|
||||
short_slot = false;
|
||||
if (erp_rates & sta->sta.supp_rates[band])
|
||||
if (erp_rates & sta->sta.supp_rates[sband->band])
|
||||
short_slot = true;
|
||||
else
|
||||
break;
|
||||
@ -249,7 +253,15 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
|
||||
mgmt->u.action.u.self_prot.action_code = action;
|
||||
|
||||
if (action != WLAN_SP_MESH_PEERING_CLOSE) {
|
||||
enum nl80211_band band = ieee80211_get_sdata_band(sdata);
|
||||
struct ieee80211_supported_band *sband;
|
||||
enum nl80211_band band;
|
||||
|
||||
sband = ieee80211_get_sband(sdata);
|
||||
if (!sband) {
|
||||
err = -EINVAL;
|
||||
goto free;
|
||||
}
|
||||
band = sband->band;
|
||||
|
||||
/* capability info */
|
||||
pos = skb_put(skb, 2);
|
||||
@ -395,13 +407,16 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee802_11_elems *elems, bool insert)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
enum nl80211_band band = ieee80211_get_sdata_band(sdata);
|
||||
struct ieee80211_supported_band *sband;
|
||||
u32 rates, basic_rates = 0, changed = 0;
|
||||
enum ieee80211_sta_rx_bandwidth bw = sta->sta.bandwidth;
|
||||
|
||||
sband = local->hw.wiphy->bands[band];
|
||||
rates = ieee80211_sta_get_rates(sdata, elems, band, &basic_rates);
|
||||
sband = ieee80211_get_sband(sdata);
|
||||
if (!sband)
|
||||
return;
|
||||
|
||||
rates = ieee80211_sta_get_rates(sdata, elems, sband->band,
|
||||
&basic_rates);
|
||||
|
||||
spin_lock_bh(&sta->mesh->plink_lock);
|
||||
sta->rx_stats.last_rx = jiffies;
|
||||
@ -412,9 +427,9 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
|
||||
goto out;
|
||||
sta->mesh->processed_beacon = true;
|
||||
|
||||
if (sta->sta.supp_rates[band] != rates)
|
||||
if (sta->sta.supp_rates[sband->band] != rates)
|
||||
changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
|
||||
sta->sta.supp_rates[band] = rates;
|
||||
sta->sta.supp_rates[sband->band] = rates;
|
||||
|
||||
if (ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
|
||||
elems->ht_cap_elem, sta))
|
||||
|
@ -6,7 +6,7 @@
|
||||
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
|
||||
* Copyright 2007, Michael Wu <flamingice@sourmilk.net>
|
||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2015 - 2016 Intel Deutschland GmbH
|
||||
* Copyright (C) 2015 - 2017 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@ -1855,11 +1855,16 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
|
||||
u16 capab, bool erp_valid, u8 erp)
|
||||
{
|
||||
struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
|
||||
struct ieee80211_supported_band *sband;
|
||||
u32 changed = 0;
|
||||
bool use_protection;
|
||||
bool use_short_preamble;
|
||||
bool use_short_slot;
|
||||
|
||||
sband = ieee80211_get_sband(sdata);
|
||||
if (!sband)
|
||||
return changed;
|
||||
|
||||
if (erp_valid) {
|
||||
use_protection = (erp & WLAN_ERP_USE_PROTECTION) != 0;
|
||||
use_short_preamble = (erp & WLAN_ERP_BARKER_PREAMBLE) == 0;
|
||||
@ -1869,7 +1874,7 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
|
||||
}
|
||||
|
||||
use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME);
|
||||
if (ieee80211_get_sdata_band(sdata) == NL80211_BAND_5GHZ)
|
||||
if (sband->band == NL80211_BAND_5GHZ)
|
||||
use_short_slot = true;
|
||||
|
||||
if (use_protection != bss_conf->use_cts_prot) {
|
||||
@ -3004,7 +3009,12 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
||||
goto out;
|
||||
}
|
||||
|
||||
sband = local->hw.wiphy->bands[ieee80211_get_sdata_band(sdata)];
|
||||
sband = ieee80211_get_sband(sdata);
|
||||
if (!sband) {
|
||||
mutex_unlock(&sdata->local->sta_mtx);
|
||||
ret = false;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Set up internal HT/VHT capabilities */
|
||||
if (elems.ht_cap_elem && !(ifmgd->flags & IEEE80211_STA_DISABLE_HT))
|
||||
@ -3088,6 +3098,18 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
||||
}
|
||||
changed |= BSS_CHANGED_QOS;
|
||||
|
||||
if (elems.max_idle_period_ie) {
|
||||
bss_conf->max_idle_period =
|
||||
le16_to_cpu(elems.max_idle_period_ie->max_idle_period);
|
||||
bss_conf->protected_keep_alive =
|
||||
!!(elems.max_idle_period_ie->idle_options &
|
||||
WLAN_IDLE_OPTIONS_PROTECTED_KEEP_ALIVE);
|
||||
changed |= BSS_CHANGED_KEEP_ALIVE;
|
||||
} else {
|
||||
bss_conf->max_idle_period = 0;
|
||||
bss_conf->protected_keep_alive = false;
|
||||
}
|
||||
|
||||
/* set AID and assoc capability,
|
||||
* ieee80211_set_associated() will tell the driver */
|
||||
bss_conf->aid = aid;
|
||||
|
@ -10,7 +10,7 @@ static void ieee80211_sched_scan_cancel(struct ieee80211_local *local)
|
||||
{
|
||||
if (ieee80211_request_sched_scan_stop(local))
|
||||
return;
|
||||
cfg80211_sched_scan_stopped_rtnl(local->hw.wiphy);
|
||||
cfg80211_sched_scan_stopped_rtnl(local->hw.wiphy, 0);
|
||||
}
|
||||
|
||||
int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
|
||||
|
@ -62,6 +62,28 @@ void rate_control_rate_init(struct sta_info *sta)
|
||||
set_sta_flag(sta, WLAN_STA_RATE_CONTROL);
|
||||
}
|
||||
|
||||
void rate_control_tx_status(struct ieee80211_local *local,
|
||||
struct ieee80211_supported_band *sband,
|
||||
struct ieee80211_tx_status *st)
|
||||
{
|
||||
struct rate_control_ref *ref = local->rate_ctrl;
|
||||
struct sta_info *sta = container_of(st->sta, struct sta_info, sta);
|
||||
void *priv_sta = sta->rate_ctrl_priv;
|
||||
|
||||
if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
|
||||
return;
|
||||
|
||||
spin_lock_bh(&sta->rate_ctrl_lock);
|
||||
if (ref->ops->tx_status_ext)
|
||||
ref->ops->tx_status_ext(ref->priv, sband, priv_sta, st);
|
||||
else if (st->skb)
|
||||
ref->ops->tx_status(ref->priv, sband, st->sta, priv_sta, st->skb);
|
||||
else
|
||||
WARN_ON_ONCE(1);
|
||||
|
||||
spin_unlock_bh(&sta->rate_ctrl_lock);
|
||||
}
|
||||
|
||||
void rate_control_rate_update(struct ieee80211_local *local,
|
||||
struct ieee80211_supported_band *sband,
|
||||
struct sta_info *sta, u32 changed)
|
||||
@ -904,7 +926,9 @@ int rate_control_set_rates(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta_rates *old;
|
||||
struct ieee80211_supported_band *sband;
|
||||
|
||||
sband = hw->wiphy->bands[ieee80211_get_sdata_band(sta->sdata)];
|
||||
sband = ieee80211_get_sband(sta->sdata);
|
||||
if (!sband)
|
||||
return -EINVAL;
|
||||
rate_control_apply_mask_ratetbl(sta, sband, rates);
|
||||
/*
|
||||
* mac80211 guarantees that this function will not be called
|
||||
|
@ -28,47 +28,9 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
|
||||
struct sta_info *sta,
|
||||
struct ieee80211_tx_rate_control *txrc);
|
||||
|
||||
static inline void rate_control_tx_status(struct ieee80211_local *local,
|
||||
struct ieee80211_supported_band *sband,
|
||||
struct sta_info *sta,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct rate_control_ref *ref = local->rate_ctrl;
|
||||
struct ieee80211_sta *ista = &sta->sta;
|
||||
void *priv_sta = sta->rate_ctrl_priv;
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
|
||||
if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
|
||||
return;
|
||||
|
||||
spin_lock_bh(&sta->rate_ctrl_lock);
|
||||
if (ref->ops->tx_status)
|
||||
ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb);
|
||||
else
|
||||
ref->ops->tx_status_noskb(ref->priv, sband, ista, priv_sta, info);
|
||||
spin_unlock_bh(&sta->rate_ctrl_lock);
|
||||
}
|
||||
|
||||
static inline void
|
||||
rate_control_tx_status_noskb(struct ieee80211_local *local,
|
||||
struct ieee80211_supported_band *sband,
|
||||
struct sta_info *sta,
|
||||
struct ieee80211_tx_info *info)
|
||||
{
|
||||
struct rate_control_ref *ref = local->rate_ctrl;
|
||||
struct ieee80211_sta *ista = &sta->sta;
|
||||
void *priv_sta = sta->rate_ctrl_priv;
|
||||
|
||||
if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
|
||||
return;
|
||||
|
||||
if (WARN_ON_ONCE(!ref->ops->tx_status_noskb))
|
||||
return;
|
||||
|
||||
spin_lock_bh(&sta->rate_ctrl_lock);
|
||||
ref->ops->tx_status_noskb(ref->priv, sband, ista, priv_sta, info);
|
||||
spin_unlock_bh(&sta->rate_ctrl_lock);
|
||||
}
|
||||
void rate_control_tx_status(struct ieee80211_local *local,
|
||||
struct ieee80211_supported_band *sband,
|
||||
struct ieee80211_tx_status *st);
|
||||
|
||||
void rate_control_rate_init(struct sta_info *sta);
|
||||
void rate_control_rate_update(struct ieee80211_local *local,
|
||||
|
@ -264,9 +264,9 @@ minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
|
||||
|
||||
static void
|
||||
minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
|
||||
struct ieee80211_sta *sta, void *priv_sta,
|
||||
struct ieee80211_tx_info *info)
|
||||
void *priv_sta, struct ieee80211_tx_status *st)
|
||||
{
|
||||
struct ieee80211_tx_info *info = st->info;
|
||||
struct minstrel_priv *mp = priv;
|
||||
struct minstrel_sta_info *mi = priv_sta;
|
||||
struct ieee80211_tx_rate *ar = info->status.rates;
|
||||
@ -726,7 +726,7 @@ static u32 minstrel_get_expected_throughput(void *priv_sta)
|
||||
|
||||
const struct rate_control_ops mac80211_minstrel = {
|
||||
.name = "minstrel",
|
||||
.tx_status_noskb = minstrel_tx_status,
|
||||
.tx_status_ext = minstrel_tx_status,
|
||||
.get_rate = minstrel_get_rate,
|
||||
.rate_init = minstrel_rate_init,
|
||||
.alloc = minstrel_alloc,
|
||||
|
@ -678,9 +678,9 @@ minstrel_aggr_check(struct ieee80211_sta *pubsta, struct sk_buff *skb)
|
||||
|
||||
static void
|
||||
minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
|
||||
struct ieee80211_sta *sta, void *priv_sta,
|
||||
struct ieee80211_tx_info *info)
|
||||
void *priv_sta, struct ieee80211_tx_status *st)
|
||||
{
|
||||
struct ieee80211_tx_info *info = st->info;
|
||||
struct minstrel_ht_sta_priv *msp = priv_sta;
|
||||
struct minstrel_ht_sta *mi = &msp->ht;
|
||||
struct ieee80211_tx_rate *ar = info->status.rates;
|
||||
@ -690,8 +690,8 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
|
||||
int i;
|
||||
|
||||
if (!msp->is_ht)
|
||||
return mac80211_minstrel.tx_status_noskb(priv, sband, sta,
|
||||
&msp->legacy, info);
|
||||
return mac80211_minstrel.tx_status_ext(priv, sband,
|
||||
&msp->legacy, st);
|
||||
|
||||
/* This packet was aggregated but doesn't carry status info */
|
||||
if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
|
||||
@ -1374,7 +1374,7 @@ static u32 minstrel_ht_get_expected_throughput(void *priv_sta)
|
||||
|
||||
static const struct rate_control_ops mac80211_minstrel_ht = {
|
||||
.name = "minstrel_ht",
|
||||
.tx_status_noskb = minstrel_ht_tx_status,
|
||||
.tx_status_ext = minstrel_ht_tx_status,
|
||||
.get_rate = minstrel_ht_get_rate,
|
||||
.rate_init = minstrel_ht_rate_init,
|
||||
.rate_update = minstrel_ht_rate_update,
|
||||
|
@ -156,7 +156,7 @@ ieee80211_rx_radiotap_hdrlen(struct ieee80211_local *local,
|
||||
/* padding for RX_FLAGS if necessary */
|
||||
len = ALIGN(len, 2);
|
||||
|
||||
if (status->flag & RX_FLAG_HT) /* HT info */
|
||||
if (status->encoding == RX_ENC_HT) /* HT info */
|
||||
len += 3;
|
||||
|
||||
if (status->flag & RX_FLAG_AMPDU_DETAILS) {
|
||||
@ -164,7 +164,7 @@ ieee80211_rx_radiotap_hdrlen(struct ieee80211_local *local,
|
||||
len += 8;
|
||||
}
|
||||
|
||||
if (status->flag & RX_FLAG_VHT) {
|
||||
if (status->encoding == RX_ENC_VHT) {
|
||||
len = ALIGN(len, 2);
|
||||
len += 12;
|
||||
}
|
||||
@ -329,12 +329,12 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
|
||||
*pos |= IEEE80211_RADIOTAP_F_FCS;
|
||||
if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC))
|
||||
*pos |= IEEE80211_RADIOTAP_F_BADFCS;
|
||||
if (status->flag & RX_FLAG_SHORTPRE)
|
||||
if (status->enc_flags & RX_ENC_FLAG_SHORTPRE)
|
||||
*pos |= IEEE80211_RADIOTAP_F_SHORTPRE;
|
||||
pos++;
|
||||
|
||||
/* IEEE80211_RADIOTAP_RATE */
|
||||
if (!rate || status->flag & (RX_FLAG_HT | RX_FLAG_VHT)) {
|
||||
if (!rate || status->encoding != RX_ENC_LEGACY) {
|
||||
/*
|
||||
* Without rate information don't add it. If we have,
|
||||
* MCS information is a separate field in radiotap,
|
||||
@ -345,9 +345,9 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
|
||||
} else {
|
||||
int shift = 0;
|
||||
rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_RATE);
|
||||
if (status->flag & RX_FLAG_10MHZ)
|
||||
if (status->bw == RATE_INFO_BW_10)
|
||||
shift = 1;
|
||||
else if (status->flag & RX_FLAG_5MHZ)
|
||||
else if (status->bw == RATE_INFO_BW_5)
|
||||
shift = 2;
|
||||
*pos = DIV_ROUND_UP(rate->bitrate, 5 * (1 << shift));
|
||||
}
|
||||
@ -356,14 +356,14 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
|
||||
/* IEEE80211_RADIOTAP_CHANNEL */
|
||||
put_unaligned_le16(status->freq, pos);
|
||||
pos += 2;
|
||||
if (status->flag & RX_FLAG_10MHZ)
|
||||
if (status->bw == RATE_INFO_BW_10)
|
||||
channel_flags |= IEEE80211_CHAN_HALF;
|
||||
else if (status->flag & RX_FLAG_5MHZ)
|
||||
else if (status->bw == RATE_INFO_BW_5)
|
||||
channel_flags |= IEEE80211_CHAN_QUARTER;
|
||||
|
||||
if (status->band == NL80211_BAND_5GHZ)
|
||||
channel_flags |= IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ;
|
||||
else if (status->flag & (RX_FLAG_HT | RX_FLAG_VHT))
|
||||
else if (status->encoding != RX_ENC_LEGACY)
|
||||
channel_flags |= IEEE80211_CHAN_DYN | IEEE80211_CHAN_2GHZ;
|
||||
else if (rate && rate->flags & IEEE80211_RATE_ERP_G)
|
||||
channel_flags |= IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ;
|
||||
@ -402,21 +402,21 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
|
||||
put_unaligned_le16(rx_flags, pos);
|
||||
pos += 2;
|
||||
|
||||
if (status->flag & RX_FLAG_HT) {
|
||||
if (status->encoding == RX_ENC_HT) {
|
||||
unsigned int stbc;
|
||||
|
||||
rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_MCS);
|
||||
*pos++ = local->hw.radiotap_mcs_details;
|
||||
*pos = 0;
|
||||
if (status->flag & RX_FLAG_SHORT_GI)
|
||||
if (status->enc_flags & RX_ENC_FLAG_SHORT_GI)
|
||||
*pos |= IEEE80211_RADIOTAP_MCS_SGI;
|
||||
if (status->flag & RX_FLAG_40MHZ)
|
||||
if (status->bw == RATE_INFO_BW_40)
|
||||
*pos |= IEEE80211_RADIOTAP_MCS_BW_40;
|
||||
if (status->flag & RX_FLAG_HT_GF)
|
||||
if (status->enc_flags & RX_ENC_FLAG_HT_GF)
|
||||
*pos |= IEEE80211_RADIOTAP_MCS_FMT_GF;
|
||||
if (status->flag & RX_FLAG_LDPC)
|
||||
if (status->enc_flags & RX_ENC_FLAG_LDPC)
|
||||
*pos |= IEEE80211_RADIOTAP_MCS_FEC_LDPC;
|
||||
stbc = (status->flag & RX_FLAG_STBC_MASK) >> RX_FLAG_STBC_SHIFT;
|
||||
stbc = (status->enc_flags & RX_ENC_FLAG_STBC_MASK) >> RX_ENC_FLAG_STBC_SHIFT;
|
||||
*pos |= stbc << IEEE80211_RADIOTAP_MCS_STBC_SHIFT;
|
||||
pos++;
|
||||
*pos++ = status->rate_idx;
|
||||
@ -449,35 +449,40 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
|
||||
*pos++ = 0;
|
||||
}
|
||||
|
||||
if (status->flag & RX_FLAG_VHT) {
|
||||
if (status->encoding == RX_ENC_VHT) {
|
||||
u16 known = local->hw.radiotap_vht_details;
|
||||
|
||||
rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_VHT);
|
||||
put_unaligned_le16(known, pos);
|
||||
pos += 2;
|
||||
/* flags */
|
||||
if (status->flag & RX_FLAG_SHORT_GI)
|
||||
if (status->enc_flags & RX_ENC_FLAG_SHORT_GI)
|
||||
*pos |= IEEE80211_RADIOTAP_VHT_FLAG_SGI;
|
||||
/* in VHT, STBC is binary */
|
||||
if (status->flag & RX_FLAG_STBC_MASK)
|
||||
if (status->enc_flags & RX_ENC_FLAG_STBC_MASK)
|
||||
*pos |= IEEE80211_RADIOTAP_VHT_FLAG_STBC;
|
||||
if (status->vht_flag & RX_VHT_FLAG_BF)
|
||||
if (status->enc_flags & RX_ENC_FLAG_BF)
|
||||
*pos |= IEEE80211_RADIOTAP_VHT_FLAG_BEAMFORMED;
|
||||
pos++;
|
||||
/* bandwidth */
|
||||
if (status->vht_flag & RX_VHT_FLAG_80MHZ)
|
||||
switch (status->bw) {
|
||||
case RATE_INFO_BW_80:
|
||||
*pos++ = 4;
|
||||
else if (status->vht_flag & RX_VHT_FLAG_160MHZ)
|
||||
break;
|
||||
case RATE_INFO_BW_160:
|
||||
*pos++ = 11;
|
||||
else if (status->flag & RX_FLAG_40MHZ)
|
||||
break;
|
||||
case RATE_INFO_BW_40:
|
||||
*pos++ = 1;
|
||||
else /* 20 MHz */
|
||||
break;
|
||||
default:
|
||||
*pos++ = 0;
|
||||
}
|
||||
/* MCS/NSS */
|
||||
*pos = (status->rate_idx << 4) | status->vht_nss;
|
||||
*pos = (status->rate_idx << 4) | status->nss;
|
||||
pos += 4;
|
||||
/* coding field */
|
||||
if (status->flag & RX_FLAG_LDPC)
|
||||
if (status->enc_flags & RX_ENC_FLAG_LDPC)
|
||||
*pos |= IEEE80211_RADIOTAP_CODING_LDPC_USER0;
|
||||
pos++;
|
||||
/* group ID */
|
||||
@ -533,6 +538,59 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
|
||||
}
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
ieee80211_make_monitor_skb(struct ieee80211_local *local,
|
||||
struct sk_buff **origskb,
|
||||
struct ieee80211_rate *rate,
|
||||
int rtap_vendor_space, bool use_origskb)
|
||||
{
|
||||
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(*origskb);
|
||||
int rt_hdrlen, needed_headroom;
|
||||
struct sk_buff *skb;
|
||||
|
||||
/* room for the radiotap header based on driver features */
|
||||
rt_hdrlen = ieee80211_rx_radiotap_hdrlen(local, status, *origskb);
|
||||
needed_headroom = rt_hdrlen - rtap_vendor_space;
|
||||
|
||||
if (use_origskb) {
|
||||
/* only need to expand headroom if necessary */
|
||||
skb = *origskb;
|
||||
*origskb = NULL;
|
||||
|
||||
/*
|
||||
* This shouldn't trigger often because most devices have an
|
||||
* RX header they pull before we get here, and that should
|
||||
* be big enough for our radiotap information. We should
|
||||
* probably export the length to drivers so that we can have
|
||||
* them allocate enough headroom to start with.
|
||||
*/
|
||||
if (skb_headroom(skb) < needed_headroom &&
|
||||
pskb_expand_head(skb, needed_headroom, 0, GFP_ATOMIC)) {
|
||||
dev_kfree_skb(skb);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Need to make a copy and possibly remove radiotap header
|
||||
* and FCS from the original.
|
||||
*/
|
||||
skb = skb_copy_expand(*origskb, needed_headroom, 0, GFP_ATOMIC);
|
||||
|
||||
if (!skb)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* prepend radiotap information */
|
||||
ieee80211_add_rx_radiotap_header(local, skb, rate, rt_hdrlen, true);
|
||||
|
||||
skb_reset_mac_header(skb);
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
skb->pkt_type = PACKET_OTHERHOST;
|
||||
skb->protocol = htons(ETH_P_802_2);
|
||||
|
||||
return skb;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function copies a received frame to all monitor interfaces and
|
||||
* returns a cleaned-up SKB that no longer includes the FCS nor the
|
||||
@ -544,13 +602,12 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
|
||||
{
|
||||
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb);
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
int rt_hdrlen, needed_headroom;
|
||||
struct sk_buff *skb, *skb2;
|
||||
struct net_device *prev_dev = NULL;
|
||||
struct sk_buff *monskb = NULL;
|
||||
int present_fcs_len = 0;
|
||||
unsigned int rtap_vendor_space = 0;
|
||||
struct ieee80211_sub_if_data *monitor_sdata =
|
||||
rcu_dereference(local->monitor_sdata);
|
||||
bool only_monitor = false;
|
||||
|
||||
if (unlikely(status->flag & RX_FLAG_RADIOTAP_VENDOR_DATA)) {
|
||||
struct ieee80211_vendor_radiotap *rtap = (void *)origskb->data;
|
||||
@ -583,9 +640,11 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
only_monitor = should_drop_frame(origskb, present_fcs_len,
|
||||
rtap_vendor_space);
|
||||
|
||||
if (!local->monitors || (status->flag & RX_FLAG_SKIP_MONITOR)) {
|
||||
if (should_drop_frame(origskb, present_fcs_len,
|
||||
rtap_vendor_space)) {
|
||||
if (only_monitor) {
|
||||
dev_kfree_skb(origskb);
|
||||
return NULL;
|
||||
}
|
||||
@ -597,67 +656,46 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
|
||||
|
||||
ieee80211_handle_mu_mimo_mon(monitor_sdata, origskb, rtap_vendor_space);
|
||||
|
||||
/* room for the radiotap header based on driver features */
|
||||
rt_hdrlen = ieee80211_rx_radiotap_hdrlen(local, status, origskb);
|
||||
needed_headroom = rt_hdrlen - rtap_vendor_space;
|
||||
|
||||
if (should_drop_frame(origskb, present_fcs_len, rtap_vendor_space)) {
|
||||
/* only need to expand headroom if necessary */
|
||||
skb = origskb;
|
||||
origskb = NULL;
|
||||
|
||||
/*
|
||||
* This shouldn't trigger often because most devices have an
|
||||
* RX header they pull before we get here, and that should
|
||||
* be big enough for our radiotap information. We should
|
||||
* probably export the length to drivers so that we can have
|
||||
* them allocate enough headroom to start with.
|
||||
*/
|
||||
if (skb_headroom(skb) < needed_headroom &&
|
||||
pskb_expand_head(skb, needed_headroom, 0, GFP_ATOMIC)) {
|
||||
dev_kfree_skb(skb);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Need to make a copy and possibly remove radiotap header
|
||||
* and FCS from the original.
|
||||
*/
|
||||
skb = skb_copy_expand(origskb, needed_headroom, 0, GFP_ATOMIC);
|
||||
remove_monitor_info(origskb, present_fcs_len,
|
||||
rtap_vendor_space);
|
||||
|
||||
if (!skb)
|
||||
return origskb;
|
||||
}
|
||||
|
||||
/* prepend radiotap information */
|
||||
ieee80211_add_rx_radiotap_header(local, skb, rate, rt_hdrlen, true);
|
||||
|
||||
skb_reset_mac_header(skb);
|
||||
skb->ip_summed = CHECKSUM_UNNECESSARY;
|
||||
skb->pkt_type = PACKET_OTHERHOST;
|
||||
skb->protocol = htons(ETH_P_802_2);
|
||||
|
||||
list_for_each_entry_rcu(sdata, &local->mon_list, u.mntr.list) {
|
||||
if (prev_dev) {
|
||||
skb2 = skb_clone(skb, GFP_ATOMIC);
|
||||
if (skb2) {
|
||||
skb2->dev = prev_dev;
|
||||
netif_receive_skb(skb2);
|
||||
bool last_monitor = list_is_last(&sdata->u.mntr.list,
|
||||
&local->mon_list);
|
||||
|
||||
if (!monskb)
|
||||
monskb = ieee80211_make_monitor_skb(local, &origskb,
|
||||
rate,
|
||||
rtap_vendor_space,
|
||||
only_monitor &&
|
||||
last_monitor);
|
||||
|
||||
if (monskb) {
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (last_monitor) {
|
||||
skb = monskb;
|
||||
monskb = NULL;
|
||||
} else {
|
||||
skb = skb_clone(monskb, GFP_ATOMIC);
|
||||
}
|
||||
|
||||
if (skb) {
|
||||
skb->dev = sdata->dev;
|
||||
ieee80211_rx_stats(skb->dev, skb->len);
|
||||
netif_receive_skb(skb);
|
||||
}
|
||||
}
|
||||
|
||||
prev_dev = sdata->dev;
|
||||
ieee80211_rx_stats(sdata->dev, skb->len);
|
||||
if (last_monitor)
|
||||
break;
|
||||
}
|
||||
|
||||
if (prev_dev) {
|
||||
skb->dev = prev_dev;
|
||||
netif_receive_skb(skb);
|
||||
} else
|
||||
dev_kfree_skb(skb);
|
||||
/* this happens if last_monitor was erroneously false */
|
||||
dev_kfree_skb(monskb);
|
||||
|
||||
/* ditto */
|
||||
if (!origskb)
|
||||
return NULL;
|
||||
|
||||
remove_monitor_info(origskb, present_fcs_len, rtap_vendor_space);
|
||||
return origskb;
|
||||
}
|
||||
|
||||
@ -3303,8 +3341,8 @@ static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
|
||||
status = IEEE80211_SKB_RXCB((rx->skb));
|
||||
|
||||
sband = rx->local->hw.wiphy->bands[status->band];
|
||||
if (!(status->flag & RX_FLAG_HT) &&
|
||||
!(status->flag & RX_FLAG_VHT))
|
||||
if (!(status->encoding == RX_ENC_HT) &&
|
||||
!(status->encoding == RX_ENC_VHT))
|
||||
rate = &sband->bitrates[status->rate_idx];
|
||||
|
||||
ieee80211_rx_cooked_monitor(rx, rate);
|
||||
@ -3541,7 +3579,7 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
|
||||
struct ieee80211_hdr *hdr = (void *)skb->data;
|
||||
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
|
||||
u8 *bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type);
|
||||
int multicast = is_multicast_ether_addr(hdr->addr1);
|
||||
bool multicast = is_multicast_ether_addr(hdr->addr1);
|
||||
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_STATION:
|
||||
@ -3565,7 +3603,7 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
|
||||
return false;
|
||||
if (!rx->sta) {
|
||||
int rate_idx;
|
||||
if (status->flag & (RX_FLAG_HT | RX_FLAG_VHT))
|
||||
if (status->encoding != RX_ENC_LEGACY)
|
||||
rate_idx = 0; /* TODO: HT/VHT rates */
|
||||
else
|
||||
rate_idx = status->rate_idx;
|
||||
@ -3585,7 +3623,7 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
|
||||
return false;
|
||||
if (!rx->sta) {
|
||||
int rate_idx;
|
||||
if (status->flag & RX_FLAG_HT)
|
||||
if (status->encoding != RX_ENC_LEGACY)
|
||||
rate_idx = 0; /* TODO: HT rates */
|
||||
else
|
||||
rate_idx = status->rate_idx;
|
||||
@ -4248,7 +4286,8 @@ void ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
|
||||
* we probably can't have a valid rate here anyway.
|
||||
*/
|
||||
|
||||
if (status->flag & RX_FLAG_HT) {
|
||||
switch (status->encoding) {
|
||||
case RX_ENC_HT:
|
||||
/*
|
||||
* rate_idx is MCS index, which can be [0-76]
|
||||
* as documented on:
|
||||
@ -4266,14 +4305,19 @@ void ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta,
|
||||
status->rate_idx,
|
||||
status->rate_idx))
|
||||
goto drop;
|
||||
} else if (status->flag & RX_FLAG_VHT) {
|
||||
break;
|
||||
case RX_ENC_VHT:
|
||||
if (WARN_ONCE(status->rate_idx > 9 ||
|
||||
!status->vht_nss ||
|
||||
status->vht_nss > 8,
|
||||
!status->nss ||
|
||||
status->nss > 8,
|
||||
"Rate marked as a VHT rate but data is invalid: MCS: %d, NSS: %d\n",
|
||||
status->rate_idx, status->vht_nss))
|
||||
status->rate_idx, status->nss))
|
||||
goto drop;
|
||||
} else {
|
||||
break;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
/* fall through */
|
||||
case RX_ENC_LEGACY:
|
||||
if (WARN_ON(status->rate_idx >= sband->n_bitrates))
|
||||
goto drop;
|
||||
rate = &sband->bitrates[status->rate_idx];
|
||||
|
@ -79,9 +79,9 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
|
||||
bss_meta.signal = (rx_status->signal * 100) / local->hw.max_signal;
|
||||
|
||||
bss_meta.scan_width = NL80211_BSS_CHAN_WIDTH_20;
|
||||
if (rx_status->flag & RX_FLAG_5MHZ)
|
||||
if (rx_status->bw == RATE_INFO_BW_5)
|
||||
bss_meta.scan_width = NL80211_BSS_CHAN_WIDTH_5;
|
||||
if (rx_status->flag & RX_FLAG_10MHZ)
|
||||
else if (rx_status->bw == RATE_INFO_BW_10)
|
||||
bss_meta.scan_width = NL80211_BSS_CHAN_WIDTH_10;
|
||||
|
||||
bss_meta.chan = channel;
|
||||
@ -174,8 +174,8 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
|
||||
if (beacon) {
|
||||
struct ieee80211_supported_band *sband =
|
||||
local->hw.wiphy->bands[rx_status->band];
|
||||
if (!(rx_status->flag & RX_FLAG_HT) &&
|
||||
!(rx_status->flag & RX_FLAG_VHT))
|
||||
if (!(rx_status->encoding == RX_ENC_HT) &&
|
||||
!(rx_status->encoding == RX_ENC_VHT))
|
||||
bss->beacon_rate =
|
||||
&sband->bitrates[rx_status->rate_idx];
|
||||
}
|
||||
@ -1219,7 +1219,7 @@ void ieee80211_sched_scan_results(struct ieee80211_hw *hw)
|
||||
|
||||
trace_api_sched_scan_results(local);
|
||||
|
||||
cfg80211_sched_scan_results(hw->wiphy);
|
||||
cfg80211_sched_scan_results(hw->wiphy, 0);
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_sched_scan_results);
|
||||
|
||||
@ -1239,7 +1239,7 @@ void ieee80211_sched_scan_end(struct ieee80211_local *local)
|
||||
|
||||
mutex_unlock(&local->mtx);
|
||||
|
||||
cfg80211_sched_scan_stopped(local->hw.wiphy);
|
||||
cfg80211_sched_scan_stopped(local->hw.wiphy, 0);
|
||||
}
|
||||
|
||||
void ieee80211_sched_scan_stopped_work(struct work_struct *work)
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Copyright 2002-2005, Instant802 Networks, Inc.
|
||||
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
|
||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2015 - 2016 Intel Deutschland GmbH
|
||||
* Copyright (C) 2015 - 2017 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@ -395,10 +395,15 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
|
||||
sta->sta.smps_mode = IEEE80211_SMPS_OFF;
|
||||
if (sdata->vif.type == NL80211_IFTYPE_AP ||
|
||||
sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
|
||||
struct ieee80211_supported_band *sband =
|
||||
hw->wiphy->bands[ieee80211_get_sdata_band(sdata)];
|
||||
u8 smps = (sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >>
|
||||
IEEE80211_HT_CAP_SM_PS_SHIFT;
|
||||
struct ieee80211_supported_band *sband;
|
||||
u8 smps;
|
||||
|
||||
sband = ieee80211_get_sband(sdata);
|
||||
if (!sband)
|
||||
goto free_txq;
|
||||
|
||||
smps = (sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >>
|
||||
IEEE80211_HT_CAP_SM_PS_SHIFT;
|
||||
/*
|
||||
* Assume that hostapd advertises our caps in the beacon and
|
||||
* this is the known_smps_mode for a station that just assciated
|
||||
@ -1957,27 +1962,32 @@ sta_get_last_rx_stats(struct sta_info *sta)
|
||||
static void sta_stats_decode_rate(struct ieee80211_local *local, u16 rate,
|
||||
struct rate_info *rinfo)
|
||||
{
|
||||
rinfo->bw = (rate & STA_STATS_RATE_BW_MASK) >>
|
||||
STA_STATS_RATE_BW_SHIFT;
|
||||
rinfo->bw = STA_STATS_GET(BW, rate);
|
||||
|
||||
switch (rate & STA_STATS_RATE_TYPE_MASK) {
|
||||
switch (STA_STATS_GET(TYPE, rate)) {
|
||||
case STA_STATS_RATE_TYPE_VHT:
|
||||
rinfo->flags = RATE_INFO_FLAGS_VHT_MCS;
|
||||
rinfo->mcs = rate & 0xf;
|
||||
rinfo->nss = (rate & 0xf0) >> 4;
|
||||
rinfo->mcs = STA_STATS_GET(VHT_MCS, rate);
|
||||
rinfo->nss = STA_STATS_GET(VHT_NSS, rate);
|
||||
if (STA_STATS_GET(SGI, rate))
|
||||
rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
|
||||
break;
|
||||
case STA_STATS_RATE_TYPE_HT:
|
||||
rinfo->flags = RATE_INFO_FLAGS_MCS;
|
||||
rinfo->mcs = rate & 0xff;
|
||||
rinfo->mcs = STA_STATS_GET(HT_MCS, rate);
|
||||
if (STA_STATS_GET(SGI, rate))
|
||||
rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
|
||||
break;
|
||||
case STA_STATS_RATE_TYPE_LEGACY: {
|
||||
struct ieee80211_supported_band *sband;
|
||||
u16 brate;
|
||||
unsigned int shift;
|
||||
int band = STA_STATS_GET(LEGACY_BAND, rate);
|
||||
int rate_idx = STA_STATS_GET(LEGACY_IDX, rate);
|
||||
|
||||
rinfo->flags = 0;
|
||||
sband = local->hw.wiphy->bands[(rate >> 4) & 0xf];
|
||||
brate = sband->bitrates[rate & 0xf].bitrate;
|
||||
sband = local->hw.wiphy->bands[band];
|
||||
brate = sband->bitrates[rate_idx].bitrate;
|
||||
if (rinfo->bw == RATE_INFO_BW_5)
|
||||
shift = 2;
|
||||
else if (rinfo->bw == RATE_INFO_BW_10)
|
||||
@ -1988,9 +1998,6 @@ static void sta_stats_decode_rate(struct ieee80211_local *local, u16 rate,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rate & STA_STATS_RATE_SGI)
|
||||
rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
|
||||
}
|
||||
|
||||
static int sta_set_rate_info_rx(struct sta_info *sta, struct rate_info *rinfo)
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright 2002-2005, Devicescape Software, Inc.
|
||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright(c) 2015-2016 Intel Deutschland GmbH
|
||||
* Copyright(c) 2015-2017 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@ -16,6 +16,7 @@
|
||||
#include <linux/if_ether.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/average.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/rhashtable.h>
|
||||
#include <linux/u64_stats_sync.h>
|
||||
@ -727,41 +728,55 @@ void ieee80211_sta_ps_deliver_uapsd(struct sta_info *sta);
|
||||
|
||||
unsigned long ieee80211_sta_last_active(struct sta_info *sta);
|
||||
|
||||
enum sta_stats_type {
|
||||
STA_STATS_RATE_TYPE_INVALID = 0,
|
||||
STA_STATS_RATE_TYPE_LEGACY,
|
||||
STA_STATS_RATE_TYPE_HT,
|
||||
STA_STATS_RATE_TYPE_VHT,
|
||||
};
|
||||
|
||||
#define STA_STATS_FIELD_HT_MCS GENMASK( 7, 0)
|
||||
#define STA_STATS_FIELD_LEGACY_IDX GENMASK( 3, 0)
|
||||
#define STA_STATS_FIELD_LEGACY_BAND GENMASK( 7, 4)
|
||||
#define STA_STATS_FIELD_VHT_MCS GENMASK( 3, 0)
|
||||
#define STA_STATS_FIELD_VHT_NSS GENMASK( 7, 4)
|
||||
#define STA_STATS_FIELD_BW GENMASK(11, 8)
|
||||
#define STA_STATS_FIELD_SGI GENMASK(12, 12)
|
||||
#define STA_STATS_FIELD_TYPE GENMASK(15, 13)
|
||||
|
||||
#define STA_STATS_FIELD(_n, _v) FIELD_PREP(STA_STATS_FIELD_ ## _n, _v)
|
||||
#define STA_STATS_GET(_n, _v) FIELD_GET(STA_STATS_FIELD_ ## _n, _v)
|
||||
|
||||
#define STA_STATS_RATE_INVALID 0
|
||||
#define STA_STATS_RATE_TYPE_MASK 0xC000
|
||||
#define STA_STATS_RATE_TYPE_LEGACY 0x4000
|
||||
#define STA_STATS_RATE_TYPE_HT 0x8000
|
||||
#define STA_STATS_RATE_TYPE_VHT 0xC000
|
||||
#define STA_STATS_RATE_SGI 0x1000
|
||||
#define STA_STATS_RATE_BW_SHIFT 9
|
||||
#define STA_STATS_RATE_BW_MASK (0x7 << STA_STATS_RATE_BW_SHIFT)
|
||||
|
||||
static inline u16 sta_stats_encode_rate(struct ieee80211_rx_status *s)
|
||||
static inline u32 sta_stats_encode_rate(struct ieee80211_rx_status *s)
|
||||
{
|
||||
u16 r = s->rate_idx;
|
||||
u16 r;
|
||||
|
||||
if (s->vht_flag & RX_VHT_FLAG_80MHZ)
|
||||
r |= RATE_INFO_BW_80 << STA_STATS_RATE_BW_SHIFT;
|
||||
else if (s->vht_flag & RX_VHT_FLAG_160MHZ)
|
||||
r |= RATE_INFO_BW_160 << STA_STATS_RATE_BW_SHIFT;
|
||||
else if (s->flag & RX_FLAG_40MHZ)
|
||||
r |= RATE_INFO_BW_40 << STA_STATS_RATE_BW_SHIFT;
|
||||
else if (s->flag & RX_FLAG_10MHZ)
|
||||
r |= RATE_INFO_BW_10 << STA_STATS_RATE_BW_SHIFT;
|
||||
else if (s->flag & RX_FLAG_5MHZ)
|
||||
r |= RATE_INFO_BW_5 << STA_STATS_RATE_BW_SHIFT;
|
||||
else
|
||||
r |= RATE_INFO_BW_20 << STA_STATS_RATE_BW_SHIFT;
|
||||
r = STA_STATS_FIELD(BW, s->bw);
|
||||
|
||||
if (s->flag & RX_FLAG_SHORT_GI)
|
||||
r |= STA_STATS_RATE_SGI;
|
||||
if (s->enc_flags & RX_ENC_FLAG_SHORT_GI)
|
||||
r |= STA_STATS_FIELD(SGI, 1);
|
||||
|
||||
if (s->flag & RX_FLAG_VHT)
|
||||
r |= STA_STATS_RATE_TYPE_VHT | (s->vht_nss << 4);
|
||||
else if (s->flag & RX_FLAG_HT)
|
||||
r |= STA_STATS_RATE_TYPE_HT;
|
||||
else
|
||||
r |= STA_STATS_RATE_TYPE_LEGACY | (s->band << 4);
|
||||
switch (s->encoding) {
|
||||
case RX_ENC_VHT:
|
||||
r |= STA_STATS_FIELD(TYPE, STA_STATS_RATE_TYPE_VHT);
|
||||
r |= STA_STATS_FIELD(VHT_NSS, s->nss);
|
||||
r |= STA_STATS_FIELD(VHT_MCS, s->rate_idx);
|
||||
break;
|
||||
case RX_ENC_HT:
|
||||
r |= STA_STATS_FIELD(TYPE, STA_STATS_RATE_TYPE_HT);
|
||||
r |= STA_STATS_FIELD(HT_MCS, s->rate_idx);
|
||||
break;
|
||||
case RX_ENC_LEGACY:
|
||||
r |= STA_STATS_FIELD(TYPE, STA_STATS_RATE_TYPE_LEGACY);
|
||||
r |= STA_STATS_FIELD(LEGACY_BAND, s->band);
|
||||
r |= STA_STATS_FIELD(LEGACY_IDX, s->rate_idx);
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
return STA_STATS_RATE_INVALID;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
@ -200,6 +200,7 @@ static void ieee80211_frame_acked(struct sta_info *sta, struct sk_buff *skb)
|
||||
}
|
||||
|
||||
if (ieee80211_is_action(mgmt->frame_control) &&
|
||||
!ieee80211_has_protected(mgmt->frame_control) &&
|
||||
mgmt->u.action.category == WLAN_CATEGORY_HT &&
|
||||
mgmt->u.action.u.ht_smps.action == WLAN_HT_ACTION_SMPS &&
|
||||
ieee80211_sdata_running(sdata)) {
|
||||
@ -630,61 +631,6 @@ static int ieee80211_tx_get_rates(struct ieee80211_hw *hw,
|
||||
return rates_idx;
|
||||
}
|
||||
|
||||
void ieee80211_tx_status_noskb(struct ieee80211_hw *hw,
|
||||
struct ieee80211_sta *pubsta,
|
||||
struct ieee80211_tx_info *info)
|
||||
{
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
struct ieee80211_supported_band *sband;
|
||||
int retry_count;
|
||||
bool acked, noack_success;
|
||||
|
||||
ieee80211_tx_get_rates(hw, info, &retry_count);
|
||||
|
||||
sband = hw->wiphy->bands[info->band];
|
||||
|
||||
acked = !!(info->flags & IEEE80211_TX_STAT_ACK);
|
||||
noack_success = !!(info->flags & IEEE80211_TX_STAT_NOACK_TRANSMITTED);
|
||||
|
||||
if (pubsta) {
|
||||
struct sta_info *sta;
|
||||
|
||||
sta = container_of(pubsta, struct sta_info, sta);
|
||||
|
||||
if (!acked)
|
||||
sta->status_stats.retry_failed++;
|
||||
sta->status_stats.retry_count += retry_count;
|
||||
|
||||
if (acked) {
|
||||
sta->status_stats.last_ack = jiffies;
|
||||
|
||||
if (sta->status_stats.lost_packets)
|
||||
sta->status_stats.lost_packets = 0;
|
||||
|
||||
/* Track when last TDLS packet was ACKed */
|
||||
if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH))
|
||||
sta->status_stats.last_tdls_pkt_time = jiffies;
|
||||
} else {
|
||||
ieee80211_lost_packet(sta, info);
|
||||
}
|
||||
|
||||
rate_control_tx_status_noskb(local, sband, sta, info);
|
||||
}
|
||||
|
||||
if (acked || noack_success) {
|
||||
I802_DEBUG_INC(local->dot11TransmittedFrameCount);
|
||||
if (!pubsta)
|
||||
I802_DEBUG_INC(local->dot11MulticastTransmittedFrameCount);
|
||||
if (retry_count > 0)
|
||||
I802_DEBUG_INC(local->dot11RetryCount);
|
||||
if (retry_count > 1)
|
||||
I802_DEBUG_INC(local->dot11MultipleRetryCount);
|
||||
} else {
|
||||
I802_DEBUG_INC(local->dot11FailedCount);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_tx_status_noskb);
|
||||
|
||||
void ieee80211_tx_monitor(struct ieee80211_local *local, struct sk_buff *skb,
|
||||
struct ieee80211_supported_band *sband,
|
||||
int retry_count, int shift, bool send_to_cooked)
|
||||
@ -742,15 +688,16 @@ void ieee80211_tx_monitor(struct ieee80211_local *local, struct sk_buff *skb,
|
||||
dev_kfree_skb(skb);
|
||||
}
|
||||
|
||||
void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
static void __ieee80211_tx_status(struct ieee80211_hw *hw,
|
||||
struct ieee80211_tx_status *status)
|
||||
{
|
||||
struct sk_buff *skb = status->skb;
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||
struct ieee80211_tx_info *info = status->info;
|
||||
struct sta_info *sta;
|
||||
__le16 fc;
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct rhlist_head *tmp;
|
||||
struct sta_info *sta;
|
||||
int retry_count;
|
||||
int rates_idx;
|
||||
bool send_to_cooked;
|
||||
@ -761,16 +708,11 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
|
||||
rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count);
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
sband = local->hw.wiphy->bands[info->band];
|
||||
fc = hdr->frame_control;
|
||||
|
||||
for_each_sta_info(local, hdr->addr1, sta, tmp) {
|
||||
/* skip wrong virtual interface */
|
||||
if (!ether_addr_equal(hdr->addr2, sta->sdata->vif.addr))
|
||||
continue;
|
||||
|
||||
if (status->sta) {
|
||||
sta = container_of(status->sta, struct sta_info, sta);
|
||||
shift = ieee80211_vif_get_shift(&sta->sdata->vif);
|
||||
|
||||
if (info->flags & IEEE80211_TX_STATUS_EOSP)
|
||||
@ -790,7 +732,6 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
* that this TX packet failed because of that.
|
||||
*/
|
||||
ieee80211_handle_filtered_frame(local, sta, skb);
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -840,7 +781,6 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
|
||||
if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
|
||||
ieee80211_handle_filtered_frame(local, sta, skb);
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
} else {
|
||||
if (!acked)
|
||||
@ -856,7 +796,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
}
|
||||
}
|
||||
|
||||
rate_control_tx_status(local, sband, sta, skb);
|
||||
rate_control_tx_status(local, sband, status);
|
||||
if (ieee80211_vif_is_mesh(&sta->sdata->vif))
|
||||
ieee80211s_update_metric(local, sta, skb);
|
||||
|
||||
@ -883,8 +823,6 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
}
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
ieee80211_led_tx(local);
|
||||
|
||||
/* SNMP counters
|
||||
@ -949,8 +887,96 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
/* send to monitor interfaces */
|
||||
ieee80211_tx_monitor(local, skb, sband, retry_count, shift, send_to_cooked);
|
||||
}
|
||||
|
||||
void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
struct ieee80211_tx_status status = {
|
||||
.skb = skb,
|
||||
.info = IEEE80211_SKB_CB(skb),
|
||||
};
|
||||
struct rhlist_head *tmp;
|
||||
struct sta_info *sta;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
for_each_sta_info(local, hdr->addr1, sta, tmp) {
|
||||
/* skip wrong virtual interface */
|
||||
if (!ether_addr_equal(hdr->addr2, sta->sdata->vif.addr))
|
||||
continue;
|
||||
|
||||
status.sta = &sta->sta;
|
||||
break;
|
||||
}
|
||||
|
||||
__ieee80211_tx_status(hw, &status);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_tx_status);
|
||||
|
||||
void ieee80211_tx_status_ext(struct ieee80211_hw *hw,
|
||||
struct ieee80211_tx_status *status)
|
||||
{
|
||||
struct ieee80211_local *local = hw_to_local(hw);
|
||||
struct ieee80211_tx_info *info = status->info;
|
||||
struct ieee80211_sta *pubsta = status->sta;
|
||||
struct ieee80211_supported_band *sband;
|
||||
int retry_count;
|
||||
bool acked, noack_success;
|
||||
|
||||
if (status->skb)
|
||||
return __ieee80211_tx_status(hw, status);
|
||||
|
||||
if (!status->sta)
|
||||
return;
|
||||
|
||||
ieee80211_tx_get_rates(hw, info, &retry_count);
|
||||
|
||||
sband = hw->wiphy->bands[info->band];
|
||||
|
||||
acked = !!(info->flags & IEEE80211_TX_STAT_ACK);
|
||||
noack_success = !!(info->flags & IEEE80211_TX_STAT_NOACK_TRANSMITTED);
|
||||
|
||||
if (pubsta) {
|
||||
struct sta_info *sta;
|
||||
|
||||
sta = container_of(pubsta, struct sta_info, sta);
|
||||
|
||||
if (!acked)
|
||||
sta->status_stats.retry_failed++;
|
||||
sta->status_stats.retry_count += retry_count;
|
||||
|
||||
if (acked) {
|
||||
sta->status_stats.last_ack = jiffies;
|
||||
|
||||
if (sta->status_stats.lost_packets)
|
||||
sta->status_stats.lost_packets = 0;
|
||||
|
||||
/* Track when last TDLS packet was ACKed */
|
||||
if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH))
|
||||
sta->status_stats.last_tdls_pkt_time = jiffies;
|
||||
} else {
|
||||
ieee80211_lost_packet(sta, info);
|
||||
}
|
||||
|
||||
rate_control_tx_status(local, sband, status);
|
||||
}
|
||||
|
||||
if (acked || noack_success) {
|
||||
I802_DEBUG_INC(local->dot11TransmittedFrameCount);
|
||||
if (!pubsta)
|
||||
I802_DEBUG_INC(local->dot11MulticastTransmittedFrameCount);
|
||||
if (retry_count > 0)
|
||||
I802_DEBUG_INC(local->dot11RetryCount);
|
||||
if (retry_count > 1)
|
||||
I802_DEBUG_INC(local->dot11MultipleRetryCount);
|
||||
} else {
|
||||
I802_DEBUG_INC(local->dot11FailedCount);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_tx_status_ext);
|
||||
|
||||
void ieee80211_report_low_ack(struct ieee80211_sta *pubsta, u32 num_packets)
|
||||
{
|
||||
struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
|
||||
|
@ -47,8 +47,7 @@ static void ieee80211_tdls_add_ext_capab(struct ieee80211_sub_if_data *sdata,
|
||||
NL80211_FEATURE_TDLS_CHANNEL_SWITCH;
|
||||
bool wider_band = ieee80211_hw_check(&local->hw, TDLS_WIDER_BW) &&
|
||||
!ifmgd->tdls_wider_bw_prohibited;
|
||||
enum nl80211_band band = ieee80211_get_sdata_band(sdata);
|
||||
struct ieee80211_supported_band *sband = local->hw.wiphy->bands[band];
|
||||
struct ieee80211_supported_band *sband = ieee80211_get_sband(sdata);
|
||||
bool vht = sband && sband->vht_cap.vht_supported;
|
||||
u8 *pos = (void *)skb_put(skb, 10);
|
||||
|
||||
@ -180,11 +179,14 @@ static void ieee80211_tdls_add_bss_coex_ie(struct sk_buff *skb)
|
||||
static u16 ieee80211_get_tdls_sta_capab(struct ieee80211_sub_if_data *sdata,
|
||||
u16 status_code)
|
||||
{
|
||||
struct ieee80211_supported_band *sband;
|
||||
|
||||
/* The capability will be 0 when sending a failure code */
|
||||
if (status_code != 0)
|
||||
return 0;
|
||||
|
||||
if (ieee80211_get_sdata_band(sdata) == NL80211_BAND_2GHZ) {
|
||||
sband = ieee80211_get_sband(sdata);
|
||||
if (sband && sband->band == NL80211_BAND_2GHZ) {
|
||||
return WLAN_CAPABILITY_SHORT_SLOT_TIME |
|
||||
WLAN_CAPABILITY_SHORT_PREAMBLE;
|
||||
}
|
||||
@ -358,17 +360,20 @@ ieee80211_tdls_add_setup_start_ies(struct ieee80211_sub_if_data *sdata,
|
||||
u8 action_code, bool initiator,
|
||||
const u8 *extra_ies, size_t extra_ies_len)
|
||||
{
|
||||
enum nl80211_band band = ieee80211_get_sdata_band(sdata);
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_sta_ht_cap ht_cap;
|
||||
struct ieee80211_sta_vht_cap vht_cap;
|
||||
struct sta_info *sta = NULL;
|
||||
size_t offset = 0, noffset;
|
||||
u8 *pos;
|
||||
|
||||
ieee80211_add_srates_ie(sdata, skb, false, band);
|
||||
ieee80211_add_ext_srates_ie(sdata, skb, false, band);
|
||||
sband = ieee80211_get_sband(sdata);
|
||||
if (!sband)
|
||||
return;
|
||||
|
||||
ieee80211_add_srates_ie(sdata, skb, false, sband->band);
|
||||
ieee80211_add_ext_srates_ie(sdata, skb, false, sband->band);
|
||||
ieee80211_tdls_add_supp_channels(sdata, skb);
|
||||
|
||||
/* add any custom IEs that go before Extended Capabilities */
|
||||
@ -439,7 +444,6 @@ ieee80211_tdls_add_setup_start_ies(struct ieee80211_sub_if_data *sdata,
|
||||
* the same on all bands. The specification limits the setup to a
|
||||
* single HT-cap, so use the current band for now.
|
||||
*/
|
||||
sband = local->hw.wiphy->bands[band];
|
||||
memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap));
|
||||
|
||||
if ((action_code == WLAN_TDLS_SETUP_REQUEST ||
|
||||
@ -545,9 +549,13 @@ ieee80211_tdls_add_setup_cfm_ies(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
size_t offset = 0, noffset;
|
||||
struct sta_info *sta, *ap_sta;
|
||||
enum nl80211_band band = ieee80211_get_sdata_band(sdata);
|
||||
struct ieee80211_supported_band *sband;
|
||||
u8 *pos;
|
||||
|
||||
sband = ieee80211_get_sband(sdata);
|
||||
if (!sband)
|
||||
return;
|
||||
|
||||
mutex_lock(&local->sta_mtx);
|
||||
|
||||
sta = sta_info_get(sdata, peer);
|
||||
@ -612,7 +620,8 @@ ieee80211_tdls_add_setup_cfm_ies(struct ieee80211_sub_if_data *sdata,
|
||||
ieee80211_tdls_add_link_ie(sdata, skb, peer, initiator);
|
||||
|
||||
/* only include VHT-operation if not on the 2.4GHz band */
|
||||
if (band != NL80211_BAND_2GHZ && sta->sta.vht_cap.vht_supported) {
|
||||
if (sband->band != NL80211_BAND_2GHZ &&
|
||||
sta->sta.vht_cap.vht_supported) {
|
||||
/*
|
||||
* if both peers support WIDER_BW, we can expand the chandef to
|
||||
* a wider compatible one, up to 80MHz
|
||||
|
@ -4297,7 +4297,10 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
|
||||
return bcn;
|
||||
|
||||
shift = ieee80211_vif_get_shift(vif);
|
||||
sband = hw->wiphy->bands[ieee80211_get_sdata_band(vif_to_sdata(vif))];
|
||||
sband = ieee80211_get_sband(vif_to_sdata(vif));
|
||||
if (!sband)
|
||||
return bcn;
|
||||
|
||||
ieee80211_tx_monitor(hw_to_local(hw), copy, sband, 1, shift, false);
|
||||
|
||||
return bcn;
|
||||
|
@ -4,7 +4,7 @@
|
||||
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
|
||||
* Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||
* Copyright (C) 2015-2016 Intel Deutschland GmbH
|
||||
* Copyright (C) 2015-2017 Intel Deutschland GmbH
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
@ -828,6 +828,7 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
|
||||
case WLAN_EID_EXT_CAPABILITY:
|
||||
case WLAN_EID_CHAN_SWITCH_TIMING:
|
||||
case WLAN_EID_LINK_ID:
|
||||
case WLAN_EID_BSS_MAX_IDLE_PERIOD:
|
||||
/*
|
||||
* not listing WLAN_EID_CHANNEL_SWITCH_WRAPPER -- it seems possible
|
||||
* that if the content gets bigger it might be needed more than once
|
||||
@ -1089,6 +1090,10 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
|
||||
else
|
||||
elem_parse_failed = true;
|
||||
break;
|
||||
case WLAN_EID_BSS_MAX_IDLE_PERIOD:
|
||||
if (elen >= sizeof(*elems->max_idle_period_ie))
|
||||
elems->max_idle_period_ie = (void *)pos;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -1590,14 +1595,14 @@ u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata,
|
||||
size_t num_rates;
|
||||
u32 supp_rates, rate_flags;
|
||||
int i, j, shift;
|
||||
|
||||
sband = sdata->local->hw.wiphy->bands[band];
|
||||
if (WARN_ON(!sband))
|
||||
return 1;
|
||||
|
||||
rate_flags = ieee80211_chandef_rate_flags(&sdata->vif.bss_conf.chandef);
|
||||
shift = ieee80211_vif_get_shift(&sdata->vif);
|
||||
|
||||
if (WARN_ON(!sband))
|
||||
return 1;
|
||||
|
||||
num_rates = sband->n_bitrates;
|
||||
supp_rates = 0;
|
||||
for (i = 0; i < elems->supp_rates_len +
|
||||
@ -1983,6 +1988,10 @@ int ieee80211_reconfig(struct ieee80211_local *local)
|
||||
if (sdata->u.mgd.have_beacon)
|
||||
changed |= BSS_CHANGED_BEACON_INFO;
|
||||
|
||||
if (sdata->vif.bss_conf.max_idle_period ||
|
||||
sdata->vif.bss_conf.protected_keep_alive)
|
||||
changed |= BSS_CHANGED_KEEP_ALIVE;
|
||||
|
||||
sdata_lock(sdata);
|
||||
ieee80211_bss_info_change_notify(sdata, changed);
|
||||
sdata_unlock(sdata);
|
||||
@ -2103,7 +2112,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
|
||||
mutex_unlock(&local->mtx);
|
||||
|
||||
if (sched_scan_stopped)
|
||||
cfg80211_sched_scan_stopped_rtnl(local->hw.wiphy);
|
||||
cfg80211_sched_scan_stopped_rtnl(local->hw.wiphy, 0);
|
||||
|
||||
wake_up:
|
||||
if (local->in_reconfig) {
|
||||
@ -2715,42 +2724,39 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
|
||||
memset(&ri, 0, sizeof(ri));
|
||||
|
||||
/* Fill cfg80211 rate info */
|
||||
if (status->flag & RX_FLAG_HT) {
|
||||
switch (status->encoding) {
|
||||
case RX_ENC_HT:
|
||||
ri.mcs = status->rate_idx;
|
||||
ri.flags |= RATE_INFO_FLAGS_MCS;
|
||||
if (status->flag & RX_FLAG_40MHZ)
|
||||
ri.bw = RATE_INFO_BW_40;
|
||||
else
|
||||
ri.bw = RATE_INFO_BW_20;
|
||||
if (status->flag & RX_FLAG_SHORT_GI)
|
||||
ri.bw = status->bw;
|
||||
if (status->enc_flags & RX_ENC_FLAG_SHORT_GI)
|
||||
ri.flags |= RATE_INFO_FLAGS_SHORT_GI;
|
||||
} else if (status->flag & RX_FLAG_VHT) {
|
||||
break;
|
||||
case RX_ENC_VHT:
|
||||
ri.flags |= RATE_INFO_FLAGS_VHT_MCS;
|
||||
ri.mcs = status->rate_idx;
|
||||
ri.nss = status->vht_nss;
|
||||
if (status->flag & RX_FLAG_40MHZ)
|
||||
ri.bw = RATE_INFO_BW_40;
|
||||
else if (status->vht_flag & RX_VHT_FLAG_80MHZ)
|
||||
ri.bw = RATE_INFO_BW_80;
|
||||
else if (status->vht_flag & RX_VHT_FLAG_160MHZ)
|
||||
ri.bw = RATE_INFO_BW_160;
|
||||
else
|
||||
ri.bw = RATE_INFO_BW_20;
|
||||
if (status->flag & RX_FLAG_SHORT_GI)
|
||||
ri.nss = status->nss;
|
||||
ri.bw = status->bw;
|
||||
if (status->enc_flags & RX_ENC_FLAG_SHORT_GI)
|
||||
ri.flags |= RATE_INFO_FLAGS_SHORT_GI;
|
||||
} else {
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
/* fall through */
|
||||
case RX_ENC_LEGACY: {
|
||||
struct ieee80211_supported_band *sband;
|
||||
int shift = 0;
|
||||
int bitrate;
|
||||
|
||||
if (status->flag & RX_FLAG_10MHZ) {
|
||||
ri.bw = status->bw;
|
||||
|
||||
switch (status->bw) {
|
||||
case RATE_INFO_BW_10:
|
||||
shift = 1;
|
||||
ri.bw = RATE_INFO_BW_10;
|
||||
} else if (status->flag & RX_FLAG_5MHZ) {
|
||||
break;
|
||||
case RATE_INFO_BW_5:
|
||||
shift = 2;
|
||||
ri.bw = RATE_INFO_BW_5;
|
||||
} else {
|
||||
ri.bw = RATE_INFO_BW_20;
|
||||
break;
|
||||
}
|
||||
|
||||
sband = local->hw.wiphy->bands[status->band];
|
||||
@ -2762,19 +2768,21 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
|
||||
if (status->band == NL80211_BAND_5GHZ) {
|
||||
ts += 20 << shift;
|
||||
mpdu_offset += 2;
|
||||
} else if (status->flag & RX_FLAG_SHORTPRE) {
|
||||
} else if (status->enc_flags & RX_ENC_FLAG_SHORTPRE) {
|
||||
ts += 96;
|
||||
} else {
|
||||
ts += 192;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rate = cfg80211_calculate_bitrate(&ri);
|
||||
if (WARN_ONCE(!rate,
|
||||
"Invalid bitrate: flags=0x%llx, idx=%d, vht_nss=%d\n",
|
||||
(unsigned long long)status->flag, status->rate_idx,
|
||||
status->vht_nss))
|
||||
status->nss))
|
||||
return 0;
|
||||
|
||||
/* rewind from end of MPDU */
|
||||
@ -2791,8 +2799,10 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
|
||||
struct ieee80211_sub_if_data *sdata;
|
||||
struct cfg80211_chan_def chandef;
|
||||
|
||||
/* for interface list, to avoid linking iflist_mtx and chanctx_mtx */
|
||||
ASSERT_RTNL();
|
||||
|
||||
mutex_lock(&local->mtx);
|
||||
mutex_lock(&local->iflist_mtx);
|
||||
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||
/* it might be waiting for the local->mtx, but then
|
||||
* by the time it gets it, sdata->wdev.cac_started
|
||||
@ -2809,7 +2819,6 @@ void ieee80211_dfs_cac_cancel(struct ieee80211_local *local)
|
||||
GFP_KERNEL);
|
||||
}
|
||||
}
|
||||
mutex_unlock(&local->iflist_mtx);
|
||||
mutex_unlock(&local->mtx);
|
||||
}
|
||||
|
||||
@ -2831,7 +2840,9 @@ void ieee80211_dfs_radar_detected_work(struct work_struct *work)
|
||||
}
|
||||
mutex_unlock(&local->chanctx_mtx);
|
||||
|
||||
rtnl_lock();
|
||||
ieee80211_dfs_cac_cancel(local);
|
||||
rtnl_unlock();
|
||||
|
||||
if (num_chanctx > 1)
|
||||
/* XXX: multi-channel is not supported yet */
|
||||
@ -2846,7 +2857,7 @@ void ieee80211_radar_detected(struct ieee80211_hw *hw)
|
||||
|
||||
trace_api_radar_detected(local);
|
||||
|
||||
ieee80211_queue_work(hw, &local->radar_detected_work);
|
||||
schedule_work(&local->radar_detected_work);
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_radar_detected);
|
||||
|
||||
|
@ -305,30 +305,14 @@ static void cfg80211_event_work(struct work_struct *work)
|
||||
|
||||
void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev)
|
||||
{
|
||||
struct cfg80211_iface_destroy *item;
|
||||
struct wireless_dev *wdev, *tmp;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
spin_lock_irq(&rdev->destroy_list_lock);
|
||||
while ((item = list_first_entry_or_null(&rdev->destroy_list,
|
||||
struct cfg80211_iface_destroy,
|
||||
list))) {
|
||||
struct wireless_dev *wdev, *tmp;
|
||||
u32 nlportid = item->nlportid;
|
||||
|
||||
list_del(&item->list);
|
||||
kfree(item);
|
||||
spin_unlock_irq(&rdev->destroy_list_lock);
|
||||
|
||||
list_for_each_entry_safe(wdev, tmp,
|
||||
&rdev->wiphy.wdev_list, list) {
|
||||
if (nlportid == wdev->owner_nlportid)
|
||||
rdev_del_virtual_intf(rdev, wdev);
|
||||
}
|
||||
|
||||
spin_lock_irq(&rdev->destroy_list_lock);
|
||||
list_for_each_entry_safe(wdev, tmp, &rdev->wiphy.wdev_list, list) {
|
||||
if (wdev->nl_owner_dead)
|
||||
rdev_del_virtual_intf(rdev, wdev);
|
||||
}
|
||||
spin_unlock_irq(&rdev->destroy_list_lock);
|
||||
}
|
||||
|
||||
static void cfg80211_destroy_iface_wk(struct work_struct *work)
|
||||
@ -346,14 +330,16 @@ static void cfg80211_destroy_iface_wk(struct work_struct *work)
|
||||
static void cfg80211_sched_scan_stop_wk(struct work_struct *work)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev;
|
||||
struct cfg80211_sched_scan_request *req, *tmp;
|
||||
|
||||
rdev = container_of(work, struct cfg80211_registered_device,
|
||||
sched_scan_stop_wk);
|
||||
|
||||
rtnl_lock();
|
||||
|
||||
__cfg80211_stop_sched_scan(rdev, false);
|
||||
|
||||
list_for_each_entry_safe(req, tmp, &rdev->sched_scan_req_list, list) {
|
||||
if (req->nl_owner_dead)
|
||||
cfg80211_stop_sched_scan_req(rdev, req, false);
|
||||
}
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
@ -468,8 +454,8 @@ use_default_name:
|
||||
spin_lock_init(&rdev->beacon_registrations_lock);
|
||||
spin_lock_init(&rdev->bss_lock);
|
||||
INIT_LIST_HEAD(&rdev->bss_list);
|
||||
INIT_LIST_HEAD(&rdev->sched_scan_req_list);
|
||||
INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done);
|
||||
INIT_WORK(&rdev->sched_scan_results_wk, __cfg80211_sched_scan_results);
|
||||
INIT_LIST_HEAD(&rdev->mlme_unreg);
|
||||
spin_lock_init(&rdev->mlme_unreg_lock);
|
||||
INIT_WORK(&rdev->mlme_unreg_wk, cfg80211_mlme_unreg_wk);
|
||||
@ -484,10 +470,9 @@ use_default_name:
|
||||
rdev->wiphy.dev.platform_data = rdev;
|
||||
device_enable_async_suspend(&rdev->wiphy.dev);
|
||||
|
||||
INIT_LIST_HEAD(&rdev->destroy_list);
|
||||
spin_lock_init(&rdev->destroy_list_lock);
|
||||
INIT_WORK(&rdev->destroy_work, cfg80211_destroy_iface_wk);
|
||||
INIT_WORK(&rdev->sched_scan_stop_wk, cfg80211_sched_scan_stop_wk);
|
||||
INIT_WORK(&rdev->sched_scan_res_wk, cfg80211_sched_scan_results_wk);
|
||||
INIT_WORK(&rdev->propagate_radar_detect_wk,
|
||||
cfg80211_propagate_radar_detect_wk);
|
||||
INIT_WORK(&rdev->propagate_cac_done_wk, cfg80211_propagate_cac_done_wk);
|
||||
@ -1046,7 +1031,7 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev)
|
||||
{
|
||||
struct net_device *dev = wdev->netdev;
|
||||
struct cfg80211_sched_scan_request *sched_scan_req;
|
||||
struct cfg80211_sched_scan_request *pos, *tmp;
|
||||
|
||||
ASSERT_RTNL();
|
||||
ASSERT_WDEV_LOCK(wdev);
|
||||
@ -1057,9 +1042,11 @@ void __cfg80211_leave(struct cfg80211_registered_device *rdev,
|
||||
break;
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
case NL80211_IFTYPE_STATION:
|
||||
sched_scan_req = rtnl_dereference(rdev->sched_scan_req);
|
||||
if (sched_scan_req && dev == sched_scan_req->dev)
|
||||
__cfg80211_stop_sched_scan(rdev, false);
|
||||
list_for_each_entry_safe(pos, tmp, &rdev->sched_scan_req_list,
|
||||
list) {
|
||||
if (dev == pos->dev)
|
||||
cfg80211_stop_sched_scan_req(rdev, pos, false);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CFG80211_WEXT
|
||||
kfree(wdev->wext.ie);
|
||||
@ -1134,7 +1121,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
|
||||
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct cfg80211_registered_device *rdev;
|
||||
struct cfg80211_sched_scan_request *sched_scan_req;
|
||||
struct cfg80211_sched_scan_request *pos, *tmp;
|
||||
|
||||
if (!wdev)
|
||||
return NOTIFY_DONE;
|
||||
@ -1211,10 +1198,10 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
|
||||
___cfg80211_scan_done(rdev, false);
|
||||
}
|
||||
|
||||
sched_scan_req = rtnl_dereference(rdev->sched_scan_req);
|
||||
if (WARN_ON(sched_scan_req &&
|
||||
sched_scan_req->dev == wdev->netdev)) {
|
||||
__cfg80211_stop_sched_scan(rdev, false);
|
||||
list_for_each_entry_safe(pos, tmp,
|
||||
&rdev->sched_scan_req_list, list) {
|
||||
if (WARN_ON(pos && pos->dev == wdev->netdev))
|
||||
cfg80211_stop_sched_scan_req(rdev, pos, false);
|
||||
}
|
||||
|
||||
rdev->opencount--;
|
||||
|
@ -74,10 +74,9 @@ struct cfg80211_registered_device {
|
||||
u32 bss_entries;
|
||||
struct cfg80211_scan_request *scan_req; /* protected by RTNL */
|
||||
struct sk_buff *scan_msg;
|
||||
struct cfg80211_sched_scan_request __rcu *sched_scan_req;
|
||||
struct list_head sched_scan_req_list;
|
||||
unsigned long suspend_at;
|
||||
struct work_struct scan_done_wk;
|
||||
struct work_struct sched_scan_results_wk;
|
||||
|
||||
struct genl_info *cur_cmd_info;
|
||||
|
||||
@ -91,11 +90,9 @@ struct cfg80211_registered_device {
|
||||
|
||||
struct cfg80211_coalesce *coalesce;
|
||||
|
||||
spinlock_t destroy_list_lock;
|
||||
struct list_head destroy_list;
|
||||
struct work_struct destroy_work;
|
||||
|
||||
struct work_struct sched_scan_stop_wk;
|
||||
struct work_struct sched_scan_res_wk;
|
||||
|
||||
struct cfg80211_chan_def radar_chandef;
|
||||
struct work_struct propagate_radar_detect_wk;
|
||||
@ -227,13 +224,7 @@ struct cfg80211_event {
|
||||
|
||||
union {
|
||||
struct cfg80211_connect_resp_params cr;
|
||||
struct {
|
||||
const u8 *req_ie;
|
||||
const u8 *resp_ie;
|
||||
size_t req_ie_len;
|
||||
size_t resp_ie_len;
|
||||
struct cfg80211_bss *bss;
|
||||
} rm;
|
||||
struct cfg80211_roam_info rm;
|
||||
struct {
|
||||
const u8 *ie;
|
||||
size_t ie_len;
|
||||
@ -264,11 +255,6 @@ struct cfg80211_beacon_registration {
|
||||
u32 nlportid;
|
||||
};
|
||||
|
||||
struct cfg80211_iface_destroy {
|
||||
struct list_head list;
|
||||
u32 nlportid;
|
||||
};
|
||||
|
||||
struct cfg80211_cqm_config {
|
||||
u32 rssi_hyst;
|
||||
s32 last_rssi_event_value;
|
||||
@ -398,9 +384,7 @@ int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev, u16 reason,
|
||||
bool wextev);
|
||||
void __cfg80211_roamed(struct wireless_dev *wdev,
|
||||
struct cfg80211_bss *bss,
|
||||
const u8 *req_ie, size_t req_ie_len,
|
||||
const u8 *resp_ie, size_t resp_ie_len);
|
||||
struct cfg80211_roam_info *info);
|
||||
int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
|
||||
struct wireless_dev *wdev);
|
||||
void cfg80211_autodisconnect_wk(struct work_struct *work);
|
||||
@ -424,9 +408,16 @@ int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
|
||||
void __cfg80211_scan_done(struct work_struct *wk);
|
||||
void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
|
||||
bool send_message);
|
||||
void __cfg80211_sched_scan_results(struct work_struct *wk);
|
||||
void cfg80211_add_sched_scan_req(struct cfg80211_registered_device *rdev,
|
||||
struct cfg80211_sched_scan_request *req);
|
||||
int cfg80211_sched_scan_req_possible(struct cfg80211_registered_device *rdev,
|
||||
bool want_multi);
|
||||
void cfg80211_sched_scan_results_wk(struct work_struct *work);
|
||||
int cfg80211_stop_sched_scan_req(struct cfg80211_registered_device *rdev,
|
||||
struct cfg80211_sched_scan_request *req,
|
||||
bool driver_initiated);
|
||||
int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
|
||||
bool driver_initiated);
|
||||
u64 reqid, bool driver_initiated);
|
||||
void cfg80211_upload_connect_keys(struct wireless_dev *wdev);
|
||||
int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev, enum nl80211_iftype ntype,
|
||||
|
@ -419,6 +419,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = {
|
||||
.len = FILS_ERP_MAX_RRK_LEN },
|
||||
[NL80211_ATTR_FILS_CACHE_ID] = { .len = 2 },
|
||||
[NL80211_ATTR_PMK] = { .type = NLA_BINARY, .len = PMK_MAX_LEN },
|
||||
[NL80211_ATTR_SCHED_SCAN_MULTI] = { .type = NLA_FLAG },
|
||||
};
|
||||
|
||||
/* policy for the key attributes */
|
||||
@ -496,6 +497,7 @@ static const struct nla_policy
|
||||
nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
|
||||
[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY,
|
||||
.len = IEEE80211_MAX_SSID_LEN },
|
||||
[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID] = { .len = ETH_ALEN },
|
||||
[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
@ -1376,7 +1378,7 @@ static int nl80211_add_commands_unsplit(struct cfg80211_registered_device *rdev,
|
||||
CMD(tdls_mgmt, TDLS_MGMT);
|
||||
CMD(tdls_oper, TDLS_OPER);
|
||||
}
|
||||
if (rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
|
||||
if (rdev->wiphy.max_sched_scan_reqs)
|
||||
CMD(sched_scan_start, START_SCHED_SCAN);
|
||||
CMD(probe_client, PROBE_CLIENT);
|
||||
CMD(set_noack_map, SET_NOACK_MAP);
|
||||
@ -1815,6 +1817,11 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
|
||||
nla_put_flag(msg, NL80211_ATTR_WIPHY_SELF_MANAGED_REG))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (rdev->wiphy.max_sched_scan_reqs &&
|
||||
nla_put_u32(msg, NL80211_ATTR_SCHED_SCAN_MAX_REQS,
|
||||
rdev->wiphy.max_sched_scan_reqs))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (nla_put(msg, NL80211_ATTR_EXT_FEATURES,
|
||||
sizeof(rdev->wiphy.ext_features),
|
||||
rdev->wiphy.ext_features))
|
||||
@ -7030,8 +7037,15 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
NULL);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
|
||||
/* SSID and BSSID are mutually exclusive */
|
||||
if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] &&
|
||||
tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID])
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
/* add other standalone attributes here */
|
||||
if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID]) {
|
||||
if (tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID] ||
|
||||
tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID]) {
|
||||
n_match_sets++;
|
||||
continue;
|
||||
}
|
||||
@ -7202,7 +7216,7 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
nla_for_each_nested(attr,
|
||||
attrs[NL80211_ATTR_SCHED_SCAN_MATCH],
|
||||
tmp) {
|
||||
struct nlattr *ssid, *rssi;
|
||||
struct nlattr *ssid, *bssid, *rssi;
|
||||
|
||||
err = nla_parse_nested(tb,
|
||||
NL80211_SCHED_SCAN_MATCH_ATTR_MAX,
|
||||
@ -7211,7 +7225,8 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
if (err)
|
||||
goto out_free;
|
||||
ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID];
|
||||
if (ssid) {
|
||||
bssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_BSSID];
|
||||
if (ssid || bssid) {
|
||||
if (WARN_ON(i >= n_match_sets)) {
|
||||
/* this indicates a programming error,
|
||||
* the loop above should have verified
|
||||
@ -7221,14 +7236,25 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
|
||||
err = -EINVAL;
|
||||
goto out_free;
|
||||
if (ssid) {
|
||||
if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) {
|
||||
err = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
memcpy(request->match_sets[i].ssid.ssid,
|
||||
nla_data(ssid), nla_len(ssid));
|
||||
request->match_sets[i].ssid.ssid_len =
|
||||
nla_len(ssid);
|
||||
}
|
||||
memcpy(request->match_sets[i].ssid.ssid,
|
||||
nla_data(ssid), nla_len(ssid));
|
||||
request->match_sets[i].ssid.ssid_len =
|
||||
nla_len(ssid);
|
||||
if (bssid) {
|
||||
if (nla_len(bssid) != ETH_ALEN) {
|
||||
err = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
memcpy(request->match_sets[i].bssid,
|
||||
nla_data(bssid), ETH_ALEN);
|
||||
}
|
||||
|
||||
/* special attribute - old implementation w/a */
|
||||
request->match_sets[i].rssi_thold =
|
||||
default_match_rssi;
|
||||
@ -7336,14 +7362,16 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
|
||||
struct net_device *dev = info->user_ptr[1];
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct cfg80211_sched_scan_request *sched_scan_req;
|
||||
bool want_multi;
|
||||
int err;
|
||||
|
||||
if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
|
||||
!rdev->ops->sched_scan_start)
|
||||
if (!rdev->wiphy.max_sched_scan_reqs || !rdev->ops->sched_scan_start)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (rdev->sched_scan_req)
|
||||
return -EINPROGRESS;
|
||||
want_multi = info->attrs[NL80211_ATTR_SCHED_SCAN_MULTI];
|
||||
err = cfg80211_sched_scan_req_possible(rdev, want_multi);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
sched_scan_req = nl80211_parse_sched_scan(&rdev->wiphy, wdev,
|
||||
info->attrs,
|
||||
@ -7353,6 +7381,14 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
|
||||
if (err)
|
||||
goto out_err;
|
||||
|
||||
/* leave request id zero for legacy request
|
||||
* or if driver does not support multi-scheduled scan
|
||||
*/
|
||||
if (want_multi && rdev->wiphy.max_sched_scan_reqs > 1) {
|
||||
while (!sched_scan_req->reqid)
|
||||
sched_scan_req->reqid = rdev->wiphy.cookie_counter++;
|
||||
}
|
||||
|
||||
err = rdev_sched_scan_start(rdev, dev, sched_scan_req);
|
||||
if (err)
|
||||
goto out_free;
|
||||
@ -7363,7 +7399,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
|
||||
if (info->attrs[NL80211_ATTR_SOCKET_OWNER])
|
||||
sched_scan_req->owner_nlportid = info->snd_portid;
|
||||
|
||||
rcu_assign_pointer(rdev->sched_scan_req, sched_scan_req);
|
||||
cfg80211_add_sched_scan_req(rdev, sched_scan_req);
|
||||
|
||||
nl80211_send_sched_scan(sched_scan_req, NL80211_CMD_START_SCHED_SCAN);
|
||||
return 0;
|
||||
@ -7377,13 +7413,27 @@ out_err:
|
||||
static int nl80211_stop_sched_scan(struct sk_buff *skb,
|
||||
struct genl_info *info)
|
||||
{
|
||||
struct cfg80211_sched_scan_request *req;
|
||||
struct cfg80211_registered_device *rdev = info->user_ptr[0];
|
||||
u64 cookie;
|
||||
|
||||
if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
|
||||
!rdev->ops->sched_scan_stop)
|
||||
if (!rdev->wiphy.max_sched_scan_reqs || !rdev->ops->sched_scan_stop)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
return __cfg80211_stop_sched_scan(rdev, false);
|
||||
if (info->attrs[NL80211_ATTR_COOKIE]) {
|
||||
cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]);
|
||||
return __cfg80211_stop_sched_scan(rdev, cookie, false);
|
||||
}
|
||||
|
||||
req = list_first_or_null_rcu(&rdev->sched_scan_req_list,
|
||||
struct cfg80211_sched_scan_request,
|
||||
list);
|
||||
if (!req || req->reqid ||
|
||||
(req->owner_nlportid &&
|
||||
req->owner_nlportid != info->snd_portid))
|
||||
return -ENOENT;
|
||||
|
||||
return cfg80211_stop_sched_scan_req(rdev, req, false);
|
||||
}
|
||||
|
||||
static int nl80211_start_radar_detection(struct sk_buff *skb,
|
||||
@ -13596,14 +13646,14 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
|
||||
}
|
||||
|
||||
void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev, const u8 *bssid,
|
||||
const u8 *req_ie, size_t req_ie_len,
|
||||
const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp)
|
||||
struct net_device *netdev,
|
||||
struct cfg80211_roam_info *info, gfp_t gfp)
|
||||
{
|
||||
struct sk_buff *msg;
|
||||
void *hdr;
|
||||
const u8 *bssid = info->bss ? info->bss->bssid : info->bssid;
|
||||
|
||||
msg = nlmsg_new(100 + req_ie_len + resp_ie_len, gfp);
|
||||
msg = nlmsg_new(100 + info->req_ie_len + info->resp_ie_len, gfp);
|
||||
if (!msg)
|
||||
return;
|
||||
|
||||
@ -13616,10 +13666,12 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
|
||||
if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) ||
|
||||
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid) ||
|
||||
(req_ie &&
|
||||
nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) ||
|
||||
(resp_ie &&
|
||||
nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie)))
|
||||
(info->req_ie &&
|
||||
nla_put(msg, NL80211_ATTR_REQ_IE, info->req_ie_len,
|
||||
info->req_ie)) ||
|
||||
(info->resp_ie &&
|
||||
nla_put(msg, NL80211_ATTR_RESP_IE, info->resp_ie_len,
|
||||
info->resp_ie)))
|
||||
goto nla_put_failure;
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
@ -14883,26 +14935,26 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
|
||||
rcu_read_lock();
|
||||
|
||||
list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
|
||||
bool schedule_destroy_work = false;
|
||||
struct cfg80211_sched_scan_request *sched_scan_req =
|
||||
rcu_dereference(rdev->sched_scan_req);
|
||||
struct cfg80211_sched_scan_request *sched_scan_req;
|
||||
|
||||
if (sched_scan_req && notify->portid &&
|
||||
sched_scan_req->owner_nlportid == notify->portid) {
|
||||
sched_scan_req->owner_nlportid = 0;
|
||||
|
||||
if (rdev->ops->sched_scan_stop &&
|
||||
rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
|
||||
list_for_each_entry_rcu(sched_scan_req,
|
||||
&rdev->sched_scan_req_list,
|
||||
list) {
|
||||
if (sched_scan_req->owner_nlportid == notify->portid) {
|
||||
sched_scan_req->nl_owner_dead = true;
|
||||
schedule_work(&rdev->sched_scan_stop_wk);
|
||||
}
|
||||
}
|
||||
|
||||
list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) {
|
||||
cfg80211_mlme_unregister_socket(wdev, notify->portid);
|
||||
|
||||
if (wdev->owner_nlportid == notify->portid)
|
||||
schedule_destroy_work = true;
|
||||
else if (wdev->conn_owner_nlportid == notify->portid)
|
||||
if (wdev->owner_nlportid == notify->portid) {
|
||||
wdev->nl_owner_dead = true;
|
||||
schedule_work(&rdev->destroy_work);
|
||||
} else if (wdev->conn_owner_nlportid == notify->portid) {
|
||||
schedule_work(&wdev->disconnect_wk);
|
||||
}
|
||||
}
|
||||
|
||||
spin_lock_bh(&rdev->beacon_registrations_lock);
|
||||
@ -14915,19 +14967,6 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
|
||||
}
|
||||
}
|
||||
spin_unlock_bh(&rdev->beacon_registrations_lock);
|
||||
|
||||
if (schedule_destroy_work) {
|
||||
struct cfg80211_iface_destroy *destroy;
|
||||
|
||||
destroy = kzalloc(sizeof(*destroy), GFP_ATOMIC);
|
||||
if (destroy) {
|
||||
destroy->nlportid = notify->portid;
|
||||
spin_lock(&rdev->destroy_list_lock);
|
||||
list_add(&destroy->list, &rdev->destroy_list);
|
||||
spin_unlock(&rdev->destroy_list_lock);
|
||||
schedule_work(&rdev->destroy_work);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
|
@ -56,9 +56,8 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
|
||||
struct cfg80211_connect_resp_params *params,
|
||||
gfp_t gfp);
|
||||
void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev, const u8 *bssid,
|
||||
const u8 *req_ie, size_t req_ie_len,
|
||||
const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp);
|
||||
struct net_device *netdev,
|
||||
struct cfg80211_roam_info *info, gfp_t gfp);
|
||||
void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *netdev, u16 reason,
|
||||
const u8 *ie, size_t ie_len, bool from_ap);
|
||||
|
@ -813,18 +813,18 @@ rdev_sched_scan_start(struct cfg80211_registered_device *rdev,
|
||||
struct cfg80211_sched_scan_request *request)
|
||||
{
|
||||
int ret;
|
||||
trace_rdev_sched_scan_start(&rdev->wiphy, dev, request);
|
||||
trace_rdev_sched_scan_start(&rdev->wiphy, dev, request->reqid);
|
||||
ret = rdev->ops->sched_scan_start(&rdev->wiphy, dev, request);
|
||||
trace_rdev_return_int(&rdev->wiphy, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int rdev_sched_scan_stop(struct cfg80211_registered_device *rdev,
|
||||
struct net_device *dev)
|
||||
struct net_device *dev, u64 reqid)
|
||||
{
|
||||
int ret;
|
||||
trace_rdev_sched_scan_stop(&rdev->wiphy, dev);
|
||||
ret = rdev->ops->sched_scan_stop(&rdev->wiphy, dev);
|
||||
trace_rdev_sched_scan_stop(&rdev->wiphy, dev, reqid);
|
||||
ret = rdev->ops->sched_scan_stop(&rdev->wiphy, dev, reqid);
|
||||
trace_rdev_return_int(&rdev->wiphy, ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -3244,9 +3244,6 @@ void regulatory_propagate_dfs_state(struct wiphy *wiphy,
|
||||
if (WARN_ON(!cfg80211_chandef_valid(chandef)))
|
||||
return;
|
||||
|
||||
if (WARN_ON(!(chandef->chan->flags & IEEE80211_CHAN_RADAR)))
|
||||
return;
|
||||
|
||||
list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
|
||||
if (wiphy == &rdev->wiphy)
|
||||
continue;
|
||||
|
@ -300,92 +300,168 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request,
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_scan_done);
|
||||
|
||||
void __cfg80211_sched_scan_results(struct work_struct *wk)
|
||||
void cfg80211_add_sched_scan_req(struct cfg80211_registered_device *rdev,
|
||||
struct cfg80211_sched_scan_request *req)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev;
|
||||
struct cfg80211_sched_scan_request *request;
|
||||
ASSERT_RTNL();
|
||||
|
||||
rdev = container_of(wk, struct cfg80211_registered_device,
|
||||
sched_scan_results_wk);
|
||||
list_add_rcu(&req->list, &rdev->sched_scan_req_list);
|
||||
}
|
||||
|
||||
rtnl_lock();
|
||||
static void cfg80211_del_sched_scan_req(struct cfg80211_registered_device *rdev,
|
||||
struct cfg80211_sched_scan_request *req)
|
||||
{
|
||||
ASSERT_RTNL();
|
||||
|
||||
request = rtnl_dereference(rdev->sched_scan_req);
|
||||
list_del_rcu(&req->list);
|
||||
kfree_rcu(req, rcu_head);
|
||||
}
|
||||
|
||||
/* we don't have sched_scan_req anymore if the scan is stopping */
|
||||
if (request) {
|
||||
if (request->flags & NL80211_SCAN_FLAG_FLUSH) {
|
||||
/* flush entries from previous scans */
|
||||
spin_lock_bh(&rdev->bss_lock);
|
||||
__cfg80211_bss_expire(rdev, request->scan_start);
|
||||
spin_unlock_bh(&rdev->bss_lock);
|
||||
request->scan_start = jiffies;
|
||||
}
|
||||
nl80211_send_sched_scan(request, NL80211_CMD_SCHED_SCAN_RESULTS);
|
||||
static struct cfg80211_sched_scan_request *
|
||||
cfg80211_find_sched_scan_req(struct cfg80211_registered_device *rdev, u64 reqid)
|
||||
{
|
||||
struct cfg80211_sched_scan_request *pos;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
list_for_each_entry(pos, &rdev->sched_scan_req_list, list) {
|
||||
if (pos->reqid == reqid)
|
||||
return pos;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Determines if a scheduled scan request can be handled. When a legacy
|
||||
* scheduled scan is running no other scheduled scan is allowed regardless
|
||||
* whether the request is for legacy or multi-support scan. When a multi-support
|
||||
* scheduled scan is running a request for legacy scan is not allowed. In this
|
||||
* case a request for multi-support scan can be handled if resources are
|
||||
* available, ie. struct wiphy::max_sched_scan_reqs limit is not yet reached.
|
||||
*/
|
||||
int cfg80211_sched_scan_req_possible(struct cfg80211_registered_device *rdev,
|
||||
bool want_multi)
|
||||
{
|
||||
struct cfg80211_sched_scan_request *pos;
|
||||
int i = 0;
|
||||
|
||||
list_for_each_entry(pos, &rdev->sched_scan_req_list, list) {
|
||||
/* request id zero means legacy in progress */
|
||||
if (!i && !pos->reqid)
|
||||
return -EINPROGRESS;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i) {
|
||||
/* no legacy allowed when multi request(s) are active */
|
||||
if (!want_multi)
|
||||
return -EINPROGRESS;
|
||||
|
||||
/* resource limit reached */
|
||||
if (i == rdev->wiphy.max_sched_scan_reqs)
|
||||
return -ENOSPC;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cfg80211_sched_scan_results_wk(struct work_struct *work)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev;
|
||||
struct cfg80211_sched_scan_request *req, *tmp;
|
||||
|
||||
rdev = container_of(work, struct cfg80211_registered_device,
|
||||
sched_scan_res_wk);
|
||||
|
||||
rtnl_lock();
|
||||
list_for_each_entry_safe(req, tmp, &rdev->sched_scan_req_list, list) {
|
||||
if (req->report_results) {
|
||||
req->report_results = false;
|
||||
if (req->flags & NL80211_SCAN_FLAG_FLUSH) {
|
||||
/* flush entries from previous scans */
|
||||
spin_lock_bh(&rdev->bss_lock);
|
||||
__cfg80211_bss_expire(rdev, req->scan_start);
|
||||
spin_unlock_bh(&rdev->bss_lock);
|
||||
req->scan_start = jiffies;
|
||||
}
|
||||
nl80211_send_sched_scan(req,
|
||||
NL80211_CMD_SCHED_SCAN_RESULTS);
|
||||
}
|
||||
}
|
||||
rtnl_unlock();
|
||||
}
|
||||
|
||||
void cfg80211_sched_scan_results(struct wiphy *wiphy)
|
||||
void cfg80211_sched_scan_results(struct wiphy *wiphy, u64 reqid)
|
||||
{
|
||||
trace_cfg80211_sched_scan_results(wiphy);
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
||||
struct cfg80211_sched_scan_request *request;
|
||||
|
||||
trace_cfg80211_sched_scan_results(wiphy, reqid);
|
||||
/* ignore if we're not scanning */
|
||||
|
||||
if (rcu_access_pointer(wiphy_to_rdev(wiphy)->sched_scan_req))
|
||||
queue_work(cfg80211_wq,
|
||||
&wiphy_to_rdev(wiphy)->sched_scan_results_wk);
|
||||
rtnl_lock();
|
||||
request = cfg80211_find_sched_scan_req(rdev, reqid);
|
||||
if (request) {
|
||||
request->report_results = true;
|
||||
queue_work(cfg80211_wq, &rdev->sched_scan_res_wk);
|
||||
}
|
||||
rtnl_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_sched_scan_results);
|
||||
|
||||
void cfg80211_sched_scan_stopped_rtnl(struct wiphy *wiphy)
|
||||
void cfg80211_sched_scan_stopped_rtnl(struct wiphy *wiphy, u64 reqid)
|
||||
{
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
trace_cfg80211_sched_scan_stopped(wiphy);
|
||||
trace_cfg80211_sched_scan_stopped(wiphy, reqid);
|
||||
|
||||
__cfg80211_stop_sched_scan(rdev, true);
|
||||
__cfg80211_stop_sched_scan(rdev, reqid, true);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_sched_scan_stopped_rtnl);
|
||||
|
||||
void cfg80211_sched_scan_stopped(struct wiphy *wiphy)
|
||||
void cfg80211_sched_scan_stopped(struct wiphy *wiphy, u64 reqid)
|
||||
{
|
||||
rtnl_lock();
|
||||
cfg80211_sched_scan_stopped_rtnl(wiphy);
|
||||
cfg80211_sched_scan_stopped_rtnl(wiphy, reqid);
|
||||
rtnl_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_sched_scan_stopped);
|
||||
|
||||
int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
|
||||
bool driver_initiated)
|
||||
int cfg80211_stop_sched_scan_req(struct cfg80211_registered_device *rdev,
|
||||
struct cfg80211_sched_scan_request *req,
|
||||
bool driver_initiated)
|
||||
{
|
||||
struct cfg80211_sched_scan_request *sched_scan_req;
|
||||
struct net_device *dev;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
if (!rdev->sched_scan_req)
|
||||
return -ENOENT;
|
||||
|
||||
sched_scan_req = rtnl_dereference(rdev->sched_scan_req);
|
||||
dev = sched_scan_req->dev;
|
||||
|
||||
if (!driver_initiated) {
|
||||
int err = rdev_sched_scan_stop(rdev, dev);
|
||||
int err = rdev_sched_scan_stop(rdev, req->dev, req->reqid);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
nl80211_send_sched_scan(sched_scan_req, NL80211_CMD_SCHED_SCAN_STOPPED);
|
||||
nl80211_send_sched_scan(req, NL80211_CMD_SCHED_SCAN_STOPPED);
|
||||
|
||||
RCU_INIT_POINTER(rdev->sched_scan_req, NULL);
|
||||
kfree_rcu(sched_scan_req, rcu_head);
|
||||
cfg80211_del_sched_scan_req(rdev, req);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
|
||||
u64 reqid, bool driver_initiated)
|
||||
{
|
||||
struct cfg80211_sched_scan_request *sched_scan_req;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
sched_scan_req = cfg80211_find_sched_scan_req(rdev, reqid);
|
||||
if (!sched_scan_req)
|
||||
return -ENOENT;
|
||||
|
||||
return cfg80211_stop_sched_scan_req(rdev, sched_scan_req,
|
||||
driver_initiated);
|
||||
}
|
||||
|
||||
void cfg80211_bss_age(struct cfg80211_registered_device *rdev,
|
||||
unsigned long age_secs)
|
||||
{
|
||||
|
@ -5,6 +5,7 @@
|
||||
*
|
||||
* Copyright 2009 Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright (C) 2009 Intel Corporation. All rights reserved.
|
||||
* Copyright 2017 Intel Deutschland GmbH
|
||||
*/
|
||||
|
||||
#include <linux/etherdevice.h>
|
||||
@ -870,9 +871,7 @@ EXPORT_SYMBOL(cfg80211_connect_done);
|
||||
|
||||
/* Consumes bss object one way or another */
|
||||
void __cfg80211_roamed(struct wireless_dev *wdev,
|
||||
struct cfg80211_bss *bss,
|
||||
const u8 *req_ie, size_t req_ie_len,
|
||||
const u8 *resp_ie, size_t resp_ie_len)
|
||||
struct cfg80211_roam_info *info)
|
||||
{
|
||||
#ifdef CONFIG_CFG80211_WEXT
|
||||
union iwreq_data wrqu;
|
||||
@ -890,97 +889,84 @@ void __cfg80211_roamed(struct wireless_dev *wdev,
|
||||
cfg80211_put_bss(wdev->wiphy, &wdev->current_bss->pub);
|
||||
wdev->current_bss = NULL;
|
||||
|
||||
cfg80211_hold_bss(bss_from_pub(bss));
|
||||
wdev->current_bss = bss_from_pub(bss);
|
||||
if (WARN_ON(!info->bss))
|
||||
return;
|
||||
|
||||
cfg80211_hold_bss(bss_from_pub(info->bss));
|
||||
wdev->current_bss = bss_from_pub(info->bss);
|
||||
|
||||
nl80211_send_roamed(wiphy_to_rdev(wdev->wiphy),
|
||||
wdev->netdev, bss->bssid,
|
||||
req_ie, req_ie_len, resp_ie, resp_ie_len,
|
||||
GFP_KERNEL);
|
||||
wdev->netdev, info, GFP_KERNEL);
|
||||
|
||||
#ifdef CONFIG_CFG80211_WEXT
|
||||
if (req_ie) {
|
||||
if (info->req_ie) {
|
||||
memset(&wrqu, 0, sizeof(wrqu));
|
||||
wrqu.data.length = req_ie_len;
|
||||
wrqu.data.length = info->req_ie_len;
|
||||
wireless_send_event(wdev->netdev, IWEVASSOCREQIE,
|
||||
&wrqu, req_ie);
|
||||
&wrqu, info->req_ie);
|
||||
}
|
||||
|
||||
if (resp_ie) {
|
||||
if (info->resp_ie) {
|
||||
memset(&wrqu, 0, sizeof(wrqu));
|
||||
wrqu.data.length = resp_ie_len;
|
||||
wrqu.data.length = info->resp_ie_len;
|
||||
wireless_send_event(wdev->netdev, IWEVASSOCRESPIE,
|
||||
&wrqu, resp_ie);
|
||||
&wrqu, info->resp_ie);
|
||||
}
|
||||
|
||||
memset(&wrqu, 0, sizeof(wrqu));
|
||||
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
|
||||
memcpy(wrqu.ap_addr.sa_data, bss->bssid, ETH_ALEN);
|
||||
memcpy(wdev->wext.prev_bssid, bss->bssid, ETH_ALEN);
|
||||
memcpy(wrqu.ap_addr.sa_data, info->bss->bssid, ETH_ALEN);
|
||||
memcpy(wdev->wext.prev_bssid, info->bss->bssid, ETH_ALEN);
|
||||
wdev->wext.prev_bssid_valid = true;
|
||||
wireless_send_event(wdev->netdev, SIOCGIWAP, &wrqu, NULL);
|
||||
#endif
|
||||
|
||||
return;
|
||||
out:
|
||||
cfg80211_put_bss(wdev->wiphy, bss);
|
||||
cfg80211_put_bss(wdev->wiphy, info->bss);
|
||||
}
|
||||
|
||||
void cfg80211_roamed(struct net_device *dev,
|
||||
struct ieee80211_channel *channel,
|
||||
const u8 *bssid,
|
||||
const u8 *req_ie, size_t req_ie_len,
|
||||
const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct cfg80211_bss *bss;
|
||||
|
||||
bss = cfg80211_get_bss(wdev->wiphy, channel, bssid, wdev->ssid,
|
||||
wdev->ssid_len,
|
||||
wdev->conn_bss_type, IEEE80211_PRIVACY_ANY);
|
||||
if (WARN_ON(!bss))
|
||||
return;
|
||||
|
||||
cfg80211_roamed_bss(dev, bss, req_ie, req_ie_len, resp_ie,
|
||||
resp_ie_len, gfp);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_roamed);
|
||||
|
||||
/* Consumes bss object one way or another */
|
||||
void cfg80211_roamed_bss(struct net_device *dev,
|
||||
struct cfg80211_bss *bss, const u8 *req_ie,
|
||||
size_t req_ie_len, const u8 *resp_ie,
|
||||
size_t resp_ie_len, gfp_t gfp)
|
||||
/* Consumes info->bss object one way or another */
|
||||
void cfg80211_roamed(struct net_device *dev, struct cfg80211_roam_info *info,
|
||||
gfp_t gfp)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
|
||||
struct cfg80211_event *ev;
|
||||
unsigned long flags;
|
||||
|
||||
if (WARN_ON(!bss))
|
||||
if (!info->bss) {
|
||||
info->bss = cfg80211_get_bss(wdev->wiphy, info->channel,
|
||||
info->bssid, wdev->ssid,
|
||||
wdev->ssid_len,
|
||||
wdev->conn_bss_type,
|
||||
IEEE80211_PRIVACY_ANY);
|
||||
}
|
||||
|
||||
if (WARN_ON(!info->bss))
|
||||
return;
|
||||
|
||||
ev = kzalloc(sizeof(*ev) + req_ie_len + resp_ie_len, gfp);
|
||||
ev = kzalloc(sizeof(*ev) + info->req_ie_len + info->resp_ie_len, gfp);
|
||||
if (!ev) {
|
||||
cfg80211_put_bss(wdev->wiphy, bss);
|
||||
cfg80211_put_bss(wdev->wiphy, info->bss);
|
||||
return;
|
||||
}
|
||||
|
||||
ev->type = EVENT_ROAMED;
|
||||
ev->rm.req_ie = ((u8 *)ev) + sizeof(*ev);
|
||||
ev->rm.req_ie_len = req_ie_len;
|
||||
memcpy((void *)ev->rm.req_ie, req_ie, req_ie_len);
|
||||
ev->rm.resp_ie = ((u8 *)ev) + sizeof(*ev) + req_ie_len;
|
||||
ev->rm.resp_ie_len = resp_ie_len;
|
||||
memcpy((void *)ev->rm.resp_ie, resp_ie, resp_ie_len);
|
||||
ev->rm.bss = bss;
|
||||
ev->rm.req_ie_len = info->req_ie_len;
|
||||
memcpy((void *)ev->rm.req_ie, info->req_ie, info->req_ie_len);
|
||||
ev->rm.resp_ie = ((u8 *)ev) + sizeof(*ev) + info->req_ie_len;
|
||||
ev->rm.resp_ie_len = info->resp_ie_len;
|
||||
memcpy((void *)ev->rm.resp_ie, info->resp_ie, info->resp_ie_len);
|
||||
ev->rm.bss = info->bss;
|
||||
|
||||
spin_lock_irqsave(&wdev->event_lock, flags);
|
||||
list_add_tail(&ev->list, &wdev->event_list);
|
||||
spin_unlock_irqrestore(&wdev->event_lock, flags);
|
||||
queue_work(cfg80211_wq, &rdev->event_work);
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_roamed_bss);
|
||||
EXPORT_SYMBOL(cfg80211_roamed);
|
||||
|
||||
void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
|
||||
size_t ie_len, u16 reason, bool from_ap)
|
||||
|
@ -576,11 +576,6 @@ DEFINE_EVENT(wiphy_netdev_evt, rdev_stop_ap,
|
||||
TP_ARGS(wiphy, netdev)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(wiphy_netdev_evt, rdev_sched_scan_stop,
|
||||
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
|
||||
TP_ARGS(wiphy, netdev)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(wiphy_netdev_evt, rdev_set_rekey_data,
|
||||
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev),
|
||||
TP_ARGS(wiphy, netdev)
|
||||
@ -1610,20 +1605,31 @@ DEFINE_EVENT(tx_rx_evt, rdev_set_antenna,
|
||||
TP_ARGS(wiphy, rx, tx)
|
||||
);
|
||||
|
||||
TRACE_EVENT(rdev_sched_scan_start,
|
||||
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
|
||||
struct cfg80211_sched_scan_request *request),
|
||||
TP_ARGS(wiphy, netdev, request),
|
||||
DECLARE_EVENT_CLASS(wiphy_netdev_id_evt,
|
||||
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u64 id),
|
||||
TP_ARGS(wiphy, netdev, id),
|
||||
TP_STRUCT__entry(
|
||||
WIPHY_ENTRY
|
||||
NETDEV_ENTRY
|
||||
__field(u64, id)
|
||||
),
|
||||
TP_fast_assign(
|
||||
WIPHY_ASSIGN;
|
||||
NETDEV_ASSIGN;
|
||||
__entry->id = id;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT,
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG)
|
||||
TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", id: %llu",
|
||||
WIPHY_PR_ARG, NETDEV_PR_ARG, __entry->id)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(wiphy_netdev_id_evt, rdev_sched_scan_start,
|
||||
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u64 id),
|
||||
TP_ARGS(wiphy, netdev, id)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(wiphy_netdev_id_evt, rdev_sched_scan_stop,
|
||||
TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, u64 id),
|
||||
TP_ARGS(wiphy, netdev, id)
|
||||
);
|
||||
|
||||
TRACE_EVENT(rdev_tdls_mgmt,
|
||||
@ -2814,14 +2820,28 @@ TRACE_EVENT(cfg80211_scan_done,
|
||||
MAC_PR_ARG(tsf_bssid))
|
||||
);
|
||||
|
||||
DEFINE_EVENT(wiphy_only_evt, cfg80211_sched_scan_results,
|
||||
TP_PROTO(struct wiphy *wiphy),
|
||||
TP_ARGS(wiphy)
|
||||
DECLARE_EVENT_CLASS(wiphy_id_evt,
|
||||
TP_PROTO(struct wiphy *wiphy, u64 id),
|
||||
TP_ARGS(wiphy, id),
|
||||
TP_STRUCT__entry(
|
||||
WIPHY_ENTRY
|
||||
__field(u64, id)
|
||||
),
|
||||
TP_fast_assign(
|
||||
WIPHY_ASSIGN;
|
||||
__entry->id = id;
|
||||
),
|
||||
TP_printk(WIPHY_PR_FMT ", id: %llu", WIPHY_PR_ARG, __entry->id)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(wiphy_only_evt, cfg80211_sched_scan_stopped,
|
||||
TP_PROTO(struct wiphy *wiphy),
|
||||
TP_ARGS(wiphy)
|
||||
DEFINE_EVENT(wiphy_id_evt, cfg80211_sched_scan_stopped,
|
||||
TP_PROTO(struct wiphy *wiphy, u64 id),
|
||||
TP_ARGS(wiphy, id)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(wiphy_id_evt, cfg80211_sched_scan_results,
|
||||
TP_PROTO(struct wiphy *wiphy, u64 id),
|
||||
TP_ARGS(wiphy, id)
|
||||
);
|
||||
|
||||
TRACE_EVENT(cfg80211_get_bss,
|
||||
|
@ -946,9 +946,7 @@ void cfg80211_process_wdev_events(struct wireless_dev *wdev)
|
||||
ev->cr.status == WLAN_STATUS_SUCCESS);
|
||||
break;
|
||||
case EVENT_ROAMED:
|
||||
__cfg80211_roamed(wdev, ev->rm.bss, ev->rm.req_ie,
|
||||
ev->rm.req_ie_len, ev->rm.resp_ie,
|
||||
ev->rm.resp_ie_len);
|
||||
__cfg80211_roamed(wdev, &ev->rm);
|
||||
break;
|
||||
case EVENT_DISCONNECTED:
|
||||
__cfg80211_disconnected(wdev->netdev,
|
||||
|
Loading…
Reference in New Issue
Block a user