wifi: iwlwifi: mvm: support wider-bandwidth OFDMA
authorJohannes Berg <johannes.berg@intel.com>
Sun, 18 Feb 2024 17:51:42 +0000 (19:51 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 21 Feb 2024 14:19:04 +0000 (15:19 +0100)
To support wider-bandwidth OFDMA we need to configure the
PHY context in the firmware, which will in turn configure
the DSP accordingly. Pass the relevant information down.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240218194912.ca666ede5dd6.I357972823d20e9045e2c97dbb7ac24fe9f5a6e41@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/d3.c
drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c
drivers/net/wireless/intel/iwlwifi/mvm/ftm-responder.c
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c

index b6a9896bce25394d338a464f0ff36aec78587613..9830a3c3600b94d25e39b56697c078a6a69c4d60 100644 (file)
@@ -720,7 +720,7 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
        struct ieee80211_chanctx_conf *ctx;
        u8 chains_static, chains_dynamic;
-       struct cfg80211_chan_def chandef;
+       struct cfg80211_chan_def chandef, ap_def;
        int ret, i;
        struct iwl_binding_cmd_v1 binding_cmd = {};
        struct iwl_time_quota_cmd quota_cmd = {};
@@ -742,12 +742,13 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                return -EINVAL;
        }
        chandef = ctx->def;
+       ap_def = ctx->ap;
        chains_static = ctx->rx_chains_static;
        chains_dynamic = ctx->rx_chains_dynamic;
        rcu_read_unlock();
 
        ret = iwl_mvm_phy_ctxt_add(mvm, mvmvif->deflink.phy_ctxt, &chandef,
-                                  chains_static, chains_dynamic);
+                                  &ap_def, chains_static, chains_dynamic);
        if (ret)
                return ret;
 
index aa3c9c2cbd7fc620636a089a711a52a867979412..51b01f7528beec1ec99c7a772bd372051e1463d1 100644 (file)
@@ -592,7 +592,7 @@ static ssize_t iwl_dbgfs_rx_phyinfo_write(struct ieee80211_vif *vif, char *buf,
 
        for_each_vif_active_link(vif, link_conf, link_id) {
                struct ieee80211_chanctx_conf *chanctx_conf;
-               struct cfg80211_chan_def min_def;
+               struct cfg80211_chan_def min_def, ap_def;
                struct iwl_mvm_phy_ctxt *phy_ctxt;
                u8 chains_static, chains_dynamic;
 
@@ -606,6 +606,7 @@ static ssize_t iwl_dbgfs_rx_phyinfo_write(struct ieee80211_vif *vif, char *buf,
                 * everything here and use it after unlocking
                 */
                min_def = chanctx_conf->min_def;
+               ap_def = chanctx_conf->ap;
                chains_static = chanctx_conf->rx_chains_static;
                chains_dynamic = chanctx_conf->rx_chains_dynamic;
                rcu_read_unlock();
@@ -614,7 +615,7 @@ static ssize_t iwl_dbgfs_rx_phyinfo_write(struct ieee80211_vif *vif, char *buf,
                if (!phy_ctxt)
                        continue;
 
-               ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &min_def,
+               ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &min_def, &ap_def,
                                               chains_static, chains_dynamic);
        }
 
index dca36b0662c73df0f58ce24b689bf16a375d6906..8e760300a1ab474af738eca2dc334588de4cee95 100644 (file)
@@ -438,7 +438,7 @@ int iwl_mvm_ftm_start_responder(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
        rcu_read_unlock();
 
        phy_ctxt = &mvm->phy_ctxts[*phy_ctxt_id];
-       ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx.def,
+       ret = iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, &ctx.def, &ctx.ap,
                                       ctx.rx_chains_static,
                                       ctx.rx_chains_dynamic);
        if (ret)
index 229d87a786df950ea9d5126375139a741bba7570..69f6a96b0cfbece46545f4bf29f0829aca65714c 100644 (file)
@@ -1644,6 +1644,9 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw,
                                     IEEE80211_VIF_SUPPORTS_CQM_RSSI;
        }
 
+       if (vif->p2p || iwl_fw_lookup_cmd_ver(mvm->fw, PHY_CONTEXT_CMD, 1) < 5)
+               vif->driver_flags |= IEEE80211_VIF_IGNORE_OFDMA_WIDER_BW;
+
        if (vif->type == NL80211_IFTYPE_P2P_DEVICE)
                mvm->p2p_device_vif = vif;
 
@@ -4651,7 +4654,7 @@ static int iwl_mvm_p2p_find_phy_ctxt(struct iwl_mvm *mvm,
        cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT);
 
        return iwl_mvm_phy_ctxt_add(mvm, mvmvif->deflink.phy_ctxt,
-                                   &chandef, 1, 1);
+                                   &chandef, NULL, 1, 1);
 }
 
 /* Execute the common part for MLD and non-MLD modes */
@@ -4772,7 +4775,7 @@ static int __iwl_mvm_add_chanctx(struct iwl_mvm *mvm,
                goto out;
        }
 
