Merge branch 'develop-3.0' of ssh://10.10.10.29/rk/kernel into develop-3.0
authorgwl <gwl@rock-chips.com>
Tue, 18 Dec 2012 06:35:35 +0000 (14:35 +0800)
committergwl <gwl@rock-chips.com>
Tue, 18 Dec 2012 06:35:35 +0000 (14:35 +0800)
include/linux/nl80211.h
include/net/cfg80211.h
net/wireless/core.c
net/wireless/core.h
net/wireless/mlme.c
net/wireless/nl80211.c
net/wireless/nl80211.h

index 27d2dd9e671730ca8b7c5588b02a8c550229ed8e..032ec974153f87ee1de8c01081eccc514984462a 100644 (file)
@@ -604,6 +604,21 @@ enum nl80211_commands {
        NL80211_CMD_STOP_SCHED_SCAN,
        NL80211_CMD_SCHED_SCAN_RESULTS,
        NL80211_CMD_SCHED_SCAN_STOPPED,
+//==============gwl=======================
+
+       NL80211_CMD_SET_REKEY_OFFLOAD,
+
+       NL80211_CMD_PMKSA_CANDIDATE,
+
+       NL80211_CMD_TDLS_OPER,
+       NL80211_CMD_TDLS_MGMT,
+
+       NL80211_CMD_UNEXPECTED_FRAME,
+
+       NL80211_CMD_PROBE_CLIENT,
+
+       NL80211_CMD_REGISTER_BEACONS,
+//=====================================
 
        /* add new commands above here */
 
@@ -1238,6 +1253,19 @@ enum nl80211_attrs {
        NL80211_ATTR_SCHED_SCAN_MATCH,
        NL80211_ATTR_MAX_MATCH_SETS,
 
+//=============== gwl =============
+       NL80211_ATTR_PMKSA_CANDIDATE,
+
+       NL80211_ATTR_TX_NO_CCK_RATE,
+
+       NL80211_ATTR_TDLS_ACTION,
+       NL80211_ATTR_TDLS_DIALOG_TOKEN,
+       NL80211_ATTR_TDLS_OPERATION,
+       NL80211_ATTR_TDLS_SUPPORT,
+       NL80211_ATTR_TDLS_EXTERNAL_SETUP,
+
+       NL80211_ATTR_DEVICE_AP_SME,
+//===================================
        /* add attributes here, update the policy in nl80211.c */
 
        __NL80211_ATTR_AFTER_LAST,
@@ -2312,6 +2340,13 @@ enum nl80211_wowlan_triggers {
        NL80211_WOWLAN_TRIG_DISCONNECT,
        NL80211_WOWLAN_TRIG_MAGIC_PKT,
        NL80211_WOWLAN_TRIG_PKT_PATTERN,
+//======== gwl ===============
+       NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED,
+       NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE,
+       NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST,
+       NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE,
+       NL80211_WOWLAN_TRIG_RFKILL_RELEASE,
+//===============================
 
        /* keep last */
        NUM_NL80211_WOWLAN_TRIG,
@@ -2424,5 +2459,55 @@ enum nl80211_plink_state {
        NUM_NL80211_PLINK_STATES,
        MAX_NL80211_PLINK_STATES = NUM_NL80211_PLINK_STATES - 1
 };
+// gwl=========================
+#define NL80211_KCK_LEN                        16
+#define NL80211_KEK_LEN                        16
+#define NL80211_REPLAY_CTR_LEN         8
+
+enum nl80211_rekey_data {
+       __NL80211_REKEY_DATA_INVALID,
+       NL80211_REKEY_DATA_KEK,
+       NL80211_REKEY_DATA_KCK,
+       NL80211_REKEY_DATA_REPLAY_CTR,
+
+       /* keep last */
+       NUM_NL80211_REKEY_DATA,
+       MAX_NL80211_REKEY_DATA = NUM_NL80211_REKEY_DATA - 1
+};
+
+enum nl80211_hidden_ssid {
+       NL80211_HIDDEN_SSID_NOT_IN_USE,
+       NL80211_HIDDEN_SSID_ZERO_LEN,
+       NL80211_HIDDEN_SSID_ZERO_CONTENTS
+};
+
+enum nl80211_sta_wme_attr {
+       __NL80211_STA_WME_INVALID,
+       NL80211_STA_WME_UAPSD_QUEUES,
+       NL80211_STA_WME_MAX_SP,
+
+       /* keep last */
+       __NL80211_STA_WME_AFTER_LAST,
+       NL80211_STA_WME_MAX = __NL80211_STA_WME_AFTER_LAST - 1
+};
+
+enum nl80211_pmksa_candidate_attr {
+       __NL80211_PMKSA_CANDIDATE_INVALID,
+       NL80211_PMKSA_CANDIDATE_INDEX,
+       NL80211_PMKSA_CANDIDATE_BSSID,
+       NL80211_PMKSA_CANDIDATE_PREAUTH,
+
+       /* keep last */
+       NUM_NL80211_PMKSA_CANDIDATE,
+       MAX_NL80211_PMKSA_CANDIDATE = NUM_NL80211_PMKSA_CANDIDATE - 1
+};
+
+enum nl80211_tdls_operation {
+       NL80211_TDLS_DISCOVERY_REQ,
+       NL80211_TDLS_SETUP,
+       NL80211_TDLS_TEARDOWN,
+       NL80211_TDLS_ENABLE_LINK,
+       NL80211_TDLS_DISABLE_LINK,
+};
 
 #endif /* __LINUX_NL80211_H */
index a2a97f34b9cbcc5d112bd339766b54b8a690267f..dc7b7d896849d55767c34b8f5ede98ace1b6b943 100755 (executable)
@@ -1178,11 +1178,21 @@ struct cfg80211_wowlan_trig_pkt_pattern {
  * @patterns: wake up on receiving packet matching a pattern
  * @n_patterns: number of patterns
  */
+// gwl
 struct cfg80211_wowlan {
-       bool any, disconnect, magic_pkt;
+       bool any, disconnect, magic_pkt, gtk_rekey_failure,
+            eap_identity_req, four_way_handshake,
+            rfkill_release;
        struct cfg80211_wowlan_trig_pkt_pattern *patterns;
        int n_patterns;
 };
+//======= gwl ======
+struct cfg80211_gtk_rekey_data {
+       u8 kek[NL80211_KEK_LEN];
+       u8 kck[NL80211_KCK_LEN];
+       u8 replay_ctr[NL80211_REPLAY_CTR_LEN];
+};
+//=============
 
 /**
  * struct cfg80211_ops - backend description for wireless configuration
@@ -1521,6 +1531,20 @@ struct cfg80211_ops {
                                struct net_device *dev,
                                struct cfg80211_sched_scan_request *request);
        int     (*sched_scan_stop)(struct wiphy *wiphy, struct net_device *dev);
+
+//========= gwl ================
+       int     (*set_rekey_data)(struct wiphy *wiphy, struct net_device *dev,
+                                 struct cfg80211_gtk_rekey_data *data);
+
+       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);
+       int     (*tdls_oper)(struct wiphy *wiphy, struct net_device *dev,
+                            u8 *peer, enum nl80211_tdls_operation oper);
+
+       int     (*probe_client)(struct wiphy *wiphy, struct net_device *dev,
+                               const u8 *peer, u64 *cookie);
+//===========================
 };
 
 /*
@@ -1584,6 +1608,14 @@ enum wiphy_flags {
        WIPHY_FLAG_MESH_AUTH                    = BIT(10),
        WIPHY_FLAG_SUPPORTS_SCHED_SCAN          = BIT(11),
        WIPHY_FLAG_ENFORCE_COMBINATIONS         = BIT(12),
+//========= gwl =================
+       WIPHY_FLAG_SUPPORTS_FW_ROAM             = BIT(13),
+       WIPHY_FLAG_AP_UAPSD                     = BIT(14),
+       WIPHY_FLAG_SUPPORTS_TDLS                = BIT(15),
+       WIPHY_FLAG_TDLS_EXTERNAL_SETUP          = BIT(16),
+       WIPHY_FLAG_HAVE_AP_SME                  = BIT(17),
+       WIPHY_FLAG_REPORTS_OBSS                 = BIT(18),
+//==============================
 };
 
 /**
@@ -1683,6 +1715,13 @@ enum wiphy_wowlan_support_flags {
        WIPHY_WOWLAN_ANY        = BIT(0),
        WIPHY_WOWLAN_MAGIC_PKT  = BIT(1),
        WIPHY_WOWLAN_DISCONNECT = BIT(2),
+//=========== gwl ===========
+       WIPHY_WOWLAN_SUPPORTS_GTK_REKEY = BIT(3),
+       WIPHY_WOWLAN_GTK_REKEY_FAILURE  = BIT(4),
+       WIPHY_WOWLAN_EAP_IDENTITY_REQ   = BIT(5),
+       WIPHY_WOWLAN_4WAY_HANDSHAKE     = BIT(6),
+       WIPHY_WOWLAN_RFKILL_RELEASE     = BIT(7),
+//=========================
 };
 
 /**
@@ -1803,7 +1842,9 @@ struct wiphy {
        u16 interface_modes;
 
        u32 flags;
-
+// gwl
+       u32 ap_sme_capa;
+//======
        enum cfg80211_signal_type signal_type;
 
        int bss_priv_size;
@@ -2053,7 +2094,9 @@ struct wireless_dev {
        int ps_timeout;
 
        int beacon_interval;
-
+       // gwl
+       u32 ap_unexpected_nlpid;
+       //=====
 #ifdef CONFIG_CFG80211_WEXT
        /* wext data */
        struct {
@@ -3063,6 +3106,70 @@ void cfg80211_cqm_rssi_notify(struct net_device *dev,
 void cfg80211_cqm_pktloss_notify(struct net_device *dev,
                                 const u8 *peer, u32 num_packets, gfp_t gfp);
 
+//============ gwl =================
+/**
+ * cfg80211_gtk_rekey_notify - notify userspace about driver rekeying
+ * @dev: network device
+ * @bssid: BSSID of AP (to avoid races)
+ * @replay_ctr: new replay counter
+ */
+void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
+                              const u8 *replay_ctr, gfp_t gfp);
+
+/**
+ * cfg80211_pmksa_candidate_notify - notify about PMKSA caching candidate
+ * @dev: network device
+ * @index: candidate index (the smaller the index, the higher the priority)
+ * @bssid: BSSID of AP
+ * @preauth: Whether AP advertises support for RSN pre-authentication
+ * @gfp: allocation flags
+ */
+void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
+                                    const u8 *bssid, bool preauth, gfp_t gfp);
+
+/**
+ * cfg80211_rx_spurious_frame - inform userspace about a spurious frame
+ * @dev: The device the frame matched to
+ * @addr: the transmitter address
+ * @gfp: context flags
+ *
+ * This function is used in AP mode (only!) to inform userspace that
+ * a spurious class 3 frame was received, to be able to deauth the
+ * sender.
+ * Returns %true if the frame was passed to userspace (or this failed
+ * for a reason other than not having a subscription.)
+ */
+bool cfg80211_rx_spurious_frame(struct net_device *dev,
+                               const u8 *addr, gfp_t gfp);
+
+/**
+ * cfg80211_probe_status - notify userspace about probe status
+ * @dev: the device the probe was sent on
+ * @addr: the address of the peer
+ * @cookie: the cookie filled in @probe_client previously
+ * @acked: indicates whether probe was acked or not
+ * @gfp: allocation flags
+ */
+void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
+                          u64 cookie, bool acked, gfp_t gfp);
+
+/**
+ * cfg80211_report_obss_beacon - report beacon from other APs
+ * @wiphy: The wiphy that received the beacon
+ * @frame: the frame
+ * @len: length of the frame
+ * @freq: frequency the frame was received on
+ * @gfp: allocation flags
+ *
+ * Use this function to report to userspace when a beacon was
+ * received. It is not useful to call this when there is no
+ * netdev that is in AP/GO mode.
+ */
+void cfg80211_report_obss_beacon(struct wiphy *wiphy,
+                                const u8 *frame, size_t len,
+                                int freq, gfp_t gfp);
+//=========================================
+
 /* Logging, debugging and troubleshooting/diagnostic helpers. */
 
 /* wiphy_printk helpers, similar to dev_printk */
index 12c80ccecb2ccc9ed8e4d8bb6cd7089ef1e44f0a..4270ab280ed6ba3164d3379314401f9e53bf4208 100644 (file)
@@ -487,6 +487,15 @@ int wiphy_register(struct wiphy *wiphy)
        bool have_band = false;
        int i;
        u16 ifmodes = wiphy->interface_modes;
+//========= gwl ========
+       if (WARN_ON((wiphy->wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
+                   !(wiphy->wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY)))
+               return -EINVAL;
+
+       if (WARN_ON(wiphy->ap_sme_capa &&
+                   !(wiphy->flags & WIPHY_FLAG_HAVE_AP_SME)))
+               return -EINVAL;
+//===================
 
        if (WARN_ON(wiphy->addresses && !wiphy->n_addresses))
                return -EINVAL;
index 83516455a1d156541707df127d014d2ceb2aa0e8..35ea9abdc8f92be66dea9fef9cf05f07d76d5c0d 100644 (file)
@@ -53,7 +53,9 @@ struct cfg80211_registered_device {
        int devlist_generation;
        int opencount; /* also protected by devlist_mtx */
        wait_queue_head_t dev_wait;
-
+//gwl 
+       u32 ap_beacons_nlpid;
+//=========
        /* BSSes/scanning */
        spinlock_t bss_lock;
        struct list_head bss_list;
index 493b939970cd6cbefbd7ebad18cbf6c4d1405ed5..e2737e481ac6490e173758bcf9c2777c507e52e8 100644 (file)
@@ -877,6 +877,10 @@ void cfg80211_mlme_unregister_socket(struct wireless_dev *wdev, u32 nlpid)
        }
 
        spin_unlock_bh(&wdev->mgmt_registrations_lock);
+//gwl
+       if (nlpid == wdev->ap_unexpected_nlpid)
+               wdev->ap_unexpected_nlpid = 0;
+//======
 }
 
 void cfg80211_mlme_purge_registrations(struct wireless_dev *wdev)
@@ -1082,3 +1086,38 @@ void cfg80211_cqm_pktloss_notify(struct net_device *dev,
        nl80211_send_cqm_pktloss_notify(rdev, dev, peer, num_packets, gfp);
 }
 EXPORT_SYMBOL(cfg80211_cqm_pktloss_notify);
+// gwl ====================
+void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid,
+                              const u8 *replay_ctr, gfp_t gfp)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       struct wiphy *wiphy = wdev->wiphy;
+       struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+
+       nl80211_gtk_rekey_notify(rdev, dev, bssid, replay_ctr, gfp);
+}
+EXPORT_SYMBOL(cfg80211_gtk_rekey_notify);
+
+void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
+                                    const u8 *bssid, bool preauth, gfp_t gfp)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       struct wiphy *wiphy = wdev->wiphy;
+       struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+
+       nl80211_pmksa_candidate_notify(rdev, dev, index, bssid, preauth, gfp);
+}
+EXPORT_SYMBOL(cfg80211_pmksa_candidate_notify);
+
+bool cfg80211_rx_spurious_frame(struct net_device *dev,
+                               const u8 *addr, gfp_t gfp)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+       if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
+                   wdev->iftype != NL80211_IFTYPE_P2P_GO))
+               return false;
+
+       return nl80211_unexpected_frame(dev, addr, gfp);
+}
+EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
index 743ce8c7a10f43c353f9702a14c19f61602700a4..5cdc78f46063631a8130f16e119d1e7010634d64 100755 (executable)
@@ -184,6 +184,14 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
                                         .len = IEEE80211_MAX_DATA_LEN },
        [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG },
        [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED },
