cfg80211: Pass TDLS peer capability information in tdls_mgmt
authorSunil Dutt Undekari <usdutt@qti.qualcomm.com>
Thu, 20 Feb 2014 10:52:09 +0000 (16:22 +0530)
committerJohannes Berg <johannes.berg@intel.com>
Thu, 20 Feb 2014 10:55:25 +0000 (11:55 +0100)
While framing the TDLS Setup Confirmation frame, the driver needs to
know if the TDLS peer is VHT/HT/WMM capable and thus shall construct
the VHT/HT operation / WMM parameter elements accordingly. Supplicant
determines if the TDLS peer is VHT/HT/WMM capable based on the
presence of the respective IEs in the received TDLS Setup Response frame.

The host driver should not need to parse the received TDLS Response
frame and thus, should be able to rely on the supplicant to indicate
the capability of the peer through additional flags while transmitting
the TDLS Setup Confirmation frame through tdls_mgmt operations.

Signed-off-by: Sunil Dutt Undekari <usdutt@qti.qualcomm.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/mwifiex/cfg80211.c
include/net/cfg80211.h
include/uapi/linux/nl80211.h
net/mac80211/cfg.c
net/wireless/nl80211.c
net/wireless/rdev-ops.h
net/wireless/trace.h

index 436ba437a4ba198f2c469cad6545818e46cba730..6948a97af8390433fa41c5de5888eb96747eb943 100644 (file)
@@ -2600,8 +2600,8 @@ static int mwifiex_cfg80211_set_coalesce(struct wiphy *wiphy,
 static int
 mwifiex_cfg80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
                           u8 *peer, u8 action_code, u8 dialog_token,
-                          u16 status_code, const u8 *extra_ies,
-                          size_t extra_ies_len)
+                          u16 status_code, u32 peer_capability,
+                          const u8 *extra_ies, size_t extra_ies_len)
 {
        struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
        int ret;
index 9f90554e88c48a1342c0d1116e1c47ba0b875d81..c89a5b5bd103461a6ff4427a191c3eb302993e86 100644 (file)
@@ -2465,7 +2465,8 @@ struct cfg80211_ops {
 
        int     (*tdls_mgmt)(struct wiphy *wiphy, struct net_device *dev,
                             u8 *peer, u8 action_code,  u8 dialog_token,
-                            u16 status_code, const u8 *buf, size_t len);
+                            u16 status_code, u32 peer_capability,
+                            const u8 *buf, size_t len);
        int     (*tdls_oper)(struct wiphy *wiphy, struct net_device *dev,
                             u8 *peer, enum nl80211_tdls_operation oper);
 
index ba1f7625625c8e23b7c9ba1b5cba143448cd7f58..47d7087513e09a1b0e419f0c5cbc632fd37d94dc 100644 (file)
@@ -1575,6 +1575,9 @@ enum nl80211_commands {
  *     advertise values that cannot always be met. In such cases, an attempt
  *     to add a new station entry with @NL80211_CMD_NEW_STATION may fail.
  *
+ * @NL80211_ATTR_TDLS_PEER_CAPABILITY: flags for TDLS peer capabilities, u32.
+ *     As specified in the &enum nl80211_tdls_peer_capability.
+ *
  * @NL80211_ATTR_MAX: highest attribute number currently defined
  * @__NL80211_ATTR_AFTER_LAST: internal use
  */
@@ -1908,6 +1911,8 @@ enum nl80211_attrs {
 
        NL80211_ATTR_MAX_AP_ASSOC_STA,
 
+       NL80211_ATTR_TDLS_PEER_CAPABILITY,
+
        /* add attributes here, update the policy in nl80211.c */
 
        __NL80211_ATTR_AFTER_LAST,
@@ -4074,4 +4079,20 @@ struct nl80211_vendor_cmd_info {
        __u32 subcmd;
 };
 
+/**
+ * enum nl80211_tdls_peer_capability - TDLS peer flags.
+ *
+ * Used by tdls_mgmt() to determine which conditional elements need
+ * to be added to TDLS Setup frames.
+ *
+ * @NL80211_TDLS_PEER_HT: TDLS peer is HT capable.
+ * @NL80211_TDLS_PEER_VHT: TDLS peer is VHT capable.
+ * @NL80211_TDLS_PEER_WMM: TDLS peer is WMM capable.
+ */
+enum nl80211_tdls_peer_capability {
+       NL80211_TDLS_PEER_HT = 1<<0,
+       NL80211_TDLS_PEER_VHT = 1<<1,
+       NL80211_TDLS_PEER_WMM = 1<<2,
+};
+
 #endif /* __LINUX_NL80211_H */
index 3849fd07a32171cf8826b1e2509c4250379a456f..1acb29109b45dfc9d76d83b0506d8ed47932b10d 100644 (file)
@@ -3644,8 +3644,8 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev,
 
 static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev,
                               u8 *peer, u8 action_code, u8 dialog_token,
-                              u16 status_code, const u8 *extra_ies,
-                              size_t extra_ies_len)
+                              u16 status_code, u32 peer_capability,
+                              const u8 *extra_ies, size_t extra_ies_len)
 {
        struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct ieee80211_local *local = sdata->local;
index 058aa0e1a462304e5e414a5f6eb4dfdac0dfa1cf..be836098d342dc132b46c339f0fdfdf1dafd5264 100644 (file)
@@ -384,6 +384,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
                                   .len = IEEE80211_QOS_MAP_LEN_MAX },
        [NL80211_ATTR_MAC_HINT] = { .len = ETH_ALEN },
        [NL80211_ATTR_WIPHY_FREQ_HINT] = { .type = NLA_U32 },
+       [NL80211_ATTR_TDLS_PEER_CAPABILITY] = { .type = NLA_U32 },
 };
 
 /* policy for the key attributes */
