enum iwl_data_path_subcmd_ids {
        UPDATE_MU_GROUPS_CMD = 0x1,
        TRIGGER_RX_QUEUES_NOTIF_CMD = 0x2,
+       MU_GROUP_MGMT_NOTIF = 0xFE,
        RX_QUEUES_NOTIFICATION = 0xFF,
 };
 
        __le32 user_position[4];
 } __packed; /* MU_GROUP_ID_MNG_TABLE_API_S_VER_1 */
 
+/**
+ * struct iwl_mu_group_mgmt_notif - VHT MU-MIMO group id notification
+ *
+ * @membership_status: a bitmap of MU groups
+ * @user_position: the position of station in a group. If the station is in the
+ *     group then bits (group * 2) is the position -1
+ */
+struct iwl_mu_group_mgmt_notif {
+       __le32 membership_status[2];
+       __le32 user_position[4];
+} __packed; /* MU_GROUP_MNG_NTFY_API_S_VER_1 */
+
 #define MAX_STORED_BEACON_SIZE 600
 
 /**
 
  *
  * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
+ * Copyright(c) 2016 Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
                                    0, sizeof(cmd), &cmd);
 }
 
+static void iwl_mvm_mu_mimo_iface_iterator(void *_data, u8 *mac,
+                                          struct ieee80211_vif *vif)
+{
+       if (vif->mu_mimo_owner) {
+               struct iwl_mu_group_mgmt_notif *notif = _data;
+
+               /*
+                * MU-MIMO Group Id action frame is little endian. We treat
+                * the data received from firmware as if it came from the
+                * action frame, so no conversion is needed.
+                */
+               ieee80211_update_mu_groups(vif,
+                                          (u8 *)¬if->membership_status,
+                                          (u8 *)¬if->user_position);
+       }
+}
+
+void iwl_mvm_mu_mimo_grp_notif(struct iwl_mvm *mvm,
+                              struct iwl_rx_cmd_buffer *rxb)
+{
+       struct iwl_rx_packet *pkt = rxb_addr(rxb);
+       struct iwl_mu_group_mgmt_notif *notif = (void *)pkt->data;
+
+       ieee80211_iterate_active_interfaces_atomic(
+                       mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
+                       iwl_mvm_mu_mimo_iface_iterator, notif);
+}
+
 static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
                                             struct ieee80211_vif *vif,
                                             struct ieee80211_bss_conf *bss_conf,
 
                /*
                 * The firmware tracks the MU-MIMO group on its own.
-                * However, on HW restart we should restore this data
+                * However, on HW restart we should restore this data.
                 */
                if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) &&
-                   changes & BSS_CHANGED_MU_GROUPS) {
+                   (changes & BSS_CHANGED_MU_GROUPS) && vif->mu_mimo_owner) {
                        ret = iwl_mvm_update_mu_groups(mvm, vif);
                        if (ret)
                                IWL_ERR(mvm,
 
                                     struct iwl_rx_cmd_buffer *rxb);
 void iwl_mvm_rx_stored_beacon_notif(struct iwl_mvm *mvm,
                                    struct iwl_rx_cmd_buffer *rxb);
+void iwl_mvm_mu_mimo_grp_notif(struct iwl_mvm *mvm,
+                              struct iwl_rx_cmd_buffer *rxb);
 void iwl_mvm_window_status_notif(struct iwl_mvm *mvm,
                                 struct iwl_rx_cmd_buffer *rxb);
 void iwl_mvm_mac_ctxt_recalc_tsf_id(struct iwl_mvm *mvm,
 
        RX_HANDLER(TOF_NOTIFICATION, iwl_mvm_tof_resp_handler, true),
        RX_HANDLER_GRP(PROT_OFFLOAD_GROUP, STORED_BEACON_NTF,
                       iwl_mvm_rx_stored_beacon_notif, false),
+       RX_HANDLER_GRP(DATA_PATH_GROUP, MU_GROUP_MGMT_NOTIF,
+                      iwl_mvm_mu_mimo_grp_notif, false),
 
 };
 #undef RX_HANDLER
 static const struct iwl_hcmd_names iwl_mvm_data_path_names[] = {
        HCMD_NAME(UPDATE_MU_GROUPS_CMD),
        HCMD_NAME(TRIGGER_RX_QUEUES_NOTIF_CMD),
+       HCMD_NAME(MU_GROUP_MGMT_NOTIF),
        HCMD_NAME(RX_QUEUES_NOTIFICATION),
 };