+// gwl ================
+       [NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG },
+       [NL80211_ATTR_TDLS_ACTION] = { .type = NLA_U8 },
+       [NL80211_ATTR_TDLS_DIALOG_TOKEN] = { .type = NLA_U8 },
+       [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
+       [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG },
+       [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG },
+//===============
 };
 
 /* policy for the key attributes */
@@ -212,6 +220,12 @@ nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = {
        [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG },
        [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG },
        [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED },
+// gwl ==============
+       [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG },
+       [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG },
+       [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG },
+       [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG },
+//===================
 };
 
 static const struct nla_policy
@@ -220,6 +234,16 @@ nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = {
                                                 .len = IEEE80211_MAX_SSID_LEN },
 };
 
+// gwl ===============
+/* policy for GTK rekey offload attributes */
+static const struct nla_policy
+nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = {
+       [NL80211_REKEY_DATA_KEK] = { .len = NL80211_KEK_LEN },
+       [NL80211_REKEY_DATA_KCK] = { .len = NL80211_KCK_LEN },
+       [NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN },
+};
+// ================
+
 /* ifidx get helper */
 static int nl80211_get_ifidx(struct netlink_callback *cb)
 {
@@ -710,6 +734,16 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
                NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN);
        if (dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH)
                NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_MESH_AUTH);
