]> Pileus Git - ~andy/linux/commitdiff
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac802...
authorJohn W. Linville <linville@tuxdriver.com>
Fri, 16 Aug 2013 18:24:51 +0000 (14:24 -0400)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 16 Aug 2013 18:24:51 +0000 (14:24 -0400)
28 files changed:
Documentation/DocBook/80211.tmpl
drivers/net/wireless/ath/ath6kl/testmode.c
drivers/net/wireless/ath/ath6kl/testmode.h
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
drivers/net/wireless/iwlwifi/dvm/tx.c
drivers/net/wireless/iwlwifi/iwl-devtrace.h
drivers/net/wireless/iwlwifi/mvm/time-event.c
drivers/net/wireless/iwlwifi/mvm/tx.c
drivers/net/wireless/mac80211_hwsim.c
drivers/net/wireless/ti/wlcore/testmode.c
drivers/net/wireless/ti/wlcore/testmode.h
include/linux/ieee80211.h
include/net/cfg80211.h
include/net/mac80211.h
net/mac80211/cfg.c
net/mac80211/ibss.c
net/mac80211/ieee80211_i.h
net/mac80211/key.c
net/mac80211/mlme.c
net/mac80211/rate.c
net/mac80211/rc80211_minstrel_ht.c
net/mac80211/rx.c
net/mac80211/tx.c
net/mac80211/util.c
net/rfkill/rfkill-regulator.c
net/wireless/nl80211.c
net/wireless/rdev-ops.h
net/wireless/trace.h

index 49267ea975684391c1f1e7144fb0c88700557d66..f403ec3c5c9a4a17cf6c534f2da8590144faf766 100644 (file)
           <title>functions/definitions</title>
 !Finclude/net/mac80211.h ieee80211_rx_status
 !Finclude/net/mac80211.h mac80211_rx_flags
+!Finclude/net/mac80211.h mac80211_tx_info_flags
 !Finclude/net/mac80211.h mac80211_tx_control_flags
 !Finclude/net/mac80211.h mac80211_rate_control_flags
 !Finclude/net/mac80211.h ieee80211_tx_rate
index acc9aa832f764df7512165f4b1c4b4e9a3050416..d67170ea1038a1d35f3acc56261e68ed2051cad4 100644 (file)
@@ -66,7 +66,8 @@ nla_put_failure:
        ath6kl_warn("nla_put failed on testmode rx skb!\n");
 }
 
-int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len)
+int ath6kl_tm_cmd(struct wiphy *wiphy, struct wireless_dev *wdev,
+                 void *data, int len)
 {
        struct ath6kl *ar = wiphy_priv(wiphy);
        struct nlattr *tb[ATH6KL_TM_ATTR_MAX + 1];
index fe651d6707df4ed36fc08b69a63b554565582fb5..9fbcdec3e208b6049f49598759f4e2f4ee7fb00a 100644 (file)
@@ -20,7 +20,8 @@
 #ifdef CONFIG_NL80211_TESTMODE
 
 void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf, size_t buf_len);
-int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len);
+int ath6kl_tm_cmd(struct wiphy *wiphy, struct wireless_dev *wdev,
+                 void *data, int len);
 
 #else
 
@@ -29,7 +30,9 @@ static inline void ath6kl_tm_rx_event(struct ath6kl *ar, void *buf,
 {
 }
 
-static inline int ath6kl_tm_cmd(struct wiphy *wiphy, void *data, int len)
+static inline int ath6kl_tm_cmd(struct wiphy *wiphy,
+                               struct wireless_dev *wdev,
+                               void *data, int len)
 {
        return 0;
 }
index 0370e44cec111348f33c60c3e09a4e268fe36a29..571f013cebbb0d0a80f32e2351975b659d7d53d1 100644 (file)
@@ -3155,7 +3155,9 @@ static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
 }
 
 #ifdef CONFIG_NL80211_TESTMODE
-static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
+static int brcmf_cfg80211_testmode(struct wiphy *wiphy,
+                                  struct wireless_dev *wdev,
+                                  void *data, int len)
 {
        struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
        struct net_device *ndev = cfg_to_ndev(cfg);
index 3db0bbb1d123c7a6136485fdcc64f527251cb7a5..da442b81370a769054b4b77a946daa4bbd856ed8 100644 (file)
@@ -87,7 +87,7 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
                 priv->lib->bt_params->advanced_bt_coexist &&
                 (ieee80211_is_auth(fc) || ieee80211_is_assoc_req(fc) ||
                 ieee80211_is_reassoc_req(fc) ||
-                skb->protocol == cpu_to_be16(ETH_P_PAE)))
+                info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO))
                tx_flags |= TX_CMD_FLG_IGNORE_BT;
 
 
index 4491c1c72cc7d6e00ade51930342b16233172690..684c416d34936c5ecdb6451f2d3707babae6b180 100644 (file)
 static inline bool iwl_trace_data(struct sk_buff *skb)
 {
        struct ieee80211_hdr *hdr = (void *)skb->data;
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 
-       if (ieee80211_is_data(hdr->frame_control))
-               return skb->protocol != cpu_to_be16(ETH_P_PAE);
-       return false;
+       if (!ieee80211_is_data(hdr->frame_control))
+               return false;
+       return !(info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO);
 }
 
 static inline size_t iwl_rx_trace_len(const struct iwl_trans *trans,
index ad9bbca992133cc096ff0b90c5048ae248b635c9..9f100363b17753ad711df0db9e089fffa0553ee9 100644 (file)
@@ -73,7 +73,6 @@
 #include "iwl-prph.h"
 
 /* A TimeUnit is 1024 microsecond */
-#define TU_TO_JIFFIES(_tu)     (usecs_to_jiffies((_tu) * 1024))
 #define MSEC_TO_TU(_msec)      (_msec*1000/1024)
 
 /*
@@ -191,8 +190,7 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
                iwl_mvm_te_clear_data(mvm, te_data);
        } else if (le32_to_cpu(notif->action) & TE_NOTIF_HOST_EVENT_START) {
                te_data->running = true;
-               te_data->end_jiffies = jiffies +
-                       TU_TO_JIFFIES(te_data->duration);
+               te_data->end_jiffies = TU_TO_EXP_TIME(te_data->duration);
 
                if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) {
                        set_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status);
@@ -329,8 +327,7 @@ void iwl_mvm_protect_session(struct iwl_mvm *mvm,
        lockdep_assert_held(&mvm->mutex);
 
        if (te_data->running &&
-           time_after(te_data->end_jiffies,
-                      jiffies + TU_TO_JIFFIES(min_duration))) {
+           time_after(te_data->end_jiffies, TU_TO_EXP_TIME(min_duration))) {
                IWL_DEBUG_TE(mvm, "We have enough time in the current TE: %u\n",
                             jiffies_to_msecs(te_data->end_jiffies - jiffies));
                return;
index f68ef9dd6a700abaaec588da2f6118d6b7091ea9..e05440d90319b339f203a2f1ff9658a0d97f615e 100644 (file)
@@ -91,11 +91,10 @@ static void iwl_mvm_set_tx_cmd(struct iwl_mvm *mvm, struct sk_buff *skb,
                tx_flags |= TX_CMD_FLG_ACK | TX_CMD_FLG_BAR;
 
        /* High prio packet (wrt. BT coex) if it is EAPOL, MCAST or MGMT */
-       if (info->band == IEEE80211_BAND_2GHZ        &&
-           (skb->protocol == cpu_to_be16(ETH_P_PAE)  ||
-            is_multicast_ether_addr(hdr->addr1)      ||
-            ieee80211_is_back_req(fc)                ||
-            ieee80211_is_mgmt(fc)))
+       if (info->band == IEEE80211_BAND_2GHZ &&
+           (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO ||
+            is_multicast_ether_addr(hdr->addr1) ||
+            ieee80211_is_back_req(fc) || ieee80211_is_mgmt(fc)))
                tx_flags |= TX_CMD_FLG_BT_DIS;
 
        if (ieee80211_has_morefrags(fc))
index 7b2a6229eedb2bfcb30e0f742e2c0108951bfade..a0d2aacd5e09c9634a37a8e3026ae867952efd57 100644 (file)
@@ -1364,6 +1364,7 @@ static const struct nla_policy hwsim_testmode_policy[HWSIM_TM_ATTR_MAX + 1] = {
 static int hwsim_fops_ps_write(void *dat, u64 val);
 
 static int mac80211_hwsim_testmode_cmd(struct ieee80211_hw *hw,
+                                      struct ieee80211_vif *vif,
                                       void *data, int len)
 {
        struct mac80211_hwsim_data *hwsim = hw->priv;
index f3442762d884b04def7e2bb2e8b8bee603b3f0ae..527590f2adfbe66b088a99c48d5ce382ff030efd 100644 (file)
@@ -356,7 +356,8 @@ out:
        return ret;
 }
 
-int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len)
+int wl1271_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+                 void *data, int len)
 {
        struct wl1271 *wl = hw->priv;
        struct nlattr *tb[WL1271_TM_ATTR_MAX + 1];
index 8071654259eacd59eaa9aba46da40329f5c6aec2..61d8434d859ab37121e5b7decf7f2e11597da00f 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <net/mac80211.h>
 
-int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len);
+int wl1271_tm_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+                 void *data, int len);
 
 #endif /* __WL1271_TESTMODE_H__ */
