aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2013-02-14 14:10:13 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-02-15 03:41:43 -0500
commit9d62a98617298c1da288f50e84c5dd67732e79b7 (patch)
tree63273fe1ade1b83c876db02ee75b951e1825b9dc /net/wireless/nl80211.c
parentc6f9d6c3bdeb337809d667ef2a41597229a1ce57 (diff)
cfg80211: Pass station (extended) capability info to kernel
The information of the peer's capabilities and extended capabilities are required for the driver to perform TDLS Peer UAPSD operations and off channel operations. This information of the peer is passed from user space using NL80211_CMD_SET_STATION command. This commit enhances the function nl80211_set_station to pass the capability information of the peer to the driver. Similarly, there may be need for capability information for other modes, so allow this to be provided with both add_station and change_station. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c36
1 files changed, 36 insertions, 0 deletions
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]);