diff options
-rw-r--r-- | include/net/cfg80211.h | 8 | ||||
-rw-r--r-- | include/uapi/linux/nl80211.h | 10 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 36 |
3 files changed, 54 insertions, 0 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index a229046d86d4..fa2612952c19 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -626,12 +626,14 @@ enum plink_actions { | |||
626 | /** | 626 | /** |
627 | * enum station_parameters_apply_mask - station parameter values to apply | 627 | * enum station_parameters_apply_mask - station parameter values to apply |
628 | * @STATION_PARAM_APPLY_UAPSD: apply new uAPSD parameters (uapsd_queues, max_sp) | 628 | * @STATION_PARAM_APPLY_UAPSD: apply new uAPSD parameters (uapsd_queues, max_sp) |
629 | * @STATION_PARAM_APPLY_CAPABILITY: apply new capability | ||
629 | * | 630 | * |
630 | * Not all station parameters have in-band "no change" signalling, | 631 | * Not all station parameters have in-band "no change" signalling, |
631 | * for those that don't these flags will are used. | 632 | * for those that don't these flags will are used. |
632 | */ | 633 | */ |
633 | enum station_parameters_apply_mask { | 634 | enum station_parameters_apply_mask { |
634 | STATION_PARAM_APPLY_UAPSD = BIT(0), | 635 | STATION_PARAM_APPLY_UAPSD = BIT(0), |
636 | STATION_PARAM_APPLY_CAPABILITY = BIT(1), | ||
635 | }; | 637 | }; |
636 | 638 | ||
637 | /** | 639 | /** |
@@ -662,6 +664,9 @@ enum station_parameters_apply_mask { | |||
662 | * see &enum station_parameters_apply_mask | 664 | * see &enum station_parameters_apply_mask |
663 | * @local_pm: local link-specific mesh power save mode (no change when set | 665 | * @local_pm: local link-specific mesh power save mode (no change when set |
664 | * to unknown) | 666 | * to unknown) |
667 | * @capability: station capability | ||
668 | * @ext_capab: extended capabilities of the station | ||
669 | * @ext_capab_len: number of extended capabilities | ||
665 | */ | 670 | */ |
666 | struct station_parameters { | 671 | struct station_parameters { |
667 | u8 *supported_rates; | 672 | u8 *supported_rates; |
@@ -678,6 +683,9 @@ struct station_parameters { | |||
678 | u8 uapsd_queues; | 683 | u8 uapsd_queues; |
679 | u8 max_sp; | 684 | u8 max_sp; |
680 | enum nl80211_mesh_power_mode local_pm; | 685 | enum nl80211_mesh_power_mode local_pm; |
686 | u16 capability; | ||
687 | u8 *ext_capab; | ||
688 | u8 ext_capab_len; | ||
681 | }; | 689 | }; |
682 | 690 | ||
683 | /** | 691 | /** |
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 1fd6e5611896..f7c35ca01efc 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h | |||
@@ -1361,6 +1361,13 @@ enum nl80211_commands { | |||
1361 | * @NL80211_ATTR_EXT_CAPA_MASK: Extended capabilities that the kernel driver | 1361 | * @NL80211_ATTR_EXT_CAPA_MASK: Extended capabilities that the kernel driver |
1362 | * has set in the %NL80211_ATTR_EXT_CAPA value, for multibit fields. | 1362 | * has set in the %NL80211_ATTR_EXT_CAPA value, for multibit fields. |
1363 | * | 1363 | * |
1364 | * @NL80211_ATTR_STA_CAPABILITY: Station capabilities (u16) are advertised to | ||
1365 | * the driver, e.g., to enable TDLS power save (PU-APSD). | ||
1366 | * | ||
1367 | * @NL80211_ATTR_STA_EXT_CAPABILITY: Station extended capabilities are | ||
1368 | * advertised to the driver, e.g., to enable TDLS off channel operations | ||
1369 | * and PU-APSD. | ||
1370 | * | ||
1364 | * @NL80211_ATTR_MAX: highest attribute number currently defined | 1371 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
1365 | * @__NL80211_ATTR_AFTER_LAST: internal use | 1372 | * @__NL80211_ATTR_AFTER_LAST: internal use |
1366 | */ | 1373 | */ |
@@ -1644,6 +1651,9 @@ enum nl80211_attrs { | |||
1644 | NL80211_ATTR_EXT_CAPA, | 1651 | NL80211_ATTR_EXT_CAPA, |
1645 | NL80211_ATTR_EXT_CAPA_MASK, | 1652 | NL80211_ATTR_EXT_CAPA_MASK, |
1646 | 1653 | ||
1654 | NL80211_ATTR_STA_CAPABILITY, | ||
1655 | NL80211_ATTR_STA_EXT_CAPABILITY, | ||
1656 | |||
1647 | /* add attributes here, update the policy in nl80211.c */ | 1657 | /* add attributes here, update the policy in nl80211.c */ |
1648 | 1658 | ||
1649 | __NL80211_ATTR_AFTER_LAST, | 1659 | __NL80211_ATTR_AFTER_LAST, |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 1237431c3efa..be9f2b5a403f 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -368,6 +368,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
368 | [NL80211_ATTR_P2P_OPPPS] = { .type = NLA_U8 }, | 368 | [NL80211_ATTR_P2P_OPPPS] = { .type = NLA_U8 }, |
369 | [NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 }, | 369 | [NL80211_ATTR_ACL_POLICY] = {. type = NLA_U32 }, |
370 | [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED }, | 370 | [NL80211_ATTR_MAC_ADDRS] = { .type = NLA_NESTED }, |
371 | [NL80211_ATTR_STA_CAPABILITY] = { .type = NLA_U16 }, | ||
372 | [NL80211_ATTR_STA_EXT_CAPABILITY] = { .type = NLA_BINARY, }, | ||
371 | }; | 373 | }; |
372 | 374 | ||
373 | /* policy for the key attributes */ | 375 | /* policy for the key attributes */ |
@@ -3435,6 +3437,19 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) | |||
3435 | nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); | 3437 | nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); |
3436 | } | 3438 | } |
3437 | 3439 | ||
3440 | if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) { | ||
3441 | params.capability = | ||
3442 | nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]); | ||
3443 | params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY; | ||
3444 | } | ||
3445 | |||
3446 | if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) { | ||
3447 | params.ext_capab = | ||
3448 | nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]); | ||
3449 | params.ext_capab_len = | ||
3450 | nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]); | ||
3451 | } | ||
3452 | |||
3438 | if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL] || | 3453 | if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL] || |
3439 | info->attrs[NL80211_ATTR_HT_CAPABILITY]) | 3454 | info->attrs[NL80211_ATTR_HT_CAPABILITY]) |
3440 | return -EINVAL; | 3455 | return -EINVAL; |
@@ -3505,6 +3520,10 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) | |||
3505 | /* reject other things that can't change */ | 3520 | /* reject other things that can't change */ |
3506 | if (params.supported_rates) | 3521 | if (params.supported_rates) |
3507 | return -EINVAL; | 3522 | return -EINVAL; |
3523 | if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) | ||
3524 | return -EINVAL; | ||
3525 | if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) | ||
3526 | return -EINVAL; | ||
3508 | 3527 | ||
3509 | /* must be last in here for error handling */ | 3528 | /* must be last in here for error handling */ |
3510 | params.vlan = get_vlan(info, rdev); | 3529 | params.vlan = get_vlan(info, rdev); |
@@ -3537,6 +3556,10 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) | |||
3537 | return -EINVAL; | 3556 | return -EINVAL; |
3538 | if (params.supported_rates) | 3557 | if (params.supported_rates) |
3539 | return -EINVAL; | 3558 | return -EINVAL; |
3559 | if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) | ||
3560 | return -EINVAL; | ||
3561 | if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) | ||
3562 | return -EINVAL; | ||
3540 | /* | 3563 | /* |
3541 | * No special handling for TDLS here -- the userspace | 3564 | * No special handling for TDLS here -- the userspace |
3542 | * mesh code doesn't have this bug. | 3565 | * mesh code doesn't have this bug. |
@@ -3601,6 +3624,19 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) | |||
3601 | if (!params.aid || params.aid > IEEE80211_MAX_AID) | 3624 | if (!params.aid || params.aid > IEEE80211_MAX_AID) |
3602 | return -EINVAL; | 3625 | return -EINVAL; |
3603 | 3626 | ||
3627 | if (info->attrs[NL80211_ATTR_STA_CAPABILITY]) { | ||
3628 | params.capability = | ||
3629 | nla_get_u16(info->attrs[NL80211_ATTR_STA_CAPABILITY]); | ||
3630 | params.sta_modify_mask |= STATION_PARAM_APPLY_CAPABILITY; | ||
3631 | } | ||
3632 | |||
3633 | if (info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]) { | ||
3634 | params.ext_capab = | ||
3635 | nla_data(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]); | ||
3636 | params.ext_capab_len = | ||
3637 | nla_len(info->attrs[NL80211_ATTR_STA_EXT_CAPABILITY]); | ||
3638 | } | ||
3639 | |||
3604 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) | 3640 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) |
3605 | params.ht_capa = | 3641 | params.ht_capa = |
3606 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); | 3642 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); |