From 55eb1c5fa4b260491d8be3299d4546d0b34465f4 Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Tue, 14 Mar 2023 19:49:19 +0200 Subject: wifi: iwlwifi: mvm: add support for the new LINK command As a part of the new MLD FW API changes, we have a new LINK command to add/remove/configure a link. Add structures and enum definitions, along with the functions that sends this command (i.e. add, remove and change mac ctxt). These functions will be in used in the next patches. Signed-off-by: Miri Korenblit Signed-off-by: Gregory Greenman Link: https://lore.kernel.org/r/20230314194113.d7808329effb.I13bea2db206b78540bc866bc3ab755ad5be78c53@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/link.c | 175 ++++++++++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 drivers/net/wireless/intel/iwlwifi/mvm/link.c (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/link.c') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/link.c b/drivers/net/wireless/intel/iwlwifi/mvm/link.c new file mode 100644 index 000000000000..2688cb49c951 --- /dev/null +++ b/drivers/net/wireless/intel/iwlwifi/mvm/link.c @@ -0,0 +1,175 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* + * Copyright (C) 2022 Intel Corporation + */ +#include "mvm.h" + +static int iwl_mvm_link_cmd_send(struct iwl_mvm *mvm, + struct iwl_link_config_cmd *cmd, + enum iwl_ctxt_action action) +{ + int ret; + + cmd->action = cpu_to_le32(action); + ret = iwl_mvm_send_cmd_pdu(mvm, + WIDE_ID(MAC_CONF_GROUP, LINK_CONFIG_CMD), 0, + sizeof(*cmd), cmd); + if (ret) + IWL_ERR(mvm, "Failed to send LINK_CONFIG_CMD (action:%d): %d\n", + action, ret); + return ret; +} + +int iwl_mvm_add_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif) +{ + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + struct iwl_link_config_cmd cmd = {}; + + if (WARN_ON_ONCE(!mvmvif->phy_ctxt)) + return -EINVAL; + + /* Update SF - Disable if needed. if this fails, SF might still be on + * while many macs are bound, which is forbidden - so fail the binding. + */ + if (iwl_mvm_sf_update(mvm, vif, false)) + return -EINVAL; + + cmd.link_id = cpu_to_le32(mvmvif->phy_ctxt->id); + cmd.mac_id = cpu_to_le32(mvmvif->id); + cmd.phy_id = cpu_to_le32(mvmvif->phy_ctxt->id); + + memcpy(cmd.local_link_addr, vif->addr, ETH_ALEN); + + return iwl_mvm_link_cmd_send(mvm, &cmd, FW_CTXT_ACTION_ADD); +} + +int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + u32 changes, bool active) +{ + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + struct iwl_mvm_phy_ctxt *phyctxt = mvmvif->phy_ctxt; + struct iwl_link_config_cmd cmd = {}; + u32 ht_flag, flags = 0, flags_mask = 0; + + if (!phyctxt) + return -EINVAL; + + cmd.link_id = cpu_to_le32(phyctxt->id); + + /* The phy_id, link address and listen_lmac can be modified only until + * the link becomes active, otherwise they will be ignored. + */ + cmd.phy_id = cpu_to_le32(phyctxt->id); + cmd.mac_id = cpu_to_le32(mvmvif->id); + + memcpy(cmd.local_link_addr, vif->addr, ETH_ALEN); + + cmd.active = cpu_to_le32(active); + + /* TODO: set a value to cmd.listen_lmac when system requiremens + * will define it + */ + + iwl_mvm_set_fw_basic_rates(mvm, vif, &cmd.cck_rates, &cmd.ofdm_rates); + + cmd.cck_short_preamble = cpu_to_le32(vif->bss_conf.use_short_preamble); + cmd.short_slot = cpu_to_le32(vif->bss_conf.use_short_slot); + + /* The fw does not distinguish between ht and fat */ + ht_flag = LINK_PROT_FLG_HT_PROT | LINK_PROT_FLG_FAT_PROT; + iwl_mvm_set_fw_protection_flags(mvm, vif, &cmd.protection_flags, + ht_flag, LINK_PROT_FLG_TGG_PROTECT); + + iwl_mvm_set_fw_qos_params(mvm, vif, &cmd.ac[0], &cmd.qos_flags); + + /* We need the dtim_period to set the MAC as associated */ + if (vif->cfg.assoc && vif->bss_conf.dtim_period) + iwl_mvm_set_fw_dtim_tbtt(mvm, vif, &cmd.dtim_tsf, + &cmd.dtim_time, + &cmd.assoc_beacon_arrive_time); + else + changes &= ~LINK_CONTEXT_MODIFY_BEACON_TIMING; + + cmd.bi = cpu_to_le32(vif->bss_conf.beacon_int); + cmd.dtim_interval = cpu_to_le32(vif->bss_conf.beacon_int * + vif->bss_conf.dtim_period); + + /* TODO: Assumes that the beacon id == mac context id */ + cmd.beacon_template = cpu_to_le32(mvmvif->id); + + if (!vif->bss_conf.he_support || iwlwifi_mod_params.disable_11ax || + !vif->cfg.assoc) { + changes &= ~LINK_CONTEXT_MODIFY_HE_PARAMS; + goto send_cmd; + } + + cmd.htc_trig_based_pkt_ext = vif->bss_conf.htc_trig_based_pkt_ext; + + if (vif->bss_conf.uora_exists) { + cmd.rand_alloc_ecwmin = + vif->bss_conf.uora_ocw_range & 0x7; + cmd.rand_alloc_ecwmax = + (vif->bss_conf.uora_ocw_range >> 3) & 0x7; + } + + /* TODO how to set ndp_fdbk_buff_th_exp? */ + + if (iwl_mvm_set_fw_mu_edca_params(mvm, mvmvif, + &cmd.trig_based_txf[0])) { + flags |= LINK_FLG_MU_EDCA_CW; + flags_mask |= LINK_FLG_MU_EDCA_CW; + } + + if (vif->bss_conf.eht_puncturing && !iwlwifi_mod_params.disable_11be) + cmd.puncture_mask = cpu_to_le16(vif->bss_conf.eht_puncturing); + else + /* This flag can be set only if the MAC has eht support */ + changes &= ~LINK_CONTEXT_MODIFY_EHT_PARAMS; + + cmd.bss_color = vif->bss_conf.he_bss_color.color; + + if (!vif->bss_conf.he_bss_color.enabled) { + flags |= LINK_FLG_BSS_COLOR_DIS; + flags_mask |= LINK_FLG_BSS_COLOR_DIS; + } + + cmd.frame_time_rts_th = cpu_to_le16(vif->bss_conf.frame_time_rts_th); + + /* Block 26-tone RU OFDMA transmissions */ + if (mvmvif->he_ru_2mhz_block) { + flags |= LINK_FLG_RU_2MHZ_BLOCK; + flags_mask |= LINK_FLG_RU_2MHZ_BLOCK; + } + + if (vif->bss_conf.nontransmitted) { + ether_addr_copy(cmd.ref_bssid_addr, + vif->bss_conf.transmitter_bssid); + cmd.bssid_index = vif->bss_conf.bssid_index; + } + +send_cmd: + cmd.modify_mask = cpu_to_le32(changes); + cmd.flags = cpu_to_le32(flags); + cmd.flags_mask = cpu_to_le32(flags_mask); + + return iwl_mvm_link_cmd_send(mvm, &cmd, FW_CTXT_ACTION_MODIFY); +} + +int iwl_mvm_remove_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif) +{ + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + struct iwl_link_config_cmd cmd = {}; + int ret; + + if (WARN_ON_ONCE(!mvmvif->phy_ctxt)) + return -EINVAL; + + cmd.link_id = cpu_to_le32(mvmvif->phy_ctxt->id); + ret = iwl_mvm_link_cmd_send(mvm, &cmd, FW_CTXT_ACTION_REMOVE); + + if (!ret) + if (iwl_mvm_sf_update(mvm, vif, true)) + IWL_ERR(mvm, "Failed to update SF state\n"); + + return ret; +} -- cgit From 650cadb730105f1894b6c8afacc57a368dd18b91 Mon Sep 17 00:00:00 2001 From: Gregory Greenman Date: Tue, 28 Mar 2023 10:58:41 +0300 Subject: wifi: iwlwifi: mvm: vif preparation for MLO In MLO, some fields of iwl_mvm_vif should be defined in the context of a link. Define a separate structure for these fields and add a deflink object to hold it as part of iwl_mvm_vif. Non-MLO legacy code will use only deflink object while MLO related code will use the corresponding link from the link array. It follows the strategy applied in mac80211 for introducing MLO changes. The below spatch takes care of updating all driver code to access fields separated into MLD specific data structure via deflink (need to convert all references to the fields listed in var to deflink.var and also to take care of calls like iwl_mvm_vif_from_mac80211(vif)->field). @iwl_mld_vif@ struct iwl_mvm_vif *v; struct ieee80211_vif *vv; identifier fn; identifier var = {bssid, ap_sta_id, bcast_sta, mcast_sta, beacon_stats, smps_requests, probe_resp_data, he_ru_2mhz_block, cab_queue, phy_ctxt, queue_params}; @@ ( v-> - var + deflink.var | fn(vv)-> - var + deflink.var ) Signed-off-by: Gregory Greenman Link: https://lore.kernel.org/r/20230328104948.4896576f0a9f.Ifaf0187c96b9fe52b24bd629331165831a877691@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/link.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/link.c') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/link.c b/drivers/net/wireless/intel/iwlwifi/mvm/link.c index 2688cb49c951..21e45f89c5f9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/link.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/link.c @@ -25,7 +25,7 @@ int iwl_mvm_add_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif) struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); struct iwl_link_config_cmd cmd = {}; - if (WARN_ON_ONCE(!mvmvif->phy_ctxt)) + if (WARN_ON_ONCE(!mvmvif->deflink.phy_ctxt)) return -EINVAL; /* Update SF - Disable if needed. if this fails, SF might still be on @@ -34,9 +34,9 @@ int iwl_mvm_add_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif) if (iwl_mvm_sf_update(mvm, vif, false)) return -EINVAL; - cmd.link_id = cpu_to_le32(mvmvif->phy_ctxt->id); + cmd.link_id = cpu_to_le32(mvmvif->deflink.phy_ctxt->id); cmd.mac_id = cpu_to_le32(mvmvif->id); - cmd.phy_id = cpu_to_le32(mvmvif->phy_ctxt->id); + cmd.phy_id = cpu_to_le32(mvmvif->deflink.phy_ctxt->id); memcpy(cmd.local_link_addr, vif->addr, ETH_ALEN); @@ -47,7 +47,7 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, u32 changes, bool active) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - struct iwl_mvm_phy_ctxt *phyctxt = mvmvif->phy_ctxt; + struct iwl_mvm_phy_ctxt *phyctxt = mvmvif->deflink.phy_ctxt; struct iwl_link_config_cmd cmd = {}; u32 ht_flag, flags = 0, flags_mask = 0; @@ -136,7 +136,7 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, cmd.frame_time_rts_th = cpu_to_le16(vif->bss_conf.frame_time_rts_th); /* Block 26-tone RU OFDMA transmissions */ - if (mvmvif->he_ru_2mhz_block) { + if (mvmvif->deflink.he_ru_2mhz_block) { flags |= LINK_FLG_RU_2MHZ_BLOCK; flags_mask |= LINK_FLG_RU_2MHZ_BLOCK; } @@ -161,10 +161,10 @@ int iwl_mvm_remove_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif) struct iwl_link_config_cmd cmd = {}; int ret; - if (WARN_ON_ONCE(!mvmvif->phy_ctxt)) + if (WARN_ON_ONCE(!mvmvif->deflink.phy_ctxt)) return -EINVAL; - cmd.link_id = cpu_to_le32(mvmvif->phy_ctxt->id); + cmd.link_id = cpu_to_le32(mvmvif->deflink.phy_ctxt->id); ret = iwl_mvm_link_cmd_send(mvm, &cmd, FW_CTXT_ACTION_REMOVE); if (!ret) -- cgit From 6b5a87df8ec8e3e24ffde62b1356aad9b4e9182d Mon Sep 17 00:00:00 2001 From: Miri Korenblit Date: Tue, 28 Mar 2023 10:58:55 +0300 Subject: wifi: iwlwifi: mvm: align to the LINK cmd update in the FW The LINK cmd host api has been updated. Align the driver to the new changes. Also, temporary use mac_id for link_id. Using the phy_id as the link_id is wrong since we might have 2 macs operating on the same phy - in this case we will have 2 different links (one for each mac) with the same link_id. On the other hand, since we don't have MLO implemented yet, we won't have 2 different links of the same mac. Therefore, we can use the mac_id as the link_id. Signed-off-by: Miri Korenblit Signed-off-by: Gregory Greenman Link: https://lore.kernel.org/r/20230328104948.78ae716884fe.Icfeb2794d9652baaccf9b0cdddbd751d0db4f952@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/link.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/link.c') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/link.c b/drivers/net/wireless/intel/iwlwifi/mvm/link.c index 21e45f89c5f9..4905dac3a048 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/link.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/link.c @@ -34,12 +34,15 @@ int iwl_mvm_add_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif) if (iwl_mvm_sf_update(mvm, vif, false)) return -EINVAL; - cmd.link_id = cpu_to_le32(mvmvif->deflink.phy_ctxt->id); + cmd.link_id = cpu_to_le32(mvmvif->id); cmd.mac_id = cpu_to_le32(mvmvif->id); cmd.phy_id = cpu_to_le32(mvmvif->deflink.phy_ctxt->id); memcpy(cmd.local_link_addr, vif->addr, ETH_ALEN); + if (vif->type == NL80211_IFTYPE_ADHOC && vif->bss_conf.bssid) + memcpy(cmd.ibss_bssid_addr, vif->bss_conf.bssid, ETH_ALEN); + return iwl_mvm_link_cmd_send(mvm, &cmd, FW_CTXT_ACTION_ADD); } @@ -54,7 +57,7 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, if (!phyctxt) return -EINVAL; - cmd.link_id = cpu_to_le32(phyctxt->id); + cmd.link_id = cpu_to_le32(mvmvif->id); /* The phy_id, link address and listen_lmac can be modified only until * the link becomes active, otherwise they will be ignored. @@ -66,6 +69,9 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, cmd.active = cpu_to_le32(active); + if (vif->type == NL80211_IFTYPE_ADHOC && vif->bss_conf.bssid) + memcpy(cmd.ibss_bssid_addr, vif->bss_conf.bssid, ETH_ALEN); + /* TODO: set a value to cmd.listen_lmac when system requiremens * will define it */ @@ -82,21 +88,11 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, iwl_mvm_set_fw_qos_params(mvm, vif, &cmd.ac[0], &cmd.qos_flags); - /* We need the dtim_period to set the MAC as associated */ - if (vif->cfg.assoc && vif->bss_conf.dtim_period) - iwl_mvm_set_fw_dtim_tbtt(mvm, vif, &cmd.dtim_tsf, - &cmd.dtim_time, - &cmd.assoc_beacon_arrive_time); - else - changes &= ~LINK_CONTEXT_MODIFY_BEACON_TIMING; cmd.bi = cpu_to_le32(vif->bss_conf.beacon_int); cmd.dtim_interval = cpu_to_le32(vif->bss_conf.beacon_int * vif->bss_conf.dtim_period); - /* TODO: Assumes that the beacon id == mac context id */ - cmd.beacon_template = cpu_to_le32(mvmvif->id); - if (!vif->bss_conf.he_support || iwlwifi_mod_params.disable_11ax || !vif->cfg.assoc) { changes &= ~LINK_CONTEXT_MODIFY_HE_PARAMS; @@ -164,7 +160,7 @@ int iwl_mvm_remove_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif) if (WARN_ON_ONCE(!mvmvif->deflink.phy_ctxt)) return -EINVAL; - cmd.link_id = cpu_to_le32(mvmvif->deflink.phy_ctxt->id); + cmd.link_id = cpu_to_le32(mvmvif->id); ret = iwl_mvm_link_cmd_send(mvm, &cmd, FW_CTXT_ACTION_REMOVE); if (!ret) -- cgit From cb145863e7abbbf4248ab11d2783a1b619349d1b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 28 Mar 2023 10:58:59 +0300 Subject: wifi: iwlwifi: mvm: add link to firmware earlier The firmware now allows adding a link that's not yet bound to a PHY context. Make use of that to align the driver with mac80211's API expectations. For now, just add the link at the same time as the MAC since we don't yet have real MLD support, but that'll obviously change later. This fixes an issue with apStaId tracking in the firmware. Signed-off-by: Johannes Berg Signed-off-by: Gregory Greenman Link: https://lore.kernel.org/r/20230328104949.097e5008b637.I4e75c6c11e21c08d28ff6a066be36629d3975db6@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/link.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/link.c') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/link.c b/drivers/net/wireless/intel/iwlwifi/mvm/link.c index 4905dac3a048..d8902e0ed2ae 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/link.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/link.c @@ -23,11 +23,9 @@ static int iwl_mvm_link_cmd_send(struct iwl_mvm *mvm, int iwl_mvm_add_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + struct iwl_mvm_phy_ctxt *phyctxt = mvmvif->deflink.phy_ctxt; struct iwl_link_config_cmd cmd = {}; - if (WARN_ON_ONCE(!mvmvif->deflink.phy_ctxt)) - return -EINVAL; - /* Update SF - Disable if needed. if this fails, SF might still be on * while many macs are bound, which is forbidden - so fail the binding. */ @@ -36,7 +34,11 @@ int iwl_mvm_add_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif) cmd.link_id = cpu_to_le32(mvmvif->id); cmd.mac_id = cpu_to_le32(mvmvif->id); - cmd.phy_id = cpu_to_le32(mvmvif->deflink.phy_ctxt->id); + /* P2P-Device already has a valid PHY context during add */ + if (phyctxt) + cmd.phy_id = cpu_to_le32(phyctxt->id); + else + cmd.phy_id = cpu_to_le32(FW_CTXT_INVALID); memcpy(cmd.local_link_addr, vif->addr, ETH_ALEN); @@ -54,15 +56,15 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct iwl_link_config_cmd cmd = {}; u32 ht_flag, flags = 0, flags_mask = 0; - if (!phyctxt) - return -EINVAL; - cmd.link_id = cpu_to_le32(mvmvif->id); /* The phy_id, link address and listen_lmac can be modified only until * the link becomes active, otherwise they will be ignored. */ - cmd.phy_id = cpu_to_le32(phyctxt->id); + if (phyctxt) + cmd.phy_id = cpu_to_le32(phyctxt->id); + else + cmd.phy_id = cpu_to_le32(FW_CTXT_INVALID); cmd.mac_id = cpu_to_le32(mvmvif->id); memcpy(cmd.local_link_addr, vif->addr, ETH_ALEN); @@ -157,9 +159,6 @@ int iwl_mvm_remove_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif) struct iwl_link_config_cmd cmd = {}; int ret; - if (WARN_ON_ONCE(!mvmvif->deflink.phy_ctxt)) - return -EINVAL; - cmd.link_id = cpu_to_le32(mvmvif->id); ret = iwl_mvm_link_cmd_send(mvm, &cmd, FW_CTXT_ACTION_REMOVE); -- cgit From cacc1d42a489f6f61cd5bdc42d216ec29b144317 Mon Sep 17 00:00:00 2001 From: Gregory Greenman Date: Tue, 28 Mar 2023 10:59:03 +0300 Subject: wifi: iwlwifi: mvm: add link_conf parameter for add/remove/change link Add link_conf parameter and change all the relevant calls accordingly. Signed-off-by: Gregory Greenman Link: https://lore.kernel.org/r/20230328104949.374015eed2e3.Icbf15a18e2599b53f4fa1c92fe3db64b551b84b1@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/link.c | 81 +++++++++++++++++---------- 1 file changed, 50 insertions(+), 31 deletions(-) (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/link.c') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/link.c b/drivers/net/wireless/intel/iwlwifi/mvm/link.c index d8902e0ed2ae..bbaac2ba9079 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/link.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/link.c @@ -20,11 +20,16 @@ static int iwl_mvm_link_cmd_send(struct iwl_mvm *mvm, return ret; } -int iwl_mvm_add_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif) +int iwl_mvm_add_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - struct iwl_mvm_phy_ctxt *phyctxt = mvmvif->deflink.phy_ctxt; + unsigned int link_id = link_conf->link_id; struct iwl_link_config_cmd cmd = {}; + struct iwl_mvm_phy_ctxt *phyctxt; + + if (WARN_ON_ONCE(!mvmvif->link[link_id])) + return -EINVAL; /* Update SF - Disable if needed. if this fails, SF might still be on * while many macs are bound, which is forbidden - so fail the binding. @@ -32,82 +37,94 @@ int iwl_mvm_add_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif) if (iwl_mvm_sf_update(mvm, vif, false)) return -EINVAL; + /* FIXME: add proper link id allocation */ cmd.link_id = cpu_to_le32(mvmvif->id); cmd.mac_id = cpu_to_le32(mvmvif->id); /* P2P-Device already has a valid PHY context during add */ + phyctxt = mvmvif->link[link_id]->phy_ctxt; if (phyctxt) cmd.phy_id = cpu_to_le32(phyctxt->id); else cmd.phy_id = cpu_to_le32(FW_CTXT_INVALID); - memcpy(cmd.local_link_addr, vif->addr, ETH_ALEN); + memcpy(cmd.local_link_addr, link_conf->addr, ETH_ALEN); - if (vif->type == NL80211_IFTYPE_ADHOC && vif->bss_conf.bssid) - memcpy(cmd.ibss_bssid_addr, vif->bss_conf.bssid, ETH_ALEN); + if (vif->type == NL80211_IFTYPE_ADHOC && link_conf->bssid) + memcpy(cmd.ibss_bssid_addr, link_conf->bssid, ETH_ALEN); return iwl_mvm_link_cmd_send(mvm, &cmd, FW_CTXT_ACTION_ADD); } int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf, u32 changes, bool active) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); - struct iwl_mvm_phy_ctxt *phyctxt = mvmvif->deflink.phy_ctxt; + unsigned int link_id = link_conf->link_id; + struct iwl_mvm_phy_ctxt *phyctxt; struct iwl_link_config_cmd cmd = {}; u32 ht_flag, flags = 0, flags_mask = 0; + if (WARN_ON_ONCE(!mvmvif->link[link_id])) + return -EINVAL; + + /* FIXME: add proper link id allocation */ cmd.link_id = cpu_to_le32(mvmvif->id); /* The phy_id, link address and listen_lmac can be modified only until * the link becomes active, otherwise they will be ignored. */ + phyctxt = mvmvif->link[link_id]->phy_ctxt; if (phyctxt) cmd.phy_id = cpu_to_le32(phyctxt->id); else cmd.phy_id = cpu_to_le32(FW_CTXT_INVALID); cmd.mac_id = cpu_to_le32(mvmvif->id); - memcpy(cmd.local_link_addr, vif->addr, ETH_ALEN); + memcpy(cmd.local_link_addr, link_conf->addr, ETH_ALEN); cmd.active = cpu_to_le32(active); - if (vif->type == NL80211_IFTYPE_ADHOC && vif->bss_conf.bssid) - memcpy(cmd.ibss_bssid_addr, vif->bss_conf.bssid, ETH_ALEN); + if (vif->type == NL80211_IFTYPE_ADHOC && link_conf->bssid) + memcpy(cmd.ibss_bssid_addr, link_conf->bssid, ETH_ALEN); /* TODO: set a value to cmd.listen_lmac when system requiremens * will define it */ - iwl_mvm_set_fw_basic_rates(mvm, vif, &cmd.cck_rates, &cmd.ofdm_rates); + iwl_mvm_set_fw_basic_rates(mvm, vif, link_conf, + &cmd.cck_rates, &cmd.ofdm_rates); - cmd.cck_short_preamble = cpu_to_le32(vif->bss_conf.use_short_preamble); - cmd.short_slot = cpu_to_le32(vif->bss_conf.use_short_slot); + cmd.cck_short_preamble = cpu_to_le32(link_conf->use_short_preamble); + cmd.short_slot = cpu_to_le32(link_conf->use_short_slot); /* The fw does not distinguish between ht and fat */ ht_flag = LINK_PROT_FLG_HT_PROT | LINK_PROT_FLG_FAT_PROT; - iwl_mvm_set_fw_protection_flags(mvm, vif, &cmd.protection_flags, + iwl_mvm_set_fw_protection_flags(mvm, vif, link_conf, + &cmd.protection_flags, ht_flag, LINK_PROT_FLG_TGG_PROTECT); - iwl_mvm_set_fw_qos_params(mvm, vif, &cmd.ac[0], &cmd.qos_flags); + iwl_mvm_set_fw_qos_params(mvm, vif, link_conf, &cmd.ac[0], + &cmd.qos_flags); - cmd.bi = cpu_to_le32(vif->bss_conf.beacon_int); - cmd.dtim_interval = cpu_to_le32(vif->bss_conf.beacon_int * - vif->bss_conf.dtim_period); + cmd.bi = cpu_to_le32(link_conf->beacon_int); + cmd.dtim_interval = cpu_to_le32(link_conf->beacon_int * + link_conf->dtim_period); - if (!vif->bss_conf.he_support || iwlwifi_mod_params.disable_11ax || + if (!link_conf->he_support || iwlwifi_mod_params.disable_11ax || !vif->cfg.assoc) { changes &= ~LINK_CONTEXT_MODIFY_HE_PARAMS; goto send_cmd; } - cmd.htc_trig_based_pkt_ext = vif->bss_conf.htc_trig_based_pkt_ext; + cmd.htc_trig_based_pkt_ext = link_conf->htc_trig_based_pkt_ext; - if (vif->bss_conf.uora_exists) { + if (link_conf->uora_exists) { cmd.rand_alloc_ecwmin = - vif->bss_conf.uora_ocw_range & 0x7; + link_conf->uora_ocw_range & 0x7; cmd.rand_alloc_ecwmax = - (vif->bss_conf.uora_ocw_range >> 3) & 0x7; + (link_conf->uora_ocw_range >> 3) & 0x7; } /* TODO how to set ndp_fdbk_buff_th_exp? */ @@ -118,20 +135,20 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, flags_mask |= LINK_FLG_MU_EDCA_CW; } - if (vif->bss_conf.eht_puncturing && !iwlwifi_mod_params.disable_11be) - cmd.puncture_mask = cpu_to_le16(vif->bss_conf.eht_puncturing); + if (link_conf->eht_puncturing && !iwlwifi_mod_params.disable_11be) + cmd.puncture_mask = cpu_to_le16(link_conf->eht_puncturing); else /* This flag can be set only if the MAC has eht support */ changes &= ~LINK_CONTEXT_MODIFY_EHT_PARAMS; - cmd.bss_color = vif->bss_conf.he_bss_color.color; + cmd.bss_color = link_conf->he_bss_color.color; - if (!vif->bss_conf.he_bss_color.enabled) { + if (!link_conf->he_bss_color.enabled) { flags |= LINK_FLG_BSS_COLOR_DIS; flags_mask |= LINK_FLG_BSS_COLOR_DIS; } - cmd.frame_time_rts_th = cpu_to_le16(vif->bss_conf.frame_time_rts_th); + cmd.frame_time_rts_th = cpu_to_le16(link_conf->frame_time_rts_th); /* Block 26-tone RU OFDMA transmissions */ if (mvmvif->deflink.he_ru_2mhz_block) { @@ -139,10 +156,10 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, flags_mask |= LINK_FLG_RU_2MHZ_BLOCK; } - if (vif->bss_conf.nontransmitted) { + if (link_conf->nontransmitted) { ether_addr_copy(cmd.ref_bssid_addr, - vif->bss_conf.transmitter_bssid); - cmd.bssid_index = vif->bss_conf.bssid_index; + link_conf->transmitter_bssid); + cmd.bssid_index = link_conf->bssid_index; } send_cmd: @@ -153,12 +170,14 @@ send_cmd: return iwl_mvm_link_cmd_send(mvm, &cmd, FW_CTXT_ACTION_MODIFY); } -int iwl_mvm_remove_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif) +int iwl_mvm_remove_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); struct iwl_link_config_cmd cmd = {}; int ret; + /* FIXME: add proper link id allocation */ cmd.link_id = cpu_to_le32(mvmvif->id); ret = iwl_mvm_link_cmd_send(mvm, &cmd, FW_CTXT_ACTION_REMOVE); -- cgit From 22c588343529d34e971b7cafae99d23f80dff7e9 Mon Sep 17 00:00:00 2001 From: Gregory Greenman Date: Tue, 28 Mar 2023 10:59:04 +0300 Subject: wifi: iwlwifi: mvm: replace bss_info_changed() with vif_cfg/link_info_changed() These are two new handlers for MLO. As the configurations done in bss_info_changed() are now split into two separate flows, use MLO specific implementation instead of common functions with the non-MLO code. Signed-off-by: Gregory Greenman Link: https://lore.kernel.org/r/20230328104949.7b238cae0895.Ieb87f204787fb1c7cb7562e1cbf54ef518d87123@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/link.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/link.c') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/link.c b/drivers/net/wireless/intel/iwlwifi/mvm/link.c index bbaac2ba9079..320a3bc4e9c0 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/link.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/link.c @@ -113,7 +113,7 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, link_conf->dtim_period); if (!link_conf->he_support || iwlwifi_mod_params.disable_11ax || - !vif->cfg.assoc) { + (vif->type == NL80211_IFTYPE_STATION && !vif->cfg.assoc)) { changes &= ~LINK_CONTEXT_MODIFY_HE_PARAMS; goto send_cmd; } -- cgit From d6f6b0d804e08e1cab1dcebe4f62dc949bb646e9 Mon Sep 17 00:00:00 2001 From: Gregory Greenman Date: Tue, 28 Mar 2023 10:59:06 +0300 Subject: wifi: iwlwifi: mvm: add fw link id allocation Driver uses link_id as an index in the array. FW currently can support only 2 concurrently active links per vif with the ids in the range 0-3. Add a mapping of dirver link ids to fw link id and track the number of active link ids. Signed-off-by: Gregory Greenman Link: https://lore.kernel.org/r/20230328104949.a53e5df49c33.I02b25648d2d5ca370c0697bf19d0d34724eae8a1@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/link.c | 87 +++++++++++++++++++++++---- 1 file changed, 74 insertions(+), 13 deletions(-) (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/link.c') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/link.c b/drivers/net/wireless/intel/iwlwifi/mvm/link.c index 320a3bc4e9c0..7a70b6ee65ac 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/link.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/link.c @@ -1,9 +1,34 @@ // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause /* - * Copyright (C) 2022 Intel Corporation + * Copyright (C) 2022 - 2023 Intel Corporation */ #include "mvm.h" +static u32 iwl_mvm_get_free_fw_link_id(struct iwl_mvm *mvm, + struct iwl_mvm_vif *mvm_vif) +{ + u32 link_id; + + lockdep_assert_held(&mvm->mutex); + + link_id = ffz(mvm->fw_link_ids_map); + + /* this case can happen if there're deactivated but not removed links */ + if (link_id > IWL_MVM_FW_MAX_LINK_ID) + return IWL_MVM_FW_LINK_ID_INVALID; + + mvm->fw_link_ids_map |= BIT(link_id); + return link_id; +} + +static void iwl_mvm_release_fw_link_id(struct iwl_mvm *mvm, u32 link_id) +{ + lockdep_assert_held(&mvm->mutex); + + if (!WARN_ON(link_id > IWL_MVM_FW_MAX_LINK_ID)) + mvm->fw_link_ids_map &= ~BIT(link_id); +} + static int iwl_mvm_link_cmd_send(struct iwl_mvm *mvm, struct iwl_link_config_cmd *cmd, enum iwl_ctxt_action action) @@ -25,23 +50,30 @@ int iwl_mvm_add_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif, { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); unsigned int link_id = link_conf->link_id; + struct iwl_mvm_vif_link_info *link_info = mvmvif->link[link_id]; struct iwl_link_config_cmd cmd = {}; struct iwl_mvm_phy_ctxt *phyctxt; - if (WARN_ON_ONCE(!mvmvif->link[link_id])) + if (WARN_ON_ONCE(!link_info)) return -EINVAL; + if (link_info->fw_link_id == IWL_MVM_FW_LINK_ID_INVALID) { + link_info->fw_link_id = iwl_mvm_get_free_fw_link_id(mvm, + mvmvif); + if (link_info->fw_link_id == IWL_MVM_FW_LINK_ID_INVALID) + return -EINVAL; + } + /* Update SF - Disable if needed. if this fails, SF might still be on * while many macs are bound, which is forbidden - so fail the binding. */ if (iwl_mvm_sf_update(mvm, vif, false)) return -EINVAL; - /* FIXME: add proper link id allocation */ - cmd.link_id = cpu_to_le32(mvmvif->id); + cmd.link_id = cpu_to_le32(link_info->fw_link_id); cmd.mac_id = cpu_to_le32(mvmvif->id); /* P2P-Device already has a valid PHY context during add */ - phyctxt = mvmvif->link[link_id]->phy_ctxt; + phyctxt = link_info->phy_ctxt; if (phyctxt) cmd.phy_id = cpu_to_le32(phyctxt->id); else @@ -61,20 +93,27 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); unsigned int link_id = link_conf->link_id; + struct iwl_mvm_vif_link_info *link_info = mvmvif->link[link_id]; struct iwl_mvm_phy_ctxt *phyctxt; struct iwl_link_config_cmd cmd = {}; u32 ht_flag, flags = 0, flags_mask = 0; + int ret; + + if (WARN_ON_ONCE(!link_info || + link_info->fw_link_id == IWL_MVM_FW_LINK_ID_INVALID)) + return -EINVAL; - if (WARN_ON_ONCE(!mvmvif->link[link_id])) + /* cannot activate third link */ + if (!link_info->active && active && + mvmvif->fw_active_links_num >= IWL_MVM_FW_MAX_ACTIVE_LINKS_NUM) return -EINVAL; - /* FIXME: add proper link id allocation */ - cmd.link_id = cpu_to_le32(mvmvif->id); + cmd.link_id = cpu_to_le32(link_info->fw_link_id); /* The phy_id, link address and listen_lmac can be modified only until * the link becomes active, otherwise they will be ignored. */ - phyctxt = mvmvif->link[link_id]->phy_ctxt; + phyctxt = link_info->phy_ctxt; if (phyctxt) cmd.phy_id = cpu_to_le32(phyctxt->id); else @@ -151,7 +190,7 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, cmd.frame_time_rts_th = cpu_to_le16(link_conf->frame_time_rts_th); /* Block 26-tone RU OFDMA transmissions */ - if (mvmvif->deflink.he_ru_2mhz_block) { + if (link_info->he_ru_2mhz_block) { flags |= LINK_FLG_RU_2MHZ_BLOCK; flags_mask |= LINK_FLG_RU_2MHZ_BLOCK; } @@ -167,18 +206,40 @@ send_cmd: cmd.flags = cpu_to_le32(flags); cmd.flags_mask = cpu_to_le32(flags_mask); - return iwl_mvm_link_cmd_send(mvm, &cmd, FW_CTXT_ACTION_MODIFY); + ret = iwl_mvm_link_cmd_send(mvm, &cmd, FW_CTXT_ACTION_MODIFY); + if (!ret) { + /* the FW is updated, so now it's possible to update the + * activation status. If activating a link, it was already + * checked above that we didn't reach the FW limit. + */ + if (link_info->active && !active) + mvmvif->fw_active_links_num--; + else if (!link_info->active && active) + mvmvif->fw_active_links_num++; + + link_info->active = active; + } + + return ret; } int iwl_mvm_remove_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif, struct ieee80211_bss_conf *link_conf) { struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + unsigned int link_id = link_conf->link_id; + struct iwl_mvm_vif_link_info *link_info = mvmvif->link[link_id]; struct iwl_link_config_cmd cmd = {}; int ret; - /* FIXME: add proper link id allocation */ - cmd.link_id = cpu_to_le32(mvmvif->id); + if (WARN_ON(!link_info || + link_info->fw_link_id == IWL_MVM_FW_LINK_ID_INVALID)) + return -EINVAL; + + cmd.link_id = cpu_to_le32(link_info->fw_link_id); + iwl_mvm_release_fw_link_id(mvm, link_info->fw_link_id); + link_info->fw_link_id = IWL_MVM_FW_LINK_ID_INVALID; + ret = iwl_mvm_link_cmd_send(mvm, &cmd, FW_CTXT_ACTION_REMOVE); if (!ret) -- cgit From bf976c814c864ec45fa32303e7080fc2e6efe4f2 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 28 Mar 2023 10:59:11 +0300 Subject: wifi: iwlwifi: mvm: implement link change ops Implement the link change ops for links and stations. Note that the stations one is empty for now as we only have support for a single link so far, and then the stations are created with the first link as deflink by mac80211, so right now we don't really need anything. Signed-off-by: Johannes Berg Signed-off-by: Gregory Greenman Link: https://lore.kernel.org/r/20230328104949.6186c5a37e99.Ifd00d3ee93356ddef273aa18f1e081cd8f2c84ae@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/link.c | 43 +++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/link.c') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/link.c b/drivers/net/wireless/intel/iwlwifi/mvm/link.c index 7a70b6ee65ac..0cd40672fade 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/link.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/link.c @@ -3,6 +3,7 @@ * Copyright (C) 2022 - 2023 Intel Corporation */ #include "mvm.h" +#include "time-event.h" static u32 iwl_mvm_get_free_fw_link_id(struct iwl_mvm *mvm, struct iwl_mvm_vif *mvm_vif) @@ -108,6 +109,28 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, mvmvif->fw_active_links_num >= IWL_MVM_FW_MAX_ACTIVE_LINKS_NUM) return -EINVAL; + if (changes & LINK_CONTEXT_MODIFY_ACTIVE) { + /* When activating a link, phy context should be valid; + * when deactivating a link, it also should be valid since + * the link was active before. So, do nothing in this case. + * Since a link is added first with FW_CTXT_INVALID, then we + * can get here in case it's removed before it was activated. + */ + if (!link_info->phy_ctxt) + return 0; + + /* Catch early if driver tries to activate or deactivate a link + * twice. + */ + WARN_ON_ONCE(active == link_info->active); + + /* When deactivating a link session protection should + * be stopped + */ + if (!active && vif->type == NL80211_IFTYPE_STATION) + iwl_mvm_stop_session_protection(mvm, vif); + } + cmd.link_id = cpu_to_le32(link_info->fw_link_id); /* The phy_id, link address and listen_lmac can be modified only until @@ -248,3 +271,23 @@ int iwl_mvm_remove_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif, return ret; } + +/* link should be deactivated before removal, so in most cases we need to + * perform these two operations together + */ +int iwl_mvm_disable_link(struct iwl_mvm *mvm, struct ieee80211_vif *vif, + struct ieee80211_bss_conf *link_conf) +{ + int ret; + + ret = iwl_mvm_link_changed(mvm, vif, link_conf, + LINK_CONTEXT_MODIFY_ACTIVE, false); + if (ret) + return ret; + + ret = iwl_mvm_remove_link(mvm, vif, link_conf); + if (ret) + return ret; + + return ret; +} -- cgit From 9deccfcd48b7c358245ed05c11b142cc945daf5e Mon Sep 17 00:00:00 2001 From: Gregory Greenman Date: Wed, 29 Mar 2023 10:05:34 +0300 Subject: wifi: iwlwifi: mvm: rework active links counting Remove fw_active_links_num counter since we now have a bitmap of active links in vif. Also, update link activation status only when LINK_CONTEXT_MODIFY_ACTIVE bit set in changes parameter. Signed-off-by: Gregory Greenman Link: https://lore.kernel.org/r/20230329100040.1ecfb27b6b84.I3a5e0bc32b3728e4caae8a231bc3f04ea1d89cad@changeid Signed-off-by: Johannes Berg --- drivers/net/wireless/intel/iwlwifi/mvm/link.c | 33 ++++++++++++++------------- 1 file changed, 17 insertions(+), 16 deletions(-) (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/link.c') diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/link.c b/drivers/net/wireless/intel/iwlwifi/mvm/link.c index 0cd40672fade..eb828de40a3c 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/link.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/link.c @@ -104,11 +104,6 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, link_info->fw_link_id == IWL_MVM_FW_LINK_ID_INVALID)) return -EINVAL; - /* cannot activate third link */ - if (!link_info->active && active && - mvmvif->fw_active_links_num >= IWL_MVM_FW_MAX_ACTIVE_LINKS_NUM) - return -EINVAL; - if (changes & LINK_CONTEXT_MODIFY_ACTIVE) { /* When activating a link, phy context should be valid; * when deactivating a link, it also should be valid since @@ -119,6 +114,22 @@ int iwl_mvm_link_changed(struct iwl_mvm *mvm, struct ieee80211_vif *vif, if (!link_info->phy_ctxt) return 0; + /* check there aren't too many active links */ + if (!link_info->active && active) { + int i, count = 0; + + /* link with phy_ctxt is active in FW */ + for_each_mvm_vif_valid_link(mvmvif, i) + if (mvmvif->link[i]->phy_ctxt) + count++; + + /* FIXME: IWL_MVM_FW_MAX_ACTIVE_LINKS_NUM should be + * defined per HW + */ + if (count >= IWL_MVM_FW_MAX_ACTIVE_LINKS_NUM) + return -EINVAL; + } + /* Catch early if driver tries to activate or deactivate a link * twice. */ @@ -230,18 +241,8 @@ send_cmd: cmd.flags_mask = cpu_to_le32(flags_mask); ret = iwl_mvm_link_cmd_send(mvm, &cmd, FW_CTXT_ACTION_MODIFY); - if (!ret) { - /* the FW is updated, so now it's possible to update the - * activation status. If activating a link, it was already - * checked above that we didn't reach the FW limit. - */ - if (link_info->active && !active) - mvmvif->fw_active_links_num--; - else if (!link_info->active && active) - mvmvif->fw_active_links_num++; - + if (!ret && (changes & LINK_CONTEXT_MODIFY_ACTIVE)) link_info->active = active; - } return ret; } -- cgit