mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 03:01:39 -04:00
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts: net/wireless/nl80211.c
This commit is contained in:
commit
57ed5cd695
119 changed files with 3772 additions and 3098 deletions
|
|
@ -2827,7 +2827,8 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
|
|||
!rcu_access_pointer(sdata->bss->beacon))
|
||||
need_offchan = true;
|
||||
if (!ieee80211_is_action(mgmt->frame_control) ||
|
||||
mgmt->u.action.category == WLAN_CATEGORY_PUBLIC)
|
||||
mgmt->u.action.category == WLAN_CATEGORY_PUBLIC ||
|
||||
mgmt->u.action.category == WLAN_CATEGORY_SELF_PROTECTED)
|
||||
break;
|
||||
rcu_read_lock();
|
||||
sta = sta_info_get(sdata, mgmt->da);
|
||||
|
|
@ -2930,19 +2931,8 @@ static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
|
|||
u16 frame_type, bool reg)
|
||||
{
|
||||
struct ieee80211_local *local = wiphy_priv(wiphy);
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
|
||||
|
||||
switch (frame_type) {
|
||||
case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH:
|
||||
if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
|
||||
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
|
||||
|
||||
if (reg)
|
||||
ifibss->auth_frame_registrations++;
|
||||
else
|
||||
ifibss->auth_frame_registrations--;
|
||||
}
|
||||
break;
|
||||
case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ:
|
||||
if (reg)
|
||||
local->probe_req_reg++;
|
||||
|
|
|
|||
|
|
@ -281,13 +281,14 @@ void ieee80211_ba_session_work(struct work_struct *work)
|
|||
sta, tid, WLAN_BACK_RECIPIENT,
|
||||
WLAN_REASON_UNSPECIFIED, true);
|
||||
|
||||
spin_lock_bh(&sta->lock);
|
||||
|
||||
tid_tx = sta->ampdu_mlme.tid_start_tx[tid];
|
||||
if (tid_tx) {
|
||||
/*
|
||||
* Assign it over to the normal tid_tx array
|
||||
* where it "goes live".
|
||||
*/
|
||||
spin_lock_bh(&sta->lock);
|
||||
|
||||
sta->ampdu_mlme.tid_start_tx[tid] = NULL;
|
||||
/* could there be a race? */
|
||||
|
|
@ -300,6 +301,7 @@ void ieee80211_ba_session_work(struct work_struct *work)
|
|||
ieee80211_tx_ba_session_handle_start(sta, tid);
|
||||
continue;
|
||||
}
|
||||
spin_unlock_bh(&sta->lock);
|
||||
|
||||
tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
|
||||
if (tid_tx && test_and_clear_bit(HT_AGG_STATE_WANT_STOP,
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
|
||||
|
||||
cfg80211_chandef_create(&chandef, chan, ifibss->channel_type);
|
||||
chandef = ifibss->chandef;
|
||||
if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) {
|
||||
chandef.width = NL80211_CHAN_WIDTH_20;
|
||||
chandef.center_freq1 = chan->center_freq;
|
||||
|
|
@ -176,6 +176,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
/* add HT capability and information IEs */
|
||||
if (chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
|
||||
chandef.width != NL80211_CHAN_WIDTH_5 &&
|
||||
chandef.width != NL80211_CHAN_WIDTH_10 &&
|
||||
sband->ht_cap.ht_supported) {
|
||||
pos = ieee80211_ie_build_ht_cap(pos, &sband->ht_cap,
|
||||
sband->ht_cap.cap);
|
||||
|
|
@ -298,8 +300,7 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
|
|||
tsf, false);
|
||||
}
|
||||
|
||||
static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta,
|
||||
bool auth)
|
||||
static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta)
|
||||
__acquires(RCU)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = sta->sdata;
|
||||
|
|
@ -321,20 +322,12 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta,
|
|||
/* If it fails, maybe we raced another insertion? */
|
||||
if (sta_info_insert_rcu(sta))
|
||||
return sta_info_get(sdata, addr);
|
||||
if (auth && !sdata->u.ibss.auth_frame_registrations) {
|
||||
ibss_dbg(sdata,
|
||||
"TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n",
|
||||
sdata->vif.addr, addr, sdata->u.ibss.bssid);
|
||||
ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, 0, NULL, 0,
|
||||
addr, sdata->u.ibss.bssid, NULL, 0, 0, 0);
|
||||
}
|
||||
return sta;
|
||||
}
|
||||
|
||||
static struct sta_info *
|
||||
ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
|
||||
const u8 *bssid, const u8 *addr,
|
||||
u32 supp_rates, bool auth)
|
||||
ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, const u8 *bssid,
|
||||
const u8 *addr, u32 supp_rates)
|
||||
__acquires(RCU)
|
||||
{
|
||||
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
|
||||
|
|
@ -385,7 +378,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
|
|||
sta->sta.supp_rates[band] = supp_rates |
|
||||
ieee80211_mandatory_rates(sband);
|
||||
|
||||
return ieee80211_ibss_finish_sta(sta, auth);
|
||||
return ieee80211_ibss_finish_sta(sta);
|
||||
}
|
||||
|
||||
static void ieee80211_rx_mgmt_deauth_ibss(struct ieee80211_sub_if_data *sdata,
|
||||
|
|
@ -407,8 +400,6 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
|
|||
size_t len)
|
||||
{
|
||||
u16 auth_alg, auth_transaction;
|
||||
struct sta_info *sta;
|
||||
u8 deauth_frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
|
||||
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
|
|
@ -425,22 +416,6 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
|
|||
if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)
|
||||
return;
|
||||
|
||||
sta_info_destroy_addr(sdata, mgmt->sa);
|
||||
sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false);
|
||||
rcu_read_unlock();
|
||||
|
||||
/*
|
||||
* if we have any problem in allocating the new station, we reply with a
|
||||
* DEAUTH frame to tell the other end that we had a problem
|
||||
*/
|
||||
if (!sta) {
|
||||
ieee80211_send_deauth_disassoc(sdata, sdata->u.ibss.bssid,
|
||||
IEEE80211_STYPE_DEAUTH,
|
||||
WLAN_REASON_UNSPECIFIED, true,
|
||||
deauth_frame_buf);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* IEEE 802.11 standard does not require authentication in IBSS
|
||||
* networks and most implementations do not seem to use it.
|
||||
|
|
@ -506,7 +481,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
|
|||
} else {
|
||||
rcu_read_unlock();
|
||||
sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid,
|
||||
mgmt->sa, supp_rates, true);
|
||||
mgmt->sa, supp_rates);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -514,7 +489,9 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
|
|||
set_sta_flag(sta, WLAN_STA_WME);
|
||||
|
||||
if (sta && elems->ht_operation && elems->ht_cap_elem &&
|
||||
sdata->u.ibss.channel_type != NL80211_CHAN_NO_HT) {
|
||||
sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
|
||||
sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_5 &&
|
||||
sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_10) {
|
||||
/* we both use HT */
|
||||
struct ieee80211_ht_cap htcap_ie;
|
||||
struct cfg80211_chan_def chandef;
|
||||
|
|
@ -529,8 +506,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
|
|||
* fall back to HT20 if we don't use or use
|
||||
* the other extension channel
|
||||
*/
|
||||
if (cfg80211_get_chandef_type(&chandef) !=
|
||||
sdata->u.ibss.channel_type)
|
||||
if (chandef.center_freq1 !=
|
||||
sdata->u.ibss.chandef.center_freq1)
|
||||
htcap_ie.cap_info &=
|
||||
cpu_to_le16(~IEEE80211_HT_CAP_SUP_WIDTH_20_40);
|
||||
|
||||
|
|
@ -569,7 +546,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
/* different channel */
|
||||
if (sdata->u.ibss.fixed_channel &&
|
||||
sdata->u.ibss.channel != cbss->channel)
|
||||
sdata->u.ibss.chandef.chan != cbss->channel)
|
||||
goto put_bss;
|
||||
|
||||
/* different SSID */
|
||||
|
|
@ -610,7 +587,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
|
|||
ieee80211_sta_join_ibss(sdata, bss);
|
||||
supp_rates = ieee80211_sta_get_rates(local, elems, band, NULL);
|
||||
ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa,
|
||||
supp_rates, true);
|
||||
supp_rates);
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
|
|
@ -759,7 +736,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
|
|||
sdata->drop_unencrypted = 0;
|
||||
|
||||
__ieee80211_sta_join_ibss(sdata, bssid, sdata->vif.bss_conf.beacon_int,
|
||||
ifibss->channel, ifibss->basic_rates,
|
||||
ifibss->chandef.chan, ifibss->basic_rates,
|
||||
capability, 0, true);
|
||||
}
|
||||
|
||||
|
|
@ -791,7 +768,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
|
|||
if (ifibss->fixed_bssid)
|
||||
bssid = ifibss->bssid;
|
||||
if (ifibss->fixed_channel)
|
||||
chan = ifibss->channel;
|
||||
chan = ifibss->chandef.chan;
|
||||
if (!is_zero_ether_addr(ifibss->bssid))
|
||||
bssid = ifibss->bssid;
|
||||
cbss = cfg80211_get_bss(local->hw.wiphy, chan, bssid,
|
||||
|
|
@ -982,7 +959,7 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)
|
|||
list_del(&sta->list);
|
||||
spin_unlock_bh(&ifibss->incomplete_lock);
|
||||
|
||||
ieee80211_ibss_finish_sta(sta, true);
|
||||
ieee80211_ibss_finish_sta(sta);
|
||||
rcu_read_unlock();
|
||||
spin_lock_bh(&ifibss->incomplete_lock);
|
||||
}
|
||||
|
|
@ -1058,9 +1035,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
sdata->vif.bss_conf.beacon_int = params->beacon_interval;
|
||||
|
||||
sdata->u.ibss.channel = params->chandef.chan;
|
||||
sdata->u.ibss.channel_type =
|
||||
cfg80211_get_chandef_type(¶ms->chandef);
|
||||
sdata->u.ibss.chandef = params->chandef;
|
||||
sdata->u.ibss.fixed_channel = params->channel_fixed;
|
||||
|
||||
if (params->ie) {
|
||||
|
|
@ -1119,7 +1094,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
|
|||
if (ifibss->privacy)
|
||||
capability |= WLAN_CAPABILITY_PRIVACY;
|
||||
|
||||
cbss = cfg80211_get_bss(local->hw.wiphy, ifibss->channel,
|
||||
cbss = cfg80211_get_bss(local->hw.wiphy, ifibss->chandef.chan,
|
||||
ifibss->bssid, ifibss->ssid,
|
||||
ifibss->ssid_len, WLAN_CAPABILITY_IBSS |
|
||||
WLAN_CAPABILITY_PRIVACY,
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@ struct ieee80211_bss {
|
|||
#define IEEE80211_MAX_SUPP_RATES 32
|
||||
u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
|
||||
size_t supp_rates_len;
|
||||
struct ieee80211_rate *beacon_rate;
|
||||
|
||||
/*
|
||||
* During association, we save an ERP value from a probe response so
|
||||
|
|
@ -497,14 +498,12 @@ struct ieee80211_if_ibss {
|
|||
bool privacy;
|
||||
|
||||
bool control_port;
|
||||
unsigned int auth_frame_registrations;
|
||||
|
||||
u8 bssid[ETH_ALEN] __aligned(2);
|
||||
u8 ssid[IEEE80211_MAX_SSID_LEN];
|
||||
u8 ssid_len, ie_len;
|
||||
u8 *ie;
|
||||
struct ieee80211_channel *channel;
|
||||
enum nl80211_channel_type channel_type;
|
||||
struct cfg80211_chan_def chandef;
|
||||
|
||||
unsigned long ibss_join_req;
|
||||
/* probe response/beacon for IBSS */
|
||||
|
|
@ -543,6 +542,7 @@ struct ieee80211_if_mesh {
|
|||
struct timer_list mesh_path_root_timer;
|
||||
|
||||
unsigned long wrkq_flags;
|
||||
unsigned long mbss_changed;
|
||||
|
||||
u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN];
|
||||
size_t mesh_id_len;
|
||||
|
|
|
|||
|
|
@ -161,11 +161,8 @@ void mesh_sta_cleanup(struct sta_info *sta)
|
|||
del_timer_sync(&sta->plink_timer);
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
sdata_lock(sdata);
|
||||
if (changed)
|
||||
ieee80211_mbss_info_change_notify(sdata, changed);
|
||||
sdata_unlock(sdata);
|
||||
}
|
||||
}
|
||||
|
||||
int mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
|
||||
|
|
@ -419,7 +416,9 @@ int mesh_add_ht_cap_ie(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
sband = local->hw.wiphy->bands[band];
|
||||
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_20_NOHT ||
|
||||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_5 ||
|
||||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_10)
|
||||
return 0;
|
||||
|
||||
if (skb_tailroom(skb) < 2 + sizeof(struct ieee80211_ht_cap))
|
||||
|
|
@ -719,14 +718,18 @@ ieee80211_mesh_rebuild_beacon(struct ieee80211_sub_if_data *sdata)
|
|||
void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata,
|
||||
u32 changed)
|
||||
{
|
||||
if (sdata->vif.bss_conf.enable_beacon &&
|
||||
(changed & (BSS_CHANGED_BEACON |
|
||||
BSS_CHANGED_HT |
|
||||
BSS_CHANGED_BASIC_RATES |
|
||||
BSS_CHANGED_BEACON_INT)))
|
||||
if (ieee80211_mesh_rebuild_beacon(sdata))
|
||||
return;
|
||||
ieee80211_bss_info_change_notify(sdata, changed);
|
||||
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
||||
unsigned long bits = changed;
|
||||
u32 bit;
|
||||
|
||||
if (!bits)
|
||||
return;
|
||||
|
||||
/* if we race with running work, worst case this work becomes a noop */
|
||||
for_each_set_bit(bit, &bits, sizeof(changed) * BITS_PER_BYTE)
|
||||
set_bit(bit, &ifmsh->mbss_changed);
|
||||
set_bit(MESH_WORK_MBSS_CHANGED, &ifmsh->wrkq_flags);
|
||||
ieee80211_queue_work(&sdata->local->hw, &sdata->work);
|
||||
}
|
||||
|
||||
int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
|
||||
|
|
@ -799,6 +802,10 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
|
|||
del_timer_sync(&sdata->u.mesh.mesh_path_root_timer);
|
||||
del_timer_sync(&sdata->u.mesh.mesh_path_timer);
|
||||
|
||||
/* clear any mesh work (for next join) we may have accrued */
|
||||
ifmsh->wrkq_flags = 0;
|
||||
ifmsh->mbss_changed = 0;
|
||||
|
||||
local->fif_other_bss--;
|
||||
atomic_dec(&local->iff_allmultis);
|
||||
ieee80211_configure_filter(local);
|
||||
|
|
@ -965,6 +972,28 @@ out:
|
|||
sdata_unlock(sdata);
|
||||
}
|
||||
|
||||
static void mesh_bss_info_changed(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
||||
u32 bit, changed = 0;
|
||||
|
||||
for_each_set_bit(bit, &ifmsh->mbss_changed,
|
||||
sizeof(changed) * BITS_PER_BYTE) {
|
||||
clear_bit(bit, &ifmsh->mbss_changed);
|
||||
changed |= BIT(bit);
|
||||
}
|
||||
|
||||
if (sdata->vif.bss_conf.enable_beacon &&
|
||||
(changed & (BSS_CHANGED_BEACON |
|
||||
BSS_CHANGED_HT |
|
||||
BSS_CHANGED_BASIC_RATES |
|
||||
BSS_CHANGED_BEACON_INT)))
|
||||
if (ieee80211_mesh_rebuild_beacon(sdata))
|
||||
return;
|
||||
|
||||
ieee80211_bss_info_change_notify(sdata, changed);
|
||||
}
|
||||
|
||||
void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
||||
|
|
@ -995,6 +1024,8 @@ void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata)
|
|||
if (test_and_clear_bit(MESH_WORK_DRIFT_ADJUST, &ifmsh->wrkq_flags))
|
||||
mesh_sync_adjust_tbtt(sdata);
|
||||
|
||||
if (test_and_clear_bit(MESH_WORK_MBSS_CHANGED, &ifmsh->wrkq_flags))
|
||||
mesh_bss_info_changed(sdata);
|
||||
out:
|
||||
sdata_unlock(sdata);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ enum mesh_path_flags {
|
|||
* @MESH_WORK_ROOT: the mesh root station needs to send a frame
|
||||
* @MESH_WORK_DRIFT_ADJUST: time to compensate for clock drift relative to other
|
||||
* mesh nodes
|
||||
* @MESH_WORK_MBSS_CHANGED: rebuild beacon and notify driver of BSS changes
|
||||
*/
|
||||
enum mesh_deferred_task_flags {
|
||||
MESH_WORK_HOUSEKEEPING,
|
||||
|
|
@ -65,6 +66,7 @@ enum mesh_deferred_task_flags {
|
|||
MESH_WORK_GROW_MPP_TABLE,
|
||||
MESH_WORK_ROOT,
|
||||
MESH_WORK_DRIFT_ADJUST,
|
||||
MESH_WORK_MBSS_CHANGED,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -154,8 +154,14 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
|
|||
u16 ht_opmode;
|
||||
bool non_ht_sta = false, ht20_sta = false;
|
||||
|
||||
if (sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
|
||||
switch (sdata->vif.bss_conf.chandef.width) {
|
||||
case NL80211_CHAN_WIDTH_20_NOHT:
|
||||
case NL80211_CHAN_WIDTH_5:
|
||||
case NL80211_CHAN_WIDTH_10:
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(sta, &local->sta_list, list) {
|
||||
|
|
|
|||
|
|
@ -190,6 +190,12 @@ static u32 chandef_downgrade(struct cfg80211_chan_def *c)
|
|||
c->width = NL80211_CHAN_WIDTH_20_NOHT;
|
||||
ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
|
||||
break;
|
||||
case NL80211_CHAN_WIDTH_5:
|
||||
case NL80211_CHAN_WIDTH_10:
|
||||
WARN_ON_ONCE(1);
|
||||
/* keep c->width */
|
||||
ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
|
||||
break;
|
||||
}
|
||||
|
||||
WARN_ON_ONCE(!cfg80211_chandef_valid(c));
|
||||
|
|
@ -1779,8 +1785,10 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
|
|||
* probably just won't work at all.
|
||||
*/
|
||||
bss_conf->dtim_period = sdata->u.mgd.dtim_period ?: 1;
|
||||
bss_conf->beacon_rate = bss->beacon_rate;
|
||||
bss_info_changed |= BSS_CHANGED_BEACON_INFO;
|
||||
} else {
|
||||
bss_conf->beacon_rate = NULL;
|
||||
bss_conf->dtim_period = 0;
|
||||
}
|
||||
|
||||
|
|
@ -1903,6 +1911,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
|
|||
del_timer_sync(&sdata->u.mgd.chswitch_timer);
|
||||
|
||||
sdata->vif.bss_conf.dtim_period = 0;
|
||||
sdata->vif.bss_conf.beacon_rate = NULL;
|
||||
|
||||
ifmgd->have_beacon = false;
|
||||
|
||||
ifmgd->flags = 0;
|
||||
|
|
@ -2785,8 +2795,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
|
|||
if (!ieee80211_assoc_success(sdata, bss, mgmt, len)) {
|
||||
/* oops -- internal error -- send timeout for now */
|
||||
ieee80211_destroy_assoc_data(sdata, false);
|
||||
cfg80211_put_bss(sdata->local->hw.wiphy, bss);
|
||||
cfg80211_assoc_timeout(sdata->dev, mgmt->bssid);
|
||||
cfg80211_assoc_timeout(sdata->dev, bss);
|
||||
return;
|
||||
}
|
||||
sdata_info(sdata, "associated\n");
|
||||
|
|
@ -2827,8 +2836,10 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
|
||||
channel);
|
||||
if (bss)
|
||||
if (bss) {
|
||||
ieee80211_rx_bss_put(local, bss);
|
||||
sdata->vif.bss_conf.beacon_rate = bss->beacon_rate;
|
||||
}
|
||||
|
||||
if (!sdata->u.mgd.associated ||
|
||||
!ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid))
|
||||
|
|
@ -3501,13 +3512,10 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
|
|||
time_after(jiffies, ifmgd->assoc_data->timeout)) {
|
||||
if ((ifmgd->assoc_data->need_beacon && !ifmgd->have_beacon) ||
|
||||
ieee80211_do_assoc(sdata)) {
|
||||
u8 bssid[ETH_ALEN];
|
||||
|
||||
memcpy(bssid, ifmgd->assoc_data->bss->bssid, ETH_ALEN);
|
||||
struct cfg80211_bss *bss = ifmgd->assoc_data->bss;
|
||||
|
||||
ieee80211_destroy_assoc_data(sdata, false);
|
||||
|
||||
cfg80211_assoc_timeout(sdata->dev, bssid);
|
||||
cfg80211_assoc_timeout(sdata->dev, bss);
|
||||
}
|
||||
} else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started)
|
||||
run_again(sdata, ifmgd->assoc_data->timeout);
|
||||
|
|
@ -3838,6 +3846,12 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
|
|||
*/
|
||||
ret = ieee80211_vif_use_channel(sdata, &chandef,
|
||||
IEEE80211_CHANCTX_SHARED);
|
||||
|
||||
/* don't downgrade for 5 and 10 MHz channels, though. */
|
||||
if (chandef.width == NL80211_CHAN_WIDTH_5 ||
|
||||
chandef.width == NL80211_CHAN_WIDTH_10)
|
||||
return ret;
|
||||
|
||||
while (ret && chandef.width != NL80211_CHAN_WIDTH_20_NOHT) {
|
||||
ifmgd->flags |= chandef_downgrade(&chandef);
|
||||
ret = ieee80211_vif_use_channel(sdata, &chandef,
|
||||
|
|
@ -4427,8 +4441,11 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
|
|||
cancel_work_sync(&ifmgd->chswitch_work);
|
||||
|
||||
sdata_lock(sdata);
|
||||
if (ifmgd->assoc_data)
|
||||
if (ifmgd->assoc_data) {
|
||||
struct cfg80211_bss *bss = ifmgd->assoc_data->bss;
|
||||
ieee80211_destroy_assoc_data(sdata, false);
|
||||
cfg80211_assoc_timeout(sdata->dev, bss);
|
||||
}
|
||||
if (ifmgd->auth_data)
|
||||
ieee80211_destroy_auth_data(sdata, false);
|
||||
del_timer_sync(&ifmgd->timer);
|
||||
|
|
|
|||
|
|
@ -397,8 +397,14 @@ static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
|
|||
return;
|
||||
|
||||
/* if HT BSS, and we handle a data frame, also try HT rates */
|
||||
if (chan_width == NL80211_CHAN_WIDTH_20_NOHT)
|
||||
switch (chan_width) {
|
||||
case NL80211_CHAN_WIDTH_20_NOHT:
|
||||
case NL80211_CHAN_WIDTH_5:
|
||||
case NL80211_CHAN_WIDTH_10:
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
alt_rate.idx = 0;
|
||||
/* keep protection flags */
|
||||
|
|
|
|||
|
|
@ -140,6 +140,15 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
|
|||
bss->valid_data |= IEEE80211_BSS_VALID_WMM;
|
||||
}
|
||||
|
||||
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))
|
||||
bss->beacon_rate =
|
||||
&sband->bitrates[rx_status->rate_idx];
|
||||
}
|
||||
|
||||
return bss;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -149,6 +149,7 @@ static void cleanup_single_sta(struct sta_info *sta)
|
|||
* directly by station destruction.
|
||||
*/
|
||||
for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
|
||||
kfree(sta->ampdu_mlme.tid_start_tx[i]);
|
||||
tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]);
|
||||
if (!tid_tx)
|
||||
continue;
|
||||
|
|
@ -346,6 +347,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
|
|||
if (ieee80211_vif_is_mesh(&sdata->vif) &&
|
||||
!sdata->u.mesh.user_mpm)
|
||||
init_timer(&sta->plink_timer);
|
||||
sta->nonpeer_pm = NL80211_MESH_POWER_ACTIVE;
|
||||
#endif
|
||||
|
||||
memcpy(sta->sta.addr, addr, ETH_ALEN);
|
||||
|
|
|
|||
|
|
@ -203,6 +203,7 @@ struct tid_ampdu_rx {
|
|||
* driver requested to close until the work for it runs
|
||||
* @mtx: mutex to protect all TX data (except non-NULL assignments
|
||||
* to tid_tx[idx], which are protected by the sta spinlock)
|
||||
* tid_start_tx is also protected by sta->lock.
|
||||
*/
|
||||
struct sta_ampdu_mlme {
|
||||
struct mutex mtx;
|
||||
|
|
|
|||
|
|
@ -396,7 +396,7 @@ void ieee80211_vht_handle_opmode(struct ieee80211_sub_if_data *sdata,
|
|||
new_bw = ieee80211_sta_cur_vht_bw(sta);
|
||||
if (new_bw != sta->sta.bandwidth) {
|
||||
sta->sta.bandwidth = new_bw;
|
||||
changed |= IEEE80211_RC_NSS_CHANGED;
|
||||
changed |= IEEE80211_RC_BW_CHANGED;
|
||||
}
|
||||
|
||||
change:
|
||||
|
|
|
|||
Loading…
Reference in a new issue