+// gwl ==================
+       if (dev->wiphy.flags & WIPHY_FLAG_AP_UAPSD)
+               NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_AP_UAPSD);
+       if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)
+               NLA_PUT_FLAG(msg, NL80211_ATTR_ROAM_SUPPORT);
+       if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS)
+               NLA_PUT_FLAG(msg, NL80211_ATTR_TDLS_SUPPORT);
+       if (dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP)
+               NLA_PUT_FLAG(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP);
+//=======================
 
        NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES,
                sizeof(u32) * dev->wiphy.n_cipher_suites,
@@ -852,8 +886,21 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
        }
        CMD(set_channel, SET_CHANNEL);
        CMD(set_wds_peer, SET_WDS_PEER);
+// gwl ======
+       if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) {
+               CMD(tdls_mgmt, TDLS_MGMT);
+               CMD(tdls_oper, TDLS_OPER);
+       }
+//===========
        if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN)
                CMD(sched_scan_start, START_SCHED_SCAN);
+// gwl ======
+       CMD(probe_client, PROBE_CLIENT);
+       if (dev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) {
+               i++;
+               NLA_PUT_U32(msg, i, NL80211_CMD_REGISTER_BEACONS);
+       }
+//============
 
 #undef CMD
 
@@ -940,6 +987,18 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
                        NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT);
                if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT)
                        NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT);
