iwlwifi: mvm: support ADD_STA_CMD_API_S ver 12
authorNathan Errera <nathan.errera@intel.com>
Thu, 8 Oct 2020 15:09:47 +0000 (18:09 +0300)
committerKalle Valo <kvalo@codeaurora.org>
Thu, 8 Oct 2020 17:09:37 +0000 (20:09 +0300)
ADD_STA_CMD_API_S ver 12 was added in order to properly support
auxiliary activities in CDB NICs. In the new version we don't need
to allocate an aux station at initialization, instead we add an
aux station only when an auxiliary activity that requires a dedicated Tx
queue is needed. For now the only case we need this kind of activity is
when using hot spot 2.0

Signed-off-by: Nathan Errera <nathan.errera@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/iwlwifi.20201008180656.700e6e2e3077.Icdd807b6a3ad3fed806449ea0a13f856aa20e632@changeid
drivers/net/wireless/intel/iwlwifi/fw/api/sta.h
drivers/net/wireless/intel/iwlwifi/mvm/fw.c
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/scan.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.h
drivers/net/wireless/intel/iwlwifi/mvm/time-event.c

index c010e6febbf475e1ff349a81cf4e9864e8bd56dd..d43e0d3f3a12230ee9725f15269297c59c06e596 100644 (file)
@@ -380,7 +380,7 @@ struct iwl_mvm_add_sta_cmd {
        u8 add_modify;
        u8 awake_acs;
        __le16 tid_disable_tx;
-       __le32 mac_id_n_color;
+       __le32 mac_id_n_color;  /* can be used for lmac id when using cmd v12 */
        u8 addr[ETH_ALEN];      /* _STA_ID_MODIFY_INFO_API_S_VER_1 */
        __le16 reserved2;
        u8 sta_id;
index e665596a4d83b81ebe8137f64dccb4c70f19be10..80b52010d47b5e99200b0e2ab1a953ecbadb11ce 100644 (file)
@@ -1491,10 +1491,23 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
                        goto error;
        }
 
-       /* Add auxiliary station for scanning */
-       ret = iwl_mvm_add_aux_sta(mvm);
-       if (ret)
-               goto error;
+       /*
+        * Add auxiliary station for scanning.
+        * Newer versions of this command implies that the fw uses
+        * internal aux station for all aux activities that don't
+        * requires a dedicated data queue.
+        */
+       if (iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
+                                 ADD_STA,
+                                 0) < 12) {
+                /*
+                 * In old version the aux station uses mac id like other
+                 * station and not lmac id
+                 */
+               ret = iwl_mvm_add_aux_sta(mvm, MAC_INDEX_AUX);
+               if (ret)
+                       goto error;
+       }
 
        /* Add all the PHY contexts */
        i = 0;
@@ -1643,10 +1656,21 @@ int iwl_mvm_load_d3_fw(struct iwl_mvm *mvm)
        for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++)
                RCU_INIT_POINTER(mvm->fw_id_to_mac_id[i], NULL);
 
-       /* Add auxiliary station for scanning */
-       ret = iwl_mvm_add_aux_sta(mvm);
-       if (ret)
-               goto error;
+       if (iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
+                                 ADD_STA,
+                                 0) < 12) {
+               /*
+                * Add auxiliary station for scanning.
+                * Newer versions of this command implies that the fw uses
+                * internal aux station for all aux activities that don't
+                * requires a dedicated data queue.
+                * In old version the aux station uses mac id like other
+                * station and not lmac id
+                */
+               ret = iwl_mvm_add_aux_sta(mvm, MAC_INDEX_AUX);
+               if (ret)
+                       goto error;
+       }
 
        return 0;
  error:
index 79770b78122d2748cff5861fbc00bd15b09a045a..27b2a68c97f69df92edab0c36efbaf6c6f1ae477 100644 (file)
@@ -1223,7 +1223,8 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *mvm)
 
        /* async_handlers_wk is now blocked */
 
