diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/cfg.c | 21 | ||||
-rw-r--r-- | net/mac80211/iface.c | 6 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 28 | ||||
-rw-r--r-- | net/mac80211/tx.c | 3 | ||||
-rw-r--r-- | net/wireless/core.c | 3 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 51 |
6 files changed, 70 insertions, 42 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 808f5fcd1ced..fb306814576a 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -3290,14 +3290,19 @@ static int ieee80211_cfg_get_channel(struct wiphy *wiphy, | |||
3290 | int ret = -ENODATA; | 3290 | int ret = -ENODATA; |
3291 | 3291 | ||
3292 | rcu_read_lock(); | 3292 | rcu_read_lock(); |
3293 | if (local->use_chanctx) { | 3293 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); |
3294 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | 3294 | if (chanctx_conf) { |
3295 | if (chanctx_conf) { | 3295 | *chandef = chanctx_conf->def; |
3296 | *chandef = chanctx_conf->def; | 3296 | ret = 0; |
3297 | ret = 0; | 3297 | } else if (local->open_count > 0 && |
3298 | } | 3298 | local->open_count == local->monitors && |
3299 | } else if (local->open_count == local->monitors) { | 3299 | sdata->vif.type == NL80211_IFTYPE_MONITOR) { |
3300 | *chandef = local->monitor_chandef; | 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); | ||
3301 | ret = 0; | 3306 | ret = 0; |
3302 | } | 3307 | } |
3303 | rcu_read_unlock(); | 3308 | rcu_read_unlock(); |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 640afab304d7..baaa8608e52d 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -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 ce78d1149f1d..8914d2d2881a 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -2745,7 +2745,8 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
2745 | cpu_to_le16(IEEE80211_FCTL_MOREDATA); | 2745 | cpu_to_le16(IEEE80211_FCTL_MOREDATA); |
2746 | } | 2746 | } |
2747 | 2747 | ||
2748 | 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); | ||
2749 | if (!ieee80211_tx_prepare(sdata, &tx, skb)) | 2750 | if (!ieee80211_tx_prepare(sdata, &tx, skb)) |
2750 | break; | 2751 | break; |
2751 | 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 e652d05ff712..d44ab216c0ec 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -557,18 +557,6 @@ static int nl80211_msg_put_channel(struct sk_buff *msg, | |||
557 | if ((chan->flags & IEEE80211_CHAN_RADAR) && | 557 | if ((chan->flags & IEEE80211_CHAN_RADAR) && |
558 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR)) | 558 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR)) |
559 | goto nla_put_failure; | 559 | goto nla_put_failure; |
560 | if ((chan->flags & IEEE80211_CHAN_NO_HT40MINUS) && | ||
561 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_MINUS)) | ||
562 | goto nla_put_failure; | ||
563 | if ((chan->flags & IEEE80211_CHAN_NO_HT40PLUS) && | ||
564 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_HT40_PLUS)) | ||
565 | goto nla_put_failure; | ||
566 | if ((chan->flags & IEEE80211_CHAN_NO_80MHZ) && | ||
567 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_80MHZ)) | ||
568 | goto nla_put_failure; | ||
569 | if ((chan->flags & IEEE80211_CHAN_NO_160MHZ) && | ||
570 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_160MHZ)) | ||
571 | goto nla_put_failure; | ||
572 | 560 | ||
573 | if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER, | 561 | if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER, |
574 | DBM_TO_MBM(chan->max_power))) | 562 | DBM_TO_MBM(chan->max_power))) |
@@ -1310,15 +1298,6 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag | |||
1310 | dev->wiphy.max_acl_mac_addrs)) | 1298 | dev->wiphy.max_acl_mac_addrs)) |
1311 | goto nla_put_failure; | 1299 | goto nla_put_failure; |
1312 | 1300 | ||
1313 | if (dev->wiphy.extended_capabilities && | ||
1314 | (nla_put(msg, NL80211_ATTR_EXT_CAPA, | ||
1315 | dev->wiphy.extended_capabilities_len, | ||
1316 | dev->wiphy.extended_capabilities) || | ||
1317 | nla_put(msg, NL80211_ATTR_EXT_CAPA_MASK, | ||
1318 | dev->wiphy.extended_capabilities_len, | ||
1319 | dev->wiphy.extended_capabilities_mask))) | ||
1320 | goto nla_put_failure; | ||
1321 | |||
1322 | return genlmsg_end(msg, hdr); | 1301 | return genlmsg_end(msg, hdr); |
1323 | 1302 | ||
1324 | nla_put_failure: | 1303 | nla_put_failure: |
@@ -1328,7 +1307,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag | |||
1328 | 1307 | ||
1329 | 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) |
1330 | { | 1309 | { |
1331 | int idx = 0; | 1310 | int idx = 0, ret; |
1332 | int start = cb->args[0]; | 1311 | int start = cb->args[0]; |
1333 | struct cfg80211_registered_device *dev; | 1312 | struct cfg80211_registered_device *dev; |
1334 | 1313 | ||
@@ -1338,9 +1317,29 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) | |||
1338 | continue; | 1317 | continue; |
1339 | if (++idx <= start) | 1318 | if (++idx <= start) |
1340 | continue; | 1319 | continue; |
1341 | if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).portid, | 1320 | ret = nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).portid, |
1342 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 1321 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
1343 | 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 | } | ||
1344 | idx--; | 1343 | idx--; |
1345 | break; | 1344 | break; |
1346 | } | 1345 | } |
@@ -1357,7 +1356,7 @@ static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
1357 | struct sk_buff *msg; | 1356 | struct sk_buff *msg; |
1358 | struct cfg80211_registered_device *dev = info->user_ptr[0]; | 1357 | struct cfg80211_registered_device *dev = info->user_ptr[0]; |
1359 | 1358 | ||
1360 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 1359 | msg = nlmsg_new(4096, GFP_KERNEL); |
1361 | if (!msg) | 1360 | if (!msg) |
1362 | return -ENOMEM; | 1361 | return -ENOMEM; |
1363 | 1362 | ||