@@ -7269,6 +7270,7 @@ static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
        struct cfg80211_registered_device *rdev = info->user_ptr[0];
        struct net_device *dev = info->user_ptr[1];
        u8 action_code, dialog_token;
+       u32 peer_capability = 0;
        u16 status_code;
        u8 *peer;
 
@@ -7287,9 +7289,12 @@ static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info)
        action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]);
        status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]);
        dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]);
+       if (info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY])
+               peer_capability =
+                       nla_get_u32(info->attrs[NL80211_ATTR_TDLS_PEER_CAPABILITY]);
 
        return rdev_tdls_mgmt(rdev, dev, peer, action_code,
-                             dialog_token, status_code,
+                             dialog_token, status_code, peer_capability,
                              nla_data(info->attrs[NL80211_ATTR_IE]),
                              nla_len(info->attrs[NL80211_ATTR_IE]));
 }
index c8e225947adb2601d31dbb0f4a1aa5a4392d8bc5..74d97d33c938e8250ef300c2c3fb82d2a39b63b6 100644 (file)
@@ -769,13 +769,16 @@ static inline int rdev_set_rekey_data(struct cfg80211_registered_device *rdev,
 static inline int rdev_tdls_mgmt(struct cfg80211_registered_device *rdev,
                                 struct net_device *dev, u8 *peer,
                                 u8 action_code, u8 dialog_token,
-                                u16 status_code, const u8 *buf, size_t len)
+                                u16 status_code, u32 peer_capability,
+                                const u8 *buf, size_t len)
 {
        int ret;
        trace_rdev_tdls_mgmt(&rdev->wiphy, dev, peer, action_code,
-                            dialog_token, status_code, buf, len);
+                            dialog_token, status_code, peer_capability,
+                            buf, len);
        ret = rdev->ops->tdls_mgmt(&rdev->wiphy, dev, peer, action_code,
-                                  dialog_token, status_code, buf, len);
+                                  dialog_token, status_code, peer_capability,
+                                  buf, len);
        trace_rdev_return_int(&rdev->wiphy, ret);
        return ret;
 }
index 5eaeed59db07651de6305320187f127c9fdd8b65..aabccf13e07b6860ef92ddc637a7879a8f961aab 100644 (file)
@@ -1468,9 +1468,10 @@ TRACE_EVENT(rdev_sched_scan_start,
 TRACE_EVENT(rdev_tdls_mgmt,
        TP_PROTO(struct wiphy *wiphy, struct net_device *netdev,
                 u8 *peer, u8 action_code, u8 dialog_token,
-                u16 status_code, const u8 *buf, size_t len),
+                u16 status_code, u32 peer_capability,
+                const u8 *buf, size_t len),
        TP_ARGS(wiphy, netdev, peer, action_code, dialog_token, status_code,
-               buf, len),
+               peer_capability, buf, len),
        TP_STRUCT__entry(
                WIPHY_ENTRY
                NETDEV_ENTRY
@@ -1478,6 +1479,7 @@ TRACE_EVENT(rdev_tdls_mgmt,
                __field(u8, action_code)
                __field(u8, dialog_token)
                __field(u16, status_code)
+               __field(u32, peer_capability)
                __dynamic_array(u8, buf, len)
        ),
        TP_fast_assign(
@@ -1487,13 +1489,15 @@ TRACE_EVENT(rdev_tdls_mgmt,
                __entry->action_code = action_code;
                __entry->dialog_token = dialog_token;
                __entry->status_code = status_code;
+               __entry->peer_capability = peer_capability;
                memcpy(__get_dynamic_array(buf), buf, len);
        ),
        TP_printk(WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " MAC_PR_FMT ", action_code: %u, "
-                 "dialog_token: %u, status_code: %u, buf: %#.2x ",
+                 "dialog_token: %u, status_code: %u, peer_capability: %u buf: %#.2x ",
                  WIPHY_PR_ARG, NETDEV_PR_ARG, MAC_PR_ARG(peer),
                  __entry->action_code, __entry->dialog_token,
-                 __entry->status_code, ((u8 *)__get_dynamic_array(buf))[0])
+                 __entry->status_code, __entry->peer_capability,
+                 ((u8 *)__get_dynamic_array(buf))[0])
 );
 
 TRACE_EVENT(rdev_dump_survey,