aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c253
1 files changed, 127 insertions, 126 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index e880f4494950..999108cd947c 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -1381,30 +1381,82 @@ static bool nl80211_valid_channel_type(struct genl_info *info,
1381 return true; 1381 return true;
1382} 1382}
1383 1383
1384static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev,
1385 struct genl_info *info,
1386 struct cfg80211_chan_def *chandef)
1387{
1388 struct ieee80211_sta_ht_cap *ht_cap;
1389 struct ieee80211_channel *sc;
1390 u32 control_freq;
1391 int offs;
1392
1393 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
1394 return -EINVAL;
1395
1396 control_freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
1397
1398 chandef->chan = ieee80211_get_channel(&rdev->wiphy, control_freq);
1399 chandef->_type = NL80211_CHAN_NO_HT;
1400
1401 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] &&
1402 !nl80211_valid_channel_type(info, &chandef->_type))
1403 return -EINVAL;
1404
1405 /* Primary channel not allowed */
1406 if (!chandef->chan || chandef->chan->flags & IEEE80211_CHAN_DISABLED)
1407 return -EINVAL;
1408
1409 ht_cap = &rdev->wiphy.bands[chandef->chan->band]->ht_cap;
1410
1411 switch (chandef->_type) {
1412 case NL80211_CHAN_NO_HT:
1413 break;
1414 case NL80211_CHAN_HT40MINUS:
1415 if (chandef->chan->flags & IEEE80211_CHAN_NO_HT40MINUS)
1416 return -EINVAL;
1417 offs = -20;
1418 /* fall through */
1419 case NL80211_CHAN_HT40PLUS:
1420 if (chandef->_type == NL80211_CHAN_HT40PLUS) {
1421 if (chandef->chan->flags & IEEE80211_CHAN_NO_HT40PLUS)
1422 return -EINVAL;
1423 offs = 20;
1424 }
1425 if (!(ht_cap->cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) ||
1426 ht_cap->cap & IEEE80211_HT_CAP_40MHZ_INTOLERANT)
1427 return -EINVAL;
1428
1429 sc = ieee80211_get_channel(&rdev->wiphy,
1430 chandef->chan->center_freq + offs);
1431 if (!sc || sc->flags & IEEE80211_CHAN_DISABLED)
1432 return -EINVAL;
1433 /* fall through */
1434 case NL80211_CHAN_HT20:
1435 if (!ht_cap->ht_supported)
1436 return -EINVAL;
1437 break;
1438 }
1439
1440 return 0;
1441}
1442
1384static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, 1443static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
1385 struct wireless_dev *wdev, 1444 struct wireless_dev *wdev,
1386 struct genl_info *info) 1445 struct genl_info *info)
1387{ 1446{
1388 struct ieee80211_channel *channel; 1447 struct cfg80211_chan_def chandef;
1389 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT;
1390 u32 freq;
1391 int result; 1448 int result;
1392 enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR; 1449 enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR;
1393 1450
1394 if (wdev) 1451 if (wdev)
1395 iftype = wdev->iftype; 1452 iftype = wdev->iftype;
1396 1453
1397 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
1398 return -EINVAL;
1399
1400 if (!nl80211_can_set_dev_channel(wdev)) 1454 if (!nl80211_can_set_dev_channel(wdev))
1401 return -EOPNOTSUPP; 1455 return -EOPNOTSUPP;
1402 1456
1403 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] && 1457 result = nl80211_parse_chandef(rdev, info, &chandef);
1404 !nl80211_valid_channel_type(info, &channel_type)) 1458 if (result)
1405 return -EINVAL; 1459 return result;
1406
1407 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
1408 1460
1409 mutex_lock(&rdev->devlist_mtx); 1461 mutex_lock(&rdev->devlist_mtx);
1410 switch (iftype) { 1462 switch (iftype) {
@@ -1414,22 +1466,18 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
1414 result = -EBUSY; 1466 result = -EBUSY;
1415 break; 1467 break;
1416 } 1468 }
1417 channel = rdev_freq_to_chan(rdev, freq, channel_type); 1469 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &chandef)) {
1418 if (!channel || !cfg80211_can_beacon_sec_chan(&rdev->wiphy,
1419 channel,
1420 channel_type)) {
1421 result = -EINVAL; 1470 result = -EINVAL;
1422 break; 1471 break;
1423 } 1472 }
1424 wdev->preset_chan = channel; 1473 wdev->preset_chandef = chandef;
1425 wdev->preset_chantype = channel_type;
1426 result = 0; 1474 result = 0;
1427 break; 1475 break;
1428 case NL80211_IFTYPE_MESH_POINT: 1476 case NL80211_IFTYPE_MESH_POINT:
1429 result = cfg80211_set_mesh_freq(rdev, wdev, freq, channel_type); 1477 result = cfg80211_set_mesh_channel(rdev, wdev, &chandef);
1430 break; 1478 break;
1431 case NL80211_IFTYPE_MONITOR: 1479 case NL80211_IFTYPE_MONITOR:
1432 result = cfg80211_set_monitor_channel(rdev, freq, channel_type); 1480 result = cfg80211_set_monitor_channel(rdev, &chandef);
1433 break; 1481 break;
1434 default: 1482 default:
1435 result = -EINVAL; 1483 result = -EINVAL;
@@ -1749,6 +1797,17 @@ static inline u64 wdev_id(struct wireless_dev *wdev)
1749 ((u64)wiphy_to_dev(wdev->wiphy)->wiphy_idx << 32); 1797 ((u64)wiphy_to_dev(wdev->wiphy)->wiphy_idx << 32);
1750} 1798}
1751 1799
1800static int nl80211_send_chandef(struct sk_buff *msg,
1801 struct cfg80211_chan_def *chandef)
1802{
1803 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ,
1804 chandef->chan->center_freq))
1805 return -ENOBUFS;
1806 if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, chandef->_type))
1807 return -ENOBUFS;
1808 return 0;
1809}
1810
1752static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags, 1811static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags,
1753 struct cfg80211_registered_device *rdev, 1812 struct cfg80211_registered_device *rdev,
1754 struct wireless_dev *wdev) 1813 struct wireless_dev *wdev)
@@ -1775,16 +1834,14 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag
1775 goto nla_put_failure; 1834 goto nla_put_failure;
1776 1835
1777 if (rdev->ops->get_channel) { 1836 if (rdev->ops->get_channel) {
1778 struct ieee80211_channel *chan; 1837 int ret;
1779 enum nl80211_channel_type channel_type; 1838 struct cfg80211_chan_def chandef;
1780 1839
1781 chan = rdev_get_channel(rdev, wdev, &channel_type); 1840 ret = rdev_get_channel(rdev, wdev, &chandef);
1782 if (chan && 1841 if (ret == 0) {
1783 (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, 1842 if (nl80211_send_chandef(msg, &chandef))
1784 chan->center_freq) || 1843 goto nla_put_failure;
1785 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, 1844 }
1786 channel_type)))
1787 goto nla_put_failure;
1788 } 1845 }
1789 1846
1790 if (wdev->ssid_len) { 1847 if (wdev->ssid_len) {
@@ -2492,11 +2549,10 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
2492 wdev->iftype != NL80211_IFTYPE_P2P_GO) 2549 wdev->iftype != NL80211_IFTYPE_P2P_GO)
2493 continue; 2550 continue;
2494 2551
2495 if (!wdev->preset_chan) 2552 if (!wdev->preset_chandef.chan)
2496 continue; 2553 continue;
2497 2554
2498 params->channel = wdev->preset_chan; 2555 params->chandef = wdev->preset_chandef;
2499 params->channel_type = wdev->preset_chantype;
2500 ret = true; 2556 ret = true;
2501 break; 2557 break;
2502 } 2558 }
@@ -2618,30 +2674,19 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
2618 } 2674 }
2619 2675
2620 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { 2676 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
2621 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; 2677 err = nl80211_parse_chandef(rdev, info, &params.chandef);
2622 2678 if (err)
2623 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] && 2679 return err;
2624 !nl80211_valid_channel_type(info, &channel_type)) 2680 } else if (wdev->preset_chandef.chan) {
2625 return -EINVAL; 2681 params.chandef = wdev->preset_chandef;
2626
2627 params.channel = rdev_freq_to_chan(rdev,
2628 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
2629 channel_type);
2630 if (!params.channel)
2631 return -EINVAL;
2632 params.channel_type = channel_type;
2633 } else if (wdev->preset_chan) {
2634 params.channel = wdev->preset_chan;
2635 params.channel_type = wdev->preset_chantype;
2636 } else if (!nl80211_get_ap_channel(rdev, &params)) 2682 } else if (!nl80211_get_ap_channel(rdev, &params))
2637 return -EINVAL; 2683 return -EINVAL;
2638 2684
2639 if (!cfg80211_can_beacon_sec_chan(&rdev->wiphy, params.channel, 2685 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &params.chandef))
2640 params.channel_type))
2641 return -EINVAL; 2686 return -EINVAL;
2642 2687
2643 mutex_lock(&rdev->devlist_mtx); 2688 mutex_lock(&rdev->devlist_mtx);
2644 err = cfg80211_can_use_chan(rdev, wdev, params.channel, 2689 err = cfg80211_can_use_chan(rdev, wdev, params.chandef.chan,
2645 CHAN_MODE_SHARED); 2690 CHAN_MODE_SHARED);
2646 mutex_unlock(&rdev->devlist_mtx); 2691 mutex_unlock(&rdev->devlist_mtx);
2647 2692
@@ -2650,10 +2695,9 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
2650 2695
2651 err = rdev_start_ap(rdev, dev, &params); 2696 err = rdev_start_ap(rdev, dev, &params);
2652 if (!err) { 2697 if (!err) {
2653 wdev->preset_chan = params.channel; 2698 wdev->preset_chandef = params.chandef;
2654 wdev->preset_chantype = params.channel_type;
2655 wdev->beacon_interval = params.beacon_interval; 2699 wdev->beacon_interval = params.beacon_interval;
2656 wdev->channel = params.channel; 2700 wdev->channel = params.chandef.chan;
2657 wdev->ssid_len = params.ssid_len; 2701 wdev->ssid_len = params.ssid_len;
2658 memcpy(wdev->ssid, params.ssid, wdev->ssid_len); 2702 memcpy(wdev->ssid, params.ssid, wdev->ssid_len);
2659 } 2703 }
@@ -5330,8 +5374,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
5330 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) 5374 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
5331 return -EINVAL; 5375 return -EINVAL;
5332 5376
5333 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] || 5377 if (!info->attrs[NL80211_ATTR_SSID] ||
5334 !info->attrs[NL80211_ATTR_SSID] ||
5335 !nla_len(info->attrs[NL80211_ATTR_SSID])) 5378 !nla_len(info->attrs[NL80211_ATTR_SSID]))
5336 return -EINVAL; 5379 return -EINVAL;
5337 5380
@@ -5366,34 +5409,11 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
5366 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); 5409 ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]);
5367 } 5410 }
5368 5411
5369 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { 5412 err = nl80211_parse_chandef(rdev, info, &ibss.chandef);
5370 enum nl80211_channel_type channel_type; 5413 if (err)
5371 5414 return err;
5372 if (!nl80211_valid_channel_type(info, &channel_type))
5373 return -EINVAL;
5374
5375 if (channel_type != NL80211_CHAN_NO_HT &&
5376 !(wiphy->features & NL80211_FEATURE_HT_IBSS))
5377 return -EINVAL;
5378
5379 ibss.channel_type = channel_type;
5380 } else {
5381 ibss.channel_type = NL80211_CHAN_NO_HT;
5382 }
5383
5384 ibss.channel = rdev_freq_to_chan(rdev,
5385 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
5386 ibss.channel_type);
5387 if (!ibss.channel ||
5388 ibss.channel->flags & IEEE80211_CHAN_NO_IBSS ||
5389 ibss.channel->flags & IEEE80211_CHAN_DISABLED)
5390 return -EINVAL;
5391 5415
5392 /* Both channels should be able to initiate communication */ 5416 if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef))
5393 if ((ibss.channel_type == NL80211_CHAN_HT40PLUS ||
5394 ibss.channel_type == NL80211_CHAN_HT40MINUS) &&
5395 !cfg80211_can_beacon_sec_chan(&rdev->wiphy, ibss.channel,
5396 ibss.channel_type))
5397 return -EINVAL; 5417 return -EINVAL;
5398 5418
5399 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED]; 5419 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
@@ -5405,7 +5425,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
5405 int n_rates = 5425 int n_rates =
5406 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); 5426 nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]);
5407 struct ieee80211_supported_band *sband = 5427 struct ieee80211_supported_band *sband =
5408 wiphy->bands[ibss.channel->band]; 5428 wiphy->bands[ibss.chandef.chan->band];
5409 5429
5410 err = ieee80211_get_ratemask(sband, rates, n_rates, 5430 err = ieee80211_get_ratemask(sband, rates, n_rates,
5411 &ibss.basic_rates); 5431 &ibss.basic_rates);
@@ -5427,7 +5447,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
5427 if (IS_ERR(connkeys)) 5447 if (IS_ERR(connkeys))
5428 return PTR_ERR(connkeys); 5448 return PTR_ERR(connkeys);
5429 5449
5430 if ((ibss.channel_type != NL80211_CHAN_NO_HT) && no_ht) { 5450 if ((ibss.chandef._type != NL80211_CHAN_NO_HT) && no_ht) {
5431 kfree(connkeys); 5451 kfree(connkeys);
5432 return -EINVAL; 5452 return -EINVAL;
5433 } 5453 }
@@ -5948,11 +5968,11 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
5948{ 5968{
5949 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 5969 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5950 struct wireless_dev *wdev = info->user_ptr[1]; 5970 struct wireless_dev *wdev = info->user_ptr[1];
5951 struct ieee80211_channel *chan; 5971 struct cfg80211_chan_def chandef;
5952 struct sk_buff *msg; 5972 struct sk_buff *msg;
5953 void *hdr; 5973 void *hdr;
5954 u64 cookie; 5974 u64 cookie;
5955 u32 freq, duration; 5975 u32 duration;
5956 int err; 5976 int err;
5957 5977
5958 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] || 5978 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] ||
@@ -5973,14 +5993,9 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
5973 duration > rdev->wiphy.max_remain_on_channel_duration) 5993 duration > rdev->wiphy.max_remain_on_channel_duration)
5974 return -EINVAL; 5994 return -EINVAL;
5975 5995
5976 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] && 5996 err = nl80211_parse_chandef(rdev, info, &chandef);
5977 !nl80211_valid_channel_type(info, NULL)) 5997 if (err)
5978 return -EINVAL; 5998 return err;
5979
5980 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]);
5981 chan = rdev_freq_to_chan(rdev, freq, NL80211_CHAN_NO_HT);
5982 if (chan == NULL)
5983 return -EINVAL;
5984 5999
5985 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 6000 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5986 if (!msg) 6001 if (!msg)
@@ -5994,7 +6009,8 @@ static int nl80211_remain_on_channel(struct sk_buff *skb,
5994 goto free_msg; 6009 goto free_msg;
5995 } 6010 }
5996 6011
5997 err = rdev_remain_on_channel(rdev, wdev, chan, duration, &cookie); 6012 err = rdev_remain_on_channel(rdev, wdev, chandef.chan,
6013 duration, &cookie);
5998 6014
5999 if (err) 6015 if (err)
6000 goto free_msg; 6016 goto free_msg;
@@ -6213,8 +6229,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
6213{ 6229{
6214 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 6230 struct cfg80211_registered_device *rdev = info->user_ptr[0];
6215 struct wireless_dev *wdev = info->user_ptr[1]; 6231 struct wireless_dev *wdev = info->user_ptr[1];
6216 struct ieee80211_channel *chan; 6232 struct cfg80211_chan_def chandef;
6217 u32 freq;
6218 int err; 6233 int err;
6219 void *hdr = NULL; 6234 void *hdr = NULL;
6220 u64 cookie; 6235 u64 cookie;
@@ -6224,8 +6239,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
6224 6239
6225 dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK]; 6240 dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK];
6226 6241
6227 if (!info->attrs[NL80211_ATTR_FRAME] || 6242 if (!info->attrs[NL80211_ATTR_FRAME])
6228 !info->attrs[NL80211_ATTR_WIPHY_FREQ])
6229 return -EINVAL; 6243 return -EINVAL;
6230 6244
6231 if (!rdev->ops->mgmt_tx) 6245 if (!rdev->ops->mgmt_tx)
@@ -6260,10 +6274,6 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
6260 6274
6261 } 6275 }
6262 6276
6263 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] &&
6264 !nl80211_valid_channel_type(info, NULL))
6265 return -EINVAL;
6266
6267 offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK]; 6277 offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK];
6268 6278
6269 if (offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX)) 6279 if (offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX))
@@ -6271,10 +6281,9 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
6271 6281
6272 no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); 6282 no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
6273 6283
6274 freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); 6284 err = nl80211_parse_chandef(rdev, info, &chandef);
6275 chan = rdev_freq_to_chan(rdev, freq, NL80211_CHAN_NO_HT); 6285 if (err)
6276 if (chan == NULL) 6286 return err;
6277 return -EINVAL;
6278 6287
6279 if (!dont_wait_for_ack) { 6288 if (!dont_wait_for_ack) {
6280 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 6289 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
@@ -6290,7 +6299,7 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info)
6290 } 6299 }
6291 } 6300 }
6292 6301
6293 err = cfg80211_mlme_mgmt_tx(rdev, wdev, chan, offchan, wait, 6302 err = cfg80211_mlme_mgmt_tx(rdev, wdev, chandef.chan, offchan, wait,
6294 nla_data(info->attrs[NL80211_ATTR_FRAME]), 6303 nla_data(info->attrs[NL80211_ATTR_FRAME]),
6295 nla_len(info->attrs[NL80211_ATTR_FRAME]), 6304 nla_len(info->attrs[NL80211_ATTR_FRAME]),
6296 no_cck, dont_wait_for_ack, &cookie); 6305 no_cck, dont_wait_for_ack, &cookie);
@@ -6554,21 +6563,12 @@ static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
6554 } 6563 }
6555 6564
6556 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { 6565 if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) {
6557 enum nl80211_channel_type channel_type = NL80211_CHAN_NO_HT; 6566 err = nl80211_parse_chandef(rdev, info, &setup.chandef);
6558 6567 if (err)
6559 if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE] && 6568 return err;
6560 !nl80211_valid_channel_type(info, &channel_type))
6561 return -EINVAL;
6562
6563 setup.channel = rdev_freq_to_chan(rdev,
6564 nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]),
6565 channel_type);
6566 if (!setup.channel)
6567 return -EINVAL;
6568 setup.channel_type = channel_type;
6569 } else { 6569 } else {
6570 /* cfg80211_join_mesh() will sort it out */ 6570 /* cfg80211_join_mesh() will sort it out */
6571 setup.channel = NULL; 6571 setup.chandef.chan = NULL;
6572 } 6572 }
6573 6573
6574 return cfg80211_join_mesh(rdev, dev, &setup, &cfg); 6574 return cfg80211_join_mesh(rdev, dev, &setup, &cfg);
@@ -8800,8 +8800,8 @@ void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
8800} 8800}
8801 8801
8802void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev, 8802void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
8803 struct net_device *netdev, int freq, 8803 struct net_device *netdev,
8804 enum nl80211_channel_type type, gfp_t gfp) 8804 struct cfg80211_chan_def *chandef, gfp_t gfp)
8805{ 8805{
8806 struct sk_buff *msg; 8806 struct sk_buff *msg;
8807 void *hdr; 8807 void *hdr;
@@ -8816,9 +8816,10 @@ void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev,
8816 return; 8816 return;
8817 } 8817 }
8818 8818
8819 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || 8819 if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex))
8820 nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) || 8820 goto nla_put_failure;
8821 nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, type)) 8821
8822 if (nl80211_send_chandef(msg, chandef))
8822 goto nla_put_failure; 8823 goto nla_put_failure;
8823 8824
8824 genlmsg_end(msg, hdr); 8825 genlmsg_end(msg, hdr);