aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c2
-rw-r--r--include/net/cfg80211.h5
-rw-r--r--net/mac80211/ibss.c14
-rw-r--r--net/mac80211/mlme.c6
-rw-r--r--net/wireless/nl80211.c27
-rw-r--r--net/wireless/scan.c7
6 files changed, 37 insertions, 24 deletions
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index 8866a2b69c94..0d018460daf9 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -164,6 +164,7 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
164 ies = rcu_dereference(bss->ies); 164 ies = rcu_dereference(bss->ies);
165 beacon_ie = kmemdup(ies->data, ies->len, GFP_ATOMIC); 165 beacon_ie = kmemdup(ies->data, ies->len, GFP_ATOMIC);
166 beacon_ie_len = ies->len; 166 beacon_ie_len = ies->len;
167 bss_desc->timestamp = ies->tsf;
167 rcu_read_unlock(); 168 rcu_read_unlock();
168 169
169 if (!beacon_ie) { 170 if (!beacon_ie) {
@@ -179,7 +180,6 @@ int mwifiex_fill_new_bss_desc(struct mwifiex_private *priv,
179 bss_desc->cap_info_bitmap = bss->capability; 180 bss_desc->cap_info_bitmap = bss->capability;
180 bss_desc->bss_band = bss_priv->band; 181 bss_desc->bss_band = bss_priv->band;
181 bss_desc->fw_tsf = bss_priv->fw_tsf; 182 bss_desc->fw_tsf = bss_priv->fw_tsf;
182 bss_desc->timestamp = bss->tsf;
183 if (bss_desc->cap_info_bitmap & WLAN_CAPABILITY_PRIVACY) { 183 if (bss_desc->cap_info_bitmap & WLAN_CAPABILITY_PRIVACY) {
184 dev_dbg(priv->adapter->dev, "info: InterpretIE: AP WEP enabled\n"); 184 dev_dbg(priv->adapter->dev, "info: InterpretIE: AP WEP enabled\n");
185 bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP; 185 bss_desc->privacy = MWIFIEX_802_11_PRIV_FILTER_8021X_WEP;
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index fb766314b3a1..77686ca28948 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1266,11 +1266,13 @@ enum cfg80211_signal_type {
1266 1266
1267/** 1267/**
1268 * struct cfg80211_bss_ie_data - BSS entry IE data 1268 * struct cfg80211_bss_ie_data - BSS entry IE data
1269 * @tsf: TSF contained in the frame that carried these IEs
1269 * @rcu_head: internal use, for freeing 1270 * @rcu_head: internal use, for freeing
1270 * @len: length of the IEs 1271 * @len: length of the IEs
1271 * @data: IE data 1272 * @data: IE data
1272 */ 1273 */
1273struct cfg80211_bss_ies { 1274struct cfg80211_bss_ies {
1275 u64 tsf;
1274 struct rcu_head rcu_head; 1276 struct rcu_head rcu_head;
1275 int len; 1277 int len;
1276 u8 data[]; 1278 u8 data[];
@@ -1284,7 +1286,6 @@ struct cfg80211_bss_ies {
1284 * 1286 *
1285 * @channel: channel this BSS is on 1287 * @channel: channel this BSS is on
1286 * @bssid: BSSID of the BSS 1288 * @bssid: BSSID of the BSS
1287 * @tsf: timestamp of last received update
1288 * @beacon_interval: the beacon interval as from the frame 1289 * @beacon_interval: the beacon interval as from the frame
1289 * @capability: the capability field in host byte order 1290 * @capability: the capability field in host byte order
1290 * @ies: the information elements (Note that there is no guarantee that these 1291 * @ies: the information elements (Note that there is no guarantee that these
@@ -1304,8 +1305,6 @@ struct cfg80211_bss_ies {
1304 * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes 1305 * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes
1305 */ 1306 */
1306struct cfg80211_bss { 1307struct cfg80211_bss {
1307 u64 tsf;
1308
1309 struct ieee80211_channel *channel; 1308 struct ieee80211_channel *channel;
1310 1309
1311 const struct cfg80211_bss_ies __rcu *ies; 1310 const struct cfg80211_bss_ies __rcu *ies;
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 71c55cc0f7b6..055fa9436e95 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -242,6 +242,8 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
242 u32 basic_rates; 242 u32 basic_rates;
243 int i, j; 243 int i, j;
244 u16 beacon_int = cbss->beacon_interval; 244 u16 beacon_int = cbss->beacon_interval;
245 const struct cfg80211_bss_ies *ies;
246 u64 tsf;
245 247
246 lockdep_assert_held(&sdata->u.ibss.mtx); 248 lockdep_assert_held(&sdata->u.ibss.mtx);
247 249
@@ -265,13 +267,17 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
265 } 267 }
266 } 268 }
267 269
270 rcu_read_lock();
271 ies = rcu_dereference(cbss->ies);
272 tsf = ies->tsf;
273 rcu_read_unlock();
274
268 __ieee80211_sta_join_ibss(sdata, cbss->bssid, 275 __ieee80211_sta_join_ibss(sdata, cbss->bssid,
269 beacon_int, 276 beacon_int,
270 cbss->channel, 277 cbss->channel,
271 basic_rates, 278 basic_rates,
272 cbss->capability, 279 cbss->capability,
273 cbss->tsf, 280 tsf, false);
274 false);
275} 281}
276 282
277static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, 283static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta,
@@ -535,8 +541,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
535 541
536 cbss = container_of((void *)bss, struct cfg80211_bss, priv); 542 cbss = container_of((void *)bss, struct cfg80211_bss, priv);
537 543
538 /* was just updated in ieee80211_bss_info_update */ 544 /* same for beacon and probe response */
539 beacon_timestamp = cbss->tsf; 545 beacon_timestamp = le64_to_cpu(mgmt->u.beacon.timestamp);
540 546
541 /* check if we need to merge IBSS */ 547 /* check if we need to merge IBSS */
542 548
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 40ce00c6d4ca..51eca5a0cdaa 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3667,6 +3667,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
3667 bool have_higher_than_11mbit; 3667 bool have_higher_than_11mbit;
3668 int min_rate = INT_MAX, min_rate_index = -1; 3668 int min_rate = INT_MAX, min_rate_index = -1;
3669 struct ieee80211_supported_band *sband; 3669 struct ieee80211_supported_band *sband;
3670 const struct cfg80211_bss_ies *ies;
3670 3671
3671 sband = local->hw.wiphy->bands[cbss->channel->band]; 3672 sband = local->hw.wiphy->bands[cbss->channel->band];
3672 3673
@@ -3710,7 +3711,10 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
3710 3711
3711 /* set timing information */ 3712 /* set timing information */
3712 sdata->vif.bss_conf.beacon_int = cbss->beacon_interval; 3713 sdata->vif.bss_conf.beacon_int = cbss->beacon_interval;
3713 sdata->vif.bss_conf.sync_tsf = cbss->tsf; 3714 rcu_read_lock();
3715 ies = rcu_dereference(cbss->ies);
3716 sdata->vif.bss_conf.sync_tsf = ies->tsf;
3717 rcu_read_unlock();
3714 sdata->vif.bss_conf.sync_device_ts = bss->device_ts; 3718 sdata->vif.bss_conf.sync_device_ts = bss->device_ts;
3715 3719
3716 /* tell driver about BSSID, basic rates and timing */ 3720 /* tell driver about BSSID, basic rates and timing */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 807d448e702e..93bc63eae076 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -4997,6 +4997,7 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
4997 const struct cfg80211_bss_ies *ies; 4997 const struct cfg80211_bss_ies *ies;
4998 void *hdr; 4998 void *hdr;
4999 struct nlattr *bss; 4999 struct nlattr *bss;
5000 bool tsf = false;
5000 5001
5001 ASSERT_WDEV_LOCK(wdev); 5002 ASSERT_WDEV_LOCK(wdev);
5002 5003
@@ -5020,22 +5021,24 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
5020 5021
5021 rcu_read_lock(); 5022 rcu_read_lock();
5022 ies = rcu_dereference(res->ies); 5023 ies = rcu_dereference(res->ies);
5023 if (ies && ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS, 5024 if (ies) {
5024 ies->len, ies->data)) { 5025 if (nla_put_u64(msg, NL80211_BSS_TSF, ies->tsf))
5025 rcu_read_unlock(); 5026 goto fail_unlock_rcu;
5026 goto nla_put_failure; 5027 tsf = true;
5028 if (ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS,
5029 ies->len, ies->data))
5030 goto fail_unlock_rcu;
5027 } 5031 }
5028 ies = rcu_dereference(res->beacon_ies); 5032 ies = rcu_dereference(res->beacon_ies);
5029 if (ies && ies->len && nla_put(msg, NL80211_BSS_BEACON_IES, 5033 if (ies) {
5030 ies->len, ies->data)) { 5034 if (!tsf && nla_put_u64(msg, NL80211_BSS_TSF, ies->tsf))
5031 rcu_read_unlock(); 5035 goto fail_unlock_rcu;
5032 goto nla_put_failure; 5036 if (ies->len && nla_put(msg, NL80211_BSS_BEACON_IES,
5037 ies->len, ies->data))
5038 goto fail_unlock_rcu;
5033 } 5039 }
5034 rcu_read_unlock(); 5040 rcu_read_unlock();
5035 5041
5036 if (res->tsf &&
5037 nla_put_u64(msg, NL80211_BSS_TSF, res->tsf))
5038 goto nla_put_failure;
5039 if (res->beacon_interval && 5042 if (res->beacon_interval &&
5040 nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval)) 5043 nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval))
5041 goto nla_put_failure; 5044 goto nla_put_failure;
@@ -5080,6 +5083,8 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
5080 5083
5081 return genlmsg_end(msg, hdr); 5084 return genlmsg_end(msg, hdr);
5082 5085
5086 fail_unlock_rcu:
5087 rcu_read_unlock();
5083 nla_put_failure: 5088 nla_put_failure:
5084 genlmsg_cancel(msg, hdr); 5089 genlmsg_cancel(msg, hdr);
5085 return -EMSGSIZE; 5090 return -EMSGSIZE;
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 02a238329c83..b7a167984986 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -695,7 +695,6 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
695 695
696 if (found) { 696 if (found) {
697 found->pub.beacon_interval = tmp->pub.beacon_interval; 697 found->pub.beacon_interval = tmp->pub.beacon_interval;
698 found->pub.tsf = tmp->pub.tsf;
699 found->pub.signal = tmp->pub.signal; 698 found->pub.signal = tmp->pub.signal;
700 found->pub.capability = tmp->pub.capability; 699 found->pub.capability = tmp->pub.capability;
701 found->ts = tmp->ts; 700 found->ts = tmp->ts;
@@ -880,7 +879,6 @@ cfg80211_inform_bss(struct wiphy *wiphy,
880 memcpy(tmp.pub.bssid, bssid, ETH_ALEN); 879 memcpy(tmp.pub.bssid, bssid, ETH_ALEN);
881 tmp.pub.channel = channel; 880 tmp.pub.channel = channel;
882 tmp.pub.signal = signal; 881 tmp.pub.signal = signal;
883 tmp.pub.tsf = tsf;
884 tmp.pub.beacon_interval = beacon_interval; 882 tmp.pub.beacon_interval = beacon_interval;
885 tmp.pub.capability = capability; 883 tmp.pub.capability = capability;
886 /* 884 /*
@@ -895,6 +893,7 @@ cfg80211_inform_bss(struct wiphy *wiphy,
895 if (!ies) 893 if (!ies)
896 return NULL; 894 return NULL;
897 ies->len = ielen; 895 ies->len = ielen;
896 ies->tsf = tsf;
898 memcpy(ies->data, ie, ielen); 897 memcpy(ies->data, ie, ielen);
899 898
900 rcu_assign_pointer(tmp.pub.beacon_ies, ies); 899 rcu_assign_pointer(tmp.pub.beacon_ies, ies);
@@ -951,6 +950,7 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
951 if (!ies) 950 if (!ies)
952 return NULL; 951 return NULL;
953 ies->len = ielen; 952 ies->len = ielen;
953 ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
954 memcpy(ies->data, mgmt->u.probe_resp.variable, ielen); 954 memcpy(ies->data, mgmt->u.probe_resp.variable, ielen);
955 955
956 if (ieee80211_is_probe_resp(mgmt->frame_control)) 956 if (ieee80211_is_probe_resp(mgmt->frame_control))
@@ -962,7 +962,6 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
962 memcpy(tmp.pub.bssid, mgmt->bssid, ETH_ALEN); 962 memcpy(tmp.pub.bssid, mgmt->bssid, ETH_ALEN);
963 tmp.pub.channel = channel; 963 tmp.pub.channel = channel;
964 tmp.pub.signal = signal; 964 tmp.pub.signal = signal;
965 tmp.pub.tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
966 tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int); 965 tmp.pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
967 tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info); 966 tmp.pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
968 967
@@ -1409,7 +1408,7 @@ ieee80211_bss(struct wiphy *wiphy, struct iw_request_info *info,
1409 if (buf) { 1408 if (buf) {
1410 memset(&iwe, 0, sizeof(iwe)); 1409 memset(&iwe, 0, sizeof(iwe));
1411 iwe.cmd = IWEVCUSTOM; 1410 iwe.cmd = IWEVCUSTOM;
1412 sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->pub.tsf)); 1411 sprintf(buf, "tsf=%016llx", (unsigned long long)(ies->tsf));
1413 iwe.u.data.length = strlen(buf); 1412 iwe.u.data.length = strlen(buf);
1414 current_ev = iwe_stream_add_point(info, current_ev, end_buf, 1413 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1415 &iwe, buf); 1414 &iwe, buf);