-       iwl_mvm_rm_aux_sta(mvm);
+       if (iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP, ADD_STA, 0) < 12)
+               iwl_mvm_rm_aux_sta(mvm);
 
        iwl_mvm_stop_device(mvm);
 
@@ -3804,6 +3805,17 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,
                if (fw_has_capa(&mvm->fw->ucode_capa,
                                IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT)) {
                        /* Use aux roc framework (HS20) */
+                       if (iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
+                                                 ADD_STA, 0) >= 12) {
+                               u32 lmac_id;
+
+                               lmac_id = iwl_mvm_get_lmac_id(mvm->fw,
+                                                             channel->band);
+                               ret = iwl_mvm_add_aux_sta(mvm, lmac_id);
+                               if (WARN(ret,
+                                        "Failed to allocate aux station"))
+                                       goto out_unlock;
+                       }
                        ret = iwl_mvm_send_aux_roc_cmd(mvm, channel,
                                                       vif, duration);
                        goto out_unlock;
index 1fbb527134930b54ad708ff678a01218a425eb50..875281cf7fc0978d89ba11523307c0d89849498e 100644 (file)
@@ -698,14 +698,28 @@ static void iwl_mvm_scan_fill_tx_cmd(struct iwl_mvm *mvm,
        tx_cmd[0].rate_n_flags = iwl_mvm_scan_rate_n_flags(mvm,
                                                           NL80211_BAND_2GHZ,
                                                           no_cck);
-       tx_cmd[0].sta_id = mvm->aux_sta.sta_id;
+
+       if (iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
+                                 ADD_STA,
+                                 0) < 12) {
+               tx_cmd[0].sta_id = mvm->aux_sta.sta_id;
+               tx_cmd[1].sta_id = mvm->aux_sta.sta_id;
+
+       /*
+        * Fw doesn't use this sta anymore, pending deprecation via HOST API
+        * change
+        */
+       } else {
+               tx_cmd[0].sta_id = 0xff;
+               tx_cmd[1].sta_id = 0xff;
+       }
 
        tx_cmd[1].tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL |
                                         TX_CMD_FLG_BT_DIS);
+
        tx_cmd[1].rate_n_flags = iwl_mvm_scan_rate_n_flags(mvm,
                                                           NL80211_BAND_5GHZ,
                                                           no_cck);
-       tx_cmd[1].sta_id = mvm->aux_sta.sta_id;
 }
 
 static void
@@ -1117,6 +1131,10 @@ static void iwl_mvm_fill_scan_config_v1(struct iwl_mvm *mvm, void *config,
 
        memcpy(&cfg->mac_addr, &mvm->addresses[0].addr, ETH_ALEN);
 
+       /* This function should not be called when using ADD_STA ver >=12 */
+       WARN_ON_ONCE(iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
+                                          ADD_STA, 0) >= 12);
+
        cfg->bcast_sta_id = mvm->aux_sta.sta_id;
        cfg->channel_flags = channel_flags;
 
@@ -1165,6 +1183,10 @@ static void iwl_mvm_fill_scan_config_v2(struct iwl_mvm *mvm, void *config,
 
        memcpy(&cfg->mac_addr, &mvm->addresses[0].addr, ETH_ALEN);
 
+       /* This function should not be called when using ADD_STA ver >=12 */
+       WARN_ON_ONCE(iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
+                                          ADD_STA, 0) >= 12);
+
        cfg->bcast_sta_id = mvm->aux_sta.sta_id;
        cfg->channel_flags = channel_flags;
 
@@ -1278,7 +1300,16 @@ int iwl_mvm_config_scan(struct iwl_mvm *mvm)
 
        memset(&cfg, 0, sizeof(cfg));
 
