diff options
author | Johannes Berg <johannes.berg@intel.com> | 2013-03-06 10:33:12 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-03-06 10:33:12 -0500 |
commit | c0f3a317f2f0e51ad2f8809c83b137958b385c7f (patch) | |
tree | c5547580ee6d47d01735124c6bd8ba1dfb70e206 | |
parent | 6dbe51c251a327e012439c4772097a13df43c5b8 (diff) | |
parent | 801d929ca7d935ee199fd61d8ef914f51e892270 (diff) |
Merge remote-tracking branch 'mac80211/master' into HEAD
There are a few things that would otherwise conflict.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r-- | net/mac80211/cfg.c | 11 | ||||
-rw-r--r-- | net/mac80211/iface.c | 8 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 28 | ||||
-rw-r--r-- | net/mac80211/tx.c | 80 | ||||
-rw-r--r-- | net/wireless/core.c | 3 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 110 |
6 files changed, 120 insertions, 120 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 09d96a8f6c2c..fb306814576a 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -3285,6 +3285,7 @@ static int ieee80211_cfg_get_channel(struct wiphy *wiphy, | |||
3285 | struct cfg80211_chan_def *chandef) | 3285 | struct cfg80211_chan_def *chandef) |
3286 | { | 3286 | { |
3287 | struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); | 3287 | struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); |
3288 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
3288 | struct ieee80211_chanctx_conf *chanctx_conf; | 3289 | struct ieee80211_chanctx_conf *chanctx_conf; |
3289 | int ret = -ENODATA; | 3290 | int ret = -ENODATA; |
3290 | 3291 | ||
@@ -3293,6 +3294,16 @@ static int ieee80211_cfg_get_channel(struct wiphy *wiphy, | |||
3293 | if (chanctx_conf) { | 3294 | if (chanctx_conf) { |
3294 | *chandef = chanctx_conf->def; | 3295 | *chandef = chanctx_conf->def; |
3295 | ret = 0; | 3296 | ret = 0; |
3297 | } else if (local->open_count > 0 && | ||
3298 | local->open_count == local->monitors && | ||
3299 | sdata->vif.type == NL80211_IFTYPE_MONITOR) { | ||
3300 | if (local->use_chanctx) | ||
3301 | *chandef = local->monitor_chandef; | ||
3302 | else | ||
3303 | cfg80211_chandef_create(chandef, | ||
3304 | local->_oper_channel, | ||
3305 | local->_oper_channel_type); | ||
3306 | ret = 0; | ||
3296 | } | 3307 | } |
3297 | rcu_read_unlock(); | 3308 | rcu_read_unlock(); |
3298 | 3309 | ||
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 2c059e54e885..baaa8608e52d 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -107,7 +107,7 @@ void ieee80211_recalc_idle(struct ieee80211_local *local) | |||
107 | 107 | ||
108 | lockdep_assert_held(&local->mtx); | 108 | lockdep_assert_held(&local->mtx); |
109 | 109 | ||
110 | active = !list_empty(&local->chanctx_list); | 110 | active = !list_empty(&local->chanctx_list) || local->monitors; |
111 | 111 | ||
112 | if (!local->ops->remain_on_channel) { | 112 | if (!local->ops->remain_on_channel) { |
113 | list_for_each_entry(roc, &local->roc_list, list) { | 113 | list_for_each_entry(roc, &local->roc_list, list) { |
@@ -541,6 +541,9 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) | |||
541 | 541 | ||
542 | ieee80211_adjust_monitor_flags(sdata, 1); | 542 | ieee80211_adjust_monitor_flags(sdata, 1); |
543 | ieee80211_configure_filter(local); | 543 | ieee80211_configure_filter(local); |
544 | mutex_lock(&local->mtx); | ||
545 | ieee80211_recalc_idle(local); | ||
546 | mutex_unlock(&local->mtx); | ||
544 | 547 | ||
545 | netif_carrier_on(dev); | 548 | netif_carrier_on(dev); |
546 | break; | 549 | break; |
@@ -812,6 +815,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
812 | 815 | ||
813 | ieee80211_adjust_monitor_flags(sdata, -1); | 816 | ieee80211_adjust_monitor_flags(sdata, -1); |
814 | ieee80211_configure_filter(local); | 817 | ieee80211_configure_filter(local); |
818 | mutex_lock(&local->mtx); | ||
819 | ieee80211_recalc_idle(local); | ||
820 | mutex_unlock(&local->mtx); | ||
815 | break; | 821 | break; |
816 | case NL80211_IFTYPE_P2P_DEVICE: | 822 | case NL80211_IFTYPE_P2P_DEVICE: |
817 | /* relies on synchronize_rcu() below */ | 823 | /* relies on synchronize_rcu() below */ |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 9f6464f3e05f..141577412d84 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -647,6 +647,9 @@ static void ieee80211_add_vht_ie(struct ieee80211_sub_if_data *sdata, | |||
647 | our_mcs = (le16_to_cpu(vht_cap.vht_mcs.rx_mcs_map) & | 647 | our_mcs = (le16_to_cpu(vht_cap.vht_mcs.rx_mcs_map) & |
648 | mask) >> shift; | 648 | mask) >> shift; |
649 | 649 | ||
650 | if (our_mcs == IEEE80211_VHT_MCS_NOT_SUPPORTED) | ||
651 | continue; | ||
652 | |||
650 | switch (ap_mcs) { | 653 | switch (ap_mcs) { |
651 | default: | 654 | default: |
652 | if (our_mcs <= ap_mcs) | 655 | if (our_mcs <= ap_mcs) |
@@ -3503,6 +3506,14 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata) | |||
3503 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 3506 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
3504 | 3507 | ||
3505 | /* | 3508 | /* |
3509 | * Stop timers before deleting work items, as timers | ||
3510 | * could race and re-add the work-items. They will be | ||
3511 | * re-established on connection. | ||
3512 | */ | ||
3513 | del_timer_sync(&ifmgd->conn_mon_timer); | ||
3514 | del_timer_sync(&ifmgd->bcn_mon_timer); | ||
3515 | |||
3516 | /* | ||
3506 | * we need to use atomic bitops for the running bits | 3517 | * we need to use atomic bitops for the running bits |
3507 | * only because both timers might fire at the same | 3518 | * only because both timers might fire at the same |
3508 | * time -- the code here is properly synchronised. | 3519 | * time -- the code here is properly synchronised. |
@@ -3516,13 +3527,9 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata) | |||
3516 | if (del_timer_sync(&ifmgd->timer)) | 3527 | if (del_timer_sync(&ifmgd->timer)) |
3517 | set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); | 3528 | set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); |
3518 | 3529 | ||
3519 | cancel_work_sync(&ifmgd->chswitch_work); | ||
3520 | if (del_timer_sync(&ifmgd->chswitch_timer)) | 3530 | if (del_timer_sync(&ifmgd->chswitch_timer)) |
3521 | set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running); | 3531 | set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running); |
3522 | 3532 | cancel_work_sync(&ifmgd->chswitch_work); | |
3523 | /* these will just be re-established on connection */ | ||
3524 | del_timer_sync(&ifmgd->conn_mon_timer); | ||
3525 | del_timer_sync(&ifmgd->bcn_mon_timer); | ||
3526 | } | 3533 | } |
3527 | 3534 | ||
3528 | void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) | 3535 | void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) |
@@ -4315,6 +4322,17 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata) | |||
4315 | { | 4322 | { |
4316 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 4323 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
4317 | 4324 | ||
4325 | /* | ||
4326 | * Make sure some work items will not run after this, | ||
4327 | * they will not do anything but might not have been | ||
4328 | * cancelled when disconnecting. | ||
4329 | */ | ||
4330 | cancel_work_sync(&ifmgd->monitor_work); | ||
4331 | cancel_work_sync(&ifmgd->beacon_connection_loss_work); | ||
4332 | cancel_work_sync(&ifmgd->request_smps_work); | ||
4333 | cancel_work_sync(&ifmgd->csa_connection_drop_work); | ||
4334 | cancel_work_sync(&ifmgd->chswitch_work); | ||
4335 | |||
4318 | mutex_lock(&ifmgd->mtx); | 4336 | mutex_lock(&ifmgd->mtx); |
4319 | if (ifmgd->assoc_data) | 4337 | if (ifmgd->assoc_data) |
4320 | ieee80211_destroy_assoc_data(sdata, false); | 4338 | ieee80211_destroy_assoc_data(sdata, false); |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index de8548bf0a7f..8914d2d2881a 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1231,34 +1231,40 @@ static bool ieee80211_tx_frags(struct ieee80211_local *local, | |||
1231 | if (local->queue_stop_reasons[q] || | 1231 | if (local->queue_stop_reasons[q] || |
1232 | (!txpending && !skb_queue_empty(&local->pending[q]))) { | 1232 | (!txpending && !skb_queue_empty(&local->pending[q]))) { |
1233 | if (unlikely(info->flags & | 1233 | if (unlikely(info->flags & |
1234 | IEEE80211_TX_INTFL_OFFCHAN_TX_OK && | 1234 | IEEE80211_TX_INTFL_OFFCHAN_TX_OK)) { |
1235 | local->queue_stop_reasons[q] & | 1235 | if (local->queue_stop_reasons[q] & |
1236 | ~BIT(IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL))) { | 1236 | ~BIT(IEEE80211_QUEUE_STOP_REASON_OFFCHANNEL)) { |
1237 | /* | ||
1238 | * Drop off-channel frames if queues | ||
1239 | * are stopped for any reason other | ||
1240 | * than off-channel operation. Never | ||
1241 | * queue them. | ||
1242 | */ | ||
1243 | spin_unlock_irqrestore( | ||
1244 | &local->queue_stop_reason_lock, | ||
1245 | flags); | ||
1246 | ieee80211_purge_tx_queue(&local->hw, | ||
1247 | skbs); | ||
1248 | return true; | ||
1249 | } | ||
1250 | } else { | ||
1251 | |||
1237 | /* | 1252 | /* |
1238 | * Drop off-channel frames if queues are stopped | 1253 | * Since queue is stopped, queue up frames for |
1239 | * for any reason other than off-channel | 1254 | * later transmission from the tx-pending |
1240 | * operation. Never queue them. | 1255 | * tasklet when the queue is woken again. |
1241 | */ | 1256 | */ |
1242 | spin_unlock_irqrestore( | 1257 | if (txpending) |
1243 | &local->queue_stop_reason_lock, flags); | 1258 | skb_queue_splice_init(skbs, |
1244 | ieee80211_purge_tx_queue(&local->hw, skbs); | 1259 | &local->pending[q]); |
1245 | return true; | 1260 | else |
1261 | skb_queue_splice_tail_init(skbs, | ||
1262 | &local->pending[q]); | ||
1263 | |||
1264 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, | ||
1265 | flags); | ||
1266 | return false; | ||
1246 | } | 1267 | } |
1247 | |||
1248 | /* | ||
1249 | * Since queue is stopped, queue up frames for later | ||
1250 | * transmission from the tx-pending tasklet when the | ||
1251 | * queue is woken again. | ||
1252 | */ | ||
1253 | if (txpending) | ||
1254 | skb_queue_splice_init(skbs, &local->pending[q]); | ||
1255 | else | ||
1256 | skb_queue_splice_tail_init(skbs, | ||
1257 | &local->pending[q]); | ||
1258 | |||
1259 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, | ||
1260 | flags); | ||
1261 | return false; | ||
1262 | } | 1268 | } |
1263 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | 1269 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); |
1264 | 1270 | ||
@@ -1844,9 +1850,24 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1844 | } | 1850 | } |
1845 | 1851 | ||
1846 | if (!is_multicast_ether_addr(skb->data)) { | 1852 | if (!is_multicast_ether_addr(skb->data)) { |
1853 | struct sta_info *next_hop; | ||
1854 | bool mpp_lookup = true; | ||
1855 | |||
1847 | mpath = mesh_path_lookup(sdata, skb->data); | 1856 | mpath = mesh_path_lookup(sdata, skb->data); |
1848 | if (!mpath) | 1857 | if (mpath) { |
1858 | mpp_lookup = false; | ||
1859 | next_hop = rcu_dereference(mpath->next_hop); | ||
1860 | if (!next_hop || | ||
1861 | !(mpath->flags & (MESH_PATH_ACTIVE | | ||
1862 | MESH_PATH_RESOLVING))) | ||
1863 | mpp_lookup = true; | ||
1864 | } | ||
1865 | |||
1866 | if (mpp_lookup) | ||
1849 | mppath = mpp_path_lookup(sdata, skb->data); | 1867 | mppath = mpp_path_lookup(sdata, skb->data); |
1868 | |||
1869 | if (mppath && mpath) | ||
1870 | mesh_path_del(mpath->sdata, mpath->dst); | ||
1850 | } | 1871 | } |
1851 | 1872 | ||
1852 | /* | 1873 | /* |
@@ -2350,9 +2371,9 @@ static int ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata, | |||
2350 | if (local->tim_in_locked_section) { | 2371 | if (local->tim_in_locked_section) { |
2351 | __ieee80211_beacon_add_tim(sdata, ps, skb); | 2372 | __ieee80211_beacon_add_tim(sdata, ps, skb); |
2352 | } else { | 2373 | } else { |
2353 | spin_lock(&local->tim_lock); | 2374 | spin_lock_bh(&local->tim_lock); |
2354 | __ieee80211_beacon_add_tim(sdata, ps, skb); | 2375 | __ieee80211_beacon_add_tim(sdata, ps, skb); |
2355 | spin_unlock(&local->tim_lock); | 2376 | spin_unlock_bh(&local->tim_lock); |
2356 | } | 2377 | } |
2357 | 2378 | ||
2358 | return 0; | 2379 | return 0; |
@@ -2724,7 +2745,8 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
2724 | cpu_to_le16(IEEE80211_FCTL_MOREDATA); | 2745 | cpu_to_le16(IEEE80211_FCTL_MOREDATA); |
2725 | } | 2746 | } |
2726 | 2747 | ||
2727 | sdata = IEEE80211_DEV_TO_SUB_IF(skb->dev); | 2748 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) |
2749 | sdata = IEEE80211_DEV_TO_SUB_IF(skb->dev); | ||
2728 | if (!ieee80211_tx_prepare(sdata, &tx, skb)) | 2750 | if (!ieee80211_tx_prepare(sdata, &tx, skb)) |
2729 | break; | 2751 | break; |
2730 | dev_kfree_skb_any(skb); | 2752 | dev_kfree_skb_any(skb); |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 5ffff039b017..ea4155fe9733 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -367,8 +367,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) | |||
367 | rdev->wiphy.rts_threshold = (u32) -1; | 367 | rdev->wiphy.rts_threshold = (u32) -1; |
368 | rdev->wiphy.coverage_class = 0; | 368 | rdev->wiphy.coverage_class = 0; |
369 | 369 | ||
370 | rdev->wiphy.features = NL80211_FEATURE_SCAN_FLUSH | | 370 | rdev->wiphy.features = NL80211_FEATURE_SCAN_FLUSH; |
371 | NL80211_FEATURE_ADVERTISE_CHAN_LIMITS; | ||
372 | 371 | ||
373 | return &rdev->wiphy; | 372 | return &rdev->wiphy; |
374 | } | 373 | } |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 35545ccc30fd..d44ab216c0ec 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -554,27 +554,8 @@ static int nl80211_msg_put_channel(struct sk_buff *msg, | |||
554 | if ((chan->flags & IEEE80211_CHAN_NO_IBSS) && | 554 | if ((chan->flags & IEEE80211_CHAN_NO_IBSS) && |
555 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IBSS)) | 555 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IBSS)) |
556 | goto nla_put_failure; | 556 | goto nla_put_failure; |
557 | if (chan->flags & IEEE80211_CHAN_RADAR) { | 557 | if ((chan->flags & IEEE80211_CHAN_RADAR) && |
558 | u32 time = elapsed_jiffies_msecs(chan->dfs_state_entered); | 558 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR)) |
559 | if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR)) | ||
560 | goto nla_put_failure; | ||
561 | if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_STATE, | ||
562 | chan->dfs_state)) | ||
563 | goto nla_put_failure; | ||
564 | if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_DFS_TIME, time)) | ||
565 | goto nla_put_failure; | ||
566 | } | ||
567 | if ((chan->flags & IEEE80211_CHAN_NO_HT40MINUS) && | ||
568 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS)) | ||
569 | goto nla_put_failure; | ||
570 | if ((chan->flags & IEEE80211_CHAN_NO_HT40PLUS) && | ||
571 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_PLUS)) | ||
572 | goto nla_put_failure; | ||
573 | if ((chan->flags & IEEE80211_CHAN_NO_80MHZ) && | ||
574 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_80MHZ)) | ||
575 | goto nla_put_failure; | ||
576 | if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) && | ||
577 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ)) | ||
578 | goto nla_put_failure; | 559 | goto nla_put_failure; |
579 | 560 | ||
580 | if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER, | 561 | if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER, |
@@ -900,9 +881,6 @@ static int nl80211_put_iface_combinations(struct wiphy *wiphy, | |||
900 | nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM, | 881 | nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM, |
901 | c->max_interfaces)) | 882 | c->max_interfaces)) |
902 | goto nla_put_failure; | 883 | goto nla_put_failure; |
903 | if (nla_put_u32(msg, NL80211_IFACE_COMB_RADAR_DETECT_WIDTHS, | ||
904 | c->radar_detect_widths)) | ||
905 | goto nla_put_failure; | ||
906 | 884 | ||
907 | nla_nest_end(msg, nl_combi); | 885 | nla_nest_end(msg, nl_combi); |
908 | } | 886 | } |
@@ -914,48 +892,6 @@ nla_put_failure: | |||
914 | return -ENOBUFS; | 892 | return -ENOBUFS; |
915 | } | 893 | } |
916 | 894 | ||
917 | #ifdef CONFIG_PM | ||
918 | static int nl80211_send_wowlan_tcp_caps(struct cfg80211_registered_device *rdev, | ||
919 | struct sk_buff *msg) | ||
920 | { | ||
921 | const struct wiphy_wowlan_tcp_support *tcp = rdev->wiphy.wowlan.tcp; | ||
922 | struct nlattr *nl_tcp; | ||
923 | |||
924 | if (!tcp) | ||
925 | return 0; | ||
926 | |||
927 | nl_tcp = nla_nest_start(msg, NL80211_WOWLAN_TRIG_TCP_CONNECTION); | ||
928 | if (!nl_tcp) | ||
929 | return -ENOBUFS; | ||
930 | |||
931 | if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD, | ||
932 | tcp->data_payload_max)) | ||
933 | return -ENOBUFS; | ||
934 | |||
935 | if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD, | ||
936 | tcp->data_payload_max)) | ||
937 | return -ENOBUFS; | ||
938 | |||
939 | if (tcp->seq && nla_put_flag(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_SEQ)) | ||
940 | return -ENOBUFS; | ||
941 | |||
942 | if (tcp->tok && nla_put(msg, NL80211_WOWLAN_TCP_DATA_PAYLOAD_TOKEN, | ||
943 | sizeof(*tcp->tok), tcp->tok)) | ||
944 | return -ENOBUFS; | ||
945 | |||
946 | if (nla_put_u32(msg, NL80211_WOWLAN_TCP_DATA_INTERVAL, | ||
947 | tcp->data_interval_max)) | ||
948 | return -ENOBUFS; | ||
949 | |||
950 | if (nla_put_u32(msg, NL80211_WOWLAN_TCP_WAKE_PAYLOAD, | ||
951 | tcp->wake_payload_max)) | ||
952 | return -ENOBUFS; | ||
953 | |||
954 | nla_nest_end(msg, nl_tcp); | ||
955 | return 0; | ||
956 | } | ||
957 | #endif | ||
958 | |||
959 | static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flags, | 895 | static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flags, |
960 | struct cfg80211_registered_device *dev) | 896 | struct cfg80211_registered_device *dev) |
961 | { | 897 | { |
@@ -1330,9 +1266,6 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag | |||
1330 | goto nla_put_failure; | 1266 | goto nla_put_failure; |
1331 | } | 1267 | } |
1332 | 1268 | ||
1333 | if (nl80211_send_wowlan_tcp_caps(dev, msg)) | ||
1334 | goto nla_put_failure; | ||
1335 | |||
1336 | nla_nest_end(msg, nl_wowlan); | 1269 | nla_nest_end(msg, nl_wowlan); |
1337 | } | 1270 | } |
1338 | #endif | 1271 | #endif |
@@ -1365,15 +1298,6 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag | |||
1365 | dev->wiphy.max_acl_mac_addrs)) | 1298 | dev->wiphy.max_acl_mac_addrs)) |
1366 | goto nla_put_failure; | 1299 | goto nla_put_failure; |
1367 | 1300 | ||
1368 | if (dev->wiphy.extended_capabilities && | ||
1369 | (nla_put(msg, NL80211_ATTR_EXT_CAPA, | ||
1370 | dev->wiphy.extended_capabilities_len, | ||
1371 | dev->wiphy.extended_capabilities) || | ||
1372 | nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK, | ||
1373 | dev->wiphy.extended_capabilities_len, | ||
1374 | dev->wiphy.extended_capabilities_mask))) | ||
1375 | goto nla_put_failure; | ||
1376 | |||
1377 | return genlmsg_end(msg, hdr); | 1301 | return genlmsg_end(msg, hdr); |
1378 | 1302 | ||
1379 | nla_put_failure: | 1303 | nla_put_failure: |
@@ -1383,7 +1307,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag | |||
1383 | 1307 | ||
1384 | static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) | 1308 | static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) |
1385 | { | 1309 | { |
1386 | int idx = 0; | 1310 | int idx = 0, ret; |
1387 | int start = cb->args[0]; | 1311 | int start = cb->args[0]; |
1388 | struct cfg80211_registered_device *dev; | 1312 | struct cfg80211_registered_device *dev; |
1389 | 1313 | ||
@@ -1393,9 +1317,29 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) | |||
1393 | continue; | 1317 | continue; |
1394 | if (++idx <= start) | 1318 | if (++idx <= start) |
1395 | continue; | 1319 | continue; |
1396 | if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).portid, | 1320 | ret = nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).portid, |
1397 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 1321 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
1398 | dev) < 0) { | 1322 | dev); |
1323 | if (ret < 0) { | ||
1324 | /* | ||
1325 | * If sending the wiphy data didn't fit (ENOBUFS or | ||
1326 | * EMSGSIZE returned), this SKB is still empty (so | ||
1327 | * it's not too big because another wiphy dataset is | ||
1328 | * already in the skb) and we've not tried to adjust | ||
1329 | * the dump allocation yet ... then adjust the alloc | ||
1330 | * size to be bigger, and return 1 but with the empty | ||
1331 | * skb. This results in an empty message being RX'ed | ||
1332 | * in userspace, but that is ignored. | ||
1333 | * | ||
1334 | * We can then retry with the larger buffer. | ||
1335 | */ | ||
1336 | if ((ret == -ENOBUFS || ret == -EMSGSIZE) && | ||
1337 | !skb->len && | ||
1338 | cb->min_dump_alloc < 4096) { | ||
1339 | cb->min_dump_alloc = 4096; | ||
1340 | mutex_unlock(&cfg80211_mutex); | ||
1341 | return 1; | ||
1342 | } | ||
1399 | idx--; | 1343 | idx--; |
1400 | break; | 1344 | break; |
1401 | } | 1345 | } |
@@ -1412,7 +1356,7 @@ static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
1412 | struct sk_buff *msg; | 1356 | struct sk_buff *msg; |
1413 | struct cfg80211_registered_device *dev = info->user_ptr[0]; | 1357 | struct cfg80211_registered_device *dev = info->user_ptr[0]; |
1414 | 1358 | ||
1415 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 1359 | msg = nlmsg_new(4096, GFP_KERNEL); |
1416 | if (!msg) | 1360 | if (!msg) |
1417 | return -ENOMEM; | 1361 | return -ENOMEM; |
1418 | 1362 | ||