+// gwl =================
+               if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY)
+                       NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED);
+               if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE)
+                       NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE);
+               if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ)
+                       NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST);
+               if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_4WAY_HANDSHAKE)
+                       NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE);
+               if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_RFKILL_RELEASE)
+                       NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE);
+//=======================
                if (dev->wiphy.wowlan.n_patterns) {
                        struct nl80211_wowlan_pattern_support pat = {
                                .max_patterns = dev->wiphy.wowlan.n_patterns,
@@ -961,6 +1020,11 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
 
        if (nl80211_put_iface_combinations(&dev->wiphy, msg))
                goto nla_put_failure;
+// gwl ==============
+       if (dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME)
+               NLA_PUT_U32(msg, NL80211_ATTR_DEVICE_AP_SME,
+                           dev->wiphy.ap_sme_capa);
+//=================
 
        return genlmsg_end(msg, hdr);
 
@@ -1206,6 +1270,12 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
                        result = -ENETDOWN;
                        goto bad_res;
                }
+// gwl ===========
+               if (!netif_running(netdev)) {
+                       result = -ENETDOWN;
+                       goto bad_res;
+               }
+//=================
 
                nla_for_each_nested(nl_txq_params,
                                    info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS],
@@ -4723,6 +4793,58 @@ static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info)
        return rdev->ops->flush_pmksa(&rdev->wiphy, dev);
 }
 
