iwlwifi: mvm: update firmware of VHT MU-MIMO groups status on restart
authorSara Sharon <sara.sharon@intel.com>
Sun, 15 Nov 2015 09:11:59 +0000 (11:11 +0200)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Sat, 27 Feb 2016 19:59:59 +0000 (21:59 +0200)
The firmware handles the VHT MU-MIMO group data on its own.
However, on HW restart (and future sniffer mode) the driver
shall update the firmware on the VHT MU-MIMO group membership
status.

Signed-off-by: Sara Sharon <sara.sharon@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c

index d5f90371054e83f94123d94cbe9b4022d50c4781..ca7fec71854f0480bd67521325728f9da3635bf0 100644 (file)
@@ -285,6 +285,10 @@ enum iwl_phy_ops_subcmd_ids {
        DTS_MEASUREMENT_NOTIF_WIDE = 0xFF,
 };
 
+enum iwl_data_path_subcmd_ids {
+       UPDATE_MU_GROUPS_CMD = 0x1,
+};
+
 enum iwl_prot_offload_subcmd_ids {
        STORED_BEACON_NTF = 0xFF,
 };
@@ -294,6 +298,7 @@ enum {
        LEGACY_GROUP = 0x0,
        LONG_GROUP = 0x1,
        PHY_OPS_GROUP = 0x4,
+       DATA_PATH_GROUP = 0x5,
        PROT_OFFLOAD_GROUP = 0xb,
 };
 
@@ -1923,6 +1928,19 @@ struct iwl_shared_mem_cfg {
        __le32 page_buff_size;
 } __packed; /* SHARED_MEM_ALLOC_API_S_VER_1 */
 
+/**
+ * VHT MU-MIMO group configuration
+ *
+ * @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_cmd {
+       __le32 reserved;
+       __le32 membership_status[2];
+       __le32 user_position[4];
+} __packed; /* MU_GROUP_ID_MNG_TABLE_API_S_VER_1 */
+
 #define MAX_STORED_BEACON_SIZE 600
 
 /**
index 53156810185d432a1192061ee1c39ede81112a40..f1ed90bc27408f0a8acbc3a72796a7123d7554a8 100644 (file)
@@ -1762,6 +1762,22 @@ static inline int iwl_mvm_configure_bcast_filter(struct iwl_mvm *mvm)
 }
 #endif
 
+static int iwl_mvm_update_mu_groups(struct iwl_mvm *mvm,
+                                   struct ieee80211_vif *vif)
+{
+       struct iwl_mu_group_mgmt_cmd cmd = {};
+
+       memcpy(cmd.membership_status, vif->bss_conf.mu_group.membership,
+              WLAN_MEMBERSHIP_LEN);
+       memcpy(cmd.user_position, vif->bss_conf.mu_group.position,
+              WLAN_USER_POSITION_LEN);
+
+       return iwl_mvm_send_cmd_pdu(mvm,
+                                   WIDE_ID(DATA_PATH_GROUP,
+                                           UPDATE_MU_GROUPS_CMD),
+                                   0, sizeof(cmd), &cmd);
+}
+
 static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
                                             struct ieee80211_vif *vif,
                                             struct ieee80211_bss_conf *bss_conf,
@@ -1870,6 +1886,18 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
                                        vif->addr);
                }
 
+               /*
+                * The firmware tracks the MU-MIMO group on its own.
+                * 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) {
+                       ret = iwl_mvm_update_mu_groups(mvm, vif);
+                       if (ret)
+                               IWL_ERR(mvm,
+                                       "failed to update VHT MU_MIMO groups\n");
+               }
+
                iwl_mvm_recalc_multicast(mvm);
                iwl_mvm_configure_bcast_filter(mvm);