*     generation in software.
  * @IEEE80211_KEY_FLAG_PAIRWISE: Set by mac80211, this flag indicates
  *     that the key is pairwise rather then a shared key.
+ * @IEEE80211_KEY_FLAG_SW_MGMT: This flag should be set by the driver for a
+ *     CCMP key if it requires CCMP encryption of management frames (MFP) to
+ *     be done in software.
  */
 enum ieee80211_key_flags {
        IEEE80211_KEY_FLAG_WMM_STA      = 1<<0,
        IEEE80211_KEY_FLAG_GENERATE_IV  = 1<<1,
        IEEE80211_KEY_FLAG_GENERATE_MMIC= 1<<2,
        IEEE80211_KEY_FLAG_PAIRWISE     = 1<<3,
+       IEEE80211_KEY_FLAG_SW_MGMT      = 1<<4,
 };
 
 /**
 
        int hdrlen, len, tail;
        u8 *pos, *pn;
        int i;
+       bool skip_hw;
+
+       skip_hw = (tx->key->conf.flags & IEEE80211_KEY_FLAG_SW_MGMT) &&
+               ieee80211_is_mgmt(hdr->frame_control);
 
        if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
-           !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
+           !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
+           !skip_hw) {
                /* hwaccel - with no need for preallocated room for CCMP
                 * header or MIC fields */
                info->control.hw_key = &tx->key->conf;
 
        ccmp_pn2hdr(pos, pn, key->conf.keyidx);
 
-       if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
+       if ((key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && !skip_hw) {
                /* hwaccel - with preallocated room for CCMP header */
                info->control.hw_key = &tx->key->conf;
                return 0;