+// gwl=================
+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;
+       u16 status_code;
+       u8 *peer;
+
+       if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
+           !rdev->ops->tdls_mgmt)
+               return -EOPNOTSUPP;
+
+       if (!info->attrs[NL80211_ATTR_TDLS_ACTION] ||
+           !info->attrs[NL80211_ATTR_STATUS_CODE] ||
+           !info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN] ||
+           !info->attrs[NL80211_ATTR_IE] ||
+           !info->attrs[NL80211_ATTR_MAC])
+               return -EINVAL;
+
+       peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
+       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]);
+
+       return rdev->ops->tdls_mgmt(&rdev->wiphy, dev, peer, action_code,
+                                   dialog_token, status_code,
+                                   nla_data(info->attrs[NL80211_ATTR_IE]),
+                                   nla_len(info->attrs[NL80211_ATTR_IE]));
+}
+
+static int nl80211_tdls_oper(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];
+       enum nl80211_tdls_operation operation;
+       u8 *peer;
+
+       if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) ||
+           !rdev->ops->tdls_oper)
+               return -EOPNOTSUPP;
+
+       if (!info->attrs[NL80211_ATTR_TDLS_OPERATION] ||
+           !info->attrs[NL80211_ATTR_MAC])
+               return -EINVAL;
+
+       operation = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_OPERATION]);
+       peer = nla_data(info->attrs[NL80211_ATTR_MAC]);
+
+       return rdev->ops->tdls_oper(&rdev->wiphy, dev, peer, operation);
+}
+// =================
 static int nl80211_remain_on_channel(struct sk_buff *skb,
                                     struct genl_info *info)
 {
@@ -5253,6 +5375,16 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info)
                        NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT);
                if (rdev->wowlan->magic_pkt)
                        NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT);
+// gwl =============
+               if (rdev->wowlan->gtk_rekey_failure)
+                       NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE);
+               if (rdev->wowlan->eap_identity_req)
+                       NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST);
+               if (rdev->wowlan->four_way_handshake)
+                       NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE);
+               if (rdev->wowlan->rfkill_release)
+                       NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE);
+//=====================
                if (rdev->wowlan->n_patterns) {
                        struct nlattr *nl_pats, *nl_pat;
                        int i, pat_len;
@@ -5329,6 +5461,34 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
                new_triggers.magic_pkt = true;
        }
 
+// gwl =============
+       if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED])
+               return -EINVAL;
+
+       if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) {
+               if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE))
+                       return -EINVAL;
+               new_triggers.gtk_rekey_failure = true;
+       }
+
+       if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) {
+               if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ))
+                       return -EINVAL;
+               new_triggers.eap_identity_req = true;
+       }
+
+       if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) {
+               if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE))
+                       return -EINVAL;
+               new_triggers.four_way_handshake = true;
+       }
+
+       if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) {
+               if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE))
+                       return -EINVAL;
+               new_triggers.rfkill_release = true;
+       }
+// ===============
        if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) {
                struct nlattr *pat;
                int n_patterns = 0;
@@ -5410,6 +5570,144 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info)
        return err;
 }
 