index b3ce299782afa70f29983a79367c79a2ace521cf..23a8877f4ded09298346170666af052cfe2c0328 100644 (file)
@@ -2288,4 +2288,8 @@ static inline bool ieee80211_check_tim(const struct ieee80211_tim_ie *tim,
        return !!(tim->virtual_map[index] & mask);
 }
 
+/* convert time units */
+#define TU_TO_JIFFIES(x)       (usecs_to_jiffies((x) * 1024))
+#define TU_TO_EXP_TIME(x)      (jiffies + TU_TO_JIFFIES(x))
+
 #endif /* LINUX_IEEE80211_H */
index b7495c72061c8d4ac199bb36f080133f8255e06f..9ab7a0690d934ea6b8e78129e3a912b5e92a1c82 100644 (file)
@@ -2081,7 +2081,7 @@ struct cfg80211_update_ft_ies_params {
  * @mgmt_tx_cancel_wait: Cancel the wait time from transmitting a management
  *     frame on another channel
  *
- * @testmode_cmd: run a test mode command
+ * @testmode_cmd: run a test mode command; @wdev may be %NULL
  * @testmode_dump: Implement a test mode dump. The cb->args[2] and up may be
  *     used by the function, but 0 and 1 must not be touched. Additionally,
  *     return error codes other than -ENOBUFS and -ENOENT will terminate the
@@ -2290,7 +2290,8 @@ struct cfg80211_ops {
        void    (*rfkill_poll)(struct wiphy *wiphy);
 
 #ifdef CONFIG_NL80211_TESTMODE
-       int     (*testmode_cmd)(struct wiphy *wiphy, void *data, int len);
+       int     (*testmode_cmd)(struct wiphy *wiphy, struct wireless_dev *wdev,
+                               void *data, int len);
        int     (*testmode_dump)(struct wiphy *wiphy, struct sk_buff *skb,
                                 struct netlink_callback *cb,
                                 void *data, int len);
index 9cda3728c2cbfc78d77efc765ff298718469108e..e3e303778936534e10595bade5d65a5d7a17ee56 100644 (file)
@@ -375,7 +375,7 @@ struct ieee80211_bss_conf {
 };
 
 /**
- * enum mac80211_tx_control_flags - flags to describe transmission information/status
+ * enum mac80211_tx_info_flags - flags to describe transmission information/status
  *
  * These flags are used with the @flags member of &ieee80211_tx_info.
  *
@@ -471,7 +471,7 @@ struct ieee80211_bss_conf {
  * Note: If you have to add new flags to the enumeration, then don't
  *      forget to update %IEEE80211_TX_TEMPORARY_FLAGS when necessary.
  */
-enum mac80211_tx_control_flags {
+enum mac80211_tx_info_flags {
        IEEE80211_TX_CTL_REQ_TX_STATUS          = BIT(0),
        IEEE80211_TX_CTL_ASSIGN_SEQ             = BIT(1),
        IEEE80211_TX_CTL_NO_ACK                 = BIT(2),
@@ -507,6 +507,18 @@ enum mac80211_tx_control_flags {
 
 #define IEEE80211_TX_CTL_STBC_SHIFT            23
 
+/**
+ * enum mac80211_tx_control_flags - flags to describe transmit control
+ *
+ * @IEEE80211_TX_CTRL_PORT_CTRL_PROTO: this frame is a port control
+ *     protocol frame (e.g. EAP)
+ *
+ * These flags are used in tx_info->control.flags.
+ */
+enum mac80211_tx_control_flags {
+       IEEE80211_TX_CTRL_PORT_CTRL_PROTO       = BIT(0),
+};
+
 /*
  * This definition is used as a mask to clear all temporary flags, which are
  * set by the tx handlers for each transmission attempt by the mac80211 stack.
@@ -680,7 +692,8 @@ struct ieee80211_tx_info {
                        /* NB: vif can be NULL for injected frames */
                        struct ieee80211_vif *vif;
                        struct ieee80211_key_conf *hw_key;
-                       /* 8 bytes free */
+                       u32 flags;
+                       /* 4 bytes free */
                } control;
                struct {
                        struct ieee80211_tx_rate rates[IEEE80211_TX_MAX_RATES];
@@ -2503,8 +2516,8 @@ enum ieee80211_roc_type {
  *     in IEEE 802.11-2007 section 17.3.8.6 and modify ACK timeout
  *     accordingly. This callback is not required and may sleep.
  *
- * @testmode_cmd: Implement a cfg80211 test mode command.
- *     The callback can sleep.
+ * @testmode_cmd: Implement a cfg80211 test mode command. The passed @vif may
+ *     be %NULL. The callback can sleep.
  * @testmode_dump: Implement a cfg80211 test mode dump. The callback can sleep.
  *
  * @flush: Flush all pending frames from the hardware queue, making sure
@@ -2765,7 +2778,8 @@ struct ieee80211_ops {
        void (*rfkill_poll)(struct ieee80211_hw *hw);
        void (*set_coverage_class)(struct ieee80211_hw *hw, u8 coverage_class);
 #ifdef CONFIG_NL80211_TESTMODE
-       int (*testmode_cmd)(struct ieee80211_hw *hw, void *data, int len);
+       int (*testmode_cmd)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+                           void *data, int len);
        int (*testmode_dump)(struct ieee80211_hw *hw, struct sk_buff *skb,
                             struct netlink_callback *cb,
                             void *data, int len);
@@ -3673,6 +3687,89 @@ void ieee80211_get_key_tx_seq(struct ieee80211_key_conf *keyconf,
 void ieee80211_get_key_rx_seq(struct ieee80211_key_conf *keyconf,
                              int tid, struct ieee80211_key_seq *seq);
 
+/**
+ * ieee80211_set_key_tx_seq - set key TX sequence counter
+ *
+ * @keyconf: the parameter passed with the set key
+ * @seq: new sequence data
+ *
+ * This function allows a driver to set the current TX IV/PNs for the
+ * given key. This is useful when resuming from WoWLAN sleep and the
+ * device may have transmitted frames using the PTK, e.g. replies to
+ * ARP requests.
+ *
+ * Note that this function may only be called when no TX processing
+ * can be done concurrently.
+ */
+void ieee80211_set_key_tx_seq(struct ieee80211_key_conf *keyconf,
+                             struct ieee80211_key_seq *seq);
+
+/**
+ * ieee80211_set_key_rx_seq - set key RX sequence counter
+ *
+ * @keyconf: the parameter passed with the set key
+ * @tid: The TID, or -1 for the management frame value (CCMP only);
+ *     the value on TID 0 is also used for non-QoS frames. For
+ *     CMAC, only TID 0 is valid.
+ * @seq: new sequence data
+ *
+ * This function allows a driver to set the current RX IV/PNs for the
+ * given key. This is useful when resuming from WoWLAN sleep and GTK
+ * rekey may have been done while suspended. It should not be called
+ * if IV checking is done by the device and not by mac80211.
+ *
+ * Note that this function may only be called when no RX processing
+ * can be done concurrently.
+ */
+void ieee80211_set_key_rx_seq(struct ieee80211_key_conf *keyconf,
+                             int tid, struct ieee80211_key_seq *seq);
+
+/**
+ * ieee80211_remove_key - remove the given key
+ * @keyconf: the parameter passed with the set key
+ *
+ * Remove the given key. If the key was uploaded to the hardware at the
+ * time this function is called, it is not deleted in the hardware but
+ * instead assumed to have been removed already.
+ *
+ * Note that due to locking considerations this function can (currently)
+ * only be called during key iteration (ieee80211_iter_keys().)
+ */
+void ieee80211_remove_key(struct ieee80211_key_conf *keyconf);
+
+/**
+ * ieee80211_gtk_rekey_add - add a GTK key from rekeying during WoWLAN
+ * @vif: the virtual interface to add the key on
+ * @keyconf: new key data
+ *
+ * When GTK rekeying was done while the system was suspended, (a) new
+ * key(s) will be available. These will be needed by mac80211 for proper
+ * RX processing, so this function allows setting them.
+ *
+ * The function returns the newly allocated key structure, which will
+ * have similar contents to the passed key configuration but point to
+ * mac80211-owned memory. In case of errors, the function returns an
+ * ERR_PTR(), use IS_ERR() etc.
+ *
+ * Note that this function assumes the key isn't added to hardware
+ * acceleration, so no TX will be done with the key. Since it's a GTK
+ * on managed (station) networks, this is true anyway. If the driver
+ * calls this function from the resume callback and subsequently uses
+ * the return code 1 to reconfigure the device, this key will be part
+ * of the reconfiguration.
+ *
+ * Note that the driver should also call ieee80211_set_key_rx_seq()
+ * for the new key for each TID to set up sequence counters properly.
+ *
+ * IMPORTANT: If this replaces a key that is present in the hardware,
+ * then it will attempt to remove it during this call. In many cases
+ * this isn't what you want, so call ieee80211_remove_key() first for
+ * the key that's being replaced.
+ */
+struct ieee80211_key_conf *
+ieee80211_gtk_rekey_add(struct ieee80211_vif *vif,
+                       struct ieee80211_key_conf *keyconf);
+
 /**
  * ieee80211_gtk_rekey_notify - notify userspace supplicant of rekeying
  * @vif: virtual interface the rekeying was done on
index 31fc2247bc372dffe9fade359f706863daa8b297..2e7855a1b10d17198adcfec98d550838daef80bd 100644 (file)
@@ -2302,14 +2302,25 @@ static void ieee80211_rfkill_poll(struct wiphy *wiphy)
 }
 
 #ifdef CONFIG_NL80211_TESTMODE
-static int ieee80211_testmode_cmd(struct wiphy *wiphy, void *data, int len)
+static int ieee80211_testmode_cmd(struct wiphy *wiphy,
+                                 struct wireless_dev *wdev,
+                                 void *data, int len)
 {
        struct ieee80211_local *local = wiphy_priv(wiphy);
+       struct ieee80211_vif *vif = NULL;
 
        if (!local->ops->testmode_cmd)
                return -EOPNOTSUPP;
 
-       return local->ops->testmode_cmd(&local->hw, data, len);
+       if (wdev) {
+               struct ieee80211_sub_if_data *sdata;
+
+               sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
+               if (sdata->flags & IEEE80211_SDATA_IN_DRIVER)
+                       vif = &sdata->vif;
+       }
+
+       return local->ops->testmode_cmd(&local->hw, vif, data, len);
 }
 
 static int ieee80211_testmode_dump(struct wiphy *wiphy,
index e08387cdc8fdb26e374f56792d25a3305d7412b1..74de0f10558a81b901f35122acedbc1fd1be0d98 100644 (file)
 
 #define IEEE80211_IBSS_MAX_STA_ENTRIES 128
 
-
-static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
-                                     const u8 *bssid, const int beacon_int,
-                                     struct ieee80211_channel *chan,
-                                     const u32 basic_rates,
-                                     const u16 capability, u64 tsf,
-                                     bool creator)
+static struct beacon_data *
+ieee80211_ibss_build_presp(struct ieee80211_sub_if_data *sdata,
+                          const int beacon_int, const u32 basic_rates,
+                          const u16 capability, u64 tsf,
+                          struct cfg80211_chan_def *chandef,
+                          bool *have_higher_than_11mbit)
 {
        struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
        struct ieee80211_local *local = sdata->local;
@@ -48,70 +47,11 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
        struct ieee80211_mgmt *mgmt;
        u8 *pos;
        struct ieee80211_supported_band *sband;
-       struct cfg80211_bss *bss;
-       u32 bss_change, rate_flags, rates = 0, rates_added = 0;
-       struct cfg80211_chan_def chandef;
-       enum nl80211_bss_scan_width scan_width;
-       bool have_higher_than_11mbit = false;
+       u32 rate_flags, rates = 0, rates_added = 0;
        struct beacon_data *presp;
        int frame_len;
        int shift;
 
-       sdata_assert_lock(sdata);
-
-       /* Reset own TSF to allow time synchronization work. */
-       drv_reset_tsf(local, sdata);
-
-       if (!ether_addr_equal(ifibss->bssid, bssid))
-               sta_info_flush(sdata);
-
-       /* if merging, indicate to driver that we leave the old IBSS */
-       if (sdata->vif.bss_conf.ibss_joined) {
-               sdata->vif.bss_conf.ibss_joined = false;
-               sdata->vif.bss_conf.ibss_creator = false;
-               sdata->vif.bss_conf.enable_beacon = false;
-               netif_carrier_off(sdata->dev);
-               ieee80211_bss_info_change_notify(sdata,
-                                                BSS_CHANGED_IBSS |
-                                                BSS_CHANGED_BEACON_ENABLED);
-       }
-
-       presp = rcu_dereference_protected(ifibss->presp,
-                                         lockdep_is_held(&sdata->wdev.mtx));
-       rcu_assign_pointer(ifibss->presp, NULL);
-       if (presp)
-               kfree_rcu(presp, rcu_head);
-
-       sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
-
-       chandef = ifibss->chandef;
-       if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) {
-               if (chandef.width == NL80211_CHAN_WIDTH_5 ||
-                   chandef.width == NL80211_CHAN_WIDTH_10 ||
-                   chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
-                   chandef.width == NL80211_CHAN_WIDTH_20) {
-                       sdata_info(sdata,
-                                  "Failed to join IBSS, beacons forbidden\n");
-                       return;
-               }
-               chandef.width = NL80211_CHAN_WIDTH_20;
-               chandef.center_freq1 = chan->center_freq;
-       }
-
-       ieee80211_vif_release_channel(sdata);
-       if (ieee80211_vif_use_channel(sdata, &chandef,
-                                     ifibss->fixed_channel ?
-                                       IEEE80211_CHANCTX_SHARED :
-                                       IEEE80211_CHANCTX_EXCLUSIVE)) {
-               sdata_info(sdata, "Failed to join IBSS, no channel context\n");
-               return;
-       }
-
-       memcpy(ifibss->bssid, bssid, ETH_ALEN);
-
-       sband = local->hw.wiphy->bands[chan->band];
-       shift = ieee80211_vif_get_shift(&sdata->vif);
-
        /* Build IBSS probe response */
        frame_len = sizeof(struct ieee80211_hdr_3addr) +
                    12 /* struct ieee80211_mgmt.u.beacon */ +
@@ -125,7 +65,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
                    ifibss->ie_len;
        presp = kzalloc(sizeof(*presp) + frame_len, GFP_KERNEL);
        if (!presp)
-               return;
+               return NULL;
 
        presp->head = (void *)(presp + 1);
 
@@ -146,12 +86,19 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
        memcpy(pos, ifibss->ssid, ifibss->ssid_len);
        pos += ifibss->ssid_len;
 
-       rate_flags = ieee80211_chandef_rate_flags(&chandef);
+       sband = local->hw.wiphy->bands[chandef->chan->band];
+       rate_flags = ieee80211_chandef_rate_flags(chandef);
+       shift = ieee80211_chandef_get_shift(chandef);
+       rates_n = 0;
+       if (have_higher_than_11mbit)
+               *have_higher_than_11mbit = false;
+
        for (i = 0; i < sband->n_bitrates; i++) {
                if ((rate_flags & sband->bitrates[i].flags) != rate_flags)
                        continue;
-               if (sband->bitrates[i].bitrate > 110)
-                       have_higher_than_11mbit = true;
+               if (sband->bitrates[i].bitrate > 110 &&
+                   have_higher_than_11mbit)
+                       *have_higher_than_11mbit = true;
 
                rates |= BIT(i);
                rates_n++;
@@ -178,7 +125,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
        if (sband->band == IEEE80211_BAND_2GHZ) {
                *pos++ = WLAN_EID_DS_PARAMS;
                *pos++ = 1;
-               *pos++ = ieee80211_frequency_to_channel(chan->center_freq);
+               *pos++ = ieee80211_frequency_to_channel(
+                               chandef->chan->center_freq);
        }
 
        *pos++ = WLAN_EID_IBSS_PARAMS;
@@ -210,9 +158,9 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
        }
 
        /* add HT capability and information IEs */
-       if (chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
-           chandef.width != NL80211_CHAN_WIDTH_5 &&
-           chandef.width != NL80211_CHAN_WIDTH_10 &&
+       if (chandef->width != NL80211_CHAN_WIDTH_20_NOHT &&
+           chandef->width != NL80211_CHAN_WIDTH_5 &&
+           chandef->width != NL80211_CHAN_WIDTH_10 &&
            sband->ht_cap.ht_supported) {
                struct ieee80211_sta_ht_cap ht_cap;
 
@@ -226,7 +174,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
                 * keep them at 0
                 */
                pos = ieee80211_ie_build_ht_oper(pos, &sband->ht_cap,
-                                                &chandef, 0);
+                                                chandef, 0);
        }
 
        if (local->hw.queues >= IEEE80211_NUM_ACS) {
@@ -243,9 +191,94 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
 
        presp->head_len = pos - presp->head;
        if (WARN_ON(presp->head_len > frame_len))
+               goto error;
+
+       return presp;
+error:
+       kfree(presp);
+       return NULL;
+}
+
+static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
+                                     const u8 *bssid, const int beacon_int,
+                                     struct ieee80211_channel *chan,
+                                     const u32 basic_rates,
+                                     const u16 capability, u64 tsf,
+                                     bool creator)
+{
+       struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
+       struct ieee80211_local *local = sdata->local;
+       struct ieee80211_supported_band *sband;
+       struct ieee80211_mgmt *mgmt;
+       struct cfg80211_bss *bss;
+       u32 bss_change;
+       struct cfg80211_chan_def chandef;
+       struct beacon_data *presp;
+       enum nl80211_bss_scan_width scan_width;
+       bool have_higher_than_11mbit;
+
+       sdata_assert_lock(sdata);
+
+       /* Reset own TSF to allow time synchronization work. */
+       drv_reset_tsf(local, sdata);
+
+       if (!ether_addr_equal(ifibss->bssid, bssid))
+               sta_info_flush(sdata);
+
+       /* if merging, indicate to driver that we leave the old IBSS */
+       if (sdata->vif.bss_conf.ibss_joined) {
+               sdata->vif.bss_conf.ibss_joined = false;
+               sdata->vif.bss_conf.ibss_creator = false;
+               sdata->vif.bss_conf.enable_beacon = false;
+               netif_carrier_off(sdata->dev);
+               ieee80211_bss_info_change_notify(sdata,
+                                                BSS_CHANGED_IBSS |
+                                                BSS_CHANGED_BEACON_ENABLED);
+       }
+
+       presp = rcu_dereference_protected(ifibss->presp,
+                                         lockdep_is_held(&sdata->wdev.mtx));
+       rcu_assign_pointer(ifibss->presp, NULL);
+       if (presp)
+               kfree_rcu(presp, rcu_head);
+
+       sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
+
+       chandef = ifibss->chandef;
+       if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) {
+               if (chandef.width == NL80211_CHAN_WIDTH_5 ||
+                   chandef.width == NL80211_CHAN_WIDTH_10 ||
+                   chandef.width == NL80211_CHAN_WIDTH_20_NOHT ||
+                   chandef.width == NL80211_CHAN_WIDTH_20) {
+                       sdata_info(sdata,
+                                  "Failed to join IBSS, beacons forbidden\n");
+                       return;
+               }
+               chandef.width = NL80211_CHAN_WIDTH_20;
+               chandef.center_freq1 = chan->center_freq;
+       }
+
+       ieee80211_vif_release_channel(sdata);
+       if (ieee80211_vif_use_channel(sdata, &chandef,
+                                     ifibss->fixed_channel ?
+                                       IEEE80211_CHANCTX_SHARED :
+                                       IEEE80211_CHANCTX_EXCLUSIVE)) {
+               sdata_info(sdata, "Failed to join IBSS, no channel context\n");
+               return;
+       }
+
+       memcpy(ifibss->bssid, bssid, ETH_ALEN);
+
+       sband = local->hw.wiphy->bands[chan->band];
+
+       presp = ieee80211_ibss_build_presp(sdata, beacon_int, basic_rates,
+                                          capability, tsf, &chandef,
+                                          &have_higher_than_11mbit);
+       if (!presp)
                return;
 
        rcu_assign_pointer(ifibss->presp, presp);
+       mgmt = (void *)presp->head;
 
        sdata->vif.bss_conf.enable_beacon = true;
        sdata->vif.bss_conf.beacon_int = beacon_int;
@@ -891,6 +924,17 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
                return;
        }
 
+       /* if a fixed bssid and a fixed freq have been provided create the IBSS
+        * directly and do not waste time scanning
+        */
+       if (ifibss->fixed_bssid && ifibss->fixed_channel) {
+               sdata_info(sdata, "Created IBSS using preconfigured BSSID %pM\n",
+                          bssid);
+               ieee80211_sta_create_ibss(sdata);
+               return;
+       }
+
+
        ibss_dbg(sdata, "sta_find_ibss: did not try to join ibss\n");
 
        /* Selected IBSS not found in current scan results - try to scan */
index e94c84050e9c214c3959088423f75ef444824dcd..b6186517ec567e85eb986d77dd6ff72c36a4379d 100644 (file)
@@ -53,9 +53,6 @@ struct ieee80211_local;
  * increased memory use (about 2 kB of RAM per entry). */
 #define IEEE80211_FRAGMENT_MAX 4
 
-#define TU_TO_JIFFIES(x)       (usecs_to_jiffies((x) * 1024))
-#define TU_TO_EXP_TIME(x)      (jiffies + TU_TO_JIFFIES(x))
-
 /* power level hasn't been configured (or set to automatic) */
 #define IEEE80211_UNSET_POWER_LEVEL    INT_MIN
 
index e39cc91d0cf125c584464ef73be6df5e97729e3d..620677e897bd0fc82fd5f4e737156096c05a9eef 100644 (file)
@@ -93,6 +93,9 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
 
        might_sleep();
 
+       if (key->flags & KEY_FLAG_TAINTED)
+               return -EINVAL;
+
        if (!key->local->ops->set_key)
                goto out_unsupported;
 
@@ -455,6 +458,7 @@ int ieee80211_key_link(struct ieee80211_key *key,
                       struct ieee80211_sub_if_data *sdata,
                       struct sta_info *sta)
 {
+       struct ieee80211_local *local = sdata->local;
        struct ieee80211_key *old_key;
        int idx, ret;
        bool pairwise;
@@ -484,10 +488,13 @@ int ieee80211_key_link(struct ieee80211_key *key,
 
        ieee80211_debugfs_key_add(key);
 
-       ret = ieee80211_key_enable_hw_accel(key);
-
-       if (ret)
-               ieee80211_key_free(key, true);
+       if (!local->wowlan) {
+               ret = ieee80211_key_enable_hw_accel(key);
+               if (ret)
+                       ieee80211_key_free(key, true);
+       } else {
+               ret = 0;
+       }
 
        mutex_unlock(&sdata->local->key_mtx);
 
@@ -540,7 +547,7 @@ void ieee80211_iter_keys(struct ieee80211_hw *hw,
                         void *iter_data)
 {
        struct ieee80211_local *local = hw_to_local(hw);
-       struct ieee80211_key *key;
+       struct ieee80211_key *key, *tmp;
        struct ieee80211_sub_if_data *sdata;
 
        ASSERT_RTNL();
@@ -548,13 +555,14 @@ void ieee80211_iter_keys(struct ieee80211_hw *hw,
        mutex_lock(&local->key_mtx);
        if (vif) {
                sdata = vif_to_sdata(vif);
-               list_for_each_entry(key, &sdata->key_list, list)
+               list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
                        iter(hw, &sdata->vif,
                             key->sta ? &key->sta->sta : NULL,
                             &key->conf, iter_data);
        } else {
                list_for_each_entry(sdata, &local->interfaces, list)
-                       list_for_each_entry(key, &sdata->key_list, list)
+                       list_for_each_entry_safe(key, tmp,
+                                                &sdata->key_list, list)
                                iter(hw, &sdata->vif,
                                     key->sta ? &key->sta->sta : NULL,
                                     &key->conf, iter_data);
@@ -751,3 +759,135 @@ void ieee80211_get_key_rx_seq(struct ieee80211_key_conf *keyconf,
        }
 }
 EXPORT_SYMBOL(ieee80211_get_key_rx_seq);
+
+void ieee80211_set_key_tx_seq(struct ieee80211_key_conf *keyconf,
+                             struct ieee80211_key_seq *seq)
+{
+       struct ieee80211_key *key;
+       u64 pn64;
+
+       key = container_of(keyconf, struct ieee80211_key, conf);
+
+       switch (key->conf.cipher) {
+       case WLAN_CIPHER_SUITE_TKIP:
+               key->u.tkip.tx.iv32 = seq->tkip.iv32;
+               key->u.tkip.tx.iv16 = seq->tkip.iv16;
+               break;
+       case WLAN_CIPHER_SUITE_CCMP:
+               pn64 = (u64)seq->ccmp.pn[5] |
+                      ((u64)seq->ccmp.pn[4] << 8) |
+                      ((u64)seq->ccmp.pn[3] << 16) |
+                      ((u64)seq->ccmp.pn[2] << 24) |
+                      ((u64)seq->ccmp.pn[1] << 32) |
+                      ((u64)seq->ccmp.pn[0] << 40);
+               atomic64_set(&key->u.ccmp.tx_pn, pn64);
+               break;
+       case WLAN_CIPHER_SUITE_AES_CMAC:
+               pn64 = (u64)seq->aes_cmac.pn[5] |
+                      ((u64)seq->aes_cmac.pn[4] << 8) |
+                      ((u64)seq->aes_cmac.pn[3] << 16) |
+                      ((u64)seq->aes_cmac.pn[2] << 24) |
+                      ((u64)seq->aes_cmac.pn[1] << 32) |
+                      ((u64)seq->aes_cmac.pn[0] << 40);
+               atomic64_set(&key->u.aes_cmac.tx_pn, pn64);
+               break;
+       default:
+               WARN_ON(1);
+               break;
+       }
+}
+EXPORT_SYMBOL_GPL(ieee80211_set_key_tx_seq);
+
+void ieee80211_set_key_rx_seq(struct ieee80211_key_conf *keyconf,
+                             int tid, struct ieee80211_key_seq *seq)
+{
+       struct ieee80211_key *key;
+       u8 *pn;
+
+       key = container_of(keyconf, struct ieee80211_key, conf);
+
+       switch (key->conf.cipher) {
+       case WLAN_CIPHER_SUITE_TKIP:
+               if (WARN_ON(tid < 0 || tid >= IEEE80211_NUM_TIDS))
+                       return;
+               key->u.tkip.rx[tid].iv32 = seq->tkip.iv32;
+               key->u.tkip.rx[tid].iv16 = seq->tkip.iv16;
+               break;
+       case WLAN_CIPHER_SUITE_CCMP:
+               if (WARN_ON(tid < -1 || tid >= IEEE80211_NUM_TIDS))
+                       return;
+               if (tid < 0)
+                       pn = key->u.ccmp.rx_pn[IEEE80211_NUM_TIDS];
+               else
+                       pn = key->u.ccmp.rx_pn[tid];
+               memcpy(pn, seq->ccmp.pn, IEEE80211_CCMP_PN_LEN);
+               break;
+       case WLAN_CIPHER_SUITE_AES_CMAC:
+               if (WARN_ON(tid != 0))
+                       return;
+               pn = key->u.aes_cmac.rx_pn;
+               memcpy(pn, seq->aes_cmac.pn, IEEE80211_CMAC_PN_LEN);
+               break;
+       default:
+               WARN_ON(1);
+               break;
+       }
+}
+EXPORT_SYMBOL_GPL(ieee80211_set_key_rx_seq);
+
+void ieee80211_remove_key(struct ieee80211_key_conf *keyconf)
+{
+       struct ieee80211_key *key;
+
+       key = container_of(keyconf, struct ieee80211_key, conf);
+
+       assert_key_lock(key->local);
+
+       /*
+        * if key was uploaded, we assume the driver will/has remove(d)
+        * it, so adjust bookkeeping accordingly
+        */
+       if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
+               key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
+
+               if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) ||
+                     (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
+                     (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
+                       increment_tailroom_need_count(key->sdata);
+       }
+
+       ieee80211_key_free(key, false);
+}
+EXPORT_SYMBOL_GPL(ieee80211_remove_key);
+
+struct ieee80211_key_conf *
+ieee80211_gtk_rekey_add(struct ieee80211_vif *vif,
+                       struct ieee80211_key_conf *keyconf)
+{
+       struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+       struct ieee80211_local *local = sdata->local;
+       struct ieee80211_key *key;
+       int err;
+
+       if (WARN_ON(!local->wowlan))
+               return ERR_PTR(-EINVAL);
+
+       if (WARN_ON(vif->type != NL80211_IFTYPE_STATION))
+               return ERR_PTR(-EINVAL);
+
+       key = ieee80211_key_alloc(keyconf->cipher, keyconf->keyidx,
+                                 keyconf->keylen, keyconf->key,
+                                 0, NULL);
+       if (IS_ERR(key))
+               return ERR_PTR(PTR_ERR(key));
+
+       if (sdata->u.mgd.mfp != IEEE80211_MFP_DISABLED)
+               key->conf.flags |= IEEE80211_KEY_FLAG_RX_MGMT;
+
+       err = ieee80211_key_link(key, sdata, NULL);
+       if (err)
+               return ERR_PTR(err);
+
+       return &key->conf;
+}
+EXPORT_SYMBOL_GPL(ieee80211_gtk_rekey_add);
index 21bccd849b3fb531952d2040f79ed303a9267ab9..2aab1308690fad0416457a6ccbd6638636d69310 100644 (file)
@@ -1113,6 +1113,15 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
        case -1:
                cfg80211_chandef_create(&new_chandef, new_chan,
                                        NL80211_CHAN_NO_HT);
+               /* keep width for 5/10 MHz channels */
+               switch (sdata->vif.bss_conf.chandef.width) {
+               case NL80211_CHAN_WIDTH_5:
+               case NL80211_CHAN_WIDTH_10:
+                       new_chandef.width = sdata->vif.bss_conf.chandef.width;
+                       break;
+               default:
+                       break;
+               }
                break;
        }
 
index ba63ac851c2ba6769d2017c6622387331d9da5a1..e126605cec66baf82aadb835856110d74105795f 100644 (file)
@@ -210,7 +210,7 @@ static bool rc_no_data_or_no_ack_use_min(struct ieee80211_tx_rate_control *txrc)
                !ieee80211_is_data(fc);
 }
 
-static void rc_send_low_broadcast(s8 *idx, u32 basic_rates,
+static void rc_send_low_basicrate(s8 *idx, u32 basic_rates,
                                  struct ieee80211_supported_band *sband)
 {
        u8 i;
@@ -263,28 +263,37 @@ static void __rate_control_send_low(struct ieee80211_hw *hw,
 }
 
 
-bool rate_control_send_low(struct ieee80211_sta *sta,
+bool rate_control_send_low(struct ieee80211_sta *pubsta,
                           void *priv_sta,
                           struct ieee80211_tx_rate_control *txrc)
 {
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);
        struct ieee80211_supported_band *sband = txrc->sband;
+       struct sta_info *sta;
        int mcast_rate;
+       bool use_basicrate = false;
 
-       if (!sta || !priv_sta || rc_no_data_or_no_ack_use_min(txrc)) {
-               __rate_control_send_low(txrc->hw, sband, sta, info);
+       if (!pubsta || !priv_sta || rc_no_data_or_no_ack_use_min(txrc)) {
+               __rate_control_send_low(txrc->hw, sband, pubsta, info);
 
-               if (!sta && txrc->bss) {
+               if (!pubsta && txrc->bss) {
                        mcast_rate = txrc->bss_conf->mcast_rate[sband->band];
                        if (mcast_rate > 0) {
                                info->control.rates[0].idx = mcast_rate - 1;
                                return true;
                        }
+                       use_basicrate = true;
+               } else if (pubsta) {
+                       sta = container_of(pubsta, struct sta_info, sta);
+                       if (ieee80211_vif_is_mesh(&sta->sdata->vif))
+                               use_basicrate = true;
+               }
 
-                       rc_send_low_broadcast(&info->control.rates[0].idx,
+               if (use_basicrate)
+                       rc_send_low_basicrate(&info->control.rates[0].idx,
                                              txrc->bss_conf->basic_rates,
                                              sband);
-               }
+
                return true;
        }
        return false;
index 61569425b7236e2b45d61bb888cb6823afe7cbdf..a9909651dc0bc2be78e895a7aa0e3b073a1c40d2 100644 (file)
@@ -439,12 +439,13 @@ minstrel_aggr_check(struct ieee80211_sta *pubsta, struct sk_buff *skb)
 {
        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
        struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
+       struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        u16 tid;
 
        if (unlikely(!ieee80211_is_data_qos(hdr->frame_control)))
                return;
 
-       if (unlikely(skb->protocol == cpu_to_be16(ETH_P_PAE)))
+       if (unlikely(info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO))
                return;
 
        tid = *ieee80211_get_qos_ctl(hdr) & IEEE80211_QOS_CTL_TID_MASK;
@@ -776,7 +777,7 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
 
        /* Don't use EAPOL frames for sampling on non-mrr hw */
        if (mp->hw->max_rates == 1 &&
-           txrc->skb->protocol == cpu_to_be16(ETH_P_PAE))
+           (info->control.flags & IEEE80211_TX_CTRL_PORT_CTRL_PROTO))
                sample_idx = -1;
        else
                sample_idx = minstrel_get_sample_rate(mp, mi);
index 6b85f95b9ba16ed010d6f8a87b2829dae3dd7ca9..a84f319c11adcc3122f12d9a679e294aa29277d2 100644 (file)
@@ -1054,207 +1054,6 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
 }
 
 
-static ieee80211_rx_result debug_noinline
-ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
-{
-       struct sk_buff *skb = rx->skb;
-       struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
-       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
-       int keyidx;
-       int hdrlen;
-       ieee80211_rx_result result = RX_DROP_UNUSABLE;
-       struct ieee80211_key *sta_ptk = NULL;
-       int mmie_keyidx = -1;
-       __le16 fc;
-
-       /*
-        * Key selection 101
-        *
-        * There are four types of keys:
-        *  - GTK (group keys)
-        *  - IGTK (group keys for management frames)
-        *  - PTK (pairwise keys)
-        *  - STK (station-to-station pairwise keys)
-        *
-        * When selecting a key, we have to distinguish between multicast
-        * (including broadcast) and unicast frames, the latter can only
-        * use PTKs and STKs while the former always use GTKs and IGTKs.
-        * Unless, of course, actual WEP keys ("pre-RSNA") are used, then
-        * unicast frames can also use key indices like GTKs. Hence, if we
-        * don't have a PTK/STK we check the key index for a WEP key.
-        *
-        * Note that in a regular BSS, multicast frames are sent by the
-        * AP only, associated stations unicast the frame to the AP first
-        * which then multicasts it on their behalf.
-        *
-        * There is also a slight problem in IBSS mode: GTKs are negotiated
-        * with each station, that is something we don't currently handle.
-        * The spec seems to expect that one negotiates the same key with
-        * every station but there's no such requirement; VLANs could be
-        * possible.
-        */
-
-       /*
-        * No point in finding a key and decrypting if the frame is neither
-        * addressed to us nor a multicast frame.
-        */
-       if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
-               return RX_CONTINUE;
-
-       /* start without a key */
-       rx->key = NULL;
-
-       if (rx->sta)
-               sta_ptk = rcu_dereference(rx->sta->ptk);
-
-       fc = hdr->frame_control;
-
-       if (!ieee80211_has_protected(fc))
-               mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb);
-
-       if (!is_multicast_ether_addr(hdr->addr1) && sta_ptk) {
-               rx->key = sta_ptk;
-               if ((status->flag & RX_FLAG_DECRYPTED) &&
-                   (status->flag & RX_FLAG_IV_STRIPPED))
-                       return RX_CONTINUE;
-               /* Skip decryption if the frame is not protected. */
-               if (!ieee80211_has_protected(fc))
-                       return RX_CONTINUE;
-       } else if (mmie_keyidx >= 0) {
-               /* Broadcast/multicast robust management frame / BIP */
-               if ((status->flag & RX_FLAG_DECRYPTED) &&
-                   (status->flag & RX_FLAG_IV_STRIPPED))
-                       return RX_CONTINUE;
-
-               if (mmie_keyidx < NUM_DEFAULT_KEYS ||
-                   mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
-                       return RX_DROP_MONITOR; /* unexpected BIP keyidx */
-               if (rx->sta)
-                       rx->key = rcu_dereference(rx->sta->gtk[mmie_keyidx]);
-               if (!rx->key)
-                       rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]);
-       } else if (!ieee80211_has_protected(fc)) {
-               /*
-                * The frame was not protected, so skip decryption. However, we
-                * need to set rx->key if there is a key that could have been
-                * used so that the frame may be dropped if encryption would
-                * have been expected.
-                */
-               struct ieee80211_key *key = NULL;
-               struct ieee80211_sub_if_data *sdata = rx->sdata;
-               int i;
-
-               if (ieee80211_is_mgmt(fc) &&
-                   is_multicast_ether_addr(hdr->addr1) &&
-                   (key = rcu_dereference(rx->sdata->default_mgmt_key)))
-                       rx->key = key;
-               else {
-                       if (rx->sta) {
-                               for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
-                                       key = rcu_dereference(rx->sta->gtk[i]);
-                                       if (key)
-                                               break;
-                               }
-                       }
-                       if (!key) {
-                               for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
-                                       key = rcu_dereference(sdata->keys[i]);
-                                       if (key)
-                                               break;
-                               }
-                       }
-                       if (key)
-                               rx->key = key;
-               }
-               return RX_CONTINUE;
-       } else {
-               u8 keyid;
-               /*
-                * The device doesn't give us the IV so we won't be
-                * able to look up the key. That's ok though, we
-                * don't need to decrypt the frame, we just won't
-                * be able to keep statistics accurate.
-                * Except for key threshold notifications, should
-                * we somehow allow the driver to tell us which key
-                * the hardware used if this flag is set?
-                */
-               if ((status->flag & RX_FLAG_DECRYPTED) &&
-                   (status->flag & RX_FLAG_IV_STRIPPED))
-                       return RX_CONTINUE;
-
-               hdrlen = ieee80211_hdrlen(fc);
-
-               if (rx->skb->len < 8 + hdrlen)
-                       return RX_DROP_UNUSABLE; /* TODO: count this? */
-
-               /*
-                * no need to call ieee80211_wep_get_keyidx,
-                * it verifies a bunch of things we've done already
-                */
-               skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1);
-               keyidx = keyid >> 6;
-
-               /* check per-station GTK first, if multicast packet */
-               if (is_multicast_ether_addr(hdr->addr1) && rx->sta)
-                       rx->key = rcu_dereference(rx->sta->gtk[keyidx]);
-
-               /* if not found, try default key */
-               if (!rx->key) {
-                       rx->key = rcu_dereference(rx->sdata->keys[keyidx]);
-
-                       /*
-                        * RSNA-protected unicast frames should always be
-                        * sent with pairwise or station-to-station keys,
-                        * but for WEP we allow using a key index as well.
-                        */
-                       if (rx->key &&
-                           rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP40 &&
-                           rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP104 &&
-                           !is_multicast_ether_addr(hdr->addr1))
-                               rx->key = NULL;
-               }
-       }
-
-       if (rx->key) {
-               if (unlikely(rx->key->flags & KEY_FLAG_TAINTED))
-                       return RX_DROP_MONITOR;
-
-               rx->key->tx_rx_count++;
-               /* TODO: add threshold stuff again */
-       } else {
-               return RX_DROP_MONITOR;
-       }
-
-       switch (rx->key->conf.cipher) {
-       case WLAN_CIPHER_SUITE_WEP40:
-       case WLAN_CIPHER_SUITE_WEP104:
-               result = ieee80211_crypto_wep_decrypt(rx);
-               break;
-       case WLAN_CIPHER_SUITE_TKIP:
-               result = ieee80211_crypto_tkip_decrypt(rx);
-               break;
-       case WLAN_CIPHER_SUITE_CCMP:
-               result = ieee80211_crypto_ccmp_decrypt(rx);
-               break;
-       case WLAN_CIPHER_SUITE_AES_CMAC:
-               result = ieee80211_crypto_aes_cmac_decrypt(rx);
-               break;
-       default:
-               /*
-                * We can reach here only with HW-only algorithms
-                * but why didn't it decrypt the frame?!
-                */
-               return RX_DROP_UNUSABLE;
-       }
-
-       /* the hdr variable is invalid after the decrypt handlers */
-
-       /* either the frame has been decrypted or will be dropped */
-       status->flag |= RX_FLAG_DECRYPTED;
-
-       return result;
-}
-
 static ieee80211_rx_result debug_noinline
 ieee80211_rx_h_check_more_data(struct ieee80211_rx_data *rx)
 {
@@ -1556,6 +1355,207 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
        return RX_CONTINUE;
 } /* ieee80211_rx_h_sta_process */
 
+static ieee80211_rx_result debug_noinline
+ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
+{
+       struct sk_buff *skb = rx->skb;
+       struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
+       struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+       int keyidx;
+       int hdrlen;
+       ieee80211_rx_result result = RX_DROP_UNUSABLE;
+       struct ieee80211_key *sta_ptk = NULL;
+       int mmie_keyidx = -1;
+       __le16 fc;
+
+       /*
+        * Key selection 101
+        *
+        * There are four types of keys:
+        *  - GTK (group keys)
+        *  - IGTK (group keys for management frames)
+        *  - PTK (pairwise keys)
+        *  - STK (station-to-station pairwise keys)
+        *
+        * When selecting a key, we have to distinguish between multicast
+        * (including broadcast) and unicast frames, the latter can only
+        * use PTKs and STKs while the former always use GTKs and IGTKs.
+        * Unless, of course, actual WEP keys ("pre-RSNA") are used, then
+        * unicast frames can also use key indices like GTKs. Hence, if we
+        * don't have a PTK/STK we check the key index for a WEP key.
+        *
+        * Note that in a regular BSS, multicast frames are sent by the
+        * AP only, associated stations unicast the frame to the AP first
+        * which then multicasts it on their behalf.
+        *
+        * There is also a slight problem in IBSS mode: GTKs are negotiated
+        * with each station, that is something we don't currently handle.
+        * The spec seems to expect that one negotiates the same key with
+        * every station but there's no such requirement; VLANs could be
+        * possible.
+        */
+
+       /*
+        * No point in finding a key and decrypting if the frame is neither
+        * addressed to us nor a multicast frame.
+        */
+       if (!(status->rx_flags & IEEE80211_RX_RA_MATCH))
+               return RX_CONTINUE;
+
+       /* start without a key */
+       rx->key = NULL;
+
+       if (rx->sta)
+               sta_ptk = rcu_dereference(rx->sta->ptk);
+
+       fc = hdr->frame_control;
+
+       if (!ieee80211_has_protected(fc))
+               mmie_keyidx = ieee80211_get_mmie_keyidx(rx->skb);
+
+       if (!is_multicast_ether_addr(hdr->addr1) && sta_ptk) {
+               rx->key = sta_ptk;
+               if ((status->flag & RX_FLAG_DECRYPTED) &&
+                   (status->flag & RX_FLAG_IV_STRIPPED))
+                       return RX_CONTINUE;
+               /* Skip decryption if the frame is not protected. */
+               if (!ieee80211_has_protected(fc))
+                       return RX_CONTINUE;
+       } else if (mmie_keyidx >= 0) {
+               /* Broadcast/multicast robust management frame / BIP */
+               if ((status->flag & RX_FLAG_DECRYPTED) &&
+                   (status->flag & RX_FLAG_IV_STRIPPED))
+                       return RX_CONTINUE;
+
+               if (mmie_keyidx < NUM_DEFAULT_KEYS ||
+                   mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
+                       return RX_DROP_MONITOR; /* unexpected BIP keyidx */
+               if (rx->sta)
+                       rx->key = rcu_dereference(rx->sta->gtk[mmie_keyidx]);
+               if (!rx->key)
+                       rx->key = rcu_dereference(rx->sdata->keys[mmie_keyidx]);
+       } else if (!ieee80211_has_protected(fc)) {
+               /*
+                * The frame was not protected, so skip decryption. However, we
+                * need to set rx->key if there is a key that could have been
+                * used so that the frame may be dropped if encryption would
+                * have been expected.
+                */
+               struct ieee80211_key *key = NULL;
+               struct ieee80211_sub_if_data *sdata = rx->sdata;
+               int i;
+
+               if (ieee80211_is_mgmt(fc) &&
+                   is_multicast_ether_addr(hdr->addr1) &&
+                   (key = rcu_dereference(rx->sdata->default_mgmt_key)))
+                       rx->key = key;
+               else {
+                       if (rx->sta) {
+                               for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
+                                       key = rcu_dereference(rx->sta->gtk[i]);
+                                       if (key)
+                                               break;
+                               }
+                       }
+                       if (!key) {
+                               for (i = 0; i < NUM_DEFAULT_KEYS; i++) {
+                                       key = rcu_dereference(sdata->keys[i]);
+                                       if (key)
+                                               break;
+                               }
+                       }
+                       if (key)
+                               rx->key = key;
+               }
+               return RX_CONTINUE;
+       } else {
+               u8 keyid;
+               /*
+                * The device doesn't give us the IV so we won't be
+                * able to look up the key. That's ok though, we
+                * don't need to decrypt the frame, we just won't
+                * be able to keep statistics accurate.
+                * Except for key threshold notifications, should
+                * we somehow allow the driver to tell us which key
+                * the hardware used if this flag is set?
+                */
+               if ((status->flag & RX_FLAG_DECRYPTED) &&
+                   (status->flag & RX_FLAG_IV_STRIPPED))
+                       return RX_CONTINUE;
+
+               hdrlen = ieee80211_hdrlen(fc);
+
+               if (rx->skb->len < 8 + hdrlen)
+                       return RX_DROP_UNUSABLE; /* TODO: count this? */
+
+               /*
+                * no need to call ieee80211_wep_get_keyidx,
+                * it verifies a bunch of things we've done already
+                */
+               skb_copy_bits(rx->skb, hdrlen + 3, &keyid, 1);
+               keyidx = keyid >> 6;
+
+               /* check per-station GTK first, if multicast packet */
+               if (is_multicast_ether_addr(hdr->addr1) && rx->sta)
+                       rx->key = rcu_dereference(rx->sta->gtk[keyidx]);
+
+               /* if not found, try default key */
+               if (!rx->key) {
+                       rx->key = rcu_dereference(rx->sdata->keys[keyidx]);
+
+                       /*
+                        * RSNA-protected unicast frames should always be
+                        * sent with pairwise or station-to-station keys,
+                        * but for WEP we allow using a key index as well.
+                        */
+                       if (rx->key &&
+                           rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP40 &&
+                           rx->key->conf.cipher != WLAN_CIPHER_SUITE_WEP104 &&
+                           !is_multicast_ether_addr(hdr->addr1))
+                               rx->key = NULL;
+               }
+       }
+
+       if (rx->key) {
+               if (unlikely(rx->key->flags & KEY_FLAG_TAINTED))
+                       return RX_DROP_MONITOR;
+
+               rx->key->tx_rx_count++;
+               /* TODO: add threshold stuff again */
+       } else {
+               return RX_DROP_MONITOR;
+       }
+
+       switch (rx->key->conf.cipher) {
+       case WLAN_CIPHER_SUITE_WEP40:
+       case WLAN_CIPHER_SUITE_WEP104:
+               result = ieee80211_crypto_wep_decrypt(rx);
+               break;
+       case WLAN_CIPHER_SUITE_TKIP:
+               result = ieee80211_crypto_tkip_decrypt(rx);
+               break;
+       case WLAN_CIPHER_SUITE_CCMP:
+               result = ieee80211_crypto_ccmp_decrypt(rx);
+               break;
+       case WLAN_CIPHER_SUITE_AES_CMAC:
+               result = ieee80211_crypto_aes_cmac_decrypt(rx);
+               break;
+       default:
+               /*
+                * We can reach here only with HW-only algorithms
+                * but why didn't it decrypt the frame?!
+                */
+               return RX_DROP_UNUSABLE;
+       }
+
+       /* the hdr variable is invalid after the decrypt handlers */
+
+       /* either the frame has been decrypted or will be dropped */
+       status->flag |= RX_FLAG_DECRYPTED;
+
+       return result;
+}
+
 static inline struct ieee80211_fragment_entry *
 ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata,
                         unsigned int frag, unsigned int seq, int rx_queue,
@@ -2939,10 +2939,10 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
                 */
                rx->skb = skb;
 
-               CALL_RXH(ieee80211_rx_h_decrypt)
                CALL_RXH(ieee80211_rx_h_check_more_data)
                CALL_RXH(ieee80211_rx_h_uapsd_and_pspoll)
                CALL_RXH(ieee80211_rx_h_sta_process)
+               CALL_RXH(ieee80211_rx_h_decrypt)
                CALL_RXH(ieee80211_rx_h_defragment)
                CALL_RXH(ieee80211_rx_h_michael_mic_verify)
                /* must be after MMIC verify so header is counted in MPDU mic */
index 0e42322aa6b157e13d7ea8ee57d3ad6f03e08ac4..098ae854ad3c31cb4984236d801bc468ab3763fa 100644 (file)
@@ -539,9 +539,11 @@ ieee80211_tx_h_check_control_port_protocol(struct ieee80211_tx_data *tx)
 {
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
 
-       if (unlikely(tx->sdata->control_port_protocol == tx->skb->protocol &&
-                    tx->sdata->control_port_no_encrypt))
-               info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
+       if (unlikely(tx->sdata->control_port_protocol == tx->skb->protocol)) {
+               if (tx->sdata->control_port_no_encrypt)
+                       info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
+               info->control.flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO;
+       }
 
        return TX_CONTINUE;
 }
index d23c5a705a6846db93596958c64139780a9874b4..e1b34a18b24344cb95a642c436fc5322054207ce 100644 (file)
@@ -1453,8 +1453,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
                local->resuming = true;
 
        if (local->wowlan) {
-               local->wowlan = false;
                res = drv_resume(local);
+               local->wowlan = false;
                if (res < 0) {
                        local->resuming = false;
                        return res;
index d11ac79246e46d8388d6bee79de663928aa0f86e..cf5b145902e5e0a4616122bbdcfecfb1662c7ec2 100644 (file)
@@ -30,6 +30,7 @@ struct rfkill_regulator_data {
 static int rfkill_regulator_set_block(void *data, bool blocked)
 {
        struct rfkill_regulator_data *rfkill_data = data;
+       int ret = 0;
 
        pr_debug("%s: blocked: %d\n", __func__, blocked);
 
@@ -40,15 +41,16 @@ static int rfkill_regulator_set_block(void *data, bool blocked)
                }
        } else {
                if (!rfkill_data->reg_enabled) {
-                       regulator_enable(rfkill_data->vcc);
-                       rfkill_data->reg_enabled = true;
+                       ret = regulator_enable(rfkill_data->vcc);
+                       if (!ret)
+                               rfkill_data->reg_enabled = true;
                }
        }
 
        pr_debug("%s: regulator_is_enabled after set_block: %d\n", __func__,
                regulator_is_enabled(rfkill_data->vcc));
 
-       return 0;
+       return ret;
 }
 
 static struct rfkill_ops rfkill_regulator_ops = {
index adf1e98f4c3ebadbb86e35c21f58f0994260b2b1..c6164da1c133066dc61d3cef800f429b500adf75 100644 (file)
@@ -6593,19 +6593,30 @@ static struct genl_multicast_group nl80211_testmode_mcgrp = {
 static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info)
 {
        struct cfg80211_registered_device *rdev = info->user_ptr[0];
+       struct wireless_dev *wdev =
+               __cfg80211_wdev_from_attrs(genl_info_net(info), info->attrs);
        int err;
 
+       if (!rdev->ops->testmode_cmd)
+               return -EOPNOTSUPP;
+
+       if (IS_ERR(wdev)) {
+               err = PTR_ERR(wdev);
+               if (err != -EINVAL)
+                       return err;
+               wdev = NULL;
+       } else if (wdev->wiphy != &rdev->wiphy) {
+               return -EINVAL;
+       }
+
        if (!info->attrs[NL80211_ATTR_TESTDATA])
                return -EINVAL;
 
-       err = -EOPNOTSUPP;
-       if (rdev->ops->testmode_cmd) {
-               rdev->testmode_info = info;
-               err = rdev_testmode_cmd(rdev,
+       rdev->testmode_info = info;
+       err = rdev_testmode_cmd(rdev, wdev,
                                nla_data(info->attrs[NL80211_ATTR_TESTDATA]),
                                nla_len(info->attrs[NL80211_ATTR_TESTDATA]));
-               rdev->testmode_info = NULL;
-       }
+       rdev->testmode_info = NULL;
 
        return err;
 }
@@ -7566,14 +7577,12 @@ static int nl80211_set_cqm_txe(struct genl_info *info,
                               u32 rate, u32 pkts, u32 intvl)
 {
        struct cfg80211_registered_device *rdev = info->user_ptr[0];
-       struct wireless_dev *wdev;
        struct net_device *dev = info->user_ptr[1];
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
 
        if (rate > 100 || intvl > NL80211_CQM_TXE_MAX_INTVL)
                return -EINVAL;
 
-       wdev = dev->ieee80211_ptr;
-
        if (!rdev->ops->set_cqm_txe_config)
                return -EOPNOTSUPP;
 
@@ -7588,13 +7597,15 @@ static int nl80211_set_cqm_rssi(struct genl_info *info,
                                s32 threshold, u32 hysteresis)
 {
        struct cfg80211_registered_device *rdev = info->user_ptr[0];
-       struct wireless_dev *wdev;
        struct net_device *dev = info->user_ptr[1];
+       struct wireless_dev *wdev = dev->ieee80211_ptr;
 
        if (threshold > 0)
                return -EINVAL;
 
-       wdev = dev->ieee80211_ptr;
+       /* disabling - hysteresis should also be zero then */
+       if (threshold == 0)
+               hysteresis = 0;
 
        if (!rdev->ops->set_cqm_rssi_config)
                return -EOPNOTSUPP;
@@ -7613,36 +7624,33 @@ static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info)
        int err;
 
        cqm = info->attrs[NL80211_ATTR_CQM];
-       if (!cqm) {
-               err = -EINVAL;
-               goto out;
-       }
+       if (!cqm)
+               return -EINVAL;
 
        err = nla_parse_nested(attrs, NL80211_ATTR_CQM_MAX, cqm,
                               nl80211_attr_cqm_policy);
        if (err)
-               goto out;
+               return err;
 
        if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] &&
            attrs[NL80211_ATTR_CQM_RSSI_HYST]) {
-               s32 threshold;
-               u32 hysteresis;
-               threshold = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
-               hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]);
-               err = nl80211_set_cqm_rssi(info, threshold, hysteresis);
-       } else if (attrs[NL80211_ATTR_CQM_TXE_RATE] &&
-                  attrs[NL80211_ATTR_CQM_TXE_PKTS] &&
-                  attrs[NL80211_ATTR_CQM_TXE_INTVL]) {
-               u32 rate, pkts, intvl;
-               rate = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_RATE]);
-               pkts = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_PKTS]);
-               intvl = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_INTVL]);
-               err = nl80211_set_cqm_txe(info, rate, pkts, intvl);
-       } else
-               err = -EINVAL;
+               s32 threshold = nla_get_s32(attrs[NL80211_ATTR_CQM_RSSI_THOLD]);
+               u32 hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]);
 
