tx_info->pkt_len = pkt_len;
 
        mwifiex_form_mgmt_frame(skb, buf, len);
-       mwifiex_queue_tx_pkt(priv, skb);
-
        *cookie = prandom_u32() | 1;
-       cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true, GFP_ATOMIC);
+
+       if (ieee80211_is_action(mgmt->frame_control))
+               skb = mwifiex_clone_skb_for_tx_status(priv,
+                                                     skb,
+                               MWIFIEX_BUF_FLAG_ACTION_TX_STATUS, cookie);
+       else
+               cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
+                                       GFP_ATOMIC);
+
+       mwifiex_queue_tx_pkt(priv, skb);
 
        wiphy_dbg(wiphy, "info: management frame transmitted\n");
        return 0;
 
 #define MWIFIEX_BUF_FLAG_BRIDGED_PKT      BIT(1)
 #define MWIFIEX_BUF_FLAG_TDLS_PKT         BIT(2)
 #define MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS   BIT(3)
+#define MWIFIEX_BUF_FLAG_ACTION_TX_STATUS  BIT(4)
 
 #define MWIFIEX_BRIDGED_PKTS_THR_HIGH      1024
 #define MWIFIEX_BRIDGED_PKTS_THR_LOW        128
        u8 bss_type;
        u32 pkt_len;
        u8 ack_frame_id;
+       u64 cookie;
 };
 
 enum mwifiex_wmm_ac_e {
 
        return 0;
 }
 
-static struct sk_buff *
+struct sk_buff *
 mwifiex_clone_skb_for_tx_status(struct mwifiex_private *priv,
-                               struct sk_buff *skb, u8 flag)
+                               struct sk_buff *skb, u8 flag, u64 *cookie)
 {
        struct sk_buff *orig_skb = skb;
        struct mwifiex_txinfo *tx_info, *orig_tx_info;
                        orig_tx_info = MWIFIEX_SKB_TXCB(orig_skb);
                        orig_tx_info->ack_frame_id = id;
                        orig_tx_info->flags |= flag;
+
+                       if (flag == MWIFIEX_BUF_FLAG_ACTION_TX_STATUS && cookie)
+                               orig_tx_info->cookie = *cookie;
+
                } else if (skb_shared(skb)) {
                        kfree_skb(orig_skb);
                } else {
                     priv->adapter->fw_api_ver == MWIFIEX_FW_V15))
                skb = mwifiex_clone_skb_for_tx_status(priv,
                                                      skb,
-                                       MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS);
+                                       MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS, NULL);
 
        /* Record the current time the packet was queued; used to
         * determine the amount of time the packet was queued in
 
 void mwifiex_parse_tx_status_event(struct mwifiex_private *priv,
                                   void *event_body);
 
+struct sk_buff *
+mwifiex_clone_skb_for_tx_status(struct mwifiex_private *priv,
+                               struct sk_buff *skb, u8 flag, u64 *cookie);
+
 #ifdef CONFIG_DEBUG_FS
 void mwifiex_debugfs_init(void);
 void mwifiex_debugfs_remove(void);
 
        local_tx_pd->pkt_delay_2ms =
                                mwifiex_wmm_compute_drv_pkt_delay(priv, skb);
 
-       if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS) {
+       if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS ||
+           tx_info->flags & MWIFIEX_BUF_FLAG_ACTION_TX_STATUS) {
                local_tx_pd->tx_token_id = tx_info->ack_frame_id;
                local_tx_pd->flags |= MWIFIEX_TXPD_FLAGS_REQ_TX_STATUS;
        }
 
        struct tx_status_event *tx_status = (void *)priv->adapter->event_body;
        struct sk_buff *ack_skb;
        unsigned long flags;
+       struct mwifiex_txinfo *tx_info;
 
        if (!tx_status->tx_token_id)
                return;
                idr_remove(&priv->ack_status_frames, tx_status->tx_token_id);
        spin_unlock_irqrestore(&priv->ack_status_lock, flags);
 
-       /* consumes ack_skb */
-       if (ack_skb)
-               skb_complete_wifi_ack(ack_skb, !tx_status->status);
+       if (ack_skb) {
+               tx_info = MWIFIEX_SKB_TXCB(ack_skb);
+
+               if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS) {
+                       /* consumes ack_skb */
+                       skb_complete_wifi_ack(ack_skb, !tx_status->status);
+               } else {
+                       cfg80211_mgmt_tx_status(priv->wdev, tx_info->cookie,
+                                               ack_skb->data, ack_skb->len,
+                                               !tx_status->status, GFP_ATOMIC);
+                       dev_kfree_skb_any(ack_skb);
+               }
+       }
 }
 
 
        txpd->pkt_delay_2ms = mwifiex_wmm_compute_drv_pkt_delay(priv, skb);
 
-       if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS) {
+       if (tx_info->flags & MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS ||
+           tx_info->flags & MWIFIEX_BUF_FLAG_ACTION_TX_STATUS) {
                txpd->tx_token_id = tx_info->ack_frame_id;
                txpd->flags |= MWIFIEX_TXPD_FLAGS_REQ_TX_STATUS;
        }