aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2009-12-28 15:09:11 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-12-28 15:09:11 -0500
commitea1e4b842049fcc4741096538114871a74859314 (patch)
treec2336ab480ac0fd62e0dc41b391d99c97158dc9c /net/mac80211
parentb6ce5c33001b1dc83e6a1a6f30c5dccccea651b6 (diff)
parent92c6f8d849178582fc527aaf1e51dd37a74767d3 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6
Diffstat (limited to 'net/mac80211')
-rw-r--r--net/mac80211/cfg.c3
-rw-r--r--net/mac80211/ht.c25
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/main.c2
-rw-r--r--net/mac80211/mesh.c2
-rw-r--r--net/mac80211/mesh.h5
-rw-r--r--net/mac80211/mesh_hwmp.c2
-rw-r--r--net/mac80211/mlme.c18
-rw-r--r--net/mac80211/rx.c1
-rw-r--r--net/mac80211/scan.c20
-rw-r--r--net/mac80211/util.c2
11 files changed, 65 insertions, 16 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index f07c4abefe56..63843e3e576a 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -354,7 +354,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
354 sinfo->rx_packets = sta->rx_packets; 354 sinfo->rx_packets = sta->rx_packets;
355 sinfo->tx_packets = sta->tx_packets; 355 sinfo->tx_packets = sta->tx_packets;
356 356
357 if (sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) { 357 if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
358 (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
358 sinfo->filled |= STATION_INFO_SIGNAL; 359 sinfo->filled |= STATION_INFO_SIGNAL;
359 sinfo->signal = (s8)sta->last_signal; 360 sinfo->signal = (s8)sta->last_signal;
360 } 361 }
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 63b8f86b7f16..bb677a73b7c9 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -34,9 +34,28 @@ void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband,
34 34
35 ht_cap->ht_supported = true; 35 ht_cap->ht_supported = true;
36 36
37 ht_cap->cap = le16_to_cpu(ht_cap_ie->cap_info) & sband->ht_cap.cap; 37 /*
38 ht_cap->cap &= ~IEEE80211_HT_CAP_SM_PS; 38 * The bits listed in this expression should be
39 ht_cap->cap |= sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS; 39 * the same for the peer and us, if the station
40 * advertises more then we can't use those thus
41 * we mask them out.
42 */
43 ht_cap->cap = le16_to_cpu(ht_cap_ie->cap_info) &
44 (sband->ht_cap.cap |
45 ~(IEEE80211_HT_CAP_LDPC_CODING |
46 IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
47 IEEE80211_HT_CAP_GRN_FLD |
48 IEEE80211_HT_CAP_SGI_20 |
49 IEEE80211_HT_CAP_SGI_40 |
50 IEEE80211_HT_CAP_DSSSCCK40));
51 /*
52 * The STBC bits are asymmetric -- if we don't have
53 * TX then mask out the peer's RX and vice versa.
54 */
55 if (!(sband->ht_cap.cap & IEEE80211_HT_CAP_TX_STBC))
56 ht_cap->cap &= ~IEEE80211_HT_CAP_RX_STBC;
57 if (!(sband->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC))
58 ht_cap->cap &= ~IEEE80211_HT_CAP_TX_STBC;
40 59
41 ampdu_info = ht_cap_ie->ampdu_params_info; 60 ampdu_info = ht_cap_ie->ampdu_params_info;
42 ht_cap->ampdu_factor = 61 ht_cap->ampdu_factor =
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 6fb3f7181536..88b0ba6c7484 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -752,6 +752,7 @@ struct ieee80211_local {
752 unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ 752 unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */
753 753
754 bool pspolling; 754 bool pspolling;
755 bool scan_ps_enabled;
755 /* 756 /*
756 * PS can only be enabled when we have exactly one managed 757 * PS can only be enabled when we have exactly one managed
757 * interface (and monitors) in PS, this then points there. 758 * interface (and monitors) in PS, this then points there.
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 25f52098b636..d4426748ab10 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -543,6 +543,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
543 * and we need some headroom for passing the frame to monitor 543 * and we need some headroom for passing the frame to monitor
544 * interfaces, but never both at the same time. 544 * interfaces, but never both at the same time.
545 */ 545 */
546 BUILD_BUG_ON(IEEE80211_TX_STATUS_HEADROOM !=
547 sizeof(struct ieee80211_tx_status_rtap_hdr));
546 local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom, 548 local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom,
547 sizeof(struct ieee80211_tx_status_rtap_hdr)); 549 sizeof(struct ieee80211_tx_status_rtap_hdr));
548 550
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 63299b72a7b0..e0bd85e3d4b6 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -427,7 +427,7 @@ int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
427 char *addr5, char *addr6) 427 char *addr5, char *addr6)
428{ 428{
429 int aelen = 0; 429 int aelen = 0;
430 memset(meshhdr, 0, sizeof(meshhdr)); 430 memset(meshhdr, 0, sizeof(*meshhdr));
431 meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL; 431 meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
432 put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum); 432 put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum);
433 sdata->u.mesh.mesh_seqnum++; 433 sdata->u.mesh.mesh_seqnum++;
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 31e102541869..85562c59d7d6 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -188,8 +188,9 @@ struct mesh_rmc {
188 */ 188 */
189#define MESH_PREQ_MIN_INT 10 189#define MESH_PREQ_MIN_INT 10
190#define MESH_DIAM_TRAVERSAL_TIME 50 190#define MESH_DIAM_TRAVERSAL_TIME 50
191/* Paths will be refreshed if they are closer than PATH_REFRESH_TIME to their 191/* A path will be refreshed if it is used PATH_REFRESH_TIME milliseconds before
192 * expiration 192 * timing out. This way it will remain ACTIVE and no data frames will be
193 * unnecesarily held in the pending queue.
193 */ 194 */
194#define MESH_PATH_REFRESH_TIME 1000 195#define MESH_PATH_REFRESH_TIME 1000
195#define MESH_MIN_DISCOVERY_TIMEOUT (2 * MESH_DIAM_TRAVERSAL_TIME) 196#define MESH_MIN_DISCOVERY_TIMEOUT (2 * MESH_DIAM_TRAVERSAL_TIME)
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 664f5cc2b273..ce84237ebad3 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -937,7 +937,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
937 937
938 if (mpath->flags & MESH_PATH_ACTIVE) { 938 if (mpath->flags & MESH_PATH_ACTIVE) {
939 if (time_after(jiffies, 939 if (time_after(jiffies,
940 mpath->exp_time + 940 mpath->exp_time -
941 msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) && 941 msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time)) &&
942 !memcmp(sdata->vif.addr, hdr->addr4, ETH_ALEN) && 942 !memcmp(sdata->vif.addr, hdr->addr4, ETH_ALEN) &&
943 !(mpath->flags & MESH_PATH_RESOLVING) && 943 !(mpath->flags & MESH_PATH_RESOLVING) &&
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 5174bfc5710d..2f9ed8b9c3f0 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -973,6 +973,14 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
973 sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL | 973 sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL |
974 IEEE80211_STA_BEACON_POLL); 974 IEEE80211_STA_BEACON_POLL);
975 975
976 /*
977 * Always handle WMM once after association regardless
978 * of the first value the AP uses. Setting -1 here has
979 * that effect because the AP values is an unsigned
980 * 4-bit value.
981 */
982 sdata->u.mgd.wmm_last_param_set = -1;
983
976 ieee80211_led_assoc(local, 1); 984 ieee80211_led_assoc(local, 1);
977 985
978 sdata->vif.bss_conf.assoc = 1; 986 sdata->vif.bss_conf.assoc = 1;
@@ -1142,8 +1150,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1142 1150
1143 ieee80211_set_wmm_default(sdata); 1151 ieee80211_set_wmm_default(sdata);
1144 1152
1145 ieee80211_recalc_idle(local);
1146
1147 /* channel(_type) changes are handled by ieee80211_hw_config */ 1153 /* channel(_type) changes are handled by ieee80211_hw_config */
1148 local->oper_channel_type = NL80211_CHAN_NO_HT; 1154 local->oper_channel_type = NL80211_CHAN_NO_HT;
1149 1155
@@ -1429,6 +1435,7 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1429 1435
1430 if (!wk) { 1436 if (!wk) {
1431 ieee80211_set_disassoc(sdata, true); 1437 ieee80211_set_disassoc(sdata, true);
1438 ieee80211_recalc_idle(sdata->local);
1432 } else { 1439 } else {
1433 list_del(&wk->list); 1440 list_del(&wk->list);
1434 kfree(wk); 1441 kfree(wk);
@@ -1462,6 +1469,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1462 sdata->name, mgmt->sa, reason_code); 1469 sdata->name, mgmt->sa, reason_code);
1463 1470
1464 ieee80211_set_disassoc(sdata, false); 1471 ieee80211_set_disassoc(sdata, false);
1472 ieee80211_recalc_idle(sdata->local);
1465 return RX_MGMT_CFG80211_DISASSOC; 1473 return RX_MGMT_CFG80211_DISASSOC;
1466} 1474}
1467 1475
@@ -2164,6 +2172,7 @@ static void ieee80211_sta_work(struct work_struct *work)
2164 " after %dms, disconnecting.\n", 2172 " after %dms, disconnecting.\n",
2165 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); 2173 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
2166 ieee80211_set_disassoc(sdata, true); 2174 ieee80211_set_disassoc(sdata, true);
2175 ieee80211_recalc_idle(local);
2167 mutex_unlock(&ifmgd->mtx); 2176 mutex_unlock(&ifmgd->mtx);
2168 /* 2177 /*
2169 * must be outside lock due to cfg80211, 2178 * must be outside lock due to cfg80211,
@@ -2612,6 +2621,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2612 IEEE80211_STYPE_DEAUTH, req->reason_code, 2621 IEEE80211_STYPE_DEAUTH, req->reason_code,
2613 cookie); 2622 cookie);
2614 2623
2624 ieee80211_recalc_idle(sdata->local);
2625
2615 return 0; 2626 return 0;
2616} 2627}
2617 2628
@@ -2644,5 +2655,8 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2644 ieee80211_send_deauth_disassoc(sdata, req->bss->bssid, 2655 ieee80211_send_deauth_disassoc(sdata, req->bss->bssid,
2645 IEEE80211_STYPE_DISASSOC, req->reason_code, 2656 IEEE80211_STYPE_DISASSOC, req->reason_code,
2646 cookie); 2657 cookie);
2658
2659 ieee80211_recalc_idle(sdata->local);
2660
2647 return 0; 2661 return 0;
2648} 2662}
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index a182e423109b..6cbf1a7b3157 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1631,7 +1631,6 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1631 mpp_path_add(proxied_addr, mpp_addr, sdata); 1631 mpp_path_add(proxied_addr, mpp_addr, sdata);
1632 } else { 1632 } else {
1633 spin_lock_bh(&mppath->state_lock); 1633 spin_lock_bh(&mppath->state_lock);
1634 mppath->exp_time = jiffies;
1635 if (compare_ether_addr(mppath->mpp, mpp_addr) != 0) 1634 if (compare_ether_addr(mppath->mpp, mpp_addr) != 0)
1636 memcpy(mppath->mpp, mpp_addr, ETH_ALEN); 1635 memcpy(mppath->mpp, mpp_addr, ETH_ALEN);
1637 spin_unlock_bh(&mppath->state_lock); 1636 spin_unlock_bh(&mppath->state_lock);
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index d3381ba5f457..66da0ab1d8fa 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -227,7 +227,8 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local)
227static void ieee80211_scan_ps_enable(struct ieee80211_sub_if_data *sdata) 227static void ieee80211_scan_ps_enable(struct ieee80211_sub_if_data *sdata)
228{ 228{
229 struct ieee80211_local *local = sdata->local; 229 struct ieee80211_local *local = sdata->local;
230 bool ps = false; 230
231 local->scan_ps_enabled = false;
231 232
232 /* FIXME: what to do when local->pspolling is true? */ 233 /* FIXME: what to do when local->pspolling is true? */
233 234
@@ -235,12 +236,13 @@ static void ieee80211_scan_ps_enable(struct ieee80211_sub_if_data *sdata)
235 cancel_work_sync(&local->dynamic_ps_enable_work); 236 cancel_work_sync(&local->dynamic_ps_enable_work);
236 237
237 if (local->hw.conf.flags & IEEE80211_CONF_PS) { 238 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
238 ps = true; 239 local->scan_ps_enabled = true;
239 local->hw.conf.flags &= ~IEEE80211_CONF_PS; 240 local->hw.conf.flags &= ~IEEE80211_CONF_PS;
240 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 241 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
241 } 242 }
242 243
243 if (!ps || !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)) 244 if (!(local->scan_ps_enabled) ||
245 !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK))
244 /* 246 /*
245 * If power save was enabled, no need to send a nullfunc 247 * If power save was enabled, no need to send a nullfunc
246 * frame because AP knows that we are sleeping. But if the 248 * frame because AP knows that we are sleeping. But if the
@@ -261,7 +263,7 @@ static void ieee80211_scan_ps_disable(struct ieee80211_sub_if_data *sdata)
261 263
262 if (!local->ps_sdata) 264 if (!local->ps_sdata)
263 ieee80211_send_nullfunc(local, sdata, 0); 265 ieee80211_send_nullfunc(local, sdata, 0);
264 else { 266 else if (local->scan_ps_enabled) {
265 /* 267 /*
266 * In !IEEE80211_HW_PS_NULLFUNC_STACK case the hardware 268 * In !IEEE80211_HW_PS_NULLFUNC_STACK case the hardware
267 * will send a nullfunc frame with the powersave bit set 269 * will send a nullfunc frame with the powersave bit set
@@ -277,6 +279,16 @@ static void ieee80211_scan_ps_disable(struct ieee80211_sub_if_data *sdata)
277 */ 279 */
278 local->hw.conf.flags |= IEEE80211_CONF_PS; 280 local->hw.conf.flags |= IEEE80211_CONF_PS;
279 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); 281 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS);
282 } else if (local->hw.conf.dynamic_ps_timeout > 0) {
283 /*
284 * If IEEE80211_CONF_PS was not set and the dynamic_ps_timer
285 * had been running before leaving the operating channel,
286 * restart the timer now and send a nullfunc frame to inform
287 * the AP that we are awake.
288 */
289 ieee80211_send_nullfunc(local, sdata, 0);
290 mod_timer(&local->dynamic_ps_timer, jiffies +
291 msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
280 } 292 }
281} 293}
282 294
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index acb6626ad0a4..b01972579c7c 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -579,7 +579,7 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
579 if (elen > left) 579 if (elen > left)
580 break; 580 break;
581 581
582 if (calc_crc && id < 64 && (filter & BIT(id))) 582 if (calc_crc && id < 64 && (filter & (1ULL << id)))
583 crc = crc32_be(crc, pos - 2, elen + 2); 583 crc = crc32_be(crc, pos - 2, elen + 2);
584 584
585 switch (id) { 585 switch (id) {