-out:
-       return err;
+               return nl80211_set_cqm_rssi(info, threshold, hysteresis);
+       }
+
+       if (attrs[NL80211_ATTR_CQM_TXE_RATE] &&
+           attrs[NL80211_ATTR_CQM_TXE_PKTS] &&
+           attrs[NL80211_ATTR_CQM_TXE_INTVL]) {
+               u32 rate = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_RATE]);
+               u32 pkts = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_PKTS]);
+               u32 intvl = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_INTVL]);
+
+               return nl80211_set_cqm_txe(info, rate, pkts, intvl);
+       }
+
+       return -EINVAL;
 }
 
 static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info)
index de870d4d0bccbdabfb12a37d07aeea1f15d853e8..37ce9fdfe934345fe6603b399b8c4d3fd4f44ec1 100644 (file)
@@ -516,11 +516,12 @@ static inline void rdev_rfkill_poll(struct cfg80211_registered_device *rdev)
 
 #ifdef CONFIG_NL80211_TESTMODE
 static inline int rdev_testmode_cmd(struct cfg80211_registered_device *rdev,
+                                   struct wireless_dev *wdev,
                                    void *data, int len)
 {
        int ret;
-       trace_rdev_testmode_cmd(&rdev->wiphy);
-       ret = rdev->ops->testmode_cmd(&rdev->wiphy, data, len);
+       trace_rdev_testmode_cmd(&rdev->wiphy, wdev);
+       ret = rdev->ops->testmode_cmd(&rdev->wiphy, wdev, data, len);
        trace_rdev_return_int(&rdev->wiphy, ret);
        return ret;
 }
index f0ebdcd394ef0d0686906e3a697bc8915474f2de..ba5f0d6614d5d4cee4d08c609bb192dd501f0b34 100644 (file)
@@ -1293,15 +1293,17 @@ TRACE_EVENT(rdev_return_int_int,
 
 #ifdef CONFIG_NL80211_TESTMODE
 TRACE_EVENT(rdev_testmode_cmd,
-       TP_PROTO(struct wiphy *wiphy),
-       TP_ARGS(wiphy),
+       TP_PROTO(struct wiphy *wiphy, struct wireless_dev *wdev),
+       TP_ARGS(wiphy, wdev),
        TP_STRUCT__entry(
                WIPHY_ENTRY
+               WDEV_ENTRY
        ),
        TP_fast_assign(
                WIPHY_ASSIGN;
+               WDEV_ASSIGN;
        ),
-       TP_printk(WIPHY_PR_FMT, WIPHY_PR_ARG)
+       TP_printk(WIPHY_PR_FMT WDEV_PR_FMT, WIPHY_PR_ARG, WDEV_PR_ARG)
 );
 
 TRACE_EVENT(rdev_testmode_dump,