+// gwl ================
+static int nl80211_set_rekey_data(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];
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       struct nlattr *tb[NUM_NL80211_REKEY_DATA];
+       struct cfg80211_gtk_rekey_data rekey_data;
+       int err;
+
+       if (!info->attrs[NL80211_ATTR_REKEY_DATA])
+               return -EINVAL;
+
+       err = nla_parse(tb, MAX_NL80211_REKEY_DATA,
+                       nla_data(info->attrs[NL80211_ATTR_REKEY_DATA]),
+                       nla_len(info->attrs[NL80211_ATTR_REKEY_DATA]),
+                       nl80211_rekey_policy);
+       if (err)
+               return err;
+
+       if (nla_len(tb[NL80211_REKEY_DATA_REPLAY_CTR]) != NL80211_REPLAY_CTR_LEN)
+               return -ERANGE;
+       if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN)
+               return -ERANGE;
+       if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN)
+               return -ERANGE;
+
+       memcpy(rekey_data.kek, nla_data(tb[NL80211_REKEY_DATA_KEK]),
+              NL80211_KEK_LEN);
+       memcpy(rekey_data.kck, nla_data(tb[NL80211_REKEY_DATA_KCK]),
+              NL80211_KCK_LEN);
+       memcpy(rekey_data.replay_ctr,
+              nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]),
+              NL80211_REPLAY_CTR_LEN);
+
+       wdev_lock(wdev);
+       if (!wdev->current_bss) {
+               err = -ENOTCONN;
+               goto out;
+       }
+
+       if (!rdev->ops->set_rekey_data) {
+               err = -EOPNOTSUPP;
+               goto out;
+       }
+
+       err = rdev->ops->set_rekey_data(&rdev->wiphy, dev, &rekey_data);
+ out:
+       wdev_unlock(wdev);
+       return err;
+}
+
+static int nl80211_register_unexpected_frame(struct sk_buff *skb,
+                                            struct genl_info *info)
+{
+       struct net_device *dev = info->user_ptr[1];
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+
+       if (wdev->iftype != NL80211_IFTYPE_AP &&
+           wdev->iftype != NL80211_IFTYPE_P2P_GO)
+               return -EINVAL;
+
+       if (wdev->ap_unexpected_nlpid)
+               return -EBUSY;
+
+       wdev->ap_unexpected_nlpid = info->snd_pid;
+       return 0;
+}
+
+static int nl80211_probe_client(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];
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       struct sk_buff *msg;
+       void *hdr;
+       const u8 *addr;
+       u64 cookie;
+       int err;
+
+       if (wdev->iftype != NL80211_IFTYPE_AP &&
+           wdev->iftype != NL80211_IFTYPE_P2P_GO)
+               return -EOPNOTSUPP;
+
+       if (!info->attrs[NL80211_ATTR_MAC])
+               return -EINVAL;
+
+       if (!rdev->ops->probe_client)
+               return -EOPNOTSUPP;
+
+       msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+       if (!msg)
+               return -ENOMEM;
+
+       hdr = nl80211hdr_put(msg, info->snd_pid, info->snd_seq, 0,
+                            NL80211_CMD_PROBE_CLIENT);
+
+       if (IS_ERR(hdr)) {
+               err = PTR_ERR(hdr);
+               goto free_msg;
+       }
+
+       addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
+
+       err = rdev->ops->probe_client(&rdev->wiphy, dev, addr, &cookie);
+       if (err)
+               goto free_msg;
+
+       NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
+
+       genlmsg_end(msg, hdr);
+
+       return genlmsg_reply(msg, info);
+
+ nla_put_failure:
+       err = -ENOBUFS;
+ free_msg:
+       nlmsg_free(msg);
+       return err;
+}
+
+static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info)
+{
+       struct cfg80211_registered_device *rdev = info->user_ptr[0];
+
+       if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS))
+               return -EOPNOTSUPP;
+
+       if (rdev->ap_beacons_nlpid)
+               return -EBUSY;
+
+       rdev->ap_beacons_nlpid = info->snd_pid;
+
+       return 0;
+}
+// =====================
+
 #define NL80211_FLAG_NEED_WIPHY                0x01
 #define NL80211_FLAG_NEED_NETDEV       0x02
 #define NL80211_FLAG_NEED_RTNL         0x04
@@ -5940,6 +6238,56 @@ static struct genl_ops nl80211_ops[] = {
                .internal_flags = NL80211_FLAG_NEED_WIPHY |
                                  NL80211_FLAG_NEED_RTNL,
        },
