mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts: drivers/net/wireless/ath/ath9k/debug.c net/mac80211/iface.c
This commit is contained in:
commit
3899ba90a4
206 changed files with 19923 additions and 3391 deletions
|
|
@ -85,7 +85,7 @@ void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
|
|||
*cpos++ = *pos++ ^ e[i];
|
||||
}
|
||||
|
||||
for (i = 0; i < CCMP_MIC_LEN; i++)
|
||||
for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++)
|
||||
mic[i] = b[i] ^ s_0[i];
|
||||
}
|
||||
|
||||
|
|
@ -123,7 +123,7 @@ int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
|
|||
crypto_cipher_encrypt_one(tfm, a, a);
|
||||
}
|
||||
|
||||
for (i = 0; i < CCMP_MIC_LEN; i++) {
|
||||
for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++) {
|
||||
if ((mic[i] ^ s_0[i]) != a[i])
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -138,7 +138,7 @@ struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[])
|
|||
|
||||
tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
|
||||
if (!IS_ERR(tfm))
|
||||
crypto_cipher_setkey(tfm, key, ALG_CCMP_KEY_LEN);
|
||||
crypto_cipher_setkey(tfm, key, WLAN_KEY_LEN_CCMP);
|
||||
|
||||
return tfm;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,16 +73,19 @@ static int ieee80211_change_iface(struct wiphy *wiphy,
|
|||
struct ieee80211_local *local = sdata->local;
|
||||
|
||||
if (ieee80211_sdata_running(sdata)) {
|
||||
u32 mask = MONITOR_FLAG_COOK_FRAMES |
|
||||
MONITOR_FLAG_ACTIVE;
|
||||
|
||||
/*
|
||||
* Prohibit MONITOR_FLAG_COOK_FRAMES to be
|
||||
* changed while the interface is up.
|
||||
* Prohibit MONITOR_FLAG_COOK_FRAMES and
|
||||
* MONITOR_FLAG_ACTIVE to be changed while the
|
||||
* interface is up.
|
||||
* Else we would need to add a lot of cruft
|
||||
* to update everything:
|
||||
* cooked_mntrs, monitor and all fif_* counters
|
||||
* reconfigure hardware
|
||||
*/
|
||||
if ((*flags & MONITOR_FLAG_COOK_FRAMES) !=
|
||||
(sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES))
|
||||
if ((*flags & mask) != (sdata->u.mntr_flags & mask))
|
||||
return -EBUSY;
|
||||
|
||||
ieee80211_adjust_monitor_flags(sdata, -1);
|
||||
|
|
@ -444,7 +447,7 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
|
|||
struct ieee80211_local *local = sdata->local;
|
||||
struct timespec uptime;
|
||||
u64 packets = 0;
|
||||
int ac;
|
||||
int i, ac;
|
||||
|
||||
sinfo->generation = sdata->local->sta_generation;
|
||||
|
||||
|
|
@ -488,6 +491,17 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
|
|||
sinfo->signal = (s8)sta->last_signal;
|
||||
sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal);
|
||||
}
|
||||
if (sta->chains) {
|
||||
sinfo->filled |= STATION_INFO_CHAIN_SIGNAL |
|
||||
STATION_INFO_CHAIN_SIGNAL_AVG;
|
||||
|
||||
sinfo->chains = sta->chains;
|
||||
for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) {
|
||||
sinfo->chain_signal[i] = sta->chain_signal_last[i];
|
||||
sinfo->chain_signal_avg[i] =
|
||||
(s8) -ewma_read(&sta->chain_signal_avg[i]);
|
||||
}
|
||||
}
|
||||
|
||||
sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
|
||||
sta_set_rate_info_rx(sta, &sinfo->rxrate);
|
||||
|
|
@ -728,7 +742,7 @@ static void ieee80211_get_et_strings(struct wiphy *wiphy,
|
|||
|
||||
if (sset == ETH_SS_STATS) {
|
||||
sz_sta_stats = sizeof(ieee80211_gstrings_sta_stats);
|
||||
memcpy(data, *ieee80211_gstrings_sta_stats, sz_sta_stats);
|
||||
memcpy(data, ieee80211_gstrings_sta_stats, sz_sta_stats);
|
||||
}
|
||||
drv_get_et_strings(sdata, sset, &(data[sz_sta_stats]));
|
||||
}
|
||||
|
|
@ -1735,6 +1749,7 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
|
|||
ifmsh->mesh_pp_id = setup->path_sel_proto;
|
||||
ifmsh->mesh_pm_id = setup->path_metric;
|
||||
ifmsh->user_mpm = setup->user_mpm;
|
||||
ifmsh->mesh_auth_id = setup->auth_id;
|
||||
ifmsh->security = IEEE80211_MESH_SEC_NONE;
|
||||
if (setup->is_authenticated)
|
||||
ifmsh->security |= IEEE80211_MESH_SEC_AUTHED;
|
||||
|
|
@ -2306,7 +2321,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
|
|||
enum ieee80211_smps_mode old_req;
|
||||
int err;
|
||||
|
||||
lockdep_assert_held(&sdata->u.mgd.mtx);
|
||||
lockdep_assert_held(&sdata->wdev.mtx);
|
||||
|
||||
old_req = sdata->u.mgd.req_smps;
|
||||
sdata->u.mgd.req_smps = smps_mode;
|
||||
|
|
@ -2363,9 +2378,9 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
|
|||
local->dynamic_ps_forced_timeout = timeout;
|
||||
|
||||
/* no change, but if automatic follow powersave */
|
||||
mutex_lock(&sdata->u.mgd.mtx);
|
||||
sdata_lock(sdata);
|
||||
__ieee80211_request_smps(sdata, sdata->u.mgd.req_smps);
|
||||
mutex_unlock(&sdata->u.mgd.mtx);
|
||||
sdata_unlock(sdata);
|
||||
|
||||
if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
|
||||
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
|
||||
|
|
|
|||
|
|
@ -228,9 +228,9 @@ static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata,
|
|||
if (sdata->vif.type != NL80211_IFTYPE_STATION)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
mutex_lock(&sdata->u.mgd.mtx);
|
||||
sdata_lock(sdata);
|
||||
err = __ieee80211_request_smps(sdata, smps_mode);
|
||||
mutex_unlock(&sdata->u.mgd.mtx);
|
||||
sdata_unlock(sdata);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
|
@ -313,16 +313,16 @@ static ssize_t ieee80211_if_parse_tkip_mic_test(
|
|||
case NL80211_IFTYPE_STATION:
|
||||
fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
|
||||
/* BSSID SA DA */
|
||||
mutex_lock(&sdata->u.mgd.mtx);
|
||||
sdata_lock(sdata);
|
||||
if (!sdata->u.mgd.associated) {
|
||||
mutex_unlock(&sdata->u.mgd.mtx);
|
||||
sdata_unlock(sdata);
|
||||
dev_kfree_skb(skb);
|
||||
return -ENOTCONN;
|
||||
}
|
||||
memcpy(hdr->addr1, sdata->u.mgd.associated->bssid, ETH_ALEN);
|
||||
memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN);
|
||||
memcpy(hdr->addr3, addr, ETH_ALEN);
|
||||
mutex_unlock(&sdata->u.mgd.mtx);
|
||||
sdata_unlock(sdata);
|
||||
break;
|
||||
default:
|
||||
dev_kfree_skb(skb);
|
||||
|
|
@ -471,6 +471,8 @@ __IEEE80211_IF_FILE_W(tsf);
|
|||
IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC);
|
||||
|
||||
#ifdef CONFIG_MAC80211_MESH
|
||||
IEEE80211_IF_FILE(estab_plinks, u.mesh.estab_plinks, ATOMIC);
|
||||
|
||||
/* Mesh stats attributes */
|
||||
IEEE80211_IF_FILE(fwded_mcast, u.mesh.mshstats.fwded_mcast, DEC);
|
||||
IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC);
|
||||
|
|
@ -480,7 +482,6 @@ IEEE80211_IF_FILE(dropped_frames_congestion,
|
|||
u.mesh.mshstats.dropped_frames_congestion, DEC);
|
||||
IEEE80211_IF_FILE(dropped_frames_no_route,
|
||||
u.mesh.mshstats.dropped_frames_no_route, DEC);
|
||||
IEEE80211_IF_FILE(estab_plinks, u.mesh.estab_plinks, ATOMIC);
|
||||
|
||||
/* Mesh parameters */
|
||||
IEEE80211_IF_FILE(dot11MeshMaxRetries,
|
||||
|
|
@ -583,6 +584,7 @@ static void add_wds_files(struct ieee80211_sub_if_data *sdata)
|
|||
static void add_mesh_files(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
DEBUGFS_ADD_MODE(tsf, 0600);
|
||||
DEBUGFS_ADD_MODE(estab_plinks, 0400);
|
||||
}
|
||||
|
||||
static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
|
||||
|
|
@ -598,7 +600,6 @@ static void add_mesh_stats(struct ieee80211_sub_if_data *sdata)
|
|||
MESHSTATS_ADD(dropped_frames_ttl);
|
||||
MESHSTATS_ADD(dropped_frames_no_route);
|
||||
MESHSTATS_ADD(dropped_frames_congestion);
|
||||
MESHSTATS_ADD(estab_plinks);
|
||||
#undef MESHSTATS_ADD
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -146,7 +146,8 @@ static inline int drv_add_interface(struct ieee80211_local *local,
|
|||
|
||||
if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
|
||||
(sdata->vif.type == NL80211_IFTYPE_MONITOR &&
|
||||
!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF))))
|
||||
!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF) &&
|
||||
!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))))
|
||||
return -EINVAL;
|
||||
|
||||
trace_drv_add_interface(local, sdata);
|
||||
|
|
|
|||
|
|
@ -429,9 +429,9 @@ void ieee80211_request_smps_work(struct work_struct *work)
|
|||
container_of(work, struct ieee80211_sub_if_data,
|
||||
u.mgd.request_smps_work);
|
||||
|
||||
mutex_lock(&sdata->u.mgd.mtx);
|
||||
sdata_lock(sdata);
|
||||
__ieee80211_request_smps(sdata, sdata->u.mgd.driver_smps_mode);
|
||||
mutex_unlock(&sdata->u.mgd.mtx);
|
||||
sdata_unlock(sdata);
|
||||
}
|
||||
|
||||
void ieee80211_request_smps(struct ieee80211_vif *vif,
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
|
|||
struct beacon_data *presp;
|
||||
int frame_len;
|
||||
|
||||
lockdep_assert_held(&ifibss->mtx);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
/* Reset own TSF to allow time synchronization work. */
|
||||
drv_reset_tsf(local, sdata);
|
||||
|
|
@ -74,7 +74,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
|
|||
}
|
||||
|
||||
presp = rcu_dereference_protected(ifibss->presp,
|
||||
lockdep_is_held(&ifibss->mtx));
|
||||
lockdep_is_held(&sdata->wdev.mtx));
|
||||
rcu_assign_pointer(ifibss->presp, NULL);
|
||||
if (presp)
|
||||
kfree_rcu(presp, rcu_head);
|
||||
|
|
@ -263,7 +263,7 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
|
|||
const struct cfg80211_bss_ies *ies;
|
||||
u64 tsf;
|
||||
|
||||
lockdep_assert_held(&sdata->u.ibss.mtx);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
if (beacon_int < 10)
|
||||
beacon_int = 10;
|
||||
|
|
@ -341,6 +341,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
|
|||
struct ieee80211_local *local = sdata->local;
|
||||
struct sta_info *sta;
|
||||
struct ieee80211_chanctx_conf *chanctx_conf;
|
||||
struct ieee80211_supported_band *sband;
|
||||
int band;
|
||||
|
||||
/*
|
||||
|
|
@ -380,8 +381,9 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
|
|||
sta->last_rx = jiffies;
|
||||
|
||||
/* make sure mandatory rates are always added */
|
||||
sband = local->hw.wiphy->bands[band];
|
||||
sta->sta.supp_rates[band] = supp_rates |
|
||||
ieee80211_mandatory_rates(local, band);
|
||||
ieee80211_mandatory_rates(sband);
|
||||
|
||||
return ieee80211_ibss_finish_sta(sta, auth);
|
||||
}
|
||||
|
|
@ -408,7 +410,7 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
|
|||
struct sta_info *sta;
|
||||
u8 deauth_frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
|
||||
|
||||
lockdep_assert_held(&sdata->u.ibss.mtx);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
if (len < 24 + 6)
|
||||
return;
|
||||
|
|
@ -492,7 +494,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
|
|||
prev_rates = sta->sta.supp_rates[band];
|
||||
/* make sure mandatory rates are always added */
|
||||
sta->sta.supp_rates[band] = supp_rates |
|
||||
ieee80211_mandatory_rates(local, band);
|
||||
ieee80211_mandatory_rates(sband);
|
||||
|
||||
if (sta->sta.supp_rates[band] != prev_rates) {
|
||||
ibss_dbg(sdata,
|
||||
|
|
@ -624,6 +626,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
|
|||
struct ieee80211_local *local = sdata->local;
|
||||
struct sta_info *sta;
|
||||
struct ieee80211_chanctx_conf *chanctx_conf;
|
||||
struct ieee80211_supported_band *sband;
|
||||
int band;
|
||||
|
||||
/*
|
||||
|
|
@ -658,8 +661,9 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
|
|||
sta->last_rx = jiffies;
|
||||
|
||||
/* make sure mandatory rates are always added */
|
||||
sband = local->hw.wiphy->bands[band];
|
||||
sta->sta.supp_rates[band] = supp_rates |
|
||||
ieee80211_mandatory_rates(local, band);
|
||||
ieee80211_mandatory_rates(sband);
|
||||
|
||||
spin_lock(&ifibss->incomplete_lock);
|
||||
list_add(&sta->list, &ifibss->incomplete_stations);
|
||||
|
|
@ -673,7 +677,7 @@ static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
|
|||
int active = 0;
|
||||
struct sta_info *sta;
|
||||
|
||||
lockdep_assert_held(&sdata->u.ibss.mtx);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
|
|
@ -699,7 +703,7 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata)
|
|||
{
|
||||
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
|
||||
|
||||
lockdep_assert_held(&ifibss->mtx);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
mod_timer(&ifibss->timer,
|
||||
round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL));
|
||||
|
|
@ -730,7 +734,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
|
|||
u16 capability;
|
||||
int i;
|
||||
|
||||
lockdep_assert_held(&ifibss->mtx);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
if (ifibss->fixed_bssid) {
|
||||
memcpy(bssid, ifibss->bssid, ETH_ALEN);
|
||||
|
|
@ -773,7 +777,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
|
|||
int active_ibss;
|
||||
u16 capability;
|
||||
|
||||
lockdep_assert_held(&ifibss->mtx);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
active_ibss = ieee80211_sta_active_ibss(sdata);
|
||||
ibss_dbg(sdata, "sta_find_ibss (active_ibss=%d)\n", active_ibss);
|
||||
|
|
@ -843,10 +847,10 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
|
|||
struct beacon_data *presp;
|
||||
u8 *pos, *end;
|
||||
|
||||
lockdep_assert_held(&ifibss->mtx);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
presp = rcu_dereference_protected(ifibss->presp,
|
||||
lockdep_is_held(&ifibss->mtx));
|
||||
lockdep_is_held(&sdata->wdev.mtx));
|
||||
|
||||
if (ifibss->state != IEEE80211_IBSS_MLME_JOINED ||
|
||||
len < 24 + 2 || !presp)
|
||||
|
|
@ -930,7 +934,7 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
|
|||
mgmt = (struct ieee80211_mgmt *) skb->data;
|
||||
fc = le16_to_cpu(mgmt->frame_control);
|
||||
|
||||
mutex_lock(&sdata->u.ibss.mtx);
|
||||
sdata_lock(sdata);
|
||||
|
||||
if (!sdata->u.ibss.ssid_len)
|
||||
goto mgmt_out; /* not ready to merge yet */
|
||||
|
|
@ -953,7 +957,7 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
|
|||
}
|
||||
|
||||
mgmt_out:
|
||||
mutex_unlock(&sdata->u.ibss.mtx);
|
||||
sdata_unlock(sdata);
|
||||
}
|
||||
|
||||
void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)
|
||||
|
|
@ -961,7 +965,7 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)
|
|||
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
|
||||
struct sta_info *sta;
|
||||
|
||||
mutex_lock(&ifibss->mtx);
|
||||
sdata_lock(sdata);
|
||||
|
||||
/*
|
||||
* Work could be scheduled after scan or similar
|
||||
|
|
@ -997,7 +1001,7 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)
|
|||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&ifibss->mtx);
|
||||
sdata_unlock(sdata);
|
||||
}
|
||||
|
||||
static void ieee80211_ibss_timer(unsigned long data)
|
||||
|
|
@ -1014,7 +1018,6 @@ void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata)
|
|||
|
||||
setup_timer(&ifibss->timer, ieee80211_ibss_timer,
|
||||
(unsigned long) sdata);
|
||||
mutex_init(&ifibss->mtx);
|
||||
INIT_LIST_HEAD(&ifibss->incomplete_stations);
|
||||
spin_lock_init(&ifibss->incomplete_lock);
|
||||
}
|
||||
|
|
@ -1041,8 +1044,6 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
|
|||
{
|
||||
u32 changed = 0;
|
||||
|
||||
mutex_lock(&sdata->u.ibss.mtx);
|
||||
|
||||
if (params->bssid) {
|
||||
memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN);
|
||||
sdata->u.ibss.fixed_bssid = true;
|
||||
|
|
@ -1075,8 +1076,6 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
|
|||
memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len);
|
||||
sdata->u.ibss.ssid_len = params->ssid_len;
|
||||
|
||||
mutex_unlock(&sdata->u.ibss.mtx);
|
||||
|
||||
/*
|
||||
* 802.11n-2009 9.13.3.1: In an IBSS, the HT Protection field is
|
||||
* reserved, but an HT STA shall protect HT transmissions as though
|
||||
|
|
@ -1112,8 +1111,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
|
|||
struct sta_info *sta;
|
||||
struct beacon_data *presp;
|
||||
|
||||
mutex_lock(&sdata->u.ibss.mtx);
|
||||
|
||||
active_ibss = ieee80211_sta_active_ibss(sdata);
|
||||
|
||||
if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) {
|
||||
|
|
@ -1157,7 +1154,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
|
|||
/* remove beacon */
|
||||
kfree(sdata->u.ibss.ie);
|
||||
presp = rcu_dereference_protected(ifibss->presp,
|
||||
lockdep_is_held(&sdata->u.ibss.mtx));
|
||||
lockdep_is_held(&sdata->wdev.mtx));
|
||||
RCU_INIT_POINTER(sdata->u.ibss.presp, NULL);
|
||||
sdata->vif.bss_conf.ibss_joined = false;
|
||||
sdata->vif.bss_conf.ibss_creator = false;
|
||||
|
|
@ -1173,7 +1170,5 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
|
|||
|
||||
del_timer_sync(&sdata->u.ibss.timer);
|
||||
|
||||
mutex_unlock(&sdata->u.ibss.mtx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -394,7 +394,6 @@ struct ieee80211_if_managed {
|
|||
bool nullfunc_failed;
|
||||
bool connection_loss;
|
||||
|
||||
struct mutex mtx;
|
||||
struct cfg80211_bss *associated;
|
||||
struct ieee80211_mgd_auth_data *auth_data;
|
||||
struct ieee80211_mgd_assoc_data *assoc_data;
|
||||
|
|
@ -488,8 +487,6 @@ struct ieee80211_if_managed {
|
|||
struct ieee80211_if_ibss {
|
||||
struct timer_list timer;
|
||||
|
||||
struct mutex mtx;
|
||||
|
||||
unsigned long last_scan_completed;
|
||||
|
||||
u32 basic_rates;
|
||||
|
|
@ -580,8 +577,6 @@ struct ieee80211_if_mesh {
|
|||
bool accepting_plinks;
|
||||
int num_gates;
|
||||
struct beacon_data __rcu *beacon;
|
||||
/* just protects beacon updates for now */
|
||||
struct mutex mtx;
|
||||
const u8 *ie;
|
||||
u8 ie_len;
|
||||
enum {
|
||||
|
|
@ -778,6 +773,26 @@ struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p)
|
|||
return container_of(p, struct ieee80211_sub_if_data, vif);
|
||||
}
|
||||
|
||||
static inline void sdata_lock(struct ieee80211_sub_if_data *sdata)
|
||||
__acquires(&sdata->wdev.mtx)
|
||||
{
|
||||
mutex_lock(&sdata->wdev.mtx);
|
||||
__acquire(&sdata->wdev.mtx);
|
||||
}
|
||||
|
||||
static inline void sdata_unlock(struct ieee80211_sub_if_data *sdata)
|
||||
__releases(&sdata->wdev.mtx)
|
||||
{
|
||||
mutex_unlock(&sdata->wdev.mtx);
|
||||
__release(&sdata->wdev.mtx);
|
||||
}
|
||||
|
||||
static inline void
|
||||
sdata_assert_lock(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
lockdep_assert_held(&sdata->wdev.mtx);
|
||||
}
|
||||
|
||||
static inline enum ieee80211_band
|
||||
ieee80211_get_sdata_band(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
|
|
@ -1506,9 +1521,6 @@ static inline void ieee802_11_parse_elems(u8 *start, size_t len, bool action,
|
|||
ieee802_11_parse_elems_crc(start, len, action, elems, 0, 0);
|
||||
}
|
||||
|
||||
u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
|
||||
enum ieee80211_band band);
|
||||
|
||||
void ieee80211_dynamic_ps_enable_work(struct work_struct *work);
|
||||
void ieee80211_dynamic_ps_disable_work(struct work_struct *work);
|
||||
void ieee80211_dynamic_ps_timer(unsigned long data);
|
||||
|
|
|
|||
|
|
@ -159,7 +159,8 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr)
|
||||
static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr,
|
||||
bool check_dup)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_sub_if_data *iter;
|
||||
|
|
@ -180,13 +181,16 @@ static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr)
|
|||
((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) |
|
||||
((u64)m[4] << 1*8) | ((u64)m[5] << 0*8);
|
||||
|
||||
if (!check_dup)
|
||||
return ret;
|
||||
|
||||
mutex_lock(&local->iflist_mtx);
|
||||
list_for_each_entry(iter, &local->interfaces, list) {
|
||||
if (iter == sdata)
|
||||
continue;
|
||||
|
||||
if (iter->vif.type == NL80211_IFTYPE_MONITOR)
|
||||
if (iter->vif.type == NL80211_IFTYPE_MONITOR &&
|
||||
!(iter->u.mntr_flags & MONITOR_FLAG_ACTIVE))
|
||||
continue;
|
||||
|
||||
m = iter->vif.addr;
|
||||
|
|
@ -208,12 +212,17 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr)
|
|||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct sockaddr *sa = addr;
|
||||
bool check_dup = true;
|
||||
int ret;
|
||||
|
||||
if (ieee80211_sdata_running(sdata))
|
||||
return -EBUSY;
|
||||
|
||||
ret = ieee80211_verify_mac(sdata, sa->sa_data);
|
||||
if (sdata->vif.type == NL80211_IFTYPE_MONITOR &&
|
||||
!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
|
||||
check_dup = false;
|
||||
|
||||
ret = ieee80211_verify_mac(sdata, sa->sa_data, check_dup);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -545,7 +554,11 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
|
|||
break;
|
||||
}
|
||||
|
||||
if (local->monitors == 0 && local->open_count == 0) {
|
||||
if (sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE) {
|
||||
res = drv_add_interface(local, sdata);
|
||||
if (res)
|
||||
goto err_stop;
|
||||
} else if (local->monitors == 0 && local->open_count == 0) {
|
||||
res = ieee80211_add_virtual_monitor(local);
|
||||
if (res)
|
||||
goto err_stop;
|
||||
|
|
@ -923,7 +936,11 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
|
|||
mutex_lock(&local->mtx);
|
||||
ieee80211_recalc_idle(local);
|
||||
mutex_unlock(&local->mtx);
|
||||
break;
|
||||
|
||||
if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
|
||||
break;
|
||||
|
||||
/* fall through */
|
||||
default:
|
||||
if (going_down)
|
||||
drv_remove_interface(local, sdata);
|
||||
|
|
@ -1072,7 +1089,7 @@ static const struct net_device_ops ieee80211_monitorif_ops = {
|
|||
.ndo_start_xmit = ieee80211_monitor_start_xmit,
|
||||
.ndo_set_rx_mode = ieee80211_set_multicast_list,
|
||||
.ndo_change_mtu = ieee80211_change_mtu,
|
||||
.ndo_set_mac_address = eth_mac_addr,
|
||||
.ndo_set_mac_address = ieee80211_change_mac,
|
||||
.ndo_select_queue = ieee80211_monitor_select_queue,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -335,12 +335,12 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
|
|||
switch (cipher) {
|
||||
case WLAN_CIPHER_SUITE_WEP40:
|
||||
case WLAN_CIPHER_SUITE_WEP104:
|
||||
key->conf.iv_len = WEP_IV_LEN;
|
||||
key->conf.icv_len = WEP_ICV_LEN;
|
||||
key->conf.iv_len = IEEE80211_WEP_IV_LEN;
|
||||
key->conf.icv_len = IEEE80211_WEP_ICV_LEN;
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_TKIP:
|
||||
key->conf.iv_len = TKIP_IV_LEN;
|
||||
key->conf.icv_len = TKIP_ICV_LEN;
|
||||
key->conf.iv_len = IEEE80211_TKIP_IV_LEN;
|
||||
key->conf.icv_len = IEEE80211_TKIP_ICV_LEN;
|
||||
if (seq) {
|
||||
for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
|
||||
key->u.tkip.rx[i].iv32 =
|
||||
|
|
@ -352,13 +352,13 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
|
|||
spin_lock_init(&key->u.tkip.txlock);
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_CCMP:
|
||||
key->conf.iv_len = CCMP_HDR_LEN;
|
||||
key->conf.icv_len = CCMP_MIC_LEN;
|
||||
key->conf.iv_len = IEEE80211_CCMP_HDR_LEN;
|
||||
key->conf.icv_len = IEEE80211_CCMP_MIC_LEN;
|
||||
if (seq) {
|
||||
for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++)
|
||||
for (j = 0; j < CCMP_PN_LEN; j++)
|
||||
for (j = 0; j < IEEE80211_CCMP_PN_LEN; j++)
|
||||
key->u.ccmp.rx_pn[i][j] =
|
||||
seq[CCMP_PN_LEN - j - 1];
|
||||
seq[IEEE80211_CCMP_PN_LEN - j - 1];
|
||||
}
|
||||
/*
|
||||
* Initialize AES key state here as an optimization so that
|
||||
|
|
@ -375,9 +375,9 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len,
|
|||
key->conf.iv_len = 0;
|
||||
key->conf.icv_len = sizeof(struct ieee80211_mmie);
|
||||
if (seq)
|
||||
for (j = 0; j < CMAC_PN_LEN; j++)
|
||||
for (j = 0; j < IEEE80211_CMAC_PN_LEN; j++)
|
||||
key->u.aes_cmac.rx_pn[j] =
|
||||
seq[CMAC_PN_LEN - j - 1];
|
||||
seq[IEEE80211_CMAC_PN_LEN - j - 1];
|
||||
/*
|
||||
* Initialize AES key state here as an optimization so that
|
||||
* it does not need to be initialized for every packet.
|
||||
|
|
@ -740,13 +740,13 @@ void ieee80211_get_key_rx_seq(struct ieee80211_key_conf *keyconf,
|
|||
pn = key->u.ccmp.rx_pn[IEEE80211_NUM_TIDS];
|
||||
else
|
||||
pn = key->u.ccmp.rx_pn[tid];
|
||||
memcpy(seq->ccmp.pn, pn, CCMP_PN_LEN);
|
||||
memcpy(seq->ccmp.pn, pn, IEEE80211_CCMP_PN_LEN);
|
||||
break;
|
||||
case WLAN_CIPHER_SUITE_AES_CMAC:
|
||||
if (WARN_ON(tid != 0))
|
||||
return;
|
||||
pn = key->u.aes_cmac.rx_pn;
|
||||
memcpy(seq->aes_cmac.pn, pn, CMAC_PN_LEN);
|
||||
memcpy(seq->aes_cmac.pn, pn, IEEE80211_CMAC_PN_LEN);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,17 +19,6 @@
|
|||
#define NUM_DEFAULT_KEYS 4
|
||||
#define NUM_DEFAULT_MGMT_KEYS 2
|
||||
|
||||
#define WEP_IV_LEN 4
|
||||
#define WEP_ICV_LEN 4
|
||||
#define ALG_CCMP_KEY_LEN 16
|
||||
#define CCMP_HDR_LEN 8
|
||||
#define CCMP_MIC_LEN 8
|
||||
#define CCMP_TK_LEN 16
|
||||
#define CCMP_PN_LEN 6
|
||||
#define TKIP_IV_LEN 8
|
||||
#define TKIP_ICV_LEN 4
|
||||
#define CMAC_PN_LEN 6
|
||||
|
||||
struct ieee80211_local;
|
||||
struct ieee80211_sub_if_data;
|
||||
struct sta_info;
|
||||
|
|
@ -93,13 +82,13 @@ struct ieee80211_key {
|
|||
* frames and the last counter is used with Robust
|
||||
* Management frames.
|
||||
*/
|
||||
u8 rx_pn[IEEE80211_NUM_TIDS + 1][CCMP_PN_LEN];
|
||||
u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN];
|
||||
struct crypto_cipher *tfm;
|
||||
u32 replays; /* dot11RSNAStatsCCMPReplays */
|
||||
} ccmp;
|
||||
struct {
|
||||
atomic64_t tx_pn;
|
||||
u8 rx_pn[CMAC_PN_LEN];
|
||||
u8 rx_pn[IEEE80211_CMAC_PN_LEN];
|
||||
struct crypto_cipher *tfm;
|
||||
u32 replays; /* dot11RSNAStatsCMACReplays */
|
||||
u32 icverrors; /* dot11RSNAStatsCMACICVErrors */
|
||||
|
|
|
|||
|
|
@ -331,7 +331,7 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
|
|||
return NOTIFY_DONE;
|
||||
|
||||
ifmgd = &sdata->u.mgd;
|
||||
mutex_lock(&ifmgd->mtx);
|
||||
sdata_lock(sdata);
|
||||
|
||||
/* Copy the addresses to the bss_conf list */
|
||||
ifa = idev->ifa_list;
|
||||
|
|
@ -349,7 +349,7 @@ static int ieee80211_ifa_changed(struct notifier_block *nb,
|
|||
ieee80211_bss_info_change_notify(sdata,
|
||||
BSS_CHANGED_ARP_FILTER);
|
||||
|
||||
mutex_unlock(&ifmgd->mtx);
|
||||
sdata_unlock(sdata);
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -161,8 +161,11 @@ void mesh_sta_cleanup(struct sta_info *sta)
|
|||
del_timer_sync(&sta->plink_timer);
|
||||
}
|
||||
|
||||
if (changed)
|
||||
if (changed) {
|
||||
sdata_lock(sdata);
|
||||
ieee80211_mbss_info_change_notify(sdata, changed);
|
||||
sdata_unlock(sdata);
|
||||
}
|
||||
}
|
||||
|
||||
int mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
|
||||
|
|
@ -577,7 +580,9 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata)
|
|||
mesh_path_expire(sdata);
|
||||
|
||||
changed = mesh_accept_plinks_update(sdata);
|
||||
sdata_lock(sdata);
|
||||
ieee80211_mbss_info_change_notify(sdata, changed);
|
||||
sdata_unlock(sdata);
|
||||
|
||||
mod_timer(&ifmsh->housekeeping_timer,
|
||||
round_jiffies(jiffies +
|
||||
|
|
@ -697,25 +702,21 @@ out_free:
|
|||
}
|
||||
|
||||
static int
|
||||
ieee80211_mesh_rebuild_beacon(struct ieee80211_if_mesh *ifmsh)
|
||||
ieee80211_mesh_rebuild_beacon(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
struct beacon_data *old_bcn;
|
||||
int ret;
|
||||
|
||||
mutex_lock(&ifmsh->mtx);
|
||||
|
||||
old_bcn = rcu_dereference_protected(ifmsh->beacon,
|
||||
lockdep_is_held(&ifmsh->mtx));
|
||||
ret = ieee80211_mesh_build_beacon(ifmsh);
|
||||
old_bcn = rcu_dereference_protected(sdata->u.mesh.beacon,
|
||||
lockdep_is_held(&sdata->wdev.mtx));
|
||||
ret = ieee80211_mesh_build_beacon(&sdata->u.mesh);
|
||||
if (ret)
|
||||
/* just reuse old beacon */
|
||||
goto out;
|
||||
return ret;
|
||||
|
||||
if (old_bcn)
|
||||
kfree_rcu(old_bcn, rcu_head);
|
||||
out:
|
||||
mutex_unlock(&ifmsh->mtx);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata,
|
||||
|
|
@ -726,7 +727,7 @@ void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata,
|
|||
BSS_CHANGED_HT |
|
||||
BSS_CHANGED_BASIC_RATES |
|
||||
BSS_CHANGED_BEACON_INT)))
|
||||
if (ieee80211_mesh_rebuild_beacon(&sdata->u.mesh))
|
||||
if (ieee80211_mesh_rebuild_beacon(sdata))
|
||||
return;
|
||||
ieee80211_bss_info_change_notify(sdata, changed);
|
||||
}
|
||||
|
|
@ -741,6 +742,8 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
|
|||
BSS_CHANGED_BASIC_RATES |
|
||||
BSS_CHANGED_BEACON_INT;
|
||||
enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
|
||||
struct ieee80211_supported_band *sband =
|
||||
sdata->local->hw.wiphy->bands[band];
|
||||
|
||||
local->fif_other_bss++;
|
||||
/* mesh ifaces must set allmulti to forward mcast traffic */
|
||||
|
|
@ -748,7 +751,6 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
|
|||
ieee80211_configure_filter(local);
|
||||
|
||||
ifmsh->mesh_cc_id = 0; /* Disabled */
|
||||
ifmsh->mesh_auth_id = 0; /* Disabled */
|
||||
/* register sync ops from extensible synchronization framework */
|
||||
ifmsh->sync_ops = ieee80211_mesh_sync_ops_get(ifmsh->mesh_sp_id);
|
||||
ifmsh->adjusting_tbtt = false;
|
||||
|
|
@ -759,8 +761,7 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
|
|||
sdata->vif.bss_conf.ht_operation_mode =
|
||||
ifmsh->mshcfg.ht_opmode;
|
||||
sdata->vif.bss_conf.enable_beacon = true;
|
||||
sdata->vif.bss_conf.basic_rates =
|
||||
ieee80211_mandatory_rates(local, band);
|
||||
sdata->vif.bss_conf.basic_rates = ieee80211_mandatory_rates(sband);
|
||||
|
||||
changed |= ieee80211_mps_local_status_update(sdata);
|
||||
|
||||
|
|
@ -788,12 +789,12 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
|
|||
sdata->vif.bss_conf.enable_beacon = false;
|
||||
clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state);
|
||||
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED);
|
||||
mutex_lock(&ifmsh->mtx);
|
||||
sdata_lock(sdata);
|
||||
bcn = rcu_dereference_protected(ifmsh->beacon,
|
||||
lockdep_is_held(&ifmsh->mtx));
|
||||
lockdep_is_held(&sdata->wdev.mtx));
|
||||
rcu_assign_pointer(ifmsh->beacon, NULL);
|
||||
kfree_rcu(bcn, rcu_head);
|
||||
mutex_unlock(&ifmsh->mtx);
|
||||
sdata_unlock(sdata);
|
||||
|
||||
/* flush STAs and mpaths on this iface */
|
||||
sta_info_flush(sdata);
|
||||
|
|
@ -1041,7 +1042,6 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
|
|||
spin_lock_init(&ifmsh->mesh_preq_queue_lock);
|
||||
spin_lock_init(&ifmsh->sync_offset_lock);
|
||||
RCU_INIT_POINTER(ifmsh->beacon, NULL);
|
||||
mutex_init(&ifmsh->mtx);
|
||||
|
||||
sdata->vif.bss_conf.bssid = zero_addr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -517,7 +517,9 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
|
|||
ieee80211_mps_frame_release(sta, elems);
|
||||
out:
|
||||
rcu_read_unlock();
|
||||
sdata_lock(sdata);
|
||||
ieee80211_mbss_info_change_notify(sdata, changed);
|
||||
sdata_unlock(sdata);
|
||||
}
|
||||
|
||||
static void mesh_plink_timer(unsigned long data)
|
||||
|
|
@ -1068,6 +1070,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
rcu_read_unlock();
|
||||
|
||||
if (changed)
|
||||
if (changed) {
|
||||
sdata_lock(sdata);
|
||||
ieee80211_mbss_info_change_notify(sdata, changed);
|
||||
sdata_unlock(sdata);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,41 +90,6 @@ MODULE_PARM_DESC(probe_wait_ms,
|
|||
*/
|
||||
#define IEEE80211_SIGNAL_AVE_MIN_COUNT 4
|
||||
|
||||
/*
|
||||
* All cfg80211 functions have to be called outside a locked
|
||||
* section so that they can acquire a lock themselves... This
|
||||
* is much simpler than queuing up things in cfg80211, but we
|
||||
* do need some indirection for that here.
|
||||
*/
|
||||
enum rx_mgmt_action {
|
||||
/* no action required */
|
||||
RX_MGMT_NONE,
|
||||
|
||||
/* caller must call cfg80211_send_deauth() */
|
||||
RX_MGMT_CFG80211_DEAUTH,
|
||||
|
||||
/* caller must call cfg80211_send_disassoc() */
|
||||
RX_MGMT_CFG80211_DISASSOC,
|
||||
|
||||
/* caller must call cfg80211_send_rx_auth() */
|
||||
RX_MGMT_CFG80211_RX_AUTH,
|
||||
|
||||
/* caller must call cfg80211_send_rx_assoc() */
|
||||
RX_MGMT_CFG80211_RX_ASSOC,
|
||||
|
||||
/* caller must call cfg80211_send_assoc_timeout() */
|
||||
RX_MGMT_CFG80211_ASSOC_TIMEOUT,
|
||||
|
||||
/* used when a processed beacon causes a deauth */
|
||||
RX_MGMT_CFG80211_TX_DEAUTH,
|
||||
};
|
||||
|
||||
/* utils */
|
||||
static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd)
|
||||
{
|
||||
lockdep_assert_held(&ifmgd->mtx);
|
||||
}
|
||||
|
||||
/*
|
||||
* We can have multiple work items (and connection probing)
|
||||
* scheduling this timer, but we need to take care to only
|
||||
|
|
@ -135,13 +100,14 @@ static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd)
|
|||
* has happened -- the work that runs from this timer will
|
||||
* do that.
|
||||
*/
|
||||
static void run_again(struct ieee80211_if_managed *ifmgd, unsigned long timeout)
|
||||
static void run_again(struct ieee80211_sub_if_data *sdata,
|
||||
unsigned long timeout)
|
||||
{
|
||||
ASSERT_MGD_MTX(ifmgd);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
if (!timer_pending(&ifmgd->timer) ||
|
||||
time_before(timeout, ifmgd->timer.expires))
|
||||
mod_timer(&ifmgd->timer, timeout);
|
||||
if (!timer_pending(&sdata->u.mgd.timer) ||
|
||||
time_before(timeout, sdata->u.mgd.timer.expires))
|
||||
mod_timer(&sdata->u.mgd.timer, timeout);
|
||||
}
|
||||
|
||||
void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata)
|
||||
|
|
@ -652,7 +618,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata)
|
|||
struct ieee80211_channel *chan;
|
||||
u32 rates = 0;
|
||||
|
||||
lockdep_assert_held(&ifmgd->mtx);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
rcu_read_lock();
|
||||
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
||||
|
|
@ -962,7 +928,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
|
|||
if (!ieee80211_sdata_running(sdata))
|
||||
return;
|
||||
|
||||
mutex_lock(&ifmgd->mtx);
|
||||
sdata_lock(sdata);
|
||||
if (!ifmgd->associated)
|
||||
goto out;
|
||||
|
||||
|
|
@ -985,7 +951,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
|
|||
IEEE80211_QUEUE_STOP_REASON_CSA);
|
||||
out:
|
||||
ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
|
||||
mutex_unlock(&ifmgd->mtx);
|
||||
sdata_unlock(sdata);
|
||||
}
|
||||
|
||||
void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success)
|
||||
|
|
@ -1036,7 +1002,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
|
|||
const struct ieee80211_ht_operation *ht_oper;
|
||||
int secondary_channel_offset = -1;
|
||||
|
||||
ASSERT_MGD_MTX(ifmgd);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
if (!cbss)
|
||||
return;
|
||||
|
|
@ -1390,6 +1356,9 @@ static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata)
|
|||
IEEE80211_STA_CONNECTION_POLL))
|
||||
return false;
|
||||
|
||||
if (!sdata->vif.bss_conf.dtim_period)
|
||||
return false;
|
||||
|
||||
rcu_read_lock();
|
||||
sta = sta_info_get(sdata, mgd->bssid);
|
||||
if (sta)
|
||||
|
|
@ -1842,7 +1811,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
|
|||
struct ieee80211_local *local = sdata->local;
|
||||
u32 changed = 0;
|
||||
|
||||
ASSERT_MGD_MTX(ifmgd);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
if (WARN_ON_ONCE(tx && !frame_buf))
|
||||
return;
|
||||
|
|
@ -2051,7 +2020,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
|
|||
}
|
||||
|
||||
ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms);
|
||||
run_again(ifmgd, ifmgd->probe_timeout);
|
||||
run_again(sdata, ifmgd->probe_timeout);
|
||||
if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)
|
||||
ieee80211_flush_queues(sdata->local, sdata);
|
||||
}
|
||||
|
|
@ -2065,7 +2034,7 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
|
|||
if (!ieee80211_sdata_running(sdata))
|
||||
return;
|
||||
|
||||
mutex_lock(&ifmgd->mtx);
|
||||
sdata_lock(sdata);
|
||||
|
||||
if (!ifmgd->associated)
|
||||
goto out;
|
||||
|
|
@ -2119,7 +2088,7 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
|
|||
ifmgd->probe_send_count = 0;
|
||||
ieee80211_mgd_probe_ap_send(sdata);
|
||||
out:
|
||||
mutex_unlock(&ifmgd->mtx);
|
||||
sdata_unlock(sdata);
|
||||
}
|
||||
|
||||
struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
|
||||
|
|
@ -2135,7 +2104,7 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
|
|||
if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
|
||||
return NULL;
|
||||
|
||||
ASSERT_MGD_MTX(ifmgd);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
if (ifmgd->associated)
|
||||
cbss = ifmgd->associated;
|
||||
|
|
@ -2168,9 +2137,9 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
|
|||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
|
||||
|
||||
mutex_lock(&ifmgd->mtx);
|
||||
sdata_lock(sdata);
|
||||
if (!ifmgd->associated) {
|
||||
mutex_unlock(&ifmgd->mtx);
|
||||
sdata_unlock(sdata);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2181,13 +2150,9 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
|
|||
ieee80211_wake_queues_by_reason(&sdata->local->hw,
|
||||
IEEE80211_MAX_QUEUE_MAP,
|
||||
IEEE80211_QUEUE_STOP_REASON_CSA);
|
||||
mutex_unlock(&ifmgd->mtx);
|
||||
|
||||
/*
|
||||
* must be outside lock due to cfg80211,
|
||||
* but that's not a problem.
|
||||
*/
|
||||
cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN);
|
||||
sdata_unlock(sdata);
|
||||
}
|
||||
|
||||
static void ieee80211_beacon_connection_loss_work(struct work_struct *work)
|
||||
|
|
@ -2254,7 +2219,7 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
|
|||
{
|
||||
struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data;
|
||||
|
||||
lockdep_assert_held(&sdata->u.mgd.mtx);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
if (!assoc) {
|
||||
sta_info_destroy_addr(sdata, auth_data->bss->bssid);
|
||||
|
|
@ -2295,27 +2260,26 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
|
|||
auth_data->key_idx, tx_flags);
|
||||
}
|
||||
|
||||
static enum rx_mgmt_action __must_check
|
||||
ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_mgmt *mgmt, size_t len)
|
||||
static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_mgmt *mgmt, size_t len)
|
||||
{
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
u8 bssid[ETH_ALEN];
|
||||
u16 auth_alg, auth_transaction, status_code;
|
||||
struct sta_info *sta;
|
||||
|
||||
lockdep_assert_held(&ifmgd->mtx);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
if (len < 24 + 6)
|
||||
return RX_MGMT_NONE;
|
||||
return;
|
||||
|
||||
if (!ifmgd->auth_data || ifmgd->auth_data->done)
|
||||
return RX_MGMT_NONE;
|
||||
return;
|
||||
|
||||
memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN);
|
||||
|
||||
if (!ether_addr_equal(bssid, mgmt->bssid))
|
||||
return RX_MGMT_NONE;
|
||||
return;
|
||||
|
||||
auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
|
||||
auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
|
||||
|
|
@ -2327,14 +2291,15 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
|
|||
mgmt->sa, auth_alg, ifmgd->auth_data->algorithm,
|
||||
auth_transaction,
|
||||
ifmgd->auth_data->expected_transaction);
|
||||
return RX_MGMT_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (status_code != WLAN_STATUS_SUCCESS) {
|
||||
sdata_info(sdata, "%pM denied authentication (status %d)\n",
|
||||
mgmt->sa, status_code);
|
||||
ieee80211_destroy_auth_data(sdata, false);
|
||||
return RX_MGMT_CFG80211_RX_AUTH;
|
||||
cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, len);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (ifmgd->auth_data->algorithm) {
|
||||
|
|
@ -2347,20 +2312,20 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
|
|||
if (ifmgd->auth_data->expected_transaction != 4) {
|
||||
ieee80211_auth_challenge(sdata, mgmt, len);
|
||||
/* need another frame */
|
||||
return RX_MGMT_NONE;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
WARN_ONCE(1, "invalid auth alg %d",
|
||||
ifmgd->auth_data->algorithm);
|
||||
return RX_MGMT_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
sdata_info(sdata, "authenticated\n");
|
||||
ifmgd->auth_data->done = true;
|
||||
ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC;
|
||||
ifmgd->auth_data->timeout_started = true;
|
||||
run_again(ifmgd, ifmgd->auth_data->timeout);
|
||||
run_again(sdata, ifmgd->auth_data->timeout);
|
||||
|
||||
if (ifmgd->auth_data->algorithm == WLAN_AUTH_SAE &&
|
||||
ifmgd->auth_data->expected_transaction != 2) {
|
||||
|
|
@ -2368,7 +2333,8 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
|
|||
* Report auth frame to user space for processing since another
|
||||
* round of Authentication frames is still needed.
|
||||
*/
|
||||
return RX_MGMT_CFG80211_RX_AUTH;
|
||||
cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, len);
|
||||
return;
|
||||
}
|
||||
|
||||
/* move station state to auth */
|
||||
|
|
@ -2384,30 +2350,29 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
|
|||
}
|
||||
mutex_unlock(&sdata->local->sta_mtx);
|
||||
|
||||
return RX_MGMT_CFG80211_RX_AUTH;
|
||||
cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, len);
|
||||
return;
|
||||
out_err:
|
||||
mutex_unlock(&sdata->local->sta_mtx);
|
||||
/* ignore frame -- wait for timeout */
|
||||
return RX_MGMT_NONE;
|
||||
}
|
||||
|
||||
|
||||
static enum rx_mgmt_action __must_check
|
||||
ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_mgmt *mgmt, size_t len)
|
||||
static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_mgmt *mgmt, size_t len)
|
||||
{
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
const u8 *bssid = NULL;
|
||||
u16 reason_code;
|
||||
|
||||
lockdep_assert_held(&ifmgd->mtx);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
if (len < 24 + 2)
|
||||
return RX_MGMT_NONE;
|
||||
return;
|
||||
|
||||
if (!ifmgd->associated ||
|
||||
!ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
|
||||
return RX_MGMT_NONE;
|
||||
return;
|
||||
|
||||
bssid = ifmgd->associated->bssid;
|
||||
|
||||
|
|
@ -2418,25 +2383,24 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
|
||||
|
||||
return RX_MGMT_CFG80211_DEAUTH;
|
||||
cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, len);
|
||||
}
|
||||
|
||||
|
||||
static enum rx_mgmt_action __must_check
|
||||
ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_mgmt *mgmt, size_t len)
|
||||
static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_mgmt *mgmt, size_t len)
|
||||
{
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
u16 reason_code;
|
||||
|
||||
lockdep_assert_held(&ifmgd->mtx);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
if (len < 24 + 2)
|
||||
return RX_MGMT_NONE;
|
||||
return;
|
||||
|
||||
if (!ifmgd->associated ||
|
||||
!ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
|
||||
return RX_MGMT_NONE;
|
||||
return;
|
||||
|
||||
reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
|
||||
|
||||
|
|
@ -2445,7 +2409,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
|
||||
|
||||
return RX_MGMT_CFG80211_DISASSOC;
|
||||
cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, len);
|
||||
}
|
||||
|
||||
static void ieee80211_get_rates(struct ieee80211_supported_band *sband,
|
||||
|
|
@ -2495,7 +2459,7 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
|
|||
{
|
||||
struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data;
|
||||
|
||||
lockdep_assert_held(&sdata->u.mgd.mtx);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
if (!assoc) {
|
||||
sta_info_destroy_addr(sdata, assoc_data->bss->bssid);
|
||||
|
|
@ -2676,10 +2640,9 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
|
|||
return true;
|
||||
}
|
||||
|
||||
static enum rx_mgmt_action __must_check
|
||||
ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_mgmt *mgmt, size_t len,
|
||||
struct cfg80211_bss **bss)
|
||||
static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_mgmt *mgmt,
|
||||
size_t len)
|
||||
{
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
|
||||
|
|
@ -2687,13 +2650,14 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
|
|||
struct ieee802_11_elems elems;
|
||||
u8 *pos;
|
||||
bool reassoc;
|
||||
struct cfg80211_bss *bss;
|
||||
|
||||
lockdep_assert_held(&ifmgd->mtx);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
if (!assoc_data)
|
||||
return RX_MGMT_NONE;
|
||||
return;
|
||||
if (!ether_addr_equal(assoc_data->bss->bssid, mgmt->bssid))
|
||||
return RX_MGMT_NONE;
|
||||
return;
|
||||
|
||||
/*
|
||||
* AssocResp and ReassocResp have identical structure, so process both
|
||||
|
|
@ -2701,7 +2665,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
|
|||
*/
|
||||
|
||||
if (len < 24 + 6)
|
||||
return RX_MGMT_NONE;
|
||||
return;
|
||||
|
||||
reassoc = ieee80211_is_reassoc_req(mgmt->frame_control);
|
||||
capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
|
||||
|
|
@ -2728,22 +2692,23 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
|
|||
assoc_data->timeout = jiffies + msecs_to_jiffies(ms);
|
||||
assoc_data->timeout_started = true;
|
||||
if (ms > IEEE80211_ASSOC_TIMEOUT)
|
||||
run_again(ifmgd, assoc_data->timeout);
|
||||
return RX_MGMT_NONE;
|
||||
run_again(sdata, assoc_data->timeout);
|
||||
return;
|
||||
}
|
||||
|
||||
*bss = assoc_data->bss;
|
||||
bss = assoc_data->bss;
|
||||
|
||||
if (status_code != WLAN_STATUS_SUCCESS) {
|
||||
sdata_info(sdata, "%pM denied association (code=%d)\n",
|
||||
mgmt->sa, status_code);
|
||||
ieee80211_destroy_assoc_data(sdata, false);
|
||||
} else {
|
||||
if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) {
|
||||
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);
|
||||
return RX_MGMT_CFG80211_ASSOC_TIMEOUT;
|
||||
cfg80211_put_bss(sdata->local->hw.wiphy, bss);
|
||||
cfg80211_send_assoc_timeout(sdata->dev, mgmt->bssid);
|
||||
return;
|
||||
}
|
||||
sdata_info(sdata, "associated\n");
|
||||
|
||||
|
|
@ -2755,7 +2720,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
|
|||
ieee80211_destroy_assoc_data(sdata, true);
|
||||
}
|
||||
|
||||
return RX_MGMT_CFG80211_RX_ASSOC;
|
||||
cfg80211_send_rx_assoc(sdata->dev, bss, (u8 *)mgmt, len);
|
||||
}
|
||||
|
||||
static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
|
||||
|
|
@ -2769,7 +2734,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
|
|||
struct ieee80211_channel *channel;
|
||||
bool need_ps = false;
|
||||
|
||||
lockdep_assert_held(&sdata->u.mgd.mtx);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
if ((sdata->u.mgd.associated &&
|
||||
ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) ||
|
||||
|
|
@ -2828,7 +2793,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
ifmgd = &sdata->u.mgd;
|
||||
|
||||
ASSERT_MGD_MTX(ifmgd);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
if (!ether_addr_equal(mgmt->da, sdata->vif.addr))
|
||||
return; /* ignore ProbeResp to foreign address */
|
||||
|
|
@ -2853,7 +2818,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
|
|||
ifmgd->auth_data->tries = 0;
|
||||
ifmgd->auth_data->timeout = jiffies;
|
||||
ifmgd->auth_data->timeout_started = true;
|
||||
run_again(ifmgd, ifmgd->auth_data->timeout);
|
||||
run_again(sdata, ifmgd->auth_data->timeout);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2878,10 +2843,9 @@ static const u64 care_about_ies =
|
|||
(1ULL << WLAN_EID_HT_CAPABILITY) |
|
||||
(1ULL << WLAN_EID_HT_OPERATION);
|
||||
|
||||
static enum rx_mgmt_action
|
||||
ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_mgmt *mgmt, size_t len,
|
||||
u8 *deauth_buf, struct ieee80211_rx_status *rx_status)
|
||||
static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
||||
struct ieee80211_mgmt *mgmt, size_t len,
|
||||
struct ieee80211_rx_status *rx_status)
|
||||
{
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
|
||||
|
|
@ -2896,24 +2860,25 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
|||
u8 erp_value = 0;
|
||||
u32 ncrc;
|
||||
u8 *bssid;
|
||||
u8 deauth_buf[IEEE80211_DEAUTH_FRAME_LEN];
|
||||
|
||||
lockdep_assert_held(&ifmgd->mtx);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
/* Process beacon from the current BSS */
|
||||
baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
|
||||
if (baselen > len)
|
||||
return RX_MGMT_NONE;
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
|
||||
if (!chanctx_conf) {
|
||||
rcu_read_unlock();
|
||||
return RX_MGMT_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
if (rx_status->freq != chanctx_conf->def.chan->center_freq) {
|
||||
rcu_read_unlock();
|
||||
return RX_MGMT_NONE;
|
||||
return;
|
||||
}
|
||||
chan = chanctx_conf->def.chan;
|
||||
rcu_read_unlock();
|
||||
|
|
@ -2940,13 +2905,13 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
|||
/* continue assoc process */
|
||||
ifmgd->assoc_data->timeout = jiffies;
|
||||
ifmgd->assoc_data->timeout_started = true;
|
||||
run_again(ifmgd, ifmgd->assoc_data->timeout);
|
||||
return RX_MGMT_NONE;
|
||||
run_again(sdata, ifmgd->assoc_data->timeout);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ifmgd->associated ||
|
||||
!ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid))
|
||||
return RX_MGMT_NONE;
|
||||
return;
|
||||
bssid = ifmgd->associated->bssid;
|
||||
|
||||
/* Track average RSSI from the Beacon frames of the current AP */
|
||||
|
|
@ -3092,7 +3057,7 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
|||
}
|
||||
|
||||
if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid)
|
||||
return RX_MGMT_NONE;
|
||||
return;
|
||||
ifmgd->beacon_crc = ncrc;
|
||||
ifmgd->beacon_crc_valid = true;
|
||||
|
||||
|
|
@ -3126,6 +3091,7 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
|||
}
|
||||
|
||||
changed |= BSS_CHANGED_DTIM_PERIOD;
|
||||
ieee80211_recalc_ps_vif(sdata);
|
||||
}
|
||||
|
||||
if (elems.erp_info) {
|
||||
|
|
@ -3147,7 +3113,9 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
|||
ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
|
||||
WLAN_REASON_DEAUTH_LEAVING,
|
||||
true, deauth_buf);
|
||||
return RX_MGMT_CFG80211_TX_DEAUTH;
|
||||
cfg80211_send_deauth(sdata->dev, deauth_buf,
|
||||
sizeof(deauth_buf));
|
||||
return;
|
||||
}
|
||||
|
||||
if (sta && elems.opmode_notif)
|
||||
|
|
@ -3164,19 +3132,13 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
|
|||
elems.pwr_constr_elem);
|
||||
|
||||
ieee80211_bss_info_change_notify(sdata, changed);
|
||||
|
||||
return RX_MGMT_NONE;
|
||||
}
|
||||
|
||||
void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
struct ieee80211_rx_status *rx_status;
|
||||
struct ieee80211_mgmt *mgmt;
|
||||
struct cfg80211_bss *bss = NULL;
|
||||
enum rx_mgmt_action rma = RX_MGMT_NONE;
|
||||
u8 deauth_buf[IEEE80211_DEAUTH_FRAME_LEN];
|
||||
u16 fc;
|
||||
struct ieee802_11_elems elems;
|
||||
int ies_len;
|
||||
|
|
@ -3185,28 +3147,27 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
|
|||
mgmt = (struct ieee80211_mgmt *) skb->data;
|
||||
fc = le16_to_cpu(mgmt->frame_control);
|
||||
|
||||
mutex_lock(&ifmgd->mtx);
|
||||
sdata_lock(sdata);
|
||||
|
||||
switch (fc & IEEE80211_FCTL_STYPE) {
|
||||
case IEEE80211_STYPE_BEACON:
|
||||
rma = ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len,
|
||||
deauth_buf, rx_status);
|
||||
ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, rx_status);
|
||||
break;
|
||||
case IEEE80211_STYPE_PROBE_RESP:
|
||||
ieee80211_rx_mgmt_probe_resp(sdata, skb);
|
||||
break;
|
||||
case IEEE80211_STYPE_AUTH:
|
||||
rma = ieee80211_rx_mgmt_auth(sdata, mgmt, skb->len);
|
||||
ieee80211_rx_mgmt_auth(sdata, mgmt, skb->len);
|
||||
break;
|
||||
case IEEE80211_STYPE_DEAUTH:
|
||||
rma = ieee80211_rx_mgmt_deauth(sdata, mgmt, skb->len);
|
||||
ieee80211_rx_mgmt_deauth(sdata, mgmt, skb->len);
|
||||
break;
|
||||
case IEEE80211_STYPE_DISASSOC:
|
||||
rma = ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len);
|
||||
ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len);
|
||||
break;
|
||||
case IEEE80211_STYPE_ASSOC_RESP:
|
||||
case IEEE80211_STYPE_REASSOC_RESP:
|
||||
rma = ieee80211_rx_mgmt_assoc_resp(sdata, mgmt, skb->len, &bss);
|
||||
ieee80211_rx_mgmt_assoc_resp(sdata, mgmt, skb->len);
|
||||
break;
|
||||
case IEEE80211_STYPE_ACTION:
|
||||
if (mgmt->u.action.category == WLAN_CATEGORY_SPECTRUM_MGMT) {
|
||||
|
|
@ -3252,34 +3213,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
|
|||
}
|
||||
break;
|
||||
}
|
||||
mutex_unlock(&ifmgd->mtx);
|
||||
|
||||
switch (rma) {
|
||||
case RX_MGMT_NONE:
|
||||
/* no action */
|
||||
break;
|
||||
case RX_MGMT_CFG80211_DEAUTH:
|
||||
cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len);
|
||||
break;
|
||||
case RX_MGMT_CFG80211_DISASSOC:
|
||||
cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len);
|
||||
break;
|
||||
case RX_MGMT_CFG80211_RX_AUTH:
|
||||
cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, skb->len);
|
||||
break;
|
||||
case RX_MGMT_CFG80211_RX_ASSOC:
|
||||
cfg80211_send_rx_assoc(sdata->dev, bss, (u8 *)mgmt, skb->len);
|
||||
break;
|
||||
case RX_MGMT_CFG80211_ASSOC_TIMEOUT:
|
||||
cfg80211_send_assoc_timeout(sdata->dev, mgmt->bssid);
|
||||
break;
|
||||
case RX_MGMT_CFG80211_TX_DEAUTH:
|
||||
cfg80211_send_deauth(sdata->dev, deauth_buf,
|
||||
sizeof(deauth_buf));
|
||||
break;
|
||||
default:
|
||||
WARN(1, "unexpected: %d", rma);
|
||||
}
|
||||
sdata_unlock(sdata);
|
||||
}
|
||||
|
||||
static void ieee80211_sta_timer(unsigned long data)
|
||||
|
|
@ -3293,20 +3227,12 @@ static void ieee80211_sta_timer(unsigned long data)
|
|||
static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
|
||||
u8 *bssid, u8 reason, bool tx)
|
||||
{
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
|
||||
|
||||
ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason,
|
||||
tx, frame_buf);
|
||||
mutex_unlock(&ifmgd->mtx);
|
||||
|
||||
/*
|
||||
* must be outside lock due to cfg80211,
|
||||
* but that's not a problem.
|
||||
*/
|
||||
cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN);
|
||||
|
||||
mutex_lock(&ifmgd->mtx);
|
||||
}
|
||||
|
||||
static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
|
||||
|
|
@ -3316,7 +3242,7 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
|
|||
struct ieee80211_mgd_auth_data *auth_data = ifmgd->auth_data;
|
||||
u32 tx_flags = 0;
|
||||
|
||||
lockdep_assert_held(&ifmgd->mtx);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
if (WARN_ON_ONCE(!auth_data))
|
||||
return -EINVAL;
|
||||
|
|
@ -3389,7 +3315,7 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata)
|
|||
if (tx_flags == 0) {
|
||||
auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
|
||||
ifmgd->auth_data->timeout_started = true;
|
||||
run_again(ifmgd, auth_data->timeout);
|
||||
run_again(sdata, auth_data->timeout);
|
||||
} else {
|
||||
auth_data->timeout_started = false;
|
||||
}
|
||||
|
|
@ -3402,7 +3328,7 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata)
|
|||
struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data;
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
|
||||
lockdep_assert_held(&sdata->u.mgd.mtx);
|
||||
sdata_assert_lock(sdata);
|
||||
|
||||
assoc_data->tries++;
|
||||
if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) {
|
||||
|
|
@ -3426,7 +3352,7 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata)
|
|||
if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) {
|
||||
assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT;
|
||||
assoc_data->timeout_started = true;
|
||||
run_again(&sdata->u.mgd, assoc_data->timeout);
|
||||
run_again(sdata, assoc_data->timeout);
|
||||
} else {
|
||||
assoc_data->timeout_started = false;
|
||||
}
|
||||
|
|
@ -3451,7 +3377,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
|
|||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
|
||||
mutex_lock(&ifmgd->mtx);
|
||||
sdata_lock(sdata);
|
||||
|
||||
if (ifmgd->status_received) {
|
||||
__le16 fc = ifmgd->status_fc;
|
||||
|
|
@ -3463,7 +3389,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
|
|||
if (status_acked) {
|
||||
ifmgd->auth_data->timeout =
|
||||
jiffies + IEEE80211_AUTH_TIMEOUT_SHORT;
|
||||
run_again(ifmgd, ifmgd->auth_data->timeout);
|
||||
run_again(sdata, ifmgd->auth_data->timeout);
|
||||
} else {
|
||||
ifmgd->auth_data->timeout = jiffies - 1;
|
||||
}
|
||||
|
|
@ -3474,7 +3400,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
|
|||
if (status_acked) {
|
||||
ifmgd->assoc_data->timeout =
|
||||
jiffies + IEEE80211_ASSOC_TIMEOUT_SHORT;
|
||||
run_again(ifmgd, ifmgd->assoc_data->timeout);
|
||||
run_again(sdata, ifmgd->assoc_data->timeout);
|
||||
} else {
|
||||
ifmgd->assoc_data->timeout = jiffies - 1;
|
||||
}
|
||||
|
|
@ -3497,12 +3423,10 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
|
|||
|
||||
ieee80211_destroy_auth_data(sdata, false);
|
||||
|
||||
mutex_unlock(&ifmgd->mtx);
|
||||
cfg80211_send_auth_timeout(sdata->dev, bssid);
|
||||
mutex_lock(&ifmgd->mtx);
|
||||
}
|
||||
} else if (ifmgd->auth_data && ifmgd->auth_data->timeout_started)
|
||||
run_again(ifmgd, ifmgd->auth_data->timeout);
|
||||
run_again(sdata, ifmgd->auth_data->timeout);
|
||||
|
||||
if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started &&
|
||||
time_after(jiffies, ifmgd->assoc_data->timeout)) {
|
||||
|
|
@ -3515,12 +3439,10 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
|
|||
|
||||
ieee80211_destroy_assoc_data(sdata, false);
|
||||
|
||||
mutex_unlock(&ifmgd->mtx);
|
||||
cfg80211_send_assoc_timeout(sdata->dev, bssid);
|
||||
mutex_lock(&ifmgd->mtx);
|
||||
}
|
||||
} else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started)
|
||||
run_again(ifmgd, ifmgd->assoc_data->timeout);
|
||||
run_again(sdata, ifmgd->assoc_data->timeout);
|
||||
|
||||
if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
|
||||
IEEE80211_STA_CONNECTION_POLL) &&
|
||||
|
|
@ -3554,7 +3476,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
|
|||
false);
|
||||
}
|
||||
} else if (time_is_after_jiffies(ifmgd->probe_timeout))
|
||||
run_again(ifmgd, ifmgd->probe_timeout);
|
||||
run_again(sdata, ifmgd->probe_timeout);
|
||||
else if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) {
|
||||
mlme_dbg(sdata,
|
||||
"Failed to send nullfunc to AP %pM after %dms, disconnecting\n",
|
||||
|
|
@ -3583,7 +3505,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
|
|||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&ifmgd->mtx);
|
||||
sdata_unlock(sdata);
|
||||
}
|
||||
|
||||
static void ieee80211_sta_bcn_mon_timer(unsigned long data)
|
||||
|
|
@ -3644,9 +3566,9 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
|
|||
{
|
||||
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
||||
|
||||
mutex_lock(&ifmgd->mtx);
|
||||
sdata_lock(sdata);
|
||||
if (!ifmgd->associated) {
|
||||
mutex_unlock(&ifmgd->mtx);
|
||||
sdata_unlock(sdata);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -3657,10 +3579,10 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
|
|||
ifmgd->associated->bssid,
|
||||
WLAN_REASON_UNSPECIFIED,
|
||||
true);
|
||||
mutex_unlock(&ifmgd->mtx);
|
||||
sdata_unlock(sdata);
|
||||
return;
|
||||
}
|
||||
mutex_unlock(&ifmgd->mtx);
|
||||
sdata_unlock(sdata);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -3692,8 +3614,6 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
|
|||
ifmgd->uapsd_max_sp_len = sdata->local->hw.uapsd_max_sp_len;
|
||||
ifmgd->p2p_noa_index = -1;
|
||||
|
||||
mutex_init(&ifmgd->mtx);
|
||||
|
||||
if (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS)
|
||||
ifmgd->req_smps = IEEE80211_SMPS_AUTOMATIC;
|
||||
else
|
||||
|
|
@ -4049,8 +3969,6 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
/* try to authenticate/probe */
|
||||
|
||||
mutex_lock(&ifmgd->mtx);
|
||||
|
||||
if ((ifmgd->auth_data && !ifmgd->auth_data->done) ||
|
||||
ifmgd->assoc_data) {
|
||||
err = -EBUSY;
|
||||
|
|
@ -4070,8 +3988,8 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
|
|||
WLAN_REASON_UNSPECIFIED,
|
||||
false, frame_buf);
|
||||
|
||||
__cfg80211_send_deauth(sdata->dev, frame_buf,
|
||||
sizeof(frame_buf));
|
||||
cfg80211_send_deauth(sdata->dev, frame_buf,
|
||||
sizeof(frame_buf));
|
||||
}
|
||||
|
||||
sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid);
|
||||
|
|
@ -4088,8 +4006,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
/* hold our own reference */
|
||||
cfg80211_ref_bss(local->hw.wiphy, auth_data->bss);
|
||||
err = 0;
|
||||
goto out_unlock;
|
||||
return 0;
|
||||
|
||||
err_clear:
|
||||
memset(ifmgd->bssid, 0, ETH_ALEN);
|
||||
|
|
@ -4097,9 +4014,6 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
|
|||
ifmgd->auth_data = NULL;
|
||||
err_free:
|
||||
kfree(auth_data);
|
||||
out_unlock:
|
||||
mutex_unlock(&ifmgd->mtx);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -4130,8 +4044,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
|||
assoc_data->ssid_len = ssidie[1];
|
||||
rcu_read_unlock();
|
||||
|
||||
mutex_lock(&ifmgd->mtx);
|
||||
|
||||
if (ifmgd->associated) {
|
||||
u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
|
||||
|
||||
|
|
@ -4139,8 +4051,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
|||
WLAN_REASON_UNSPECIFIED,
|
||||
false, frame_buf);
|
||||
|
||||
__cfg80211_send_deauth(sdata->dev, frame_buf,
|
||||
sizeof(frame_buf));
|
||||
cfg80211_send_deauth(sdata->dev, frame_buf,
|
||||
sizeof(frame_buf));
|
||||
}
|
||||
|
||||
if (ifmgd->auth_data && !ifmgd->auth_data->done) {
|
||||
|
|
@ -4334,7 +4246,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
|||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
run_again(ifmgd, assoc_data->timeout);
|
||||
run_again(sdata, assoc_data->timeout);
|
||||
|
||||
if (bss->corrupt_data) {
|
||||
char *corrupt_type = "data";
|
||||
|
|
@ -4350,17 +4262,13 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
|
|||
corrupt_type);
|
||||
}
|
||||
|
||||
err = 0;
|
||||
goto out;
|
||||
return 0;
|
||||
err_clear:
|
||||
memset(ifmgd->bssid, 0, ETH_ALEN);
|
||||
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID);
|
||||
ifmgd->assoc_data = NULL;
|
||||
err_free:
|
||||
kfree(assoc_data);
|
||||
out:
|
||||
mutex_unlock(&ifmgd->mtx);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -4372,8 +4280,6 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
|
|||
bool tx = !req->local_state_change;
|
||||
bool report_frame = false;
|
||||
|
||||
mutex_lock(&ifmgd->mtx);
|
||||
|
||||
sdata_info(sdata,
|
||||
"deauthenticating from %pM by local choice (reason=%d)\n",
|
||||
req->bssid, req->reason_code);
|
||||
|
|
@ -4385,7 +4291,6 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
|
|||
req->reason_code, tx,
|
||||
frame_buf);
|
||||
ieee80211_destroy_auth_data(sdata, false);
|
||||
mutex_unlock(&ifmgd->mtx);
|
||||
|
||||
report_frame = true;
|
||||
goto out;
|
||||
|
|
@ -4397,12 +4302,11 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
|
|||
req->reason_code, tx, frame_buf);
|
||||
report_frame = true;
|
||||
}
|
||||
mutex_unlock(&ifmgd->mtx);
|
||||
|
||||
out:
|
||||
if (report_frame)
|
||||
__cfg80211_send_deauth(sdata->dev, frame_buf,
|
||||
IEEE80211_DEAUTH_FRAME_LEN);
|
||||
cfg80211_send_deauth(sdata->dev, frame_buf,
|
||||
IEEE80211_DEAUTH_FRAME_LEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -4414,18 +4318,14 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
|
|||
u8 bssid[ETH_ALEN];
|
||||
u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
|
||||
|
||||
mutex_lock(&ifmgd->mtx);
|
||||
|
||||
/*
|
||||
* cfg80211 should catch this ... but it's racy since
|
||||
* we can receive a disassoc frame, process it, hand it
|
||||
* to cfg80211 while that's in a locked section already
|
||||
* trying to tell us that the user wants to disconnect.
|
||||
*/
|
||||
if (ifmgd->associated != req->bss) {
|
||||
mutex_unlock(&ifmgd->mtx);
|
||||
if (ifmgd->associated != req->bss)
|
||||
return -ENOLINK;
|
||||
}
|
||||
|
||||
sdata_info(sdata,
|
||||
"disassociating from %pM by local choice (reason=%d)\n",
|
||||
|
|
@ -4435,10 +4335,9 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
|
|||
ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC,
|
||||
req->reason_code, !req->local_state_change,
|
||||
frame_buf);
|
||||
mutex_unlock(&ifmgd->mtx);
|
||||
|
||||
__cfg80211_send_disassoc(sdata->dev, frame_buf,
|
||||
IEEE80211_DEAUTH_FRAME_LEN);
|
||||
cfg80211_send_disassoc(sdata->dev, frame_buf,
|
||||
IEEE80211_DEAUTH_FRAME_LEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -4458,13 +4357,13 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
|
|||
cancel_work_sync(&ifmgd->csa_connection_drop_work);
|
||||
cancel_work_sync(&ifmgd->chswitch_work);
|
||||
|
||||
mutex_lock(&ifmgd->mtx);
|
||||
sdata_lock(sdata);
|
||||
if (ifmgd->assoc_data)
|
||||
ieee80211_destroy_assoc_data(sdata, false);
|
||||
if (ifmgd->auth_data)
|
||||
ieee80211_destroy_auth_data(sdata, false);
|
||||
del_timer_sync(&ifmgd->timer);
|
||||
mutex_unlock(&ifmgd->mtx);
|
||||
sdata_unlock(sdata);
|
||||
}
|
||||
|
||||
void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif,
|
||||
|
|
|
|||
|
|
@ -258,6 +258,8 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
|
|||
pos += 2;
|
||||
|
||||
if (status->flag & RX_FLAG_HT) {
|
||||
unsigned int stbc;
|
||||
|
||||
rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_MCS);
|
||||
*pos++ = local->hw.radiotap_mcs_details;
|
||||
*pos = 0;
|
||||
|
|
@ -267,6 +269,8 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
|
|||
*pos |= IEEE80211_RADIOTAP_MCS_BW_40;
|
||||
if (status->flag & RX_FLAG_HT_GF)
|
||||
*pos |= IEEE80211_RADIOTAP_MCS_FMT_GF;
|
||||
stbc = (status->flag & RX_FLAG_STBC_MASK) >> RX_FLAG_STBC_SHIFT;
|
||||
*pos |= stbc << IEEE80211_RADIOTAP_MCS_STBC_SHIFT;
|
||||
pos++;
|
||||
*pos++ = status->rate_idx;
|
||||
}
|
||||
|
|
@ -1372,6 +1376,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
|
|||
struct sk_buff *skb = rx->skb;
|
||||
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
|
||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||
int i;
|
||||
|
||||
if (!sta)
|
||||
return RX_CONTINUE;
|
||||
|
|
@ -1422,6 +1427,19 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
|
|||
ewma_add(&sta->avg_signal, -status->signal);
|
||||
}
|
||||
|
||||
if (status->chains) {
|
||||
sta->chains = status->chains;
|
||||
for (i = 0; i < ARRAY_SIZE(status->chain_signal); i++) {
|
||||
int signal = status->chain_signal[i];
|
||||
|
||||
if (!(status->chains & BIT(i)))
|
||||
continue;
|
||||
|
||||
sta->chain_signal_last[i] = signal;
|
||||
ewma_add(&sta->chain_signal_avg[i], -signal);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Change STA power saving mode only at the end of a frame
|
||||
* exchange sequence.
|
||||
|
|
@ -1608,7 +1626,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
|
|||
entry->ccmp = 1;
|
||||
memcpy(entry->last_pn,
|
||||
rx->key->u.ccmp.rx_pn[queue],
|
||||
CCMP_PN_LEN);
|
||||
IEEE80211_CCMP_PN_LEN);
|
||||
}
|
||||
return RX_QUEUED;
|
||||
}
|
||||
|
|
@ -1627,21 +1645,21 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
|
|||
* (IEEE 802.11i, 8.3.3.4.5) */
|
||||
if (entry->ccmp) {
|
||||
int i;
|
||||
u8 pn[CCMP_PN_LEN], *rpn;
|
||||
u8 pn[IEEE80211_CCMP_PN_LEN], *rpn;
|
||||
int queue;
|
||||
if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP)
|
||||
return RX_DROP_UNUSABLE;
|
||||
memcpy(pn, entry->last_pn, CCMP_PN_LEN);
|
||||
for (i = CCMP_PN_LEN - 1; i >= 0; i--) {
|
||||
memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN);
|
||||
for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) {
|
||||
pn[i]++;
|
||||
if (pn[i])
|
||||
break;
|
||||
}
|
||||
queue = rx->security_idx;
|
||||
rpn = rx->key->u.ccmp.rx_pn[queue];
|
||||
if (memcmp(pn, rpn, CCMP_PN_LEN))
|
||||
if (memcmp(pn, rpn, IEEE80211_CCMP_PN_LEN))
|
||||
return RX_DROP_UNUSABLE;
|
||||
memcpy(entry->last_pn, pn, CCMP_PN_LEN);
|
||||
memcpy(entry->last_pn, pn, IEEE80211_CCMP_PN_LEN);
|
||||
}
|
||||
|
||||
skb_pull(rx->skb, ieee80211_hdrlen(fc));
|
||||
|
|
|
|||
|
|
@ -358,6 +358,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
|
|||
do_posix_clock_monotonic_gettime(&uptime);
|
||||
sta->last_connected = uptime.tv_sec;
|
||||
ewma_init(&sta->avg_signal, 1024, 8);
|
||||
for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++)
|
||||
ewma_init(&sta->chain_signal_avg[i], 1024, 8);
|
||||
|
||||
if (sta_prepare_rate_control(local, sta, gfp)) {
|
||||
kfree(sta);
|
||||
|
|
|
|||
|
|
@ -344,6 +344,11 @@ struct sta_info {
|
|||
int last_signal;
|
||||
struct ewma avg_signal;
|
||||
int last_ack_signal;
|
||||
|
||||
u8 chains;
|
||||
s8 chain_signal_last[IEEE80211_MAX_CHAINS];
|
||||
struct ewma chain_signal_avg[IEEE80211_MAX_CHAINS];
|
||||
|
||||
/* Plus 1 for non-QoS frames */
|
||||
__le16 last_seq_ctrl[IEEE80211_NUM_TIDS + 1];
|
||||
|
||||
|
|
|
|||
|
|
@ -398,13 +398,14 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
|
|||
if (ieee80211_has_order(hdr->frame_control))
|
||||
return TX_CONTINUE;
|
||||
|
||||
if (tx->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)
|
||||
info->hw_queue = tx->sdata->vif.cab_queue;
|
||||
|
||||
/* no stations in PS mode */
|
||||
if (!atomic_read(&ps->num_sta_ps))
|
||||
return TX_CONTINUE;
|
||||
|
||||
info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM;
|
||||
if (tx->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL)
|
||||
info->hw_queue = tx->sdata->vif.cab_queue;
|
||||
|
||||
/* device releases frame after DTIM beacon */
|
||||
if (!(tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING))
|
||||
|
|
|
|||
|
|
@ -560,6 +560,9 @@ void ieee80211_iterate_active_interfaces(
|
|||
list_for_each_entry(sdata, &local->interfaces, list) {
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
|
||||
continue;
|
||||
break;
|
||||
case NL80211_IFTYPE_AP_VLAN:
|
||||
continue;
|
||||
default:
|
||||
|
|
@ -598,6 +601,9 @@ void ieee80211_iterate_active_interfaces_atomic(
|
|||
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE))
|
||||
continue;
|
||||
break;
|
||||
case NL80211_IFTYPE_AP_VLAN:
|
||||
continue;
|
||||
default:
|
||||
|
|
@ -1072,32 +1078,6 @@ void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
|
|||
ieee80211_set_wmm_default(sdata, true);
|
||||
}
|
||||
|
||||
u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
|
||||
enum ieee80211_band band)
|
||||
{
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_rate *bitrates;
|
||||
u32 mandatory_rates;
|
||||
enum ieee80211_rate_flags mandatory_flag;
|
||||
int i;
|
||||
|
||||
sband = local->hw.wiphy->bands[band];
|
||||
if (WARN_ON(!sband))
|
||||
return 1;
|
||||
|
||||
if (band == IEEE80211_BAND_2GHZ)
|
||||
mandatory_flag = IEEE80211_RATE_MANDATORY_B;
|
||||
else
|
||||
mandatory_flag = IEEE80211_RATE_MANDATORY_A;
|
||||
|
||||
bitrates = sband->bitrates;
|
||||
mandatory_rates = 0;
|
||||
for (i = 0; i < sband->n_bitrates; i++)
|
||||
if (bitrates[i].flags & mandatory_flag)
|
||||
mandatory_rates |= BIT(i);
|
||||
return mandatory_rates;
|
||||
}
|
||||
|
||||
void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
|
||||
u16 transaction, u16 auth_alg, u16 status,
|
||||
const u8 *extra, size_t extra_len, const u8 *da,
|
||||
|
|
@ -1607,9 +1587,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
|
|||
if (sdata->u.mgd.dtim_period)
|
||||
changed |= BSS_CHANGED_DTIM_PERIOD;
|
||||
|
||||
mutex_lock(&sdata->u.mgd.mtx);
|
||||
sdata_lock(sdata);
|
||||
ieee80211_bss_info_change_notify(sdata, changed);
|
||||
mutex_unlock(&sdata->u.mgd.mtx);
|
||||
sdata_unlock(sdata);
|
||||
break;
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
changed |= BSS_CHANGED_IBSS;
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
int ieee80211_wep_init(struct ieee80211_local *local)
|
||||
{
|
||||
/* start WEP IV from a random value */
|
||||
get_random_bytes(&local->wep_iv, WEP_IV_LEN);
|
||||
get_random_bytes(&local->wep_iv, IEEE80211_WEP_IV_LEN);
|
||||
|
||||
local->wep_tx_tfm = crypto_alloc_cipher("arc4", 0, CRYPTO_ALG_ASYNC);
|
||||
if (IS_ERR(local->wep_tx_tfm)) {
|
||||
|
|
@ -98,20 +98,21 @@ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local,
|
|||
|
||||
hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
|
||||
|
||||
if (WARN_ON(skb_tailroom(skb) < WEP_ICV_LEN ||
|
||||
skb_headroom(skb) < WEP_IV_LEN))
|
||||
if (WARN_ON(skb_tailroom(skb) < IEEE80211_WEP_ICV_LEN ||
|
||||
skb_headroom(skb) < IEEE80211_WEP_IV_LEN))
|
||||
return NULL;
|
||||
|
||||
hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
newhdr = skb_push(skb, WEP_IV_LEN);
|
||||
memmove(newhdr, newhdr + WEP_IV_LEN, hdrlen);
|
||||
newhdr = skb_push(skb, IEEE80211_WEP_IV_LEN);
|
||||
memmove(newhdr, newhdr + IEEE80211_WEP_IV_LEN, hdrlen);
|
||||
|
||||
/* the HW only needs room for the IV, but not the actual IV */
|
||||
if (info->control.hw_key &&
|
||||
(info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE))
|
||||
return newhdr + hdrlen;
|
||||
|
||||
skb_set_network_header(skb, skb_network_offset(skb) + WEP_IV_LEN);
|
||||
skb_set_network_header(skb, skb_network_offset(skb) +
|
||||
IEEE80211_WEP_IV_LEN);
|
||||
ieee80211_wep_get_iv(local, keylen, keyidx, newhdr + hdrlen);
|
||||
return newhdr + hdrlen;
|
||||
}
|
||||
|
|
@ -125,8 +126,8 @@ static void ieee80211_wep_remove_iv(struct ieee80211_local *local,
|
|||
unsigned int hdrlen;
|
||||
|
||||
hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
memmove(skb->data + WEP_IV_LEN, skb->data, hdrlen);
|
||||
skb_pull(skb, WEP_IV_LEN);
|
||||
memmove(skb->data + IEEE80211_WEP_IV_LEN, skb->data, hdrlen);
|
||||
skb_pull(skb, IEEE80211_WEP_IV_LEN);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -146,7 +147,7 @@ int ieee80211_wep_encrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
|
|||
put_unaligned(icv, (__le32 *)(data + data_len));
|
||||
|
||||
crypto_cipher_setkey(tfm, rc4key, klen);
|
||||
for (i = 0; i < data_len + WEP_ICV_LEN; i++)
|
||||
for (i = 0; i < data_len + IEEE80211_WEP_ICV_LEN; i++)
|
||||
crypto_cipher_encrypt_one(tfm, data + i, data + i);
|
||||
|
||||
return 0;
|
||||
|
|
@ -172,7 +173,7 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local,
|
|||
if (!iv)
|
||||
return -1;
|
||||
|
||||
len = skb->len - (iv + WEP_IV_LEN - skb->data);
|
||||
len = skb->len - (iv + IEEE80211_WEP_IV_LEN - skb->data);
|
||||
|
||||
/* Prepend 24-bit IV to RC4 key */
|
||||
memcpy(rc4key, iv, 3);
|
||||
|
|
@ -181,10 +182,10 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local,
|
|||
memcpy(rc4key + 3, key, keylen);
|
||||
|
||||
/* Add room for ICV */
|
||||
skb_put(skb, WEP_ICV_LEN);
|
||||
skb_put(skb, IEEE80211_WEP_ICV_LEN);
|
||||
|
||||
return ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, keylen + 3,
|
||||
iv + WEP_IV_LEN, len);
|
||||
iv + IEEE80211_WEP_IV_LEN, len);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -201,11 +202,11 @@ int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
|
|||
return -1;
|
||||
|
||||
crypto_cipher_setkey(tfm, rc4key, klen);
|
||||
for (i = 0; i < data_len + WEP_ICV_LEN; i++)
|
||||
for (i = 0; i < data_len + IEEE80211_WEP_ICV_LEN; i++)
|
||||
crypto_cipher_decrypt_one(tfm, data + i, data + i);
|
||||
|
||||
crc = cpu_to_le32(~crc32_le(~0, data, data_len));
|
||||
if (memcmp(&crc, data + data_len, WEP_ICV_LEN) != 0)
|
||||
if (memcmp(&crc, data + data_len, IEEE80211_WEP_ICV_LEN) != 0)
|
||||
/* ICV mismatch */
|
||||
return -1;
|
||||
|
||||
|
|
@ -237,10 +238,10 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
|
|||
return -1;
|
||||
|
||||
hdrlen = ieee80211_hdrlen(hdr->frame_control);
|
||||
if (skb->len < hdrlen + WEP_IV_LEN + WEP_ICV_LEN)
|
||||
if (skb->len < hdrlen + IEEE80211_WEP_IV_LEN + IEEE80211_WEP_ICV_LEN)
|
||||
return -1;
|
||||
|
||||
len = skb->len - hdrlen - WEP_IV_LEN - WEP_ICV_LEN;
|
||||
len = skb->len - hdrlen - IEEE80211_WEP_IV_LEN - IEEE80211_WEP_ICV_LEN;
|
||||
|
||||
keyidx = skb->data[hdrlen + 3] >> 6;
|
||||
|
||||
|
|
@ -256,16 +257,16 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
|
|||
memcpy(rc4key + 3, key->conf.key, key->conf.keylen);
|
||||
|
||||
if (ieee80211_wep_decrypt_data(local->wep_rx_tfm, rc4key, klen,
|
||||
skb->data + hdrlen + WEP_IV_LEN,
|
||||
len))
|
||||
skb->data + hdrlen +
|
||||
IEEE80211_WEP_IV_LEN, len))
|
||||
ret = -1;
|
||||
|
||||
/* Trim ICV */
|
||||
skb_trim(skb, skb->len - WEP_ICV_LEN);
|
||||
skb_trim(skb, skb->len - IEEE80211_WEP_ICV_LEN);
|
||||
|
||||
/* Remove IV */
|
||||
memmove(skb->data + WEP_IV_LEN, skb->data, hdrlen);
|
||||
skb_pull(skb, WEP_IV_LEN);
|
||||
memmove(skb->data + IEEE80211_WEP_IV_LEN, skb->data, hdrlen);
|
||||
skb_pull(skb, IEEE80211_WEP_IV_LEN);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -305,13 +306,14 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx)
|
|||
if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key))
|
||||
return RX_DROP_UNUSABLE;
|
||||
} else if (!(status->flag & RX_FLAG_IV_STRIPPED)) {
|
||||
if (!pskb_may_pull(rx->skb, ieee80211_hdrlen(fc) + WEP_IV_LEN))
|
||||
if (!pskb_may_pull(rx->skb, ieee80211_hdrlen(fc) +
|
||||
IEEE80211_WEP_IV_LEN))
|
||||
return RX_DROP_UNUSABLE;
|
||||
if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key))
|
||||
rx->sta->wep_weak_iv_count++;
|
||||
ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key);
|
||||
/* remove ICV */
|
||||
if (pskb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN))
|
||||
if (pskb_trim(rx->skb, rx->skb->len - IEEE80211_WEP_ICV_LEN))
|
||||
return RX_DROP_UNUSABLE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,10 +62,10 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
|
|||
|
||||
tail = MICHAEL_MIC_LEN;
|
||||
if (!info->control.hw_key)
|
||||
tail += TKIP_ICV_LEN;
|
||||
tail += IEEE80211_TKIP_ICV_LEN;
|
||||
|
||||
if (WARN_ON(skb_tailroom(skb) < tail ||
|
||||
skb_headroom(skb) < TKIP_IV_LEN))
|
||||
skb_headroom(skb) < IEEE80211_TKIP_IV_LEN))
|
||||
return TX_DROP;
|
||||
|
||||
key = &tx->key->conf.key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY];
|
||||
|
|
@ -198,15 +198,16 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
|
|||
if (info->control.hw_key)
|
||||
tail = 0;
|
||||
else
|
||||
tail = TKIP_ICV_LEN;
|
||||
tail = IEEE80211_TKIP_ICV_LEN;
|
||||
|
||||
if (WARN_ON(skb_tailroom(skb) < tail ||
|
||||
skb_headroom(skb) < TKIP_IV_LEN))
|
||||
skb_headroom(skb) < IEEE80211_TKIP_IV_LEN))
|
||||
return -1;
|
||||
|
||||
pos = skb_push(skb, TKIP_IV_LEN);
|
||||
memmove(pos, pos + TKIP_IV_LEN, hdrlen);
|
||||
skb_set_network_header(skb, skb_network_offset(skb) + TKIP_IV_LEN);
|
||||
pos = skb_push(skb, IEEE80211_TKIP_IV_LEN);
|
||||
memmove(pos, pos + IEEE80211_TKIP_IV_LEN, hdrlen);
|
||||
skb_set_network_header(skb, skb_network_offset(skb) +
|
||||
IEEE80211_TKIP_IV_LEN);
|
||||
pos += hdrlen;
|
||||
|
||||
/* the HW only needs room for the IV, but not the actual IV */
|
||||
|
|
@ -227,7 +228,7 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
|
|||
return 0;
|
||||
|
||||
/* Add room for ICV */
|
||||
skb_put(skb, TKIP_ICV_LEN);
|
||||
skb_put(skb, IEEE80211_TKIP_ICV_LEN);
|
||||
|
||||
return ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm,
|
||||
key, skb, pos, len);
|
||||
|
|
@ -290,11 +291,11 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
|
|||
return RX_DROP_UNUSABLE;
|
||||
|
||||
/* Trim ICV */
|
||||
skb_trim(skb, skb->len - TKIP_ICV_LEN);
|
||||
skb_trim(skb, skb->len - IEEE80211_TKIP_ICV_LEN);
|
||||
|
||||
/* Remove IV */
|
||||
memmove(skb->data + TKIP_IV_LEN, skb->data, hdrlen);
|
||||
skb_pull(skb, TKIP_IV_LEN);
|
||||
memmove(skb->data + IEEE80211_TKIP_IV_LEN, skb->data, hdrlen);
|
||||
skb_pull(skb, IEEE80211_TKIP_IV_LEN);
|
||||
|
||||
return RX_CONTINUE;
|
||||
}
|
||||
|
|
@ -337,9 +338,9 @@ static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch,
|
|||
else
|
||||
qos_tid = 0;
|
||||
|
||||
data_len = skb->len - hdrlen - CCMP_HDR_LEN;
|
||||
data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN;
|
||||
if (encrypted)
|
||||
data_len -= CCMP_MIC_LEN;
|
||||
data_len -= IEEE80211_CCMP_MIC_LEN;
|
||||
|
||||
/* First block, b_0 */
|
||||
b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */
|
||||
|
|
@ -348,7 +349,7 @@ static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch,
|
|||
*/
|
||||
b_0[1] = qos_tid | (mgmt << 4);
|
||||
memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
|
||||
memcpy(&b_0[8], pn, CCMP_PN_LEN);
|
||||
memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN);
|
||||
/* l(m) */
|
||||
put_unaligned_be16(data_len, &b_0[14]);
|
||||
|
||||
|
|
@ -424,15 +425,16 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
|
|||
if (info->control.hw_key)
|
||||
tail = 0;
|
||||
else
|
||||
tail = CCMP_MIC_LEN;
|
||||
tail = IEEE80211_CCMP_MIC_LEN;
|
||||
|
||||
if (WARN_ON(skb_tailroom(skb) < tail ||
|
||||
skb_headroom(skb) < CCMP_HDR_LEN))
|
||||
skb_headroom(skb) < IEEE80211_CCMP_HDR_LEN))
|
||||
return -1;
|
||||
|
||||
pos = skb_push(skb, CCMP_HDR_LEN);
|
||||
memmove(pos, pos + CCMP_HDR_LEN, hdrlen);
|
||||
skb_set_network_header(skb, skb_network_offset(skb) + CCMP_HDR_LEN);
|
||||
pos = skb_push(skb, IEEE80211_CCMP_HDR_LEN);
|
||||
memmove(pos, pos + IEEE80211_CCMP_HDR_LEN, hdrlen);
|
||||
skb_set_network_header(skb, skb_network_offset(skb) +
|
||||
IEEE80211_CCMP_HDR_LEN);
|
||||
|
||||
/* the HW only needs room for the IV, but not the actual IV */
|
||||
if (info->control.hw_key &&
|
||||
|
|
@ -457,10 +459,10 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
|
|||
if (info->control.hw_key)
|
||||
return 0;
|
||||
|
||||
pos += CCMP_HDR_LEN;
|
||||
pos += IEEE80211_CCMP_HDR_LEN;
|
||||
ccmp_special_blocks(skb, pn, scratch, 0);
|
||||
ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, scratch, pos, len,
|
||||
pos, skb_put(skb, CCMP_MIC_LEN));
|
||||
pos, skb_put(skb, IEEE80211_CCMP_MIC_LEN));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -490,7 +492,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
|
|||
struct ieee80211_key *key = rx->key;
|
||||
struct sk_buff *skb = rx->skb;
|
||||
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
|
||||
u8 pn[CCMP_PN_LEN];
|
||||
u8 pn[IEEE80211_CCMP_PN_LEN];
|
||||
int data_len;
|
||||
int queue;
|
||||
|
||||
|
|
@ -500,12 +502,13 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
|
|||
!ieee80211_is_robust_mgmt_frame(hdr))
|
||||
return RX_CONTINUE;
|
||||
|
||||
data_len = skb->len - hdrlen - CCMP_HDR_LEN - CCMP_MIC_LEN;
|
||||
data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN -
|
||||
IEEE80211_CCMP_MIC_LEN;
|
||||
if (!rx->sta || data_len < 0)
|
||||
return RX_DROP_UNUSABLE;
|
||||
|
||||
if (status->flag & RX_FLAG_DECRYPTED) {
|
||||
if (!pskb_may_pull(rx->skb, hdrlen + CCMP_HDR_LEN))
|
||||
if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_CCMP_HDR_LEN))
|
||||
return RX_DROP_UNUSABLE;
|
||||
} else {
|
||||
if (skb_linearize(rx->skb))
|
||||
|
|
@ -516,7 +519,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
|
|||
|
||||
queue = rx->security_idx;
|
||||
|
||||
if (memcmp(pn, key->u.ccmp.rx_pn[queue], CCMP_PN_LEN) <= 0) {
|
||||
if (memcmp(pn, key->u.ccmp.rx_pn[queue], IEEE80211_CCMP_PN_LEN) <= 0) {
|
||||
key->u.ccmp.replays++;
|
||||
return RX_DROP_UNUSABLE;
|
||||
}
|
||||
|
|
@ -528,19 +531,20 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx)
|
|||
|
||||
if (ieee80211_aes_ccm_decrypt(
|
||||
key->u.ccmp.tfm, scratch,
|
||||
skb->data + hdrlen + CCMP_HDR_LEN, data_len,
|
||||
skb->data + skb->len - CCMP_MIC_LEN,
|
||||
skb->data + hdrlen + CCMP_HDR_LEN))
|
||||
skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
|
||||
data_len,
|
||||
skb->data + skb->len - IEEE80211_CCMP_MIC_LEN,
|
||||
skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN))
|
||||
return RX_DROP_UNUSABLE;
|
||||
}
|
||||
|
||||
memcpy(key->u.ccmp.rx_pn[queue], pn, CCMP_PN_LEN);
|
||||
memcpy(key->u.ccmp.rx_pn[queue], pn, IEEE80211_CCMP_PN_LEN);
|
||||
|
||||
/* Remove CCMP header and MIC */
|
||||
if (pskb_trim(skb, skb->len - CCMP_MIC_LEN))
|
||||
if (pskb_trim(skb, skb->len - IEEE80211_CCMP_MIC_LEN))
|
||||
return RX_DROP_UNUSABLE;
|
||||
memmove(skb->data + CCMP_HDR_LEN, skb->data, hdrlen);
|
||||
skb_pull(skb, CCMP_HDR_LEN);
|
||||
memmove(skb->data + IEEE80211_CCMP_HDR_LEN, skb->data, hdrlen);
|
||||
skb_pull(skb, IEEE80211_CCMP_HDR_LEN);
|
||||
|
||||
return RX_CONTINUE;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue