aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
authorArik Nemtsov <arik@wizery.com>2011-09-28 07:12:50 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-09-30 15:57:05 -0400
commit109086ce0b0f94760bdb0e8e2566ff8a2d673639 (patch)
tree217a3d18f203fe1cf8652f9b33c4ade1f61594c2 /net/wireless/nl80211.c
parenta76011e2cbb6915f60488477311e0f269cee6496 (diff)
nl80211: support sending TDLS commands/frames
Add support for sending high-level TDLS commands and TDLS frames via NL80211_CMD_TDLS_OPER and NL80211_CMD_TDLS_MGMT, respectively. Add appropriate cfg80211 callbacks for lower level drivers. Add wiphy capability flags for TDLS support and advertise them via nl80211. Signed-off-by: Arik Nemtsov <arik@wizery.com> Cc: Kalyan C Gaddam <chakkal@iit.edu> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c81
1 files changed, 80 insertions, 1 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 3799623e7f46..25a37fc951e3 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -192,6 +192,11 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
192 [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG }, 192 [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG },
193 [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED }, 193 [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED },
194 [NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG }, 194 [NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG },
195 [NL80211_ATTR_TDLS_ACTION] = { .type = NLA_U8 },
196 [NL80211_ATTR_TDLS_DIALOG_TOKEN] = { .type = NLA_U8 },
197 [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
198 [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
199 [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
195}; 200};
196 201
197/* policy for the key attributes */ 202/* policy for the key attributes */
@@ -732,9 +737,12 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
732 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_MESH_AUTH); 737 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_MESH_AUTH);
733 if (dev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) 738 if (dev->wiphy.flags & WIPHY_FLAG_AP_UAPSD)
734 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_AP_UAPSD); 739 NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_AP_UAPSD);
735
736 if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) 740 if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)
737 NLA_PUT_FLAG(msg, NL80211_ATTR_ROAM_SUPPORT); 741 NLA_PUT_FLAG(msg, NL80211_ATTR_ROAM_SUPPORT);
742 if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS)
743 NLA_PUT_FLAG(msg, NL80211_ATTR_TDLS_SUPPORT);
744 if (dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP)
745 NLA_PUT_FLAG(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP);
738 746
739 NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES, 747 NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES,
740 sizeof(u32) * dev->wiphy.n_cipher_suites, 748 sizeof(u32) * dev->wiphy.n_cipher_suites,
@@ -877,6 +885,10 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
877 } 885 }
878 CMD(set_channel, SET_CHANNEL); 886 CMD(set_channel, SET_CHANNEL);
879 CMD(set_wds_peer, SET_WDS_PEER); 887 CMD(set_wds_peer, SET_WDS_PEER);
888 if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) {
889 CMD(tdls_mgmt, TDLS_MGMT);
890 CMD(tdls_oper, TDLS_OPER);
891 }
880 if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) 892 if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
881 CMD(sched_scan_start, START_SCHED_SCAN); 893 CMD(sched_scan_start, START_SCHED_SCAN);
882 894
@@ -4966,6 +4978,57 @@ static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
4966 return rdev->ops->flush_pmksa(&rdev->wiphy, dev); 4978 return rdev->ops->flush_pmksa(&rdev->wiphy, dev);
4967} 4979}
4968 4980
4981static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
4982{
4983 struct cfg80211_registered_device *rdev = info->user_ptr[0];
4984 struct net_device *dev = info->user_ptr[1];
4985 u8 action_code, dialog_token;
4986 u16 status_code;
4987 u8 *peer;
4988
4989 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
4990 !rdev->ops->tdls_mgmt)
4991 return -EOPNOTSUPP;
4992
4993 if (!info->attrs[NL80211_ATTR_TDLS_ACTION] ||
4994 !info->attrs[NL80211_ATTR_STATUS_CODE] ||
4995 !info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN] ||
4996 !info->attrs[NL80211_ATTR_IE] ||
4997 !info->attrs[NL80211_ATTR_MAC])
4998 return -EINVAL;
4999
5000 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
5001 action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]);
5002 status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
5003 dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]);
5004
5005 return rdev->ops->tdls_mgmt(&rdev->wiphy, dev, peer, action_code,
5006 dialog_token, status_code,
5007 nla_data(info->attrs[NL80211_ATTR_IE]),
5008 nla_len(info->attrs[NL80211_ATTR_IE]));
5009}
5010
5011static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info)
5012{
5013 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5014 struct net_device *dev = info->user_ptr[1];
5015 enum nl80211_tdls_operation operation;
5016 u8 *peer;
5017
5018 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
5019 !rdev->ops->tdls_oper)
5020 return -EOPNOTSUPP;
5021
5022 if (!info->attrs[NL80211_ATTR_TDLS_OPERATION] ||
5023 !info->attrs[NL80211_ATTR_MAC])
5024 return -EINVAL;
5025
5026 operation = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_OPERATION]);
5027 peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
5028
5029 return rdev->ops->tdls_oper(&rdev->wiphy, dev, peer, operation);
5030}
5031
4969static int nl80211_remain_on_channel(struct sk_buff *skb, 5032static int nl80211_remain_on_channel(struct sk_buff *skb,
4970 struct genl_info *info) 5033 struct genl_info *info)
4971{ 5034{
@@ -6281,6 +6344,22 @@ static struct genl_ops nl80211_ops[] = {
6281 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | 6344 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6282 NL80211_FLAG_NEED_RTNL, 6345 NL80211_FLAG_NEED_RTNL,
6283 }, 6346 },
6347 {
6348 .cmd = NL80211_CMD_TDLS_MGMT,
6349 .doit = nl80211_tdls_mgmt,
6350 .policy = nl80211_policy,
6351 .flags = GENL_ADMIN_PERM,
6352 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6353 NL80211_FLAG_NEED_RTNL,
6354 },
6355 {
6356 .cmd = NL80211_CMD_TDLS_OPER,
6357 .doit = nl80211_tdls_oper,
6358 .policy = nl80211_policy,
6359 .flags = GENL_ADMIN_PERM,
6360 .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
6361 NL80211_FLAG_NEED_RTNL,
6362 },
6284}; 6363};
6285 6364
6286static struct genl_multicast_group nl80211_mlme_mcgrp = { 6365static struct genl_multicast_group nl80211_mlme_mcgrp = {