aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2010-10-15 16:11:56 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-10-15 16:11:56 -0400
commitc64557d666eb62eb5f296c6b93bd0a5525ed1e36 (patch)
tree1e25cc32521d06ae876de18bb8e48b3cf9d30808 /net
parent1a63c353c856c9f6d44a533afb6ad6dbbcdea683 (diff)
parent0d91f22b75347d9503b17a42b6c74d3f7750acd6 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c22
-rw-r--r--net/mac80211/ht.c2
-rw-r--r--net/mac80211/ieee80211_i.h4
-rw-r--r--net/mac80211/iface.c9
-rw-r--r--net/mac80211/main.c3
-rw-r--r--net/mac80211/mesh_plink.c17
-rw-r--r--net/mac80211/mlme.c18
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c7
-rw-r--r--net/mac80211/rx.c24
-rw-r--r--net/mac80211/wep.c8
-rw-r--r--net/wireless/core.c54
-rw-r--r--net/wireless/mlme.c23
-rw-r--r--net/wireless/nl80211.c15
-rw-r--r--net/wireless/radiotap.c58
-rw-r--r--net/wireless/sysfs.c9
-rw-r--r--net/wireless/wext-compat.c4
16 files changed, 195 insertions, 82 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index ecf9b7166ed1..18bd0e550600 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -329,7 +329,8 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
329 STATION_INFO_TX_PACKETS | 329 STATION_INFO_TX_PACKETS |
330 STATION_INFO_TX_RETRIES | 330 STATION_INFO_TX_RETRIES |
331 STATION_INFO_TX_FAILED | 331 STATION_INFO_TX_FAILED |
332 STATION_INFO_TX_BITRATE; 332 STATION_INFO_TX_BITRATE |
333 STATION_INFO_RX_DROP_MISC;
333 334
334 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); 335 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
335 sinfo->rx_bytes = sta->rx_bytes; 336 sinfo->rx_bytes = sta->rx_bytes;
@@ -338,6 +339,7 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
338 sinfo->tx_packets = sta->tx_packets; 339 sinfo->tx_packets = sta->tx_packets;
339 sinfo->tx_retries = sta->tx_retry_count; 340 sinfo->tx_retries = sta->tx_retry_count;
340 sinfo->tx_failed = sta->tx_retry_failed; 341 sinfo->tx_failed = sta->tx_retry_failed;
342 sinfo->rx_dropped_misc = sta->rx_dropped;
341 343
342 if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || 344 if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) ||
343 (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { 345 (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) {
@@ -1602,6 +1604,23 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1602 return 0; 1604 return 0;
1603} 1605}
1604 1606
1607static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
1608 struct net_device *dev,
1609 u16 frame_type, bool reg)
1610{
1611 struct ieee80211_local *local = wiphy_priv(wiphy);
1612
1613 if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
1614 return;
1615
1616 if (reg)
1617 local->probe_req_reg++;
1618 else
1619 local->probe_req_reg--;
1620
1621 ieee80211_queue_work(&local->hw, &local->reconfig_filter);
1622}
1623
1605struct cfg80211_ops mac80211_config_ops = { 1624struct cfg80211_ops mac80211_config_ops = {
1606 .add_virtual_intf = ieee80211_add_iface, 1625 .add_virtual_intf = ieee80211_add_iface,
1607 .del_virtual_intf = ieee80211_del_iface, 1626 .del_virtual_intf = ieee80211_del_iface,
@@ -1653,4 +1672,5 @@ struct cfg80211_ops mac80211_config_ops = {
1653 .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel, 1672 .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,
1654 .mgmt_tx = ieee80211_mgmt_tx, 1673 .mgmt_tx = ieee80211_mgmt_tx,
1655 .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config, 1674 .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config,
1675 .mgmt_frame_register = ieee80211_mgmt_frame_register,
1656}; 1676};
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
index 4214bb6e12fc..75d679d75e63 100644
--- a/net/mac80211/ht.c
+++ b/net/mac80211/ht.c
@@ -291,6 +291,8 @@ void ieee80211_request_smps(struct ieee80211_vif *vif,
291 if (WARN_ON(smps_mode == IEEE80211_SMPS_OFF)) 291 if (WARN_ON(smps_mode == IEEE80211_SMPS_OFF))
292 smps_mode = IEEE80211_SMPS_AUTOMATIC; 292 smps_mode = IEEE80211_SMPS_AUTOMATIC;
293 293
294 sdata->u.mgd.driver_smps_mode = smps_mode;
295
294 ieee80211_queue_work(&sdata->local->hw, 296 ieee80211_queue_work(&sdata->local->hw,
295 &sdata->u.mgd.request_smps_work); 297 &sdata->u.mgd.request_smps_work);
296} 298}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index f0610fa4fbe0..b80c38689927 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -707,7 +707,9 @@ struct ieee80211_local {
707 int open_count; 707 int open_count;
708 int monitors, cooked_mntrs; 708 int monitors, cooked_mntrs;
709 /* number of interfaces with corresponding FIF_ flags */ 709 /* number of interfaces with corresponding FIF_ flags */
710 int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll; 710 int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll,
711 fif_probe_req;
712 int probe_req_reg;
711 unsigned int filter_flags; /* FIF_* */ 713 unsigned int filter_flags; /* FIF_* */
712 714
713 bool wiphy_ciphers_allocated; 715 bool wiphy_ciphers_allocated;
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index e99d1b60557c..f9163b12c7f1 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -280,8 +280,11 @@ static int ieee80211_do_open(struct net_device *dev, bool coming_up)
280 ieee80211_start_mesh(sdata); 280 ieee80211_start_mesh(sdata);
281 } else if (sdata->vif.type == NL80211_IFTYPE_AP) { 281 } else if (sdata->vif.type == NL80211_IFTYPE_AP) {
282 local->fif_pspoll++; 282 local->fif_pspoll++;
283 local->fif_probe_req++;
283 284
284 ieee80211_configure_filter(local); 285 ieee80211_configure_filter(local);
286 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
287 local->fif_probe_req++;
285 } 288 }
286 289
287 changed |= ieee80211_reset_erp_info(sdata); 290 changed |= ieee80211_reset_erp_info(sdata);
@@ -428,8 +431,12 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
428 if (sdata->flags & IEEE80211_SDATA_PROMISC) 431 if (sdata->flags & IEEE80211_SDATA_PROMISC)
429 atomic_dec(&local->iff_promiscs); 432 atomic_dec(&local->iff_promiscs);
430 433
431 if (sdata->vif.type == NL80211_IFTYPE_AP) 434 if (sdata->vif.type == NL80211_IFTYPE_AP) {
432 local->fif_pspoll--; 435 local->fif_pspoll--;
436 local->fif_probe_req--;
437 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
438 local->fif_probe_req--;
439 }
433 440
434 netif_addr_lock_bh(sdata->dev); 441 netif_addr_lock_bh(sdata->dev);
435 spin_lock_bh(&local->filter_lock); 442 spin_lock_bh(&local->filter_lock);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index eb0f59977676..22bc42b18991 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -54,6 +54,9 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
54 if (local->monitors || local->scanning) 54 if (local->monitors || local->scanning)
55 new_flags |= FIF_BCN_PRBRESP_PROMISC; 55 new_flags |= FIF_BCN_PRBRESP_PROMISC;
56 56
57 if (local->fif_probe_req || local->probe_req_reg)
58 new_flags |= FIF_PROBE_REQ;
59
57 if (local->fif_fcsfail) 60 if (local->fif_fcsfail)
58 new_flags |= FIF_FCSFAIL; 61 new_flags |= FIF_FCSFAIL;
59 62
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index ea13a80a476c..1c91f0f3c307 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -412,7 +412,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
412 enum plink_event event; 412 enum plink_event event;
413 enum plink_frame_type ftype; 413 enum plink_frame_type ftype;
414 size_t baselen; 414 size_t baselen;
415 bool deactivated; 415 bool deactivated, matches_local = true;
416 u8 ie_len; 416 u8 ie_len;
417 u8 *baseaddr; 417 u8 *baseaddr;
418 __le16 plid, llid, reason; 418 __le16 plid, llid, reason;
@@ -487,6 +487,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
487 /* Now we will figure out the appropriate event... */ 487 /* Now we will figure out the appropriate event... */
488 event = PLINK_UNDEFINED; 488 event = PLINK_UNDEFINED;
489 if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) { 489 if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) {
490 matches_local = false;
490 switch (ftype) { 491 switch (ftype) {
491 case PLINK_OPEN: 492 case PLINK_OPEN:
492 event = OPN_RJCT; 493 event = OPN_RJCT;
@@ -498,7 +499,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
498 /* avoid warning */ 499 /* avoid warning */
499 break; 500 break;
500 } 501 }
501 spin_lock_bh(&sta->lock); 502 }
503
504 if (!sta && !matches_local) {
505 rcu_read_unlock();
506 reason = cpu_to_le16(MESH_CAPABILITY_POLICY_VIOLATION);
507 llid = 0;
508 mesh_plink_frame_tx(sdata, PLINK_CLOSE, mgmt->sa, llid,
509 plid, reason);
510 return;
502 } else if (!sta) { 511 } else if (!sta) {
503 /* ftype == PLINK_OPEN */ 512 /* ftype == PLINK_OPEN */
504 u32 rates; 513 u32 rates;
@@ -522,7 +531,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
522 } 531 }
523 event = OPN_ACPT; 532 event = OPN_ACPT;
524 spin_lock_bh(&sta->lock); 533 spin_lock_bh(&sta->lock);
525 } else { 534 } else if (matches_local) {
526 spin_lock_bh(&sta->lock); 535 spin_lock_bh(&sta->lock);
527 switch (ftype) { 536 switch (ftype) {
528 case PLINK_OPEN: 537 case PLINK_OPEN:
@@ -564,6 +573,8 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m
564 rcu_read_unlock(); 573 rcu_read_unlock();
565 return; 574 return;
566 } 575 }
576 } else {
577 spin_lock_bh(&sta->lock);
567 } 578 }
568 579
569 mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n", 580 mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n",
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 5695c94c49aa..a3a9421555af 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1864,10 +1864,12 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
1864 1864
1865 else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) { 1865 else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) {
1866#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 1866#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1867 printk(KERN_DEBUG "No probe response from AP %pM" 1867 wiphy_debug(local->hw.wiphy,
1868 " after %dms, try %d\n", bssid, 1868 "%s: No probe response from AP %pM"
1869 (1000 * IEEE80211_PROBE_WAIT)/HZ, 1869 " after %dms, try %d\n",
1870 ifmgd->probe_send_count); 1870 sdata->name,
1871 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ,
1872 ifmgd->probe_send_count);
1871#endif 1873#endif
1872 ieee80211_mgd_probe_ap_send(sdata); 1874 ieee80211_mgd_probe_ap_send(sdata);
1873 } else { 1875 } else {
@@ -1877,9 +1879,11 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
1877 */ 1879 */
1878 ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | 1880 ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
1879 IEEE80211_STA_BEACON_POLL); 1881 IEEE80211_STA_BEACON_POLL);
1880 printk(KERN_DEBUG "No probe response from AP %pM" 1882 wiphy_debug(local->hw.wiphy,
1881 " after %dms, disconnecting.\n", 1883 "%s: No probe response from AP %pM"
1882 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); 1884 " after %dms, disconnecting.\n",
1885 sdata->name,
1886 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
1883 ieee80211_set_disassoc(sdata, true, true); 1887 ieee80211_set_disassoc(sdata, true, true);
1884 mutex_unlock(&ifmgd->mtx); 1888 mutex_unlock(&ifmgd->mtx);
1885 mutex_lock(&local->mtx); 1889 mutex_lock(&local->mtx);
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index c5b465904e3b..2a18d6602d4a 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -397,8 +397,9 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
397 !(info->flags & IEEE80211_TX_STAT_AMPDU)) 397 !(info->flags & IEEE80211_TX_STAT_AMPDU))
398 return; 398 return;
399 399
400 if (!info->status.ampdu_len) { 400 if (!(info->flags & IEEE80211_TX_STAT_AMPDU)) {
401 info->status.ampdu_ack_len = 1; 401 info->status.ampdu_ack_len =
402 (info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0);
402 info->status.ampdu_len = 1; 403 info->status.ampdu_len = 1;
403 } 404 }
404 405
@@ -426,7 +427,7 @@ minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
426 group = minstrel_ht_get_group_idx(&ar[i]); 427 group = minstrel_ht_get_group_idx(&ar[i]);
427 rate = &mi->groups[group].rates[ar[i].idx % 8]; 428 rate = &mi->groups[group].rates[ar[i].idx % 8];
428 429
429 if (last && (info->flags & IEEE80211_TX_STAT_ACK)) 430 if (last)
430 rate->success += info->status.ampdu_ack_len; 431 rate->success += info->status.ampdu_ack_len;
431 432
432 rate->attempts += ar[i].count * info->status.ampdu_len; 433 rate->attempts += ar[i].count * info->status.ampdu_len;
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b67221def584..902b03ee8f60 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -622,6 +622,26 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
622 tid_agg_rx->buf_size; 622 tid_agg_rx->buf_size;
623 } 623 }
624 624
625 /*
626 * Disable the reorder release timer for now.
627 *
628 * The current implementation lacks a proper locking scheme
629 * which would protect vital statistic and debug counters
630 * from being updated by two different but concurrent BHs.
631 *
632 * More information about the topic is available from:
633 * - thread: http://marc.info/?t=128635927000001
634 *
635 * What was wrong:
636 * => http://marc.info/?l=linux-wireless&m=128636170811964
637 * "Basically the thing is that until your patch, the data
638 * in the struct didn't actually need locking because it
639 * was accessed by the RX path only which is not concurrent."
640 *
641 * List of what needs to be fixed:
642 * => http://marc.info/?l=linux-wireless&m=128656352920957
643 *
644
625 if (tid_agg_rx->stored_mpdu_num) { 645 if (tid_agg_rx->stored_mpdu_num) {
626 j = index = seq_sub(tid_agg_rx->head_seq_num, 646 j = index = seq_sub(tid_agg_rx->head_seq_num,
627 tid_agg_rx->ssn) % tid_agg_rx->buf_size; 647 tid_agg_rx->ssn) % tid_agg_rx->buf_size;
@@ -640,6 +660,10 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw,
640 } else { 660 } else {
641 del_timer(&tid_agg_rx->reorder_timer); 661 del_timer(&tid_agg_rx->reorder_timer);
642 } 662 }
663 */
664
665set_release_timer:
666 return;
643} 667}
644 668
645/* 669/*
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index f27484c22b9f..2ff6d1e3ed21 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -222,7 +222,7 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
222 struct ieee80211_key *key) 222 struct ieee80211_key *key)
223{ 223{
224 u32 klen; 224 u32 klen;
225 u8 *rc4key; 225 u8 rc4key[3 + WLAN_KEY_LEN_WEP104];
226 u8 keyidx; 226 u8 keyidx;
227 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 227 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
228 unsigned int hdrlen; 228 unsigned int hdrlen;
@@ -245,10 +245,6 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
245 245
246 klen = 3 + key->conf.keylen; 246 klen = 3 + key->conf.keylen;
247 247
248 rc4key = kmalloc(klen, GFP_ATOMIC);
249 if (!rc4key)
250 return -1;
251
252 /* Prepend 24-bit IV to RC4 key */ 248 /* Prepend 24-bit IV to RC4 key */
253 memcpy(rc4key, skb->data + hdrlen, 3); 249 memcpy(rc4key, skb->data + hdrlen, 3);
254 250
@@ -260,8 +256,6 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local,
260 len)) 256 len))
261 ret = -1; 257 ret = -1;
262 258
263 kfree(rc4key);
264
265 /* Trim ICV */ 259 /* Trim ICV */
266 skb_trim(skb, skb->len - WEP_ICV_LEN); 260 skb_trim(skb, skb->len - WEP_ICV_LEN);
267 261
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 1684ad91763c..9c21ebf9780e 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -178,10 +178,26 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
178 char *newname) 178 char *newname)
179{ 179{
180 struct cfg80211_registered_device *rdev2; 180 struct cfg80211_registered_device *rdev2;
181 int result; 181 int wiphy_idx, taken = -1, result, digits;
182 182
183 assert_cfg80211_lock(); 183 assert_cfg80211_lock();
184 184
185 /* prohibit calling the thing phy%d when %d is not its number */
186 sscanf(newname, PHY_NAME "%d%n", &wiphy_idx, &taken);
187 if (taken == strlen(newname) && wiphy_idx != rdev->wiphy_idx) {
188 /* count number of places needed to print wiphy_idx */
189 digits = 1;
190 while (wiphy_idx /= 10)
191 digits++;
192 /*
193 * deny the name if it is phy<idx> where <idx> is printed
194 * without leading zeroes. taken == strlen(newname) here
195 */
196 if (taken == strlen(PHY_NAME) + digits)
197 return -EINVAL;
198 }
199
200
185 /* Ignore nop renames */ 201 /* Ignore nop renames */
186 if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0) 202 if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0)
187 return 0; 203 return 0;
@@ -189,7 +205,7 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
189 /* Ensure another device does not already have this name. */ 205 /* Ensure another device does not already have this name. */
190 list_for_each_entry(rdev2, &cfg80211_rdev_list, list) 206 list_for_each_entry(rdev2, &cfg80211_rdev_list, list)
191 if (strcmp(newname, dev_name(&rdev2->wiphy.dev)) == 0) 207 if (strcmp(newname, dev_name(&rdev2->wiphy.dev)) == 0)
192 return -EEXIST; 208 return -EINVAL;
193 209
194 result = device_rename(&rdev->wiphy.dev, newname); 210 result = device_rename(&rdev->wiphy.dev, newname);
195 if (result) 211 if (result)
@@ -304,11 +320,9 @@ static void cfg80211_event_work(struct work_struct *work)
304struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) 320struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
305{ 321{
306 static int wiphy_counter; 322 static int wiphy_counter;
307 int i; 323
308 struct cfg80211_registered_device *rdev, *rdev2; 324 struct cfg80211_registered_device *rdev;
309 int alloc_size; 325 int alloc_size;
310 char nname[IFNAMSIZ + 1];
311 bool found = false;
312 326
313 WARN_ON(ops->add_key && (!ops->del_key || !ops->set_default_key)); 327 WARN_ON(ops->add_key && (!ops->del_key || !ops->set_default_key));
314 WARN_ON(ops->auth && (!ops->assoc || !ops->deauth || !ops->disassoc)); 328 WARN_ON(ops->auth && (!ops->assoc || !ops->deauth || !ops->disassoc));
@@ -332,37 +346,17 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
332 346
333 if (unlikely(!wiphy_idx_valid(rdev->wiphy_idx))) { 347 if (unlikely(!wiphy_idx_valid(rdev->wiphy_idx))) {
334 wiphy_counter--; 348 wiphy_counter--;
335 goto too_many_devs;
336 }
337
338 /* 64k wiphy devices is enough for anyone! */
339 for (i = 0; i < 0xFFFF; i++) {
340 found = false;
341 snprintf(nname, sizeof(nname)-1, PHY_NAME "%d", i);
342 nname[sizeof(nname)-1] = 0;
343 list_for_each_entry(rdev2, &cfg80211_rdev_list, list)
344 if (strcmp(nname, dev_name(&rdev2->wiphy.dev)) == 0) {
345 found = true;
346 break;
347 }
348
349 if (!found)
350 break;
351 }
352
353 if (unlikely(found)) {
354too_many_devs:
355 mutex_unlock(&cfg80211_mutex); 349 mutex_unlock(&cfg80211_mutex);
356 /* ugh, too many devices already! */ 350 /* ugh, wrapped! */
357 kfree(rdev); 351 kfree(rdev);
358 return NULL; 352 return NULL;
359 } 353 }
360 354
361 /* give it a proper name */
362 dev_set_name(&rdev->wiphy.dev, "%s", nname);
363
364 mutex_unlock(&cfg80211_mutex); 355 mutex_unlock(&cfg80211_mutex);
365 356
357 /* give it a proper name */
358 dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx);
359
366 mutex_init(&rdev->mtx); 360 mutex_init(&rdev->mtx);
367 mutex_init(&rdev->devlist_mtx); 361 mutex_init(&rdev->devlist_mtx);
368 INIT_LIST_HEAD(&rdev->netdev_list); 362 INIT_LIST_HEAD(&rdev->netdev_list);
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index caf11a427507..26838d903b9a 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -764,6 +764,8 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
764 u16 frame_type, const u8 *match_data, 764 u16 frame_type, const u8 *match_data,
765 int match_len) 765 int match_len)
766{ 766{
767 struct wiphy *wiphy = wdev->wiphy;
768 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
767 struct cfg80211_mgmt_registration *reg, *nreg; 769 struct cfg80211_mgmt_registration *reg, *nreg;
768 int err = 0; 770 int err = 0;
769 u16 mgmt_type; 771 u16 mgmt_type;
@@ -810,22 +812,37 @@ int cfg80211_mlme_register_mgmt(struct wireless_dev *wdev, u32 snd_pid,
810 nreg->frame_type = cpu_to_le16(frame_type); 812 nreg->frame_type = cpu_to_le16(frame_type);
811 list_add(&nreg->list, &wdev->mgmt_registrations); 813 list_add(&nreg->list, &wdev->mgmt_registrations);
812 814
815 if (rdev->ops->mgmt_frame_register)
816 rdev->ops->mgmt_frame_register(wiphy, wdev->netdev,
817 frame_type, true);
818
813 out: 819 out:
814 spin_unlock_bh(&wdev->mgmt_registrations_lock); 820 spin_unlock_bh(&wdev->mgmt_registrations_lock);
821
815 return err; 822 return err;
816} 823}
817 824
818void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid) 825void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid)
819{ 826{
827 struct wiphy *wiphy = wdev->wiphy;
828 struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
820 struct cfg80211_mgmt_registration *reg, *tmp; 829 struct cfg80211_mgmt_registration *reg, *tmp;
821 830
822 spin_lock_bh(&wdev->mgmt_registrations_lock); 831 spin_lock_bh(&wdev->mgmt_registrations_lock);
823 832
824 list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) { 833 list_for_each_entry_safe(reg, tmp, &wdev->mgmt_registrations, list) {
825 if (reg->nlpid == nlpid) { 834 if (reg->nlpid != nlpid)
826 list_del(&reg->list); 835 continue;
827 kfree(reg); 836
837 if (rdev->ops->mgmt_frame_register) {
838 u16 frame_type = le16_to_cpu(reg->frame_type);
839
840 rdev->ops->mgmt_frame_register(wiphy, wdev->netdev,
841 frame_type, false);
828 } 842 }
843
844 list_del(&reg->list);
845 kfree(reg);
829 } 846 }
830 847
831 spin_unlock_bh(&wdev->mgmt_registrations_lock); 848 spin_unlock_bh(&wdev->mgmt_registrations_lock);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 882dc921103b..c506241f8637 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3153,6 +3153,21 @@ static int nl80211_send_survey(struct sk_buff *msg, u32 pid, u32 seq,
3153 survey->noise); 3153 survey->noise);
3154 if (survey->filled & SURVEY_INFO_IN_USE) 3154 if (survey->filled & SURVEY_INFO_IN_USE)
3155 NLA_PUT_FLAG(msg, NL80211_SURVEY_INFO_IN_USE); 3155 NLA_PUT_FLAG(msg, NL80211_SURVEY_INFO_IN_USE);
3156 if (survey->filled & SURVEY_INFO_CHANNEL_TIME)
3157 NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME,
3158 survey->channel_time);
3159 if (survey->filled & SURVEY_INFO_CHANNEL_TIME_BUSY)
3160 NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY,
3161 survey->channel_time_busy);
3162 if (survey->filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY)
3163 NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY,
3164 survey->channel_time_ext_busy);
3165 if (survey->filled & SURVEY_INFO_CHANNEL_TIME_RX)
3166 NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_RX,
3167 survey->channel_time_rx);
3168 if (survey->filled & SURVEY_INFO_CHANNEL_TIME_TX)
3169 NLA_PUT_U64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_TX,
3170 survey->channel_time_tx);
3156 3171
3157 nla_nest_end(msg, infoattr); 3172 nla_nest_end(msg, infoattr);
3158 3173
diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c
index c774bc0f155e..dbe35e138e94 100644
--- a/net/wireless/radiotap.c
+++ b/net/wireless/radiotap.c
@@ -201,7 +201,7 @@ int ieee80211_radiotap_iterator_next(
201{ 201{
202 while (1) { 202 while (1) {
203 int hit = 0; 203 int hit = 0;
204 int pad, align, size, subns, vnslen; 204 int pad, align, size, subns;
205 uint32_t oui; 205 uint32_t oui;
206 206
207 /* if no more EXT bits, that's it */ 207 /* if no more EXT bits, that's it */
@@ -261,6 +261,27 @@ int ieee80211_radiotap_iterator_next(
261 if (pad) 261 if (pad)
262 iterator->_arg += align - pad; 262 iterator->_arg += align - pad;
263 263
264 if (iterator->_arg_index % 32 == IEEE80211_RADIOTAP_VENDOR_NAMESPACE) {
265 int vnslen;
266
267 if ((unsigned long)iterator->_arg + size -
268 (unsigned long)iterator->_rtheader >
269 (unsigned long)iterator->_max_length)
270 return -EINVAL;
271
272 oui = (*iterator->_arg << 16) |
273 (*(iterator->_arg + 1) << 8) |
274 *(iterator->_arg + 2);
275 subns = *(iterator->_arg + 3);
276
277 find_ns(iterator, oui, subns);
278
279 vnslen = get_unaligned_le16(iterator->_arg + 4);
280 iterator->_next_ns_data = iterator->_arg + size + vnslen;
281 if (!iterator->current_namespace)
282 size += vnslen;
283 }
284
264 /* 285 /*
265 * this is what we will return to user, but we need to 286 * this is what we will return to user, but we need to
266 * move on first so next call has something fresh to test 287 * move on first so next call has something fresh to test
@@ -287,40 +308,25 @@ int ieee80211_radiotap_iterator_next(
287 /* these special ones are valid in each bitmap word */ 308 /* these special ones are valid in each bitmap word */
288 switch (iterator->_arg_index % 32) { 309 switch (iterator->_arg_index % 32) {
289 case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: 310 case IEEE80211_RADIOTAP_VENDOR_NAMESPACE:
290 iterator->_bitmap_shifter >>= 1;
291 iterator->_arg_index++;
292
293 iterator->_reset_on_ext = 1; 311 iterator->_reset_on_ext = 1;
294 312
295 vnslen = get_unaligned_le16(iterator->this_arg + 4);
296 iterator->_next_ns_data = iterator->_arg + vnslen;
297 oui = (*iterator->this_arg << 16) |
298 (*(iterator->this_arg + 1) << 8) |
299 *(iterator->this_arg + 2);
300 subns = *(iterator->this_arg + 3);
301
302 find_ns(iterator, oui, subns);
303
304 iterator->is_radiotap_ns = 0; 313 iterator->is_radiotap_ns = 0;
305 /* allow parsers to show this information */ 314 /*
315 * If parser didn't register this vendor
316 * namespace with us, allow it to show it
317 * as 'raw. Do do that, set argument index
318 * to vendor namespace.
319 */
306 iterator->this_arg_index = 320 iterator->this_arg_index =
307 IEEE80211_RADIOTAP_VENDOR_NAMESPACE; 321 IEEE80211_RADIOTAP_VENDOR_NAMESPACE;
308 iterator->this_arg_size += vnslen; 322 if (!iterator->current_namespace)
309 if ((unsigned long)iterator->this_arg + 323 hit = 1;
310 iterator->this_arg_size - 324 goto next_entry;
311 (unsigned long)iterator->_rtheader >
312 (unsigned long)(unsigned long)iterator->_max_length)
313 return -EINVAL;
314 hit = 1;
315 break;
316 case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE: 325 case IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE:
317 iterator->_bitmap_shifter >>= 1;
318 iterator->_arg_index++;
319
320 iterator->_reset_on_ext = 1; 326 iterator->_reset_on_ext = 1;
321 iterator->current_namespace = &radiotap_ns; 327 iterator->current_namespace = &radiotap_ns;
322 iterator->is_radiotap_ns = 1; 328 iterator->is_radiotap_ns = 1;
323 break; 329 goto next_entry;
324 case IEEE80211_RADIOTAP_EXT: 330 case IEEE80211_RADIOTAP_EXT:
325 /* 331 /*
326 * bit 31 was set, there is more 332 * bit 31 was set, there is more
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 74a9e3cce452..4294fa22bb2d 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -35,6 +35,14 @@ SHOW_FMT(index, "%d", wiphy_idx);
35SHOW_FMT(macaddress, "%pM", wiphy.perm_addr); 35SHOW_FMT(macaddress, "%pM", wiphy.perm_addr);
36SHOW_FMT(address_mask, "%pM", wiphy.addr_mask); 36SHOW_FMT(address_mask, "%pM", wiphy.addr_mask);
37 37
38static ssize_t name_show(struct device *dev,
39 struct device_attribute *attr,
40 char *buf) {
41 struct wiphy *wiphy = &dev_to_rdev(dev)->wiphy;
42 return sprintf(buf, "%s\n", dev_name(&wiphy->dev));
43}
44
45
38static ssize_t addresses_show(struct device *dev, 46static ssize_t addresses_show(struct device *dev,
39 struct device_attribute *attr, 47 struct device_attribute *attr,
40 char *buf) 48 char *buf)
@@ -57,6 +65,7 @@ static struct device_attribute ieee80211_dev_attrs[] = {
57 __ATTR_RO(macaddress), 65 __ATTR_RO(macaddress),
58 __ATTR_RO(address_mask), 66 __ATTR_RO(address_mask),
59 __ATTR_RO(addresses), 67 __ATTR_RO(addresses),
68 __ATTR_RO(name),
60 {} 69 {}
61}; 70};
62 71
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 6002265289c6..12222ee6ebf2 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -1366,6 +1366,10 @@ struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
1366 } 1366 }
1367 1367
1368 wstats.qual.updated |= IW_QUAL_NOISE_INVALID; 1368 wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
1369 if (sinfo.filled & STATION_INFO_RX_DROP_MISC)
1370 wstats.discard.misc = sinfo.rx_dropped_misc;
1371 if (sinfo.filled & STATION_INFO_TX_FAILED)
1372 wstats.discard.retries = sinfo.tx_failed;
1369 1373
1370 return &wstats; 1374 return &wstats;
1371} 1375}