-       ret = iwl_mvm_phy_ctxt_add(mvm, phy_ctxt, def,
+       ret = iwl_mvm_phy_ctxt_add(mvm, phy_ctxt, def, &ctx->ap,
                                   ctx->rx_chains_static,
                                   ctx->rx_chains_dynamic);
        if (ret) {
@@ -4850,7 +4853,7 @@ void iwl_mvm_change_chanctx(struct ieee80211_hw *hw,
        }
 
        iwl_mvm_bt_coex_vif_change(mvm);
-       iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, def,
+       iwl_mvm_phy_ctxt_changed(mvm, phy_ctxt, def, &ctx->ap,
                                 ctx->rx_chains_static,
                                 ctx->rx_chains_dynamic);
 
index ce78c21883e927f50d35a7a4d70ef0db0016a001..fcae5199ac90b2d77b271215048b13575c7e4dca 100644 (file)
@@ -1810,9 +1810,11 @@ void iwl_mvm_rx_shared_mem_cfg_notif(struct iwl_mvm *mvm,
 struct iwl_mvm_phy_ctxt *iwl_mvm_get_free_phy_ctxt(struct iwl_mvm *mvm);
 int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
                         const struct cfg80211_chan_def *chandef,
+                        const struct cfg80211_chan_def *ap,
                         u8 chains_static, u8 chains_dynamic);
 int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
                             const struct cfg80211_chan_def *chandef,
+                            const struct cfg80211_chan_def *ap,
                             u8 chains_static, u8 chains_dynamic);
 void iwl_mvm_phy_ctxt_ref(struct iwl_mvm *mvm,
                          struct iwl_mvm_phy_ctxt *ctxt);
index bac655834f32fe2c0d643179314f396072da5309..e208e3c34c25433264c91e4363cc9ae6b76b03a6 100644 (file)
@@ -198,12 +198,16 @@ int iwl_mvm_phy_send_rlc(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
 static int iwl_mvm_phy_ctxt_apply(struct iwl_mvm *mvm,
                                  struct iwl_mvm_phy_ctxt *ctxt,
                                  const struct cfg80211_chan_def *chandef,
+                                 const struct cfg80211_chan_def *ap,
                                  u8 chains_static, u8 chains_dynamic,
                                  u32 action)
 {
        int ret;
        int ver = iwl_fw_lookup_cmd_ver(mvm->fw, PHY_CONTEXT_CMD, 1);
 
+       if (ver < 5 || !ap || !ap->chan)
+               ap = NULL;
+
        if (ver >= 3 && ver <= 5) {
                struct iwl_phy_context_cmd cmd = {};
 
@@ -215,6 +219,11 @@ static int iwl_mvm_phy_ctxt_apply(struct iwl_mvm *mvm,
                                          chains_static,
                                          chains_dynamic);
 
+               if (ap) {
+                       cmd.v5.sbb_bandwidth = iwl_mvm_get_channel_width(ap);
+                       cmd.v5.sbb_ctrl_channel_loc = iwl_mvm_get_ctrl_pos(ap);
+               }
+
                ret = iwl_mvm_send_cmd_pdu(mvm, PHY_CONTEXT_CMD,
                                           0, sizeof(cmd), &cmd);
        } else if (ver < 3) {
@@ -255,6 +264,7 @@ static int iwl_mvm_phy_ctxt_apply(struct iwl_mvm *mvm,
  */
 int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
                         const struct cfg80211_chan_def *chandef,
+                        const struct cfg80211_chan_def *ap,
                         u8 chains_static, u8 chains_dynamic)
 {
        int ret;
@@ -267,7 +277,7 @@ int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
        ctxt->width = chandef->width;
        ctxt->center_freq1 = chandef->center_freq1;
 
-       ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef,
+       ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, ap,
                                     chains_static, chains_dynamic,
                                     FW_CTXT_ACTION_ADD);
 
@@ -301,6 +311,7 @@ void iwl_mvm_phy_ctxt_ref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
  */
 int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
                             const struct cfg80211_chan_def *chandef,
+                            const struct cfg80211_chan_def *ap,
                             u8 chains_static, u8 chains_dynamic)
 {
        enum iwl_ctxt_action action = FW_CTXT_ACTION_MODIFY;
@@ -324,7 +335,7 @@ int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
                int ret;
 
                /* ... remove it here ...*/
-               ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef,
+               ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, NULL,
                                             chains_static, chains_dynamic,
                                             FW_CTXT_ACTION_REMOVE);
                if (ret)
@@ -338,7 +349,7 @@ int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
        ctxt->width = chandef->width;
        ctxt->center_freq1 = chandef->center_freq1;
 
-       return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef,
+       return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, ap,
                                      chains_static, chains_dynamic,
                                      action);
 }
@@ -358,7 +369,7 @@ void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt)
 
        cfg80211_chandef_create(&chandef, ctxt->channel, NL80211_CHAN_NO_HT);
 
-       iwl_mvm_phy_ctxt_apply(mvm, ctxt, &chandef, 1, 1,
+       iwl_mvm_phy_ctxt_apply(mvm, ctxt, &chandef, NULL, 1, 1,
                               FW_CTXT_ACTION_REMOVE);
 }