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.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 16f86356ac97..5a9a5c6c71db 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -61,6 +61,10 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
61 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED }, 61 [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED },
62 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 }, 62 [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 },
63 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 }, 63 [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 },
64 [NL80211_ATTR_WIPHY_RETRY_SHORT] = { .type = NLA_U8 },
65 [NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 },
66 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
67 [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
64 68
65 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 }, 69 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
66 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, 70 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
@@ -204,6 +208,16 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
204 208
205 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx); 209 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx);
206 NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)); 210 NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy));
211
212 NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT,
213 dev->wiphy.retry_short);
214 NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_RETRY_LONG,
215 dev->wiphy.retry_long);
216 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD,
217 dev->wiphy.frag_threshold);
218 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
219 dev->wiphy.rts_threshold);
220
207 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS, 221 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
208 dev->wiphy.max_scan_ssids); 222 dev->wiphy.max_scan_ssids);
209 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN, 223 NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN,
@@ -416,6 +430,9 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
416 struct cfg80211_registered_device *rdev; 430 struct cfg80211_registered_device *rdev;
417 int result = 0, rem_txq_params = 0; 431 int result = 0, rem_txq_params = 0;
418 struct nlattr *nl_txq_params; 432 struct nlattr *nl_txq_params;
433 u32 changed;
434 u8 retry_short = 0, retry_long = 0;
435 u32 frag_threshold = 0, rts_threshold = 0;
419 436
420 rtnl_lock(); 437 rtnl_lock();
421 438
@@ -530,6 +547,84 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
530 goto bad_res; 547 goto bad_res;
531 } 548 }
532 549
550 changed = 0;
551
552 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) {
553 retry_short = nla_get_u8(
554 info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]);
555 if (retry_short == 0) {
556 result = -EINVAL;
557 goto bad_res;
558 }
559 changed |= WIPHY_PARAM_RETRY_SHORT;
560 }
561
562 if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) {
563 retry_long = nla_get_u8(
564 info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]);
565 if (retry_long == 0) {
566 result = -EINVAL;
567 goto bad_res;
568 }
569 changed |= WIPHY_PARAM_RETRY_LONG;
570 }
571
572 if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) {
573 frag_threshold = nla_get_u32(
574 info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]);
575 if (frag_threshold < 256) {
576 result = -EINVAL;
577 goto bad_res;
578 }
579 if (frag_threshold != (u32) -1) {
580 /*
581 * Fragments (apart from the last one) are required to
582 * have even length. Make the fragmentation code
583 * simpler by stripping LSB should someone try to use
584 * odd threshold value.
585 */
586 frag_threshold &= ~0x1;
587 }
588 changed |= WIPHY_PARAM_FRAG_THRESHOLD;
589 }
590
591 if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) {
592 rts_threshold = nla_get_u32(
593 info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]);
594 changed |= WIPHY_PARAM_RTS_THRESHOLD;
595 }
596
597 if (changed) {
598 u8 old_retry_short, old_retry_long;
599 u32 old_frag_threshold, old_rts_threshold;
600
601 if (!rdev->ops->set_wiphy_params) {
602 result = -EOPNOTSUPP;
603 goto bad_res;
604 }
605
606 old_retry_short = rdev->wiphy.retry_short;
607 old_retry_long = rdev->wiphy.retry_long;
608 old_frag_threshold = rdev->wiphy.frag_threshold;
609 old_rts_threshold = rdev->wiphy.rts_threshold;
610
611 if (changed & WIPHY_PARAM_RETRY_SHORT)
612 rdev->wiphy.retry_short = retry_short;
613 if (changed & WIPHY_PARAM_RETRY_LONG)
614 rdev->wiphy.retry_long = retry_long;
615 if (changed & WIPHY_PARAM_FRAG_THRESHOLD)
616 rdev->wiphy.frag_threshold = frag_threshold;
617 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
618 rdev->wiphy.rts_threshold = rts_threshold;
619
620 result = rdev->ops->set_wiphy_params(&rdev->wiphy, changed);
621 if (result) {
622 rdev->wiphy.retry_short = old_retry_short;
623 rdev->wiphy.retry_long = old_retry_long;
624 rdev->wiphy.frag_threshold = old_frag_threshold;
625 rdev->wiphy.rts_threshold = old_rts_threshold;
626 }
627 }
533 628
534 bad_res: 629 bad_res:
535 mutex_unlock(&rdev->mtx); 630 mutex_unlock(&rdev->mtx);