diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-10-15 16:11:56 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-10-15 16:11:56 -0400 |
commit | c64557d666eb62eb5f296c6b93bd0a5525ed1e36 (patch) | |
tree | 1e25cc32521d06ae876de18bb8e48b3cf9d30808 /net | |
parent | 1a63c353c856c9f6d44a533afb6ad6dbbcdea683 (diff) | |
parent | 0d91f22b75347d9503b17a42b6c74d3f7750acd6 (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.c | 22 | ||||
-rw-r--r-- | net/mac80211/ht.c | 2 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 4 | ||||
-rw-r--r-- | net/mac80211/iface.c | 9 | ||||
-rw-r--r-- | net/mac80211/main.c | 3 | ||||
-rw-r--r-- | net/mac80211/mesh_plink.c | 17 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 18 | ||||
-rw-r--r-- | net/mac80211/rc80211_minstrel_ht.c | 7 | ||||
-rw-r--r-- | net/mac80211/rx.c | 24 | ||||
-rw-r--r-- | net/mac80211/wep.c | 8 | ||||
-rw-r--r-- | net/wireless/core.c | 54 | ||||
-rw-r--r-- | net/wireless/mlme.c | 23 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 15 | ||||
-rw-r--r-- | net/wireless/radiotap.c | 58 | ||||
-rw-r--r-- | net/wireless/sysfs.c | 9 | ||||
-rw-r--r-- | net/wireless/wext-compat.c | 4 |
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 | ||
1607 | static 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 | |||
1605 | struct cfg80211_ops mac80211_config_ops = { | 1624 | struct 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 | |||
665 | set_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) | |||
304 | struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) | 320 | struct 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)) { | ||
354 | too_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 | ||
818 | void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid) | 825 | void 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(®->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(®->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); | |||
35 | SHOW_FMT(macaddress, "%pM", wiphy.perm_addr); | 35 | SHOW_FMT(macaddress, "%pM", wiphy.perm_addr); |
36 | SHOW_FMT(address_mask, "%pM", wiphy.addr_mask); | 36 | SHOW_FMT(address_mask, "%pM", wiphy.addr_mask); |
37 | 37 | ||
38 | static 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 | |||
38 | static ssize_t addresses_show(struct device *dev, | 46 | static 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 | } |