+// gwl ===============
+       {
+               .cmd = NL80211_CMD_SET_REKEY_OFFLOAD,
+               .doit = nl80211_set_rekey_data,
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+                                 NL80211_FLAG_NEED_RTNL,
+       },
+       {
+               .cmd = NL80211_CMD_TDLS_MGMT,
+               .doit = nl80211_tdls_mgmt,
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+                                 NL80211_FLAG_NEED_RTNL,
+       },
+       {
+               .cmd = NL80211_CMD_TDLS_OPER,
+               .doit = nl80211_tdls_oper,
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+               .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+                                 NL80211_FLAG_NEED_RTNL,
+       },
+       {
+               .cmd = NL80211_CMD_UNEXPECTED_FRAME,
+               .doit = nl80211_register_unexpected_frame,
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+               .internal_flags = NL80211_FLAG_NEED_NETDEV |
+                                 NL80211_FLAG_NEED_RTNL,
+       },
+       {
+               .cmd = NL80211_CMD_PROBE_CLIENT,
+               .doit = nl80211_probe_client,
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+               .internal_flags = NL80211_FLAG_NEED_NETDEV |
+                                 NL80211_FLAG_NEED_RTNL,
+       },
+       {
+               .cmd = NL80211_CMD_REGISTER_BEACONS,
+               .doit = nl80211_register_beacons,
+               .policy = nl80211_policy,
+               .flags = GENL_ADMIN_PERM,
+               .internal_flags = NL80211_FLAG_NEED_WIPHY |
+                                 NL80211_FLAG_NEED_RTNL,
+       },
+//=======================
 };
 
 static struct genl_multicast_group nl80211_mlme_mcgrp = {
@@ -6760,6 +7108,48 @@ void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev,
        nlmsg_free(msg);
 }
 
+// gwl ==============
+bool nl80211_unexpected_frame(struct net_device *dev, const u8 *addr, gfp_t gfp)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+       struct sk_buff *msg;
+       void *hdr;
+       int err;
+       u32 nlpid = ACCESS_ONCE(wdev->ap_unexpected_nlpid);
+
+       if (!nlpid)
+               return false;
+
+       msg = nlmsg_new(100, gfp);
+       if (!msg)
+               return true;
+
+       hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_UNEXPECTED_FRAME);
+       if (!hdr) {
+               nlmsg_free(msg);
+               return true;
+       }
+
+       NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
+       NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
+
+       err = genlmsg_end(msg, hdr);
+       if (err < 0) {
+               nlmsg_free(msg);
+               return true;
+       }
+
+       genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid);
+       return true;
+
+ nla_put_failure:
+       genlmsg_cancel(msg, hdr);
+       nlmsg_free(msg);
+       return true;
+}
+// ==================
 int nl80211_send_mgmt(struct cfg80211_registered_device *rdev,
                      struct net_device *netdev, u32 nlpid,
                      int freq, const u8 *buf, size_t len, gfp_t gfp)
@@ -6884,6 +7274,99 @@ nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev,
        nlmsg_free(msg);
 }
 
+// gwl ============
+void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
+                             struct net_device *netdev, const u8 *bssid,
+                             const u8 *replay_ctr, gfp_t gfp)
+{
+       struct sk_buff *msg;
+       struct nlattr *rekey_attr;
+       void *hdr;
+
+       msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
+       if (!msg)
+               return;
+
+       hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_REKEY_OFFLOAD);
+       if (!hdr) {
+               nlmsg_free(msg);
+               return;
+       }
+
+       NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+       NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid);
+
+       rekey_attr = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA);
+       if (!rekey_attr)
+               goto nla_put_failure;
+
+       NLA_PUT(msg, NL80211_REKEY_DATA_REPLAY_CTR,
+               NL80211_REPLAY_CTR_LEN, replay_ctr);
+
+       nla_nest_end(msg, rekey_attr);
+
+       if (genlmsg_end(msg, hdr) < 0) {
+               nlmsg_free(msg);
+               return;
+       }
+
+       genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+                               nl80211_mlme_mcgrp.id, gfp);
+       return;
+
+ nla_put_failure:
+       genlmsg_cancel(msg, hdr);
+       nlmsg_free(msg);
+}
+
+void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
+                                   struct net_device *netdev, int index,
+                                   const u8 *bssid, bool preauth, gfp_t gfp)
+{
+       struct sk_buff *msg;
+       struct nlattr *attr;
+       void *hdr;
+
+       msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
+       if (!msg)
+               return;
+
+       hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE);
+       if (!hdr) {
+               nlmsg_free(msg);
+               return;
+       }
+
+       NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+
+       attr = nla_nest_start(msg, NL80211_ATTR_PMKSA_CANDIDATE);
+       if (!attr)
+               goto nla_put_failure;
+
+       NLA_PUT_U32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index);
+       NLA_PUT(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid);
+       if (preauth)
+               NLA_PUT_FLAG(msg, NL80211_PMKSA_CANDIDATE_PREAUTH);
+
+       nla_nest_end(msg, attr);
+
+       if (genlmsg_end(msg, hdr) < 0) {
+               nlmsg_free(msg);
+               return;
+       }
+
+       genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+                               nl80211_mlme_mcgrp.id, gfp);
+       return;
+
+ nla_put_failure:
+       genlmsg_cancel(msg, hdr);
+       nlmsg_free(msg);
+}
+//=======================
+
 void
 nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
                                struct net_device *netdev, const u8 *peer,
