struct sk_buff *skb, const u8 *peer,
                                   u8 action_code, u16 status_code,
                                   bool initiator, const u8 *extra_ies,
-                                  size_t extra_ies_len)
+                                  size_t extra_ies_len, u8 oper_class,
+                                  struct cfg80211_chan_def *chandef)
 {
        switch (action_code) {
        case WLAN_TDLS_SETUP_REQUEST:
        return 0;
 }
 
-static int
-ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
-                               const u8 *peer, u8 action_code,
-                               u8 dialog_token, u16 status_code,
-                               u32 peer_capability, bool initiator,
-                               const u8 *extra_ies, size_t extra_ies_len)
+static struct sk_buff *
+ieee80211_tdls_build_mgmt_packet_data(struct ieee80211_sub_if_data *sdata,
+                                     const u8 *peer, u8 action_code,
+                                     u8 dialog_token, u16 status_code,
+                                     bool initiator, const u8 *extra_ies,
+                                     size_t extra_ies_len, u8 oper_class,
+                                     struct cfg80211_chan_def *chandef)
 {
-       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
        struct ieee80211_local *local = sdata->local;
-       struct sk_buff *skb = NULL;
-       u32 flags = 0;
-       bool send_direct;
-       struct sta_info *sta;
+       struct sk_buff *skb;
        int ret;
 
-       skb = netdev_alloc_skb(dev,
+       skb = netdev_alloc_skb(sdata->dev,
                               local->hw.extra_tx_headroom +
                               max(sizeof(struct ieee80211_mgmt),
                                   sizeof(struct ieee80211_tdls_data)) +
                               extra_ies_len +
                               sizeof(struct ieee80211_tdls_lnkie));
        if (!skb)
-               return -ENOMEM;
+               return NULL;
 
        skb_reserve(skb, local->hw.extra_tx_headroom);
 
        case WLAN_TDLS_SETUP_CONFIRM:
        case WLAN_TDLS_TEARDOWN:
        case WLAN_TDLS_DISCOVERY_REQUEST:
-               ret = ieee80211_prep_tdls_encap_data(wiphy, dev, peer,
+               ret = ieee80211_prep_tdls_encap_data(local->hw.wiphy,
+                                                    sdata->dev, peer,
                                                     action_code, dialog_token,
                                                     status_code, skb);
-               send_direct = false;
                break;
        case WLAN_PUB_ACTION_TDLS_DISCOVER_RES:
-               ret = ieee80211_prep_tdls_direct(wiphy, dev, peer, action_code,
+               ret = ieee80211_prep_tdls_direct(local->hw.wiphy, sdata->dev,
+                                                peer, action_code,
                                                 dialog_token, status_code,
                                                 skb);
-               send_direct = true;
                break;
        default:
                ret = -ENOTSUPP;
        if (ret < 0)
                goto fail;
 
+       ieee80211_tdls_add_ies(sdata, skb, peer, action_code, status_code,
+                              initiator, extra_ies, extra_ies_len, oper_class,
+                              chandef);
+       return skb;
+
+fail:
+       dev_kfree_skb(skb);
+       return NULL;
+}
+
+static int
+ieee80211_tdls_prep_mgmt_packet(struct wiphy *wiphy, struct net_device *dev,
+                               const u8 *peer, u8 action_code, u8 dialog_token,
+                               u16 status_code, u32 peer_capability,
+                               bool initiator, const u8 *extra_ies,
+                               size_t extra_ies_len, u8 oper_class,
+                               struct cfg80211_chan_def *chandef)
+{
+       struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+       struct sk_buff *skb = NULL;
+       struct sta_info *sta;
+       u32 flags = 0;
+       int ret = 0;
+
        rcu_read_lock();
        sta = sta_info_get(sdata, peer);
 
        if (ret < 0)
                goto fail;
 
-       ieee80211_tdls_add_ies(sdata, skb, peer, action_code, status_code,
-                              initiator, extra_ies, extra_ies_len);
-       if (send_direct) {
+       skb = ieee80211_tdls_build_mgmt_packet_data(sdata, peer, action_code,
+                                                   dialog_token, status_code,
+                                                   initiator, extra_ies,
+                                                   extra_ies_len, oper_class,
+                                                   chandef);
+       if (!skb) {
+               ret = -EINVAL;
+               goto fail;
+       }
+
+       if (action_code == WLAN_PUB_ACTION_TDLS_DISCOVER_RES) {
                ieee80211_tx_skb(sdata, skb);
                return 0;
        }
         * packet through the AP.
         */
        if ((action_code == WLAN_TDLS_TEARDOWN) &&
-           (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) {
+           (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) {
                struct sta_info *sta = NULL;
                bool try_resend; /* Should we keep skb for possible resend */
 
        ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
                                              dialog_token, status_code,
                                              peer_capability, initiator,
-                                             extra_ies, extra_ies_len);
+                                             extra_ies, extra_ies_len, 0,
+                                             NULL);
        if (ret < 0)
                goto exit;
 
        ret = ieee80211_tdls_prep_mgmt_packet(wiphy, dev, peer, action_code,
                                              dialog_token, status_code,
                                              peer_capability, initiator,
-                                             extra_ies, extra_ies_len);
+                                             extra_ies, extra_ies_len, 0,
+                                             NULL);
        if (ret < 0)
                sdata_err(sdata, "Failed sending TDLS teardown packet %d\n",
                          ret);
                                                      status_code,
                                                      peer_capability,
                                                      initiator, extra_ies,
-                                                     extra_ies_len);
+                                                     extra_ies_len, 0, NULL);
                break;
        default:
                ret = -EOPNOTSUPP;