-       cfg.bcast_sta_id = mvm->aux_sta.sta_id;
+       if (iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
+                                 ADD_STA, 0) < 12)
+               cfg.bcast_sta_id = mvm->aux_sta.sta_id;
+       /*
+        * Fw doesn't use this sta anymore, pending deprecation via HOST API
+        * change.
+        */
+       else
+               cfg.bcast_sta_id = 0xff;
+
        cfg.tx_chains = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm));
        cfg.rx_chains = cpu_to_le32(iwl_mvm_scan_rx_ant(mvm));
 
index 4b2dcd60d4968d75e3e3195395afd5682d6ef1a6..017537944fd0353ad7d26d1f5ca4a5619ef16b4e 100644 (file)
@@ -1538,8 +1538,15 @@ static int iwl_mvm_add_int_sta_common(struct iwl_mvm *mvm,
 
        memset(&cmd, 0, sizeof(cmd));
        cmd.sta_id = sta->sta_id;
-       cmd.mac_id_n_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mac_id,
-                                                            color));
+
+       if (iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP, ADD_STA,
+                                 0) >= 12 &&
+           sta->type == IWL_STA_AUX_ACTIVITY)
+               cmd.mac_id_n_color = cpu_to_le32(mac_id);
+       else
+               cmd.mac_id_n_color = cpu_to_le32(FW_CMD_ID_AND_COLOR(mac_id,
+                                                                    color));
+
        if (fw_has_api(&mvm->fw->ucode_capa, IWL_UCODE_TLV_API_STA_TYPE))
                cmd.station_type = sta->type;
 
@@ -2032,7 +2039,7 @@ static int iwl_mvm_add_int_sta_with_queue(struct iwl_mvm *mvm, int macidx,
        return 0;
 }
 
-int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
+int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm, u32 lmac_id)
 {
        int ret;
 
@@ -2045,7 +2052,11 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm)
        if (ret)
                return ret;
 
-       ret = iwl_mvm_add_int_sta_with_queue(mvm, MAC_INDEX_AUX, 0, NULL,
+       /*
+        * In CDB NICs we need to specify which lmac to use for aux activity
+        * using the mac_id argument place to send lmac_id to the function
+        */
+       ret = iwl_mvm_add_int_sta_with_queue(mvm, lmac_id, 0, NULL,
                                             &mvm->aux_sta, &mvm->aux_queue,
                                             IWL_MVM_TX_FIFO_MCAST);
        if (ret) {
index 7b4120ce208c726cf341ccc09d3ddd215c6c0d42..d7578c981a653ce6865b5e9e6ab5bc7c66fd6751 100644 (file)
@@ -540,7 +540,7 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 int iwl_mvm_sta_tx_agg(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
                       int tid, u8 queue, bool start);
 
-int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm);
+int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm, u32 lmac_id);
 int iwl_mvm_rm_aux_sta(struct iwl_mvm *mvm);
 
 int iwl_mvm_alloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
@@ -582,5 +582,4 @@ void iwl_mvm_add_new_dqa_stream_wk(struct work_struct *wk);
 int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                         struct iwl_mvm_int_sta *sta, u8 *addr, u32 cipher,
                         u8 *key, u32 key_len);
-
 #endif /* __sta_h__ */
index 3a57a260081aade1660b8befd92e8853da84edef..7ad6c9ab4737b352a4d9ac1e5b1384161d87a9c8 100644 (file)
@@ -134,6 +134,12 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk)
        } else {
                /* do the same in case of hot spot 2.0 */
                iwl_mvm_flush_sta(mvm, &mvm->aux_sta, true);
+               /* In newer version of this command an aux station is added only
+                * in cases of dedicated tx queue and need to be removed in end
+                * of use */
+               if (iwl_fw_lookup_cmd_ver(mvm->fw, LONG_GROUP,
+                                         ADD_STA, 0) >= 12)
+                       iwl_mvm_rm_aux_sta(mvm);
        }
 
        mutex_unlock(&mvm->mutex);