diff options
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r-- | net/wireless/nl80211.c | 95 |
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); |