@@ -6929,6 +7412,88 @@ nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
        nlmsg_free(msg);
 }
 
+// gwl ===============
+void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
+                          u64 cookie, bool acked, gfp_t gfp)
+{
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
+       struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+       struct sk_buff *msg;
+       void *hdr;
+       int err;
+
+       msg = nlmsg_new(NLMSG_GOODSIZE, gfp);
+       if (!msg)
+               return;
+
+       hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PROBE_CLIENT);
+       if (!hdr) {
+               nlmsg_free(msg);
+               return;
+       }
+
+       NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+       NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
+       NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr);
+       NLA_PUT_U64(msg, NL80211_ATTR_COOKIE, cookie);
+       if (acked)
+               NLA_PUT_FLAG(msg, NL80211_ATTR_ACK);
+
+       err = genlmsg_end(msg, hdr);
+       if (err < 0) {
+               nlmsg_free(msg);
+               return;
+       }
+
+       genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+                               nl80211_mlme_mcgrp.id, gfp);
+       return;
+
+ nla_put_failure:
+       genlmsg_cancel(msg, hdr);
+       nlmsg_free(msg);
+}
+EXPORT_SYMBOL(cfg80211_probe_status);
+
+void cfg80211_report_obss_beacon(struct wiphy *wiphy,
+                                const u8 *frame, size_t len,
+                                int freq, gfp_t gfp)
+{
+       struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy);
+       struct sk_buff *msg;
+       void *hdr;
+       u32 nlpid = ACCESS_ONCE(rdev->ap_beacons_nlpid);
+
+       if (!nlpid)
+               return;
+
+       msg = nlmsg_new(len + 100, gfp);
+       if (!msg)
+               return;
+
+       hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME);
+       if (!hdr) {
+               nlmsg_free(msg);
+               return;
+       }
+
+       NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+       if (freq)
+               NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_FREQ, freq);
+       NLA_PUT(msg, NL80211_ATTR_FRAME, len, frame);
+
+       genlmsg_end(msg, hdr);
+
+       genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlpid);
+       return;
+
+ nla_put_failure:
+       genlmsg_cancel(msg, hdr);
+       nlmsg_free(msg);
+}
+EXPORT_SYMBOL(cfg80211_report_obss_beacon);
+// ==================
+
 static int nl80211_netlink_notify(struct notifier_block * nb,
                                  unsigned long state,
                                  void *_notify)
@@ -6941,10 +7506,13 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
                return NOTIFY_DONE;
 
        rcu_read_lock();
-
-       list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list)
+// gwl
+       list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) {
                list_for_each_entry_rcu(wdev, &rdev->netdev_list, list)
                        cfg80211_mlme_unregister_socket(wdev, notify->pid);
+               if (rdev->ap_beacons_nlpid == notify->pid)
+                       rdev->ap_beacons_nlpid = 0;
+       }
 
        rcu_read_unlock();
 
index 2f1bfb87a651f43f8d698b567832bfb6d468adcc..473ca55bd3cda48df99a87863452d8912b79c1de 100644 (file)
@@ -109,4 +109,16 @@ nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev,
                                struct net_device *netdev, const u8 *peer,
                                u32 num_packets, gfp_t gfp);
 
+// gwl =======
+void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev,
+                             struct net_device *netdev, const u8 *bssid,
+                             const u8 *replay_ctr, gfp_t gfp);
+
+void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev,
+                                   struct net_device *netdev, int index,
+                                   const u8 *bssid, bool preauth, gfp_t gfp);
+
+bool nl80211_unexpected_frame(struct net_device *dev,
+                             const u8 *addr, gfp_t gfp);
+//=================
 #endif /* __NET_WIRELESS_NL80211_H */