]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
iwlwifi: mvm: support VHT MU-MIMO notification
authorSara Sharon <sara.sharon@intel.com>
Wed, 3 Feb 2016 13:04:49 +0000 (15:04 +0200)
committerEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Sat, 27 Feb 2016 20:00:11 +0000 (22:00 +0200)
When the device is in d0i3/d3 we will not receive the VHT
MU-MIMO group id management frame. Instead, firmware will
notify us upon exit on the current status and we can in turn
update mac80211. Support this notification.
While at it, also check as a precaution that the vif is indeed
the VHT MU-MIMO owner before updating the firmware.

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
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/ops.c

index f432ddd4cde3f3442bb1c36e718d306a1d259370..4a0fc47c81f2fad865af95ae579e9dfef50cca34 100644 (file)
@@ -290,6 +290,7 @@ enum iwl_phy_ops_subcmd_ids {
 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,
 };
 
@@ -1965,6 +1966,18 @@ struct iwl_mu_group_mgmt_cmd {
        __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
 
 /**
index 1a4946fc9b276cf785c29162bf987233f37da775..b7551610f37eb314a8ff707b7c47ab913dd6bdb5 100644 (file)
@@ -7,6 +7,7 @@
  *
  * 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
@@ -1780,6 +1781,34 @@ static int iwl_mvm_update_mu_groups(struct iwl_mvm *mvm,
                                    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 *)&notif->membership_status,
+                                          (u8 *)&notif->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,
@@ -1890,10 +1919,10 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
 
                /*
                 * 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,
index f05d2a1f44673cc14937192fb8dfd830a24b9d7b..21986f63682e8b08e1565179c56ca86ea988bd91 100644 (file)
@@ -1272,6 +1272,8 @@ void iwl_mvm_rx_missed_beacons_notif(struct iwl_mvm *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,
index ac271ffe477b727beb7620386e4db873fb7697b1..8bdaa7b27ab18ece925924b8c96215a7597f6e36 100644 (file)
@@ -275,6 +275,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
        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
@@ -405,6 +407,7 @@ static const struct iwl_hcmd_names iwl_mvm_phy_names[] = {
 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),
 };