The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/iwlwifi/mvm/scan.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
    2 /*
    3  * Copyright (C) 2012-2014, 2018-2021 Intel Corporation
    4  * Copyright (C) 2013-2015 Intel Mobile Communications GmbH
    5  * Copyright (C) 2016-2017 Intel Deutschland GmbH
    6  */
    7 #include <linux/etherdevice.h>
    8 #include <net/mac80211.h>
    9 #include <linux/crc32.h>
   10 
   11 #include "mvm.h"
   12 #include "fw/api/scan.h"
   13 #include "iwl-io.h"
   14 
   15 #define IWL_DENSE_EBS_SCAN_RATIO 5
   16 #define IWL_SPARSE_EBS_SCAN_RATIO 1
   17 
   18 #define IWL_SCAN_DWELL_ACTIVE           10
   19 #define IWL_SCAN_DWELL_PASSIVE          110
   20 #define IWL_SCAN_DWELL_FRAGMENTED       44
   21 #define IWL_SCAN_DWELL_EXTENDED         90
   22 #define IWL_SCAN_NUM_OF_FRAGS           3
   23 
   24 /* adaptive dwell max budget time [TU] for full scan */
   25 #define IWL_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN 300
   26 /* adaptive dwell max budget time [TU] for directed scan */
   27 #define IWL_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN 100
   28 /* adaptive dwell default high band APs number */
   29 #define IWL_SCAN_ADWELL_DEFAULT_HB_N_APS 8
   30 /* adaptive dwell default low band APs number */
   31 #define IWL_SCAN_ADWELL_DEFAULT_LB_N_APS 2
   32 /* adaptive dwell default APs number in social channels (1, 6, 11) */
   33 #define IWL_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL 10
   34 /* number of scan channels */
   35 #define IWL_SCAN_NUM_CHANNELS 112
   36 /* adaptive dwell number of APs override mask for p2p friendly GO */
   37 #define IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY_BIT BIT(20)
   38 /* adaptive dwell number of APs override mask for social channels */
   39 #define IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS_BIT BIT(21)
   40 /* adaptive dwell number of APs override for p2p friendly GO channels */
   41 #define IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY 10
   42 /* adaptive dwell number of APs override for social channels */
   43 #define IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS 2
   44 
   45 /* minimal number of 2GHz and 5GHz channels in the regular scan request */
   46 #define IWL_MVM_6GHZ_PASSIVE_SCAN_MIN_CHANS 4
   47 
   48 struct iwl_mvm_scan_timing_params {
   49         u32 suspend_time;
   50         u32 max_out_time;
   51 };
   52 
   53 static struct iwl_mvm_scan_timing_params scan_timing[] = {
   54         [IWL_SCAN_TYPE_UNASSOC] = {
   55                 .suspend_time = 0,
   56                 .max_out_time = 0,
   57         },
   58         [IWL_SCAN_TYPE_WILD] = {
   59                 .suspend_time = 30,
   60                 .max_out_time = 120,
   61         },
   62         [IWL_SCAN_TYPE_MILD] = {
   63                 .suspend_time = 120,
   64                 .max_out_time = 120,
   65         },
   66         [IWL_SCAN_TYPE_FRAGMENTED] = {
   67                 .suspend_time = 95,
   68                 .max_out_time = 44,
   69         },
   70         [IWL_SCAN_TYPE_FAST_BALANCE] = {
   71                 .suspend_time = 30,
   72                 .max_out_time = 37,
   73         },
   74 };
   75 
   76 struct iwl_mvm_scan_params {
   77         /* For CDB this is low band scan type, for non-CDB - type. */
   78         enum iwl_mvm_scan_type type;
   79         enum iwl_mvm_scan_type hb_type;
   80         u32 n_channels;
   81         u16 delay;
   82         int n_ssids;
   83         struct cfg80211_ssid *ssids;
   84         struct ieee80211_channel **channels;
   85         u32 flags;
   86         u8 *mac_addr;
   87         u8 *mac_addr_mask;
   88         bool no_cck;
   89         bool pass_all;
   90         int n_match_sets;
   91         struct iwl_scan_probe_req preq;
   92         struct cfg80211_match_set *match_sets;
   93         int n_scan_plans;
   94         struct cfg80211_sched_scan_plan *scan_plans;
   95         bool iter_notif;
   96         struct cfg80211_scan_6ghz_params *scan_6ghz_params;
   97         u32 n_6ghz_params;
   98         bool scan_6ghz;
   99         bool enable_6ghz_passive;
  100         bool respect_p2p_go, respect_p2p_go_hb;
  101 };
  102 
  103 static inline void *iwl_mvm_get_scan_req_umac_data(struct iwl_mvm *mvm)
  104 {
  105         struct iwl_scan_req_umac *cmd = mvm->scan_cmd;
  106 
  107         if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm))
  108                 return (void *)&cmd->v8.data;
  109 
  110         if (iwl_mvm_is_adaptive_dwell_supported(mvm))
  111                 return (void *)&cmd->v7.data;
  112 
  113         if (iwl_mvm_cdb_scan_api(mvm))
  114                 return (void *)&cmd->v6.data;
  115 
  116         return (void *)&cmd->v1.data;
  117 }
  118 
  119 static inline struct iwl_scan_umac_chan_param *
  120 iwl_mvm_get_scan_req_umac_channel(struct iwl_mvm *mvm)
  121 {
  122         struct iwl_scan_req_umac *cmd = mvm->scan_cmd;
  123 
  124         if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm))
  125                 return &cmd->v8.channel;
  126 
  127         if (iwl_mvm_is_adaptive_dwell_supported(mvm))
  128                 return &cmd->v7.channel;
  129 
  130         if (iwl_mvm_cdb_scan_api(mvm))
  131                 return &cmd->v6.channel;
  132 
  133         return &cmd->v1.channel;
  134 }
  135 
  136 static u8 iwl_mvm_scan_rx_ant(struct iwl_mvm *mvm)
  137 {
  138         if (mvm->scan_rx_ant != ANT_NONE)
  139                 return mvm->scan_rx_ant;
  140         return iwl_mvm_get_valid_rx_ant(mvm);
  141 }
  142 
  143 static inline __le16 iwl_mvm_scan_rx_chain(struct iwl_mvm *mvm)
  144 {
  145         u16 rx_chain;
  146         u8 rx_ant;
  147 
  148         rx_ant = iwl_mvm_scan_rx_ant(mvm);
  149         rx_chain = rx_ant << PHY_RX_CHAIN_VALID_POS;
  150         rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_MIMO_SEL_POS;
  151         rx_chain |= rx_ant << PHY_RX_CHAIN_FORCE_SEL_POS;
  152         rx_chain |= 0x1 << PHY_RX_CHAIN_DRIVER_FORCE_POS;
  153         return cpu_to_le16(rx_chain);
  154 }
  155 
  156 static inline __le32
  157 iwl_mvm_scan_rate_n_flags(struct iwl_mvm *mvm, enum nl80211_band band,
  158                           bool no_cck)
  159 {
  160         u32 tx_ant;
  161 
  162         iwl_mvm_toggle_tx_ant(mvm, &mvm->scan_last_antenna_idx);
  163         tx_ant = BIT(mvm->scan_last_antenna_idx) << RATE_MCS_ANT_POS;
  164 
  165         if (band == NL80211_BAND_2GHZ && !no_cck)
  166                 return cpu_to_le32(IWL_RATE_1M_PLCP | RATE_MCS_CCK_MSK_V1 |
  167                                    tx_ant);
  168         else
  169                 return cpu_to_le32(IWL_RATE_6M_PLCP | tx_ant);
  170 }
  171 
  172 static enum iwl_mvm_traffic_load iwl_mvm_get_traffic_load(struct iwl_mvm *mvm)
  173 {
  174         return mvm->tcm.result.global_load;
  175 }
  176 
  177 static enum iwl_mvm_traffic_load
  178 iwl_mvm_get_traffic_load_band(struct iwl_mvm *mvm, enum nl80211_band band)
  179 {
  180         return mvm->tcm.result.band_load[band];
  181 }
  182 
  183 struct iwl_mvm_scan_iter_data {
  184         u32 global_cnt;
  185         struct ieee80211_vif *current_vif;
  186         bool is_dcm_with_p2p_go;
  187 };
  188 
  189 static void iwl_mvm_scan_iterator(void *_data, u8 *mac,
  190                                   struct ieee80211_vif *vif)
  191 {
  192         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
  193         struct iwl_mvm_scan_iter_data *data = _data;
  194         struct iwl_mvm_vif *curr_mvmvif;
  195 
  196         if (vif->type != NL80211_IFTYPE_P2P_DEVICE && mvmvif->phy_ctxt &&
  197             mvmvif->phy_ctxt->id < NUM_PHY_CTX)
  198                 data->global_cnt += 1;
  199 
  200         if (!data->current_vif || vif == data->current_vif)
  201                 return;
  202 
  203         curr_mvmvif = iwl_mvm_vif_from_mac80211(data->current_vif);
  204 
  205         if (vif->type == NL80211_IFTYPE_AP && vif->p2p &&
  206             mvmvif->phy_ctxt && curr_mvmvif->phy_ctxt &&
  207             mvmvif->phy_ctxt->id != curr_mvmvif->phy_ctxt->id)
  208                 data->is_dcm_with_p2p_go = true;
  209 }
  210 
  211 static enum
  212 iwl_mvm_scan_type _iwl_mvm_get_scan_type(struct iwl_mvm *mvm,
  213                                          struct ieee80211_vif *vif,
  214                                          enum iwl_mvm_traffic_load load,
  215                                          bool low_latency)
  216 {
  217         struct iwl_mvm_scan_iter_data data = {
  218                 .current_vif = vif,
  219                 .is_dcm_with_p2p_go = false,
  220                 .global_cnt = 0,
  221         };
  222 
  223         ieee80211_iterate_active_interfaces_atomic(mvm->hw,
  224                                                    IEEE80211_IFACE_ITER_NORMAL,
  225                                                    iwl_mvm_scan_iterator,
  226                                                    &data);
  227 
  228         if (!data.global_cnt)
  229                 return IWL_SCAN_TYPE_UNASSOC;
  230 
  231         if (fw_has_api(&mvm->fw->ucode_capa,
  232                        IWL_UCODE_TLV_API_FRAGMENTED_SCAN)) {
  233                 if ((load == IWL_MVM_TRAFFIC_HIGH || low_latency) &&
  234                     (!vif || vif->type != NL80211_IFTYPE_P2P_DEVICE))
  235                         return IWL_SCAN_TYPE_FRAGMENTED;
  236 
  237                 /*
  238                  * in case of DCM with GO where BSS DTIM interval < 220msec
  239                  * set all scan requests as fast-balance scan
  240                  */
  241                 if (vif && vif->type == NL80211_IFTYPE_STATION &&
  242                     vif->bss_conf.dtim_period < 220 &&
  243                     data.is_dcm_with_p2p_go)
  244                         return IWL_SCAN_TYPE_FAST_BALANCE;
  245         }
  246 
  247         if (load >= IWL_MVM_TRAFFIC_MEDIUM || low_latency)
  248                 return IWL_SCAN_TYPE_MILD;
  249 
  250         return IWL_SCAN_TYPE_WILD;
  251 }
  252 
  253 static enum
  254 iwl_mvm_scan_type iwl_mvm_get_scan_type(struct iwl_mvm *mvm,
  255                                         struct ieee80211_vif *vif)
  256 {
  257         enum iwl_mvm_traffic_load load;
  258         bool low_latency;
  259 
  260         load = iwl_mvm_get_traffic_load(mvm);
  261         low_latency = iwl_mvm_low_latency(mvm);
  262 
  263         return _iwl_mvm_get_scan_type(mvm, vif, load, low_latency);
  264 }
  265 
  266 static enum
  267 iwl_mvm_scan_type iwl_mvm_get_scan_type_band(struct iwl_mvm *mvm,
  268                                              struct ieee80211_vif *vif,
  269                                              enum nl80211_band band)
  270 {
  271         enum iwl_mvm_traffic_load load;
  272         bool low_latency;
  273 
  274         load = iwl_mvm_get_traffic_load_band(mvm, band);
  275         low_latency = iwl_mvm_low_latency_band(mvm, band);
  276 
  277         return _iwl_mvm_get_scan_type(mvm, vif, load, low_latency);
  278 }
  279 
  280 static inline bool iwl_mvm_rrm_scan_needed(struct iwl_mvm *mvm)
  281 {
  282         /* require rrm scan whenever the fw supports it */
  283         return fw_has_capa(&mvm->fw->ucode_capa,
  284                            IWL_UCODE_TLV_CAPA_DS_PARAM_SET_IE_SUPPORT);
  285 }
  286 
  287 static int iwl_mvm_max_scan_ie_fw_cmd_room(struct iwl_mvm *mvm)
  288 {
  289         int max_probe_len;
  290 
  291         max_probe_len = SCAN_OFFLOAD_PROBE_REQ_SIZE;
  292 
  293         /* we create the 802.11 header and SSID element */
  294         max_probe_len -= 24 + 2;
  295 
  296         /* DS parameter set element is added on 2.4GHZ band if required */
  297         if (iwl_mvm_rrm_scan_needed(mvm))
  298                 max_probe_len -= 3;
  299 
  300         return max_probe_len;
  301 }
  302 
  303 int iwl_mvm_max_scan_ie_len(struct iwl_mvm *mvm)
  304 {
  305         int max_ie_len = iwl_mvm_max_scan_ie_fw_cmd_room(mvm);
  306 
  307         /* TODO: [BUG] This function should return the maximum allowed size of
  308          * scan IEs, however the LMAC scan api contains both 2GHZ and 5GHZ IEs
  309          * in the same command. So the correct implementation of this function
  310          * is just iwl_mvm_max_scan_ie_fw_cmd_room() / 2. Currently the scan
  311          * command has only 512 bytes and it would leave us with about 240
  312          * bytes for scan IEs, which is clearly not enough. So meanwhile
  313          * we will report an incorrect value. This may result in a failure to
  314          * issue a scan in unified_scan_lmac and unified_sched_scan_lmac
  315          * functions with -ENOBUFS, if a large enough probe will be provided.
  316          */
  317         return max_ie_len;
  318 }
  319 
  320 void iwl_mvm_rx_lmac_scan_iter_complete_notif(struct iwl_mvm *mvm,
  321                                               struct iwl_rx_cmd_buffer *rxb)
  322 {
  323         struct iwl_rx_packet *pkt = rxb_addr(rxb);
  324         struct iwl_lmac_scan_complete_notif *notif = (void *)pkt->data;
  325 
  326         IWL_DEBUG_SCAN(mvm,
  327                        "Scan offload iteration complete: status=0x%x scanned channels=%d\n",
  328                        notif->status, notif->scanned_channels);
  329 
  330         if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_FOUND) {
  331                 IWL_DEBUG_SCAN(mvm, "Pass all scheduled scan results found\n");
  332                 ieee80211_sched_scan_results(mvm->hw);
  333                 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_ENABLED;
  334         }
  335 }
  336 
  337 void iwl_mvm_rx_scan_match_found(struct iwl_mvm *mvm,
  338                                  struct iwl_rx_cmd_buffer *rxb)
  339 {
  340         IWL_DEBUG_SCAN(mvm, "Scheduled scan results\n");
  341         ieee80211_sched_scan_results(mvm->hw);
  342 }
  343 
  344 static const char *iwl_mvm_ebs_status_str(enum iwl_scan_ebs_status status)
  345 {
  346         switch (status) {
  347         case IWL_SCAN_EBS_SUCCESS:
  348                 return "successful";
  349         case IWL_SCAN_EBS_INACTIVE:
  350                 return "inactive";
  351         case IWL_SCAN_EBS_FAILED:
  352         case IWL_SCAN_EBS_CHAN_NOT_FOUND:
  353         default:
  354                 return "failed";
  355         }
  356 }
  357 
  358 void iwl_mvm_rx_lmac_scan_complete_notif(struct iwl_mvm *mvm,
  359                                          struct iwl_rx_cmd_buffer *rxb)
  360 {
  361         struct iwl_rx_packet *pkt = rxb_addr(rxb);
  362         struct iwl_periodic_scan_complete *scan_notif = (void *)pkt->data;
  363         bool aborted = (scan_notif->status == IWL_SCAN_OFFLOAD_ABORTED);
  364 
  365         /* If this happens, the firmware has mistakenly sent an LMAC
  366          * notification during UMAC scans -- warn and ignore it.
  367          */
  368         if (WARN_ON_ONCE(fw_has_capa(&mvm->fw->ucode_capa,
  369                                      IWL_UCODE_TLV_CAPA_UMAC_SCAN)))
  370                 return;
  371 
  372         /* scan status must be locked for proper checking */
  373         lockdep_assert_held(&mvm->mutex);
  374 
  375         /* We first check if we were stopping a scan, in which case we
  376          * just clear the stopping flag.  Then we check if it was a
  377          * firmware initiated stop, in which case we need to inform
  378          * mac80211.
  379          * Note that we can have a stopping and a running scan
  380          * simultaneously, but we can't have two different types of
  381          * scans stopping or running at the same time (since LMAC
  382          * doesn't support it).
  383          */
  384 
  385         if (mvm->scan_status & IWL_MVM_SCAN_STOPPING_SCHED) {
  386                 WARN_ON_ONCE(mvm->scan_status & IWL_MVM_SCAN_STOPPING_REGULAR);
  387 
  388                 IWL_DEBUG_SCAN(mvm, "Scheduled scan %s, EBS status %s\n",
  389                                aborted ? "aborted" : "completed",
  390                                iwl_mvm_ebs_status_str(scan_notif->ebs_status));
  391                 IWL_DEBUG_SCAN(mvm,
  392                                "Last line %d, Last iteration %d, Time after last iteration %d\n",
  393                                scan_notif->last_schedule_line,
  394                                scan_notif->last_schedule_iteration,
  395                                __le32_to_cpu(scan_notif->time_after_last_iter));
  396 
  397                 mvm->scan_status &= ~IWL_MVM_SCAN_STOPPING_SCHED;
  398         } else if (mvm->scan_status & IWL_MVM_SCAN_STOPPING_REGULAR) {
  399                 IWL_DEBUG_SCAN(mvm, "Regular scan %s, EBS status %s\n",
  400                                aborted ? "aborted" : "completed",
  401                                iwl_mvm_ebs_status_str(scan_notif->ebs_status));
  402 
  403                 mvm->scan_status &= ~IWL_MVM_SCAN_STOPPING_REGULAR;
  404         } else if (mvm->scan_status & IWL_MVM_SCAN_SCHED) {
  405                 WARN_ON_ONCE(mvm->scan_status & IWL_MVM_SCAN_REGULAR);
  406 
  407                 IWL_DEBUG_SCAN(mvm, "Scheduled scan %s, EBS status %s\n",
  408                                aborted ? "aborted" : "completed",
  409                                iwl_mvm_ebs_status_str(scan_notif->ebs_status));
  410                 IWL_DEBUG_SCAN(mvm,
  411                                "Last line %d, Last iteration %d, Time after last iteration %d (FW)\n",
  412                                scan_notif->last_schedule_line,
  413                                scan_notif->last_schedule_iteration,
  414                                __le32_to_cpu(scan_notif->time_after_last_iter));
  415 
  416                 mvm->scan_status &= ~IWL_MVM_SCAN_SCHED;
  417                 ieee80211_sched_scan_stopped(mvm->hw);
  418                 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
  419         } else if (mvm->scan_status & IWL_MVM_SCAN_REGULAR) {
  420                 struct cfg80211_scan_info info = {
  421                         .aborted = aborted,
  422                 };
  423 
  424                 IWL_DEBUG_SCAN(mvm, "Regular scan %s, EBS status %s (FW)\n",
  425                                aborted ? "aborted" : "completed",
  426                                iwl_mvm_ebs_status_str(scan_notif->ebs_status));
  427 
  428                 mvm->scan_status &= ~IWL_MVM_SCAN_REGULAR;
  429                 ieee80211_scan_completed(mvm->hw, &info);
  430                 cancel_delayed_work(&mvm->scan_timeout_dwork);
  431                 iwl_mvm_resume_tcm(mvm);
  432         } else {
  433                 IWL_ERR(mvm,
  434                         "got scan complete notification but no scan is running\n");
  435         }
  436 
  437         mvm->last_ebs_successful =
  438                         scan_notif->ebs_status == IWL_SCAN_EBS_SUCCESS ||
  439                         scan_notif->ebs_status == IWL_SCAN_EBS_INACTIVE;
  440 }
  441 
  442 static int iwl_ssid_exist(u8 *ssid, u8 ssid_len, struct iwl_ssid_ie *ssid_list)
  443 {
  444         int i;
  445 
  446         for (i = 0; i < PROBE_OPTION_MAX; i++) {
  447                 if (!ssid_list[i].len)
  448                         break;
  449                 if (ssid_list[i].len == ssid_len &&
  450                     !memcmp(ssid_list->ssid, ssid, ssid_len))
  451                         return i;
  452         }
  453         return -1;
  454 }
  455 
  456 /* We insert the SSIDs in an inverted order, because the FW will
  457  * invert it back.
  458  */
  459 static void iwl_scan_build_ssids(struct iwl_mvm_scan_params *params,
  460                                  struct iwl_ssid_ie *ssids,
  461                                  u32 *ssid_bitmap)
  462 {
  463         int i, j;
  464         int index;
  465         u32 tmp_bitmap = 0;
  466 
  467         /*
  468          * copy SSIDs from match list.
  469          * iwl_config_sched_scan_profiles() uses the order of these ssids to
  470          * config match list.
  471          */
  472         for (i = 0, j = params->n_match_sets - 1;
  473              j >= 0 && i < PROBE_OPTION_MAX;
  474              i++, j--) {
  475                 /* skip empty SSID matchsets */
  476                 if (!params->match_sets[j].ssid.ssid_len)
  477                         continue;
  478                 ssids[i].id = WLAN_EID_SSID;
  479                 ssids[i].len = params->match_sets[j].ssid.ssid_len;
  480                 memcpy(ssids[i].ssid, params->match_sets[j].ssid.ssid,
  481                        ssids[i].len);
  482         }
  483 
  484         /* add SSIDs from scan SSID list */
  485         for (j = params->n_ssids - 1;
  486              j >= 0 && i < PROBE_OPTION_MAX;
  487              i++, j--) {
  488                 index = iwl_ssid_exist(params->ssids[j].ssid,
  489                                        params->ssids[j].ssid_len,
  490                                        ssids);
  491                 if (index < 0) {
  492                         ssids[i].id = WLAN_EID_SSID;
  493                         ssids[i].len = params->ssids[j].ssid_len;
  494                         memcpy(ssids[i].ssid, params->ssids[j].ssid,
  495                                ssids[i].len);
  496                         tmp_bitmap |= BIT(i);
  497                 } else {
  498                         tmp_bitmap |= BIT(index);
  499                 }
  500         }
  501         if (ssid_bitmap)
  502                 *ssid_bitmap = tmp_bitmap;
  503 }
  504 
  505 static int
  506 iwl_mvm_config_sched_scan_profiles(struct iwl_mvm *mvm,
  507                                    struct cfg80211_sched_scan_request *req)
  508 {
  509         struct iwl_scan_offload_profile *profile;
  510         struct iwl_scan_offload_profile_cfg_v1 *profile_cfg_v1;
  511         struct iwl_scan_offload_blocklist *blocklist;
  512         struct iwl_scan_offload_profile_cfg_data *data;
  513         int max_profiles = iwl_umac_scan_get_max_profiles(mvm->fw);
  514         int profile_cfg_size = sizeof(*data) +
  515                 sizeof(*profile) * max_profiles;
  516         struct iwl_host_cmd cmd = {
  517                 .id = SCAN_OFFLOAD_UPDATE_PROFILES_CMD,
  518                 .len[1] = profile_cfg_size,
  519                 .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
  520                 .dataflags[1] = IWL_HCMD_DFL_NOCOPY,
  521         };
  522         int blocklist_len;
  523         int i;
  524         int ret;
  525 
  526         if (WARN_ON(req->n_match_sets > max_profiles))
  527                 return -EIO;
  528 
  529         if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_SHORT_BL)
  530                 blocklist_len = IWL_SCAN_SHORT_BLACKLIST_LEN;
  531         else
  532                 blocklist_len = IWL_SCAN_MAX_BLACKLIST_LEN;
  533 
  534         blocklist = kcalloc(blocklist_len, sizeof(*blocklist), GFP_KERNEL);
  535         if (!blocklist)
  536                 return -ENOMEM;
  537 
  538         profile_cfg_v1 = kzalloc(profile_cfg_size, GFP_KERNEL);
  539         if (!profile_cfg_v1) {
  540                 ret = -ENOMEM;
  541                 goto free_blocklist;
  542         }
  543 
  544         cmd.data[0] = blocklist;
  545         cmd.len[0] = sizeof(*blocklist) * blocklist_len;
  546         cmd.data[1] = profile_cfg_v1;
  547 
  548         /* if max_profile is MAX_PROFILES_V2, we have the new API */
  549         if (max_profiles == IWL_SCAN_MAX_PROFILES_V2) {
  550                 struct iwl_scan_offload_profile_cfg *profile_cfg =
  551                         (struct iwl_scan_offload_profile_cfg *)profile_cfg_v1;
  552 
  553                 data = &profile_cfg->data;
  554         } else {
  555                 data = &profile_cfg_v1->data;
  556         }
  557 
  558         /* No blocklist configuration */
  559         data->num_profiles = req->n_match_sets;
  560         data->active_clients = SCAN_CLIENT_SCHED_SCAN;
  561         data->pass_match = SCAN_CLIENT_SCHED_SCAN;
  562         data->match_notify = SCAN_CLIENT_SCHED_SCAN;
  563 
  564         if (!req->n_match_sets || !req->match_sets[0].ssid.ssid_len)
  565                 data->any_beacon_notify = SCAN_CLIENT_SCHED_SCAN;
  566 
  567         for (i = 0; i < req->n_match_sets; i++) {
  568                 profile = &profile_cfg_v1->profiles[i];
  569                 profile->ssid_index = i;
  570                 /* Support any cipher and auth algorithm */
  571                 profile->unicast_cipher = 0xff;
  572                 profile->auth_alg = IWL_AUTH_ALGO_UNSUPPORTED |
  573                         IWL_AUTH_ALGO_NONE | IWL_AUTH_ALGO_PSK | IWL_AUTH_ALGO_8021X |
  574                         IWL_AUTH_ALGO_SAE | IWL_AUTH_ALGO_8021X_SHA384 | IWL_AUTH_ALGO_OWE;
  575                 profile->network_type = IWL_NETWORK_TYPE_ANY;
  576                 profile->band_selection = IWL_SCAN_OFFLOAD_SELECT_ANY;
  577                 profile->client_bitmap = SCAN_CLIENT_SCHED_SCAN;
  578         }
  579 
  580         IWL_DEBUG_SCAN(mvm, "Sending scheduled scan profile config\n");
  581 
  582         ret = iwl_mvm_send_cmd(mvm, &cmd);
  583         kfree(profile_cfg_v1);
  584 free_blocklist:
  585         kfree(blocklist);
  586 
  587         return ret;
  588 }
  589 
  590 static bool iwl_mvm_scan_pass_all(struct iwl_mvm *mvm,
  591                                   struct cfg80211_sched_scan_request *req)
  592 {
  593         if (req->n_match_sets && req->match_sets[0].ssid.ssid_len) {
  594                 IWL_DEBUG_SCAN(mvm,
  595                                "Sending scheduled scan with filtering, n_match_sets %d\n",
  596                                req->n_match_sets);
  597                 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
  598                 return false;
  599         }
  600 
  601         IWL_DEBUG_SCAN(mvm, "Sending Scheduled scan without filtering\n");
  602 
  603         mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_ENABLED;
  604         return true;
  605 }
  606 
  607 static int iwl_mvm_lmac_scan_abort(struct iwl_mvm *mvm)
  608 {
  609         int ret;
  610         struct iwl_host_cmd cmd = {
  611                 .id = SCAN_OFFLOAD_ABORT_CMD,
  612         };
  613         u32 status = CAN_ABORT_STATUS;
  614 
  615         ret = iwl_mvm_send_cmd_status(mvm, &cmd, &status);
  616         if (ret)
  617                 return ret;
  618 
  619         if (status != CAN_ABORT_STATUS) {
  620                 /*
  621                  * The scan abort will return 1 for success or
  622                  * 2 for "failure".  A failure condition can be
  623                  * due to simply not being in an active scan which
  624                  * can occur if we send the scan abort before the
  625                  * microcode has notified us that a scan is completed.
  626                  */
  627                 IWL_DEBUG_SCAN(mvm, "SCAN OFFLOAD ABORT ret %d.\n", status);
  628                 ret = -ENOENT;
  629         }
  630 
  631         return ret;
  632 }
  633 
  634 static void iwl_mvm_scan_fill_tx_cmd(struct iwl_mvm *mvm,
  635                                      struct iwl_scan_req_tx_cmd *tx_cmd,
  636                                      bool no_cck)
  637 {
  638         tx_cmd[0].tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL |
  639                                          TX_CMD_FLG_BT_DIS);
  640         tx_cmd[0].rate_n_flags = iwl_mvm_scan_rate_n_flags(mvm,
  641                                                            NL80211_BAND_2GHZ,
  642                                                            no_cck);
  643 
  644         if (iwl_fw_lookup_cmd_ver(mvm->fw, ADD_STA, 0) < 12) {
  645                 tx_cmd[0].sta_id = mvm->aux_sta.sta_id;
  646                 tx_cmd[1].sta_id = mvm->aux_sta.sta_id;
  647 
  648         /*
  649          * Fw doesn't use this sta anymore, pending deprecation via HOST API
  650          * change
  651          */
  652         } else {
  653                 tx_cmd[0].sta_id = 0xff;
  654                 tx_cmd[1].sta_id = 0xff;
  655         }
  656 
  657         tx_cmd[1].tx_flags = cpu_to_le32(TX_CMD_FLG_SEQ_CTL |
  658                                          TX_CMD_FLG_BT_DIS);
  659 
  660         tx_cmd[1].rate_n_flags = iwl_mvm_scan_rate_n_flags(mvm,
  661                                                            NL80211_BAND_5GHZ,
  662                                                            no_cck);
  663 }
  664 
  665 static void
  666 iwl_mvm_lmac_scan_cfg_channels(struct iwl_mvm *mvm,
  667                                struct ieee80211_channel **channels,
  668                                int n_channels, u32 ssid_bitmap,
  669                                struct iwl_scan_req_lmac *cmd)
  670 {
  671         struct iwl_scan_channel_cfg_lmac *channel_cfg = (void *)&cmd->data;
  672         int i;
  673 
  674         for (i = 0; i < n_channels; i++) {
  675                 channel_cfg[i].channel_num =
  676                         cpu_to_le16(channels[i]->hw_value);
  677                 channel_cfg[i].iter_count = cpu_to_le16(1);
  678                 channel_cfg[i].iter_interval = 0;
  679                 channel_cfg[i].flags =
  680                         cpu_to_le32(IWL_UNIFIED_SCAN_CHANNEL_PARTIAL |
  681                                     ssid_bitmap);
  682         }
  683 }
  684 
  685 static u8 *iwl_mvm_copy_and_insert_ds_elem(struct iwl_mvm *mvm, const u8 *ies,
  686                                            size_t len, u8 *const pos)
  687 {
  688         static const u8 before_ds_params[] = {
  689                         WLAN_EID_SSID,
  690                         WLAN_EID_SUPP_RATES,
  691                         WLAN_EID_REQUEST,
  692                         WLAN_EID_EXT_SUPP_RATES,
  693         };
  694         size_t offs;
  695         u8 *newpos = pos;
  696 
  697         if (!iwl_mvm_rrm_scan_needed(mvm)) {
  698                 memcpy(newpos, ies, len);
  699                 return newpos + len;
  700         }
  701 
  702         offs = ieee80211_ie_split(ies, len,
  703                                   before_ds_params,
  704                                   ARRAY_SIZE(before_ds_params),
  705                                   0);
  706 
  707         memcpy(newpos, ies, offs);
  708         newpos += offs;
  709 
  710         /* Add a placeholder for DS Parameter Set element */
  711         *newpos++ = WLAN_EID_DS_PARAMS;
  712         *newpos++ = 1;
  713         *newpos++ = 0;
  714 
  715         memcpy(newpos, ies + offs, len - offs);
  716         newpos += len - offs;
  717 
  718         return newpos;
  719 }
  720 
  721 #define WFA_TPC_IE_LEN  9
  722 
  723 static void iwl_mvm_add_tpc_report_ie(u8 *pos)
  724 {
  725         pos[0] = WLAN_EID_VENDOR_SPECIFIC;
  726         pos[1] = WFA_TPC_IE_LEN - 2;
  727         pos[2] = (WLAN_OUI_MICROSOFT >> 16) & 0xff;
  728         pos[3] = (WLAN_OUI_MICROSOFT >> 8) & 0xff;
  729         pos[4] = WLAN_OUI_MICROSOFT & 0xff;
  730         pos[5] = WLAN_OUI_TYPE_MICROSOFT_TPC;
  731         pos[6] = 0;
  732         /* pos[7] - tx power will be inserted by the FW */
  733         pos[7] = 0;
  734         pos[8] = 0;
  735 }
  736 
  737 static void
  738 iwl_mvm_build_scan_probe(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
  739                          struct ieee80211_scan_ies *ies,
  740                          struct iwl_mvm_scan_params *params)
  741 {
  742         struct ieee80211_mgmt *frame = (void *)params->preq.buf;
  743         u8 *pos, *newpos;
  744         const u8 *mac_addr = params->flags & NL80211_SCAN_FLAG_RANDOM_ADDR ?
  745                 params->mac_addr : NULL;
  746 
  747         /*
  748          * Unfortunately, right now the offload scan doesn't support randomising
  749          * within the firmware, so until the firmware API is ready we implement
  750          * it in the driver. This means that the scan iterations won't really be
  751          * random, only when it's restarted, but at least that helps a bit.
  752          */
  753         if (mac_addr)
  754                 get_random_mask_addr(frame->sa, mac_addr,
  755                                      params->mac_addr_mask);
  756         else
  757                 memcpy(frame->sa, vif->addr, ETH_ALEN);
  758 
  759         frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
  760         eth_broadcast_addr(frame->da);
  761         eth_broadcast_addr(frame->bssid);
  762         frame->seq_ctrl = 0;
  763 
  764         pos = frame->u.probe_req.variable;
  765         *pos++ = WLAN_EID_SSID;
  766         *pos++ = 0;
  767 
  768         params->preq.mac_header.offset = 0;
  769         params->preq.mac_header.len = cpu_to_le16(24 + 2);
  770 
  771         /* Insert ds parameter set element on 2.4 GHz band */
  772         newpos = iwl_mvm_copy_and_insert_ds_elem(mvm,
  773                                                  ies->ies[NL80211_BAND_2GHZ],
  774                                                  ies->len[NL80211_BAND_2GHZ],
  775                                                  pos);
  776         params->preq.band_data[0].offset = cpu_to_le16(pos - params->preq.buf);
  777         params->preq.band_data[0].len = cpu_to_le16(newpos - pos);
  778         pos = newpos;
  779 
  780         memcpy(pos, ies->ies[NL80211_BAND_5GHZ],
  781                ies->len[NL80211_BAND_5GHZ]);
  782         params->preq.band_data[1].offset = cpu_to_le16(pos - params->preq.buf);
  783         params->preq.band_data[1].len =
  784                 cpu_to_le16(ies->len[NL80211_BAND_5GHZ]);
  785         pos += ies->len[NL80211_BAND_5GHZ];
  786 
  787         memcpy(pos, ies->ies[NL80211_BAND_6GHZ],
  788                ies->len[NL80211_BAND_6GHZ]);
  789         params->preq.band_data[2].offset = cpu_to_le16(pos - params->preq.buf);
  790         params->preq.band_data[2].len =
  791                 cpu_to_le16(ies->len[NL80211_BAND_6GHZ]);
  792         pos += ies->len[NL80211_BAND_6GHZ];
  793         memcpy(pos, ies->common_ies, ies->common_ie_len);
  794         params->preq.common_data.offset = cpu_to_le16(pos - params->preq.buf);
  795 
  796         if (iwl_mvm_rrm_scan_needed(mvm) &&
  797             !fw_has_capa(&mvm->fw->ucode_capa,
  798                          IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT)) {
  799                 iwl_mvm_add_tpc_report_ie(pos + ies->common_ie_len);
  800                 params->preq.common_data.len = cpu_to_le16(ies->common_ie_len +
  801                                                            WFA_TPC_IE_LEN);
  802         } else {
  803                 params->preq.common_data.len = cpu_to_le16(ies->common_ie_len);
  804         }
  805 }
  806 
  807 static void iwl_mvm_scan_lmac_dwell(struct iwl_mvm *mvm,
  808                                     struct iwl_scan_req_lmac *cmd,
  809                                     struct iwl_mvm_scan_params *params)
  810 {
  811         cmd->active_dwell = IWL_SCAN_DWELL_ACTIVE;
  812         cmd->passive_dwell = IWL_SCAN_DWELL_PASSIVE;
  813         cmd->fragmented_dwell = IWL_SCAN_DWELL_FRAGMENTED;
  814         cmd->extended_dwell = IWL_SCAN_DWELL_EXTENDED;
  815         cmd->max_out_time = cpu_to_le32(scan_timing[params->type].max_out_time);
  816         cmd->suspend_time = cpu_to_le32(scan_timing[params->type].suspend_time);
  817         cmd->scan_prio = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6);
  818 }
  819 
  820 static inline bool iwl_mvm_scan_fits(struct iwl_mvm *mvm, int n_ssids,
  821                                      struct ieee80211_scan_ies *ies,
  822                                      int n_channels)
  823 {
  824         return ((n_ssids <= PROBE_OPTION_MAX) &&
  825                 (n_channels <= mvm->fw->ucode_capa.n_scan_channels) &
  826                 (ies->common_ie_len +
  827                  ies->len[NL80211_BAND_2GHZ] +
  828                  ies->len[NL80211_BAND_5GHZ] <=
  829                  iwl_mvm_max_scan_ie_fw_cmd_room(mvm)));
  830 }
  831 
  832 static inline bool iwl_mvm_scan_use_ebs(struct iwl_mvm *mvm,
  833                                         struct ieee80211_vif *vif)
  834 {
  835         const struct iwl_ucode_capabilities *capa = &mvm->fw->ucode_capa;
  836         bool low_latency;
  837 
  838         if (iwl_mvm_is_cdb_supported(mvm))
  839                 low_latency = iwl_mvm_low_latency_band(mvm, NL80211_BAND_5GHZ);
  840         else
  841                 low_latency = iwl_mvm_low_latency(mvm);
  842 
  843         /* We can only use EBS if:
  844          *      1. the feature is supported;
  845          *      2. the last EBS was successful;
  846          *      3. if only single scan, the single scan EBS API is supported;
  847          *      4. it's not a p2p find operation.
  848          *      5. we are not in low latency mode,
  849          *         or if fragmented ebs is supported by the FW
  850          */
  851         return ((capa->flags & IWL_UCODE_TLV_FLAGS_EBS_SUPPORT) &&
  852                 mvm->last_ebs_successful && IWL_MVM_ENABLE_EBS &&
  853                 vif->type != NL80211_IFTYPE_P2P_DEVICE &&
  854                 (!low_latency || iwl_mvm_is_frag_ebs_supported(mvm)));
  855 }
  856 
  857 static inline bool iwl_mvm_is_regular_scan(struct iwl_mvm_scan_params *params)
  858 {
  859         return params->n_scan_plans == 1 &&
  860                 params->scan_plans[0].iterations == 1;
  861 }
  862 
  863 static bool iwl_mvm_is_scan_fragmented(enum iwl_mvm_scan_type type)
  864 {
  865         return (type == IWL_SCAN_TYPE_FRAGMENTED ||
  866                 type == IWL_SCAN_TYPE_FAST_BALANCE);
  867 }
  868 
  869 static int iwl_mvm_scan_lmac_flags(struct iwl_mvm *mvm,
  870                                    struct iwl_mvm_scan_params *params,
  871                                    struct ieee80211_vif *vif)
  872 {
  873         int flags = 0;
  874 
  875         if (params->n_ssids == 0)
  876                 flags |= IWL_MVM_LMAC_SCAN_FLAG_PASSIVE;
  877 
  878         if (params->n_ssids == 1 && params->ssids[0].ssid_len != 0)
  879                 flags |= IWL_MVM_LMAC_SCAN_FLAG_PRE_CONNECTION;
  880 
  881         if (iwl_mvm_is_scan_fragmented(params->type))
  882                 flags |= IWL_MVM_LMAC_SCAN_FLAG_FRAGMENTED;
  883 
  884         if (iwl_mvm_rrm_scan_needed(mvm) &&
  885             fw_has_capa(&mvm->fw->ucode_capa,
  886                         IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT))
  887                 flags |= IWL_MVM_LMAC_SCAN_FLAGS_RRM_ENABLED;
  888 
  889         if (params->pass_all)
  890                 flags |= IWL_MVM_LMAC_SCAN_FLAG_PASS_ALL;
  891         else
  892                 flags |= IWL_MVM_LMAC_SCAN_FLAG_MATCH;
  893 
  894 #ifdef CONFIG_IWLWIFI_DEBUGFS
  895         if (mvm->scan_iter_notif_enabled)
  896                 flags |= IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE;
  897 #endif
  898 
  899         if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_ENABLED)
  900                 flags |= IWL_MVM_LMAC_SCAN_FLAG_ITER_COMPLETE;
  901 
  902         if (iwl_mvm_is_regular_scan(params) &&
  903             vif->type != NL80211_IFTYPE_P2P_DEVICE &&
  904             !iwl_mvm_is_scan_fragmented(params->type))
  905                 flags |= IWL_MVM_LMAC_SCAN_FLAG_EXTENDED_DWELL;
  906 
  907         return flags;
  908 }
  909 
  910 static void
  911 iwl_mvm_scan_set_legacy_probe_req(struct iwl_scan_probe_req_v1 *p_req,
  912                                   struct iwl_scan_probe_req *src_p_req)
  913 {
  914         int i;
  915 
  916         p_req->mac_header = src_p_req->mac_header;
  917         for (i = 0; i < SCAN_NUM_BAND_PROBE_DATA_V_1; i++)
  918                 p_req->band_data[i] = src_p_req->band_data[i];
  919         p_req->common_data = src_p_req->common_data;
  920         memcpy(p_req->buf, src_p_req->buf, sizeof(p_req->buf));
  921 }
  922 
  923 static int iwl_mvm_scan_lmac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
  924                              struct iwl_mvm_scan_params *params)
  925 {
  926         struct iwl_scan_req_lmac *cmd = mvm->scan_cmd;
  927         struct iwl_scan_probe_req_v1 *preq =
  928                 (void *)(cmd->data + sizeof(struct iwl_scan_channel_cfg_lmac) *
  929                          mvm->fw->ucode_capa.n_scan_channels);
  930         u32 ssid_bitmap = 0;
  931         int i;
  932         u8 band;
  933 
  934         if (WARN_ON(params->n_scan_plans > IWL_MAX_SCHED_SCAN_PLANS))
  935                 return -EINVAL;
  936 
  937         iwl_mvm_scan_lmac_dwell(mvm, cmd, params);
  938 
  939         cmd->rx_chain_select = iwl_mvm_scan_rx_chain(mvm);
  940         cmd->iter_num = cpu_to_le32(1);
  941         cmd->n_channels = (u8)params->n_channels;
  942 
  943         cmd->delay = cpu_to_le32(params->delay);
  944 
  945         cmd->scan_flags = cpu_to_le32(iwl_mvm_scan_lmac_flags(mvm, params,
  946                                                               vif));
  947 
  948         band = iwl_mvm_phy_band_from_nl80211(params->channels[0]->band);
  949         cmd->flags = cpu_to_le32(band);
  950         cmd->filter_flags = cpu_to_le32(MAC_FILTER_ACCEPT_GRP |
  951                                         MAC_FILTER_IN_BEACON);
  952         iwl_mvm_scan_fill_tx_cmd(mvm, cmd->tx_cmd, params->no_cck);
  953         iwl_scan_build_ssids(params, cmd->direct_scan, &ssid_bitmap);
  954 
  955         /* this API uses bits 1-20 instead of 0-19 */
  956         ssid_bitmap <<= 1;
  957 
  958         for (i = 0; i < params->n_scan_plans; i++) {
  959                 struct cfg80211_sched_scan_plan *scan_plan =
  960                         &params->scan_plans[i];
  961 
  962                 cmd->schedule[i].delay =
  963                         cpu_to_le16(scan_plan->interval);
  964                 cmd->schedule[i].iterations = scan_plan->iterations;
  965                 cmd->schedule[i].full_scan_mul = 1;
  966         }
  967 
  968         /*
  969          * If the number of iterations of the last scan plan is set to
  970          * zero, it should run infinitely. However, this is not always the case.
  971          * For example, when regular scan is requested the driver sets one scan
  972          * plan with one iteration.
  973          */
  974         if (!cmd->schedule[i - 1].iterations)
  975                 cmd->schedule[i - 1].iterations = 0xff;
  976 
  977         if (iwl_mvm_scan_use_ebs(mvm, vif)) {
  978                 cmd->channel_opt[0].flags =
  979                         cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
  980                                     IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
  981                                     IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
  982                 cmd->channel_opt[0].non_ebs_ratio =
  983                         cpu_to_le16(IWL_DENSE_EBS_SCAN_RATIO);
  984                 cmd->channel_opt[1].flags =
  985                         cpu_to_le16(IWL_SCAN_CHANNEL_FLAG_EBS |
  986                                     IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
  987                                     IWL_SCAN_CHANNEL_FLAG_CACHE_ADD);
  988                 cmd->channel_opt[1].non_ebs_ratio =
  989                         cpu_to_le16(IWL_SPARSE_EBS_SCAN_RATIO);
  990         }
  991 
  992         iwl_mvm_lmac_scan_cfg_channels(mvm, params->channels,
  993                                        params->n_channels, ssid_bitmap, cmd);
  994 
  995         iwl_mvm_scan_set_legacy_probe_req(preq, &params->preq);
  996 
  997         return 0;
  998 }
  999 
 1000 static int rate_to_scan_rate_flag(unsigned int rate)
 1001 {
 1002         static const int rate_to_scan_rate[IWL_RATE_COUNT] = {
 1003                 [IWL_RATE_1M_INDEX]     = SCAN_CONFIG_RATE_1M,
 1004                 [IWL_RATE_2M_INDEX]     = SCAN_CONFIG_RATE_2M,
 1005                 [IWL_RATE_5M_INDEX]     = SCAN_CONFIG_RATE_5M,
 1006                 [IWL_RATE_11M_INDEX]    = SCAN_CONFIG_RATE_11M,
 1007                 [IWL_RATE_6M_INDEX]     = SCAN_CONFIG_RATE_6M,
 1008                 [IWL_RATE_9M_INDEX]     = SCAN_CONFIG_RATE_9M,
 1009                 [IWL_RATE_12M_INDEX]    = SCAN_CONFIG_RATE_12M,
 1010                 [IWL_RATE_18M_INDEX]    = SCAN_CONFIG_RATE_18M,
 1011                 [IWL_RATE_24M_INDEX]    = SCAN_CONFIG_RATE_24M,
 1012                 [IWL_RATE_36M_INDEX]    = SCAN_CONFIG_RATE_36M,
 1013                 [IWL_RATE_48M_INDEX]    = SCAN_CONFIG_RATE_48M,
 1014                 [IWL_RATE_54M_INDEX]    = SCAN_CONFIG_RATE_54M,
 1015         };
 1016 
 1017         return rate_to_scan_rate[rate];
 1018 }
 1019 
 1020 static __le32 iwl_mvm_scan_config_rates(struct iwl_mvm *mvm)
 1021 {
 1022         struct ieee80211_supported_band *band;
 1023         unsigned int rates = 0;
 1024         int i;
 1025 
 1026         band = &mvm->nvm_data->bands[NL80211_BAND_2GHZ];
 1027         for (i = 0; i < band->n_bitrates; i++)
 1028                 rates |= rate_to_scan_rate_flag(band->bitrates[i].hw_value);
 1029         band = &mvm->nvm_data->bands[NL80211_BAND_5GHZ];
 1030         for (i = 0; i < band->n_bitrates; i++)
 1031                 rates |= rate_to_scan_rate_flag(band->bitrates[i].hw_value);
 1032 
 1033         /* Set both basic rates and supported rates */
 1034         rates |= SCAN_CONFIG_SUPPORTED_RATE(rates);
 1035 
 1036         return cpu_to_le32(rates);
 1037 }
 1038 
 1039 static void iwl_mvm_fill_scan_dwell(struct iwl_mvm *mvm,
 1040                                     struct iwl_scan_dwell *dwell)
 1041 {
 1042         dwell->active = IWL_SCAN_DWELL_ACTIVE;
 1043         dwell->passive = IWL_SCAN_DWELL_PASSIVE;
 1044         dwell->fragmented = IWL_SCAN_DWELL_FRAGMENTED;
 1045         dwell->extended = IWL_SCAN_DWELL_EXTENDED;
 1046 }
 1047 
 1048 static void iwl_mvm_fill_channels(struct iwl_mvm *mvm, u8 *channels,
 1049                                   u32 max_channels)
 1050 {
 1051         struct ieee80211_supported_band *band;
 1052         int i, j = 0;
 1053 
 1054         band = &mvm->nvm_data->bands[NL80211_BAND_2GHZ];
 1055         for (i = 0; i < band->n_channels && j < max_channels; i++, j++)
 1056                 channels[j] = band->channels[i].hw_value;
 1057         band = &mvm->nvm_data->bands[NL80211_BAND_5GHZ];
 1058         for (i = 0; i < band->n_channels && j < max_channels; i++, j++)
 1059                 channels[j] = band->channels[i].hw_value;
 1060 }
 1061 
 1062 static void iwl_mvm_fill_scan_config_v1(struct iwl_mvm *mvm, void *config,
 1063                                         u32 flags, u8 channel_flags,
 1064                                         u32 max_channels)
 1065 {
 1066         enum iwl_mvm_scan_type type = iwl_mvm_get_scan_type(mvm, NULL);
 1067         struct iwl_scan_config_v1 *cfg = config;
 1068 
 1069         cfg->flags = cpu_to_le32(flags);
 1070         cfg->tx_chains = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm));
 1071         cfg->rx_chains = cpu_to_le32(iwl_mvm_scan_rx_ant(mvm));
 1072         cfg->legacy_rates = iwl_mvm_scan_config_rates(mvm);
 1073         cfg->out_of_channel_time = cpu_to_le32(scan_timing[type].max_out_time);
 1074         cfg->suspend_time = cpu_to_le32(scan_timing[type].suspend_time);
 1075 
 1076         iwl_mvm_fill_scan_dwell(mvm, &cfg->dwell);
 1077 
 1078         memcpy(&cfg->mac_addr, &mvm->addresses[0].addr, ETH_ALEN);
 1079 
 1080         /* This function should not be called when using ADD_STA ver >=12 */
 1081         WARN_ON_ONCE(iwl_fw_lookup_cmd_ver(mvm->fw, ADD_STA, 0) >= 12);
 1082 
 1083         cfg->bcast_sta_id = mvm->aux_sta.sta_id;
 1084         cfg->channel_flags = channel_flags;
 1085 
 1086         iwl_mvm_fill_channels(mvm, cfg->channel_array, max_channels);
 1087 }
 1088 
 1089 static void iwl_mvm_fill_scan_config_v2(struct iwl_mvm *mvm, void *config,
 1090                                         u32 flags, u8 channel_flags,
 1091                                         u32 max_channels)
 1092 {
 1093         struct iwl_scan_config_v2 *cfg = config;
 1094 
 1095         cfg->flags = cpu_to_le32(flags);
 1096         cfg->tx_chains = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm));
 1097         cfg->rx_chains = cpu_to_le32(iwl_mvm_scan_rx_ant(mvm));
 1098         cfg->legacy_rates = iwl_mvm_scan_config_rates(mvm);
 1099 
 1100         if (iwl_mvm_is_cdb_supported(mvm)) {
 1101                 enum iwl_mvm_scan_type lb_type, hb_type;
 1102 
 1103                 lb_type = iwl_mvm_get_scan_type_band(mvm, NULL,
 1104                                                      NL80211_BAND_2GHZ);
 1105                 hb_type = iwl_mvm_get_scan_type_band(mvm, NULL,
 1106                                                      NL80211_BAND_5GHZ);
 1107 
 1108                 cfg->out_of_channel_time[SCAN_LB_LMAC_IDX] =
 1109                         cpu_to_le32(scan_timing[lb_type].max_out_time);
 1110                 cfg->suspend_time[SCAN_LB_LMAC_IDX] =
 1111                         cpu_to_le32(scan_timing[lb_type].suspend_time);
 1112 
 1113                 cfg->out_of_channel_time[SCAN_HB_LMAC_IDX] =
 1114                         cpu_to_le32(scan_timing[hb_type].max_out_time);
 1115                 cfg->suspend_time[SCAN_HB_LMAC_IDX] =
 1116                         cpu_to_le32(scan_timing[hb_type].suspend_time);
 1117         } else {
 1118                 enum iwl_mvm_scan_type type =
 1119                         iwl_mvm_get_scan_type(mvm, NULL);
 1120 
 1121                 cfg->out_of_channel_time[SCAN_LB_LMAC_IDX] =
 1122                         cpu_to_le32(scan_timing[type].max_out_time);
 1123                 cfg->suspend_time[SCAN_LB_LMAC_IDX] =
 1124                         cpu_to_le32(scan_timing[type].suspend_time);
 1125         }
 1126 
 1127         iwl_mvm_fill_scan_dwell(mvm, &cfg->dwell);
 1128 
 1129         memcpy(&cfg->mac_addr, &mvm->addresses[0].addr, ETH_ALEN);
 1130 
 1131         /* This function should not be called when using ADD_STA ver >=12 */
 1132         WARN_ON_ONCE(iwl_fw_lookup_cmd_ver(mvm->fw, ADD_STA, 0) >= 12);
 1133 
 1134         cfg->bcast_sta_id = mvm->aux_sta.sta_id;
 1135         cfg->channel_flags = channel_flags;
 1136 
 1137         iwl_mvm_fill_channels(mvm, cfg->channel_array, max_channels);
 1138 }
 1139 
 1140 static int iwl_mvm_legacy_config_scan(struct iwl_mvm *mvm)
 1141 {
 1142         void *cfg;
 1143         int ret, cmd_size;
 1144         struct iwl_host_cmd cmd = {
 1145                 .id = WIDE_ID(IWL_ALWAYS_LONG_GROUP, SCAN_CFG_CMD),
 1146         };
 1147         enum iwl_mvm_scan_type type;
 1148         enum iwl_mvm_scan_type hb_type = IWL_SCAN_TYPE_NOT_SET;
 1149         int num_channels =
 1150                 mvm->nvm_data->bands[NL80211_BAND_2GHZ].n_channels +
 1151                 mvm->nvm_data->bands[NL80211_BAND_5GHZ].n_channels;
 1152         u32 flags;
 1153         u8 channel_flags;
 1154 
 1155         if (WARN_ON(num_channels > mvm->fw->ucode_capa.n_scan_channels))
 1156                 num_channels = mvm->fw->ucode_capa.n_scan_channels;
 1157 
 1158         if (iwl_mvm_is_cdb_supported(mvm)) {
 1159                 type = iwl_mvm_get_scan_type_band(mvm, NULL,
 1160                                                   NL80211_BAND_2GHZ);
 1161                 hb_type = iwl_mvm_get_scan_type_band(mvm, NULL,
 1162                                                      NL80211_BAND_5GHZ);
 1163                 if (type == mvm->scan_type && hb_type == mvm->hb_scan_type)
 1164                         return 0;
 1165         } else {
 1166                 type = iwl_mvm_get_scan_type(mvm, NULL);
 1167                 if (type == mvm->scan_type)
 1168                         return 0;
 1169         }
 1170 
 1171         if (iwl_mvm_cdb_scan_api(mvm))
 1172                 cmd_size = sizeof(struct iwl_scan_config_v2);
 1173         else
 1174                 cmd_size = sizeof(struct iwl_scan_config_v1);
 1175         cmd_size += mvm->fw->ucode_capa.n_scan_channels;
 1176 
 1177         cfg = kzalloc(cmd_size, GFP_KERNEL);
 1178         if (!cfg)
 1179                 return -ENOMEM;
 1180 
 1181         flags = SCAN_CONFIG_FLAG_ACTIVATE |
 1182                  SCAN_CONFIG_FLAG_ALLOW_CHUB_REQS |
 1183                  SCAN_CONFIG_FLAG_SET_TX_CHAINS |
 1184                  SCAN_CONFIG_FLAG_SET_RX_CHAINS |
 1185                  SCAN_CONFIG_FLAG_SET_AUX_STA_ID |
 1186                  SCAN_CONFIG_FLAG_SET_ALL_TIMES |
 1187                  SCAN_CONFIG_FLAG_SET_LEGACY_RATES |
 1188                  SCAN_CONFIG_FLAG_SET_MAC_ADDR |
 1189                  SCAN_CONFIG_FLAG_SET_CHANNEL_FLAGS |
 1190                  SCAN_CONFIG_N_CHANNELS(num_channels) |
 1191                  (iwl_mvm_is_scan_fragmented(type) ?
 1192                   SCAN_CONFIG_FLAG_SET_FRAGMENTED :
 1193                   SCAN_CONFIG_FLAG_CLEAR_FRAGMENTED);
 1194 
 1195         channel_flags = IWL_CHANNEL_FLAG_EBS |
 1196                         IWL_CHANNEL_FLAG_ACCURATE_EBS |
 1197                         IWL_CHANNEL_FLAG_EBS_ADD |
 1198                         IWL_CHANNEL_FLAG_PRE_SCAN_PASSIVE2ACTIVE;
 1199 
 1200         /*
 1201          * Check for fragmented scan on LMAC2 - high band.
 1202          * LMAC1 - low band is checked above.
 1203          */
 1204         if (iwl_mvm_cdb_scan_api(mvm)) {
 1205                 if (iwl_mvm_is_cdb_supported(mvm))
 1206                         flags |= (iwl_mvm_is_scan_fragmented(hb_type)) ?
 1207                                  SCAN_CONFIG_FLAG_SET_LMAC2_FRAGMENTED :
 1208                                  SCAN_CONFIG_FLAG_CLEAR_LMAC2_FRAGMENTED;
 1209                 iwl_mvm_fill_scan_config_v2(mvm, cfg, flags, channel_flags,
 1210                                             num_channels);
 1211         } else {
 1212                 iwl_mvm_fill_scan_config_v1(mvm, cfg, flags, channel_flags,
 1213                                             num_channels);
 1214         }
 1215 
 1216         cmd.data[0] = cfg;
 1217         cmd.len[0] = cmd_size;
 1218         cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
 1219 
 1220         IWL_DEBUG_SCAN(mvm, "Sending UMAC scan config\n");
 1221 
 1222         ret = iwl_mvm_send_cmd(mvm, &cmd);
 1223         if (!ret) {
 1224                 mvm->scan_type = type;
 1225                 mvm->hb_scan_type = hb_type;
 1226         }
 1227 
 1228         kfree(cfg);
 1229         return ret;
 1230 }
 1231 
 1232 int iwl_mvm_config_scan(struct iwl_mvm *mvm)
 1233 {
 1234         struct iwl_scan_config cfg;
 1235         struct iwl_host_cmd cmd = {
 1236                 .id = WIDE_ID(IWL_ALWAYS_LONG_GROUP, SCAN_CFG_CMD),
 1237                 .len[0] = sizeof(cfg),
 1238                 .data[0] = &cfg,
 1239                 .dataflags[0] = IWL_HCMD_DFL_NOCOPY,
 1240         };
 1241 
 1242         if (!iwl_mvm_is_reduced_config_scan_supported(mvm))
 1243                 return iwl_mvm_legacy_config_scan(mvm);
 1244 
 1245         memset(&cfg, 0, sizeof(cfg));
 1246 
 1247         if (iwl_fw_lookup_cmd_ver(mvm->fw, ADD_STA, 0) < 12) {
 1248                 cfg.bcast_sta_id = mvm->aux_sta.sta_id;
 1249         } else if (iwl_fw_lookup_cmd_ver(mvm->fw, SCAN_CFG_CMD, 0) < 5) {
 1250                 /*
 1251                  * Fw doesn't use this sta anymore. Deprecated on SCAN_CFG_CMD
 1252                  * version 5.
 1253                  */
 1254                 cfg.bcast_sta_id = 0xff;
 1255         }
 1256 
 1257         cfg.tx_chains = cpu_to_le32(iwl_mvm_get_valid_tx_ant(mvm));
 1258         cfg.rx_chains = cpu_to_le32(iwl_mvm_scan_rx_ant(mvm));
 1259 
 1260         IWL_DEBUG_SCAN(mvm, "Sending UMAC scan config\n");
 1261 
 1262         return iwl_mvm_send_cmd(mvm, &cmd);
 1263 }
 1264 
 1265 static int iwl_mvm_scan_uid_by_status(struct iwl_mvm *mvm, int status)
 1266 {
 1267         int i;
 1268 
 1269         for (i = 0; i < mvm->max_scans; i++)
 1270                 if (mvm->scan_uid_status[i] == status)
 1271                         return i;
 1272 
 1273         return -ENOENT;
 1274 }
 1275 
 1276 static void iwl_mvm_scan_umac_dwell(struct iwl_mvm *mvm,
 1277                                     struct iwl_scan_req_umac *cmd,
 1278                                     struct iwl_mvm_scan_params *params)
 1279 {
 1280         struct iwl_mvm_scan_timing_params *timing, *hb_timing;
 1281         u8 active_dwell, passive_dwell;
 1282 
 1283         timing = &scan_timing[params->type];
 1284         active_dwell = IWL_SCAN_DWELL_ACTIVE;
 1285         passive_dwell = IWL_SCAN_DWELL_PASSIVE;
 1286 
 1287         if (iwl_mvm_is_adaptive_dwell_supported(mvm)) {
 1288                 cmd->v7.adwell_default_n_aps_social =
 1289                         IWL_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL;
 1290                 cmd->v7.adwell_default_n_aps =
 1291                         IWL_SCAN_ADWELL_DEFAULT_LB_N_APS;
 1292 
 1293                 if (iwl_mvm_is_adwell_hb_ap_num_supported(mvm))
 1294                         cmd->v9.adwell_default_hb_n_aps =
 1295                                 IWL_SCAN_ADWELL_DEFAULT_HB_N_APS;
 1296 
 1297                 /* if custom max budget was configured with debugfs */
 1298                 if (IWL_MVM_ADWELL_MAX_BUDGET)
 1299                         cmd->v7.adwell_max_budget =
 1300                                 cpu_to_le16(IWL_MVM_ADWELL_MAX_BUDGET);
 1301                 else if (params->ssids && params->ssids[0].ssid_len)
 1302                         cmd->v7.adwell_max_budget =
 1303                                 cpu_to_le16(IWL_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN);
 1304                 else
 1305                         cmd->v7.adwell_max_budget =
 1306                                 cpu_to_le16(IWL_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN);
 1307 
 1308                 cmd->v7.scan_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6);
 1309                 cmd->v7.max_out_time[SCAN_LB_LMAC_IDX] =
 1310                         cpu_to_le32(timing->max_out_time);
 1311                 cmd->v7.suspend_time[SCAN_LB_LMAC_IDX] =
 1312                         cpu_to_le32(timing->suspend_time);
 1313 
 1314                 if (iwl_mvm_is_cdb_supported(mvm)) {
 1315                         hb_timing = &scan_timing[params->hb_type];
 1316 
 1317                         cmd->v7.max_out_time[SCAN_HB_LMAC_IDX] =
 1318                                 cpu_to_le32(hb_timing->max_out_time);
 1319                         cmd->v7.suspend_time[SCAN_HB_LMAC_IDX] =
 1320                                 cpu_to_le32(hb_timing->suspend_time);
 1321                 }
 1322 
 1323                 if (!iwl_mvm_is_adaptive_dwell_v2_supported(mvm)) {
 1324                         cmd->v7.active_dwell = active_dwell;
 1325                         cmd->v7.passive_dwell = passive_dwell;
 1326                         cmd->v7.fragmented_dwell = IWL_SCAN_DWELL_FRAGMENTED;
 1327                 } else {
 1328                         cmd->v8.active_dwell[SCAN_LB_LMAC_IDX] = active_dwell;
 1329                         cmd->v8.passive_dwell[SCAN_LB_LMAC_IDX] = passive_dwell;
 1330                         if (iwl_mvm_is_cdb_supported(mvm)) {
 1331                                 cmd->v8.active_dwell[SCAN_HB_LMAC_IDX] =
 1332                                         active_dwell;
 1333                                 cmd->v8.passive_dwell[SCAN_HB_LMAC_IDX] =
 1334                                         passive_dwell;
 1335                         }
 1336                 }
 1337         } else {
 1338                 cmd->v1.extended_dwell = IWL_SCAN_DWELL_EXTENDED;
 1339                 cmd->v1.active_dwell = active_dwell;
 1340                 cmd->v1.passive_dwell = passive_dwell;
 1341                 cmd->v1.fragmented_dwell = IWL_SCAN_DWELL_FRAGMENTED;
 1342 
 1343                 if (iwl_mvm_is_cdb_supported(mvm)) {
 1344                         hb_timing = &scan_timing[params->hb_type];
 1345 
 1346                         cmd->v6.max_out_time[SCAN_HB_LMAC_IDX] =
 1347                                         cpu_to_le32(hb_timing->max_out_time);
 1348                         cmd->v6.suspend_time[SCAN_HB_LMAC_IDX] =
 1349                                         cpu_to_le32(hb_timing->suspend_time);
 1350                 }
 1351 
 1352                 if (iwl_mvm_cdb_scan_api(mvm)) {
 1353                         cmd->v6.scan_priority =
 1354                                 cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6);
 1355                         cmd->v6.max_out_time[SCAN_LB_LMAC_IDX] =
 1356                                 cpu_to_le32(timing->max_out_time);
 1357                         cmd->v6.suspend_time[SCAN_LB_LMAC_IDX] =
 1358                                 cpu_to_le32(timing->suspend_time);
 1359                 } else {
 1360                         cmd->v1.scan_priority =
 1361                                 cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6);
 1362                         cmd->v1.max_out_time =
 1363                                 cpu_to_le32(timing->max_out_time);
 1364                         cmd->v1.suspend_time =
 1365                                 cpu_to_le32(timing->suspend_time);
 1366                 }
 1367         }
 1368 
 1369         if (iwl_mvm_is_regular_scan(params))
 1370                 cmd->ooc_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6);
 1371         else
 1372                 cmd->ooc_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_2);
 1373 }
 1374 
 1375 static u32 iwl_mvm_scan_umac_ooc_priority(struct iwl_mvm_scan_params *params)
 1376 {
 1377         return iwl_mvm_is_regular_scan(params) ?
 1378                 IWL_SCAN_PRIORITY_EXT_6 :
 1379                 IWL_SCAN_PRIORITY_EXT_2;
 1380 }
 1381 
 1382 static void
 1383 iwl_mvm_scan_umac_dwell_v11(struct iwl_mvm *mvm,
 1384                             struct iwl_scan_general_params_v11 *general_params,
 1385                             struct iwl_mvm_scan_params *params)
 1386 {
 1387         struct iwl_mvm_scan_timing_params *timing, *hb_timing;
 1388         u8 active_dwell, passive_dwell;
 1389 
 1390         timing = &scan_timing[params->type];
 1391         active_dwell = IWL_SCAN_DWELL_ACTIVE;
 1392         passive_dwell = IWL_SCAN_DWELL_PASSIVE;
 1393 
 1394         general_params->adwell_default_social_chn =
 1395                 IWL_SCAN_ADWELL_DEFAULT_N_APS_SOCIAL;
 1396         general_params->adwell_default_2g = IWL_SCAN_ADWELL_DEFAULT_LB_N_APS;
 1397         general_params->adwell_default_5g = IWL_SCAN_ADWELL_DEFAULT_HB_N_APS;
 1398 
 1399         /* if custom max budget was configured with debugfs */
 1400         if (IWL_MVM_ADWELL_MAX_BUDGET)
 1401                 general_params->adwell_max_budget =
 1402                         cpu_to_le16(IWL_MVM_ADWELL_MAX_BUDGET);
 1403         else if (params->ssids && params->ssids[0].ssid_len)
 1404                 general_params->adwell_max_budget =
 1405                         cpu_to_le16(IWL_SCAN_ADWELL_MAX_BUDGET_DIRECTED_SCAN);
 1406         else
 1407                 general_params->adwell_max_budget =
 1408                         cpu_to_le16(IWL_SCAN_ADWELL_MAX_BUDGET_FULL_SCAN);
 1409 
 1410         general_params->scan_priority = cpu_to_le32(IWL_SCAN_PRIORITY_EXT_6);
 1411         general_params->max_out_of_time[SCAN_LB_LMAC_IDX] =
 1412                 cpu_to_le32(timing->max_out_time);
 1413         general_params->suspend_time[SCAN_LB_LMAC_IDX] =
 1414                 cpu_to_le32(timing->suspend_time);
 1415 
 1416         hb_timing = &scan_timing[params->hb_type];
 1417 
 1418         general_params->max_out_of_time[SCAN_HB_LMAC_IDX] =
 1419                 cpu_to_le32(hb_timing->max_out_time);
 1420         general_params->suspend_time[SCAN_HB_LMAC_IDX] =
 1421                 cpu_to_le32(hb_timing->suspend_time);
 1422 
 1423         general_params->active_dwell[SCAN_LB_LMAC_IDX] = active_dwell;
 1424         general_params->passive_dwell[SCAN_LB_LMAC_IDX] = passive_dwell;
 1425         general_params->active_dwell[SCAN_HB_LMAC_IDX] = active_dwell;
 1426         general_params->passive_dwell[SCAN_HB_LMAC_IDX] = passive_dwell;
 1427 }
 1428 
 1429 struct iwl_mvm_scan_channel_segment {
 1430         u8 start_idx;
 1431         u8 end_idx;
 1432         u8 first_channel_id;
 1433         u8 last_channel_id;
 1434         u8 channel_spacing_shift;
 1435         u8 band;
 1436 };
 1437 
 1438 static const struct iwl_mvm_scan_channel_segment scan_channel_segments[] = {
 1439         {
 1440                 .start_idx = 0,
 1441                 .end_idx = 13,
 1442                 .first_channel_id = 1,
 1443                 .last_channel_id = 14,
 1444                 .channel_spacing_shift = 0,
 1445                 .band = PHY_BAND_24
 1446         },
 1447         {
 1448                 .start_idx = 14,
 1449                 .end_idx = 41,
 1450                 .first_channel_id = 36,
 1451                 .last_channel_id = 144,
 1452                 .channel_spacing_shift = 2,
 1453                 .band = PHY_BAND_5
 1454         },
 1455         {
 1456                 .start_idx = 42,
 1457                 .end_idx = 50,
 1458                 .first_channel_id = 149,
 1459                 .last_channel_id = 181,
 1460                 .channel_spacing_shift = 2,
 1461                 .band = PHY_BAND_5
 1462         },
 1463         {
 1464                 .start_idx = 51,
 1465                 .end_idx = 111,
 1466                 .first_channel_id = 1,
 1467                 .last_channel_id = 241,
 1468                 .channel_spacing_shift = 2,
 1469                 .band = PHY_BAND_6
 1470         },
 1471 };
 1472 
 1473 static int iwl_mvm_scan_ch_and_band_to_idx(u8 channel_id, u8 band)
 1474 {
 1475         int i, index;
 1476 
 1477         if (!channel_id)
 1478                 return -EINVAL;
 1479 
 1480         for (i = 0; i < ARRAY_SIZE(scan_channel_segments); i++) {
 1481                 const struct iwl_mvm_scan_channel_segment *ch_segment =
 1482                         &scan_channel_segments[i];
 1483                 u32 ch_offset;
 1484 
 1485                 if (ch_segment->band != band ||
 1486                     ch_segment->first_channel_id > channel_id ||
 1487                     ch_segment->last_channel_id < channel_id)
 1488                         continue;
 1489 
 1490                 ch_offset = (channel_id - ch_segment->first_channel_id) >>
 1491                         ch_segment->channel_spacing_shift;
 1492 
 1493                 index = scan_channel_segments[i].start_idx + ch_offset;
 1494                 if (index < IWL_SCAN_NUM_CHANNELS)
 1495                         return index;
 1496 
 1497                 break;
 1498         }
 1499 
 1500         return -EINVAL;
 1501 }
 1502 
 1503 static const u8 p2p_go_friendly_chs[] = {
 1504         36, 40, 44, 48, 149, 153, 157, 161, 165,
 1505 };
 1506 
 1507 static const u8 social_chs[] = {
 1508         1, 6, 11
 1509 };
 1510 
 1511 static void iwl_mvm_scan_ch_add_n_aps_override(enum nl80211_iftype vif_type,
 1512                                                u8 ch_id, u8 band, u8 *ch_bitmap,
 1513                                                size_t bitmap_n_entries)
 1514 {
 1515         int i;
 1516 
 1517         if (vif_type != NL80211_IFTYPE_P2P_DEVICE)
 1518                 return;
 1519 
 1520         for (i = 0; i < ARRAY_SIZE(p2p_go_friendly_chs); i++) {
 1521                 if (p2p_go_friendly_chs[i] == ch_id) {
 1522                         int ch_idx, bitmap_idx;
 1523 
 1524                         ch_idx = iwl_mvm_scan_ch_and_band_to_idx(ch_id, band);
 1525                         if (ch_idx < 0)
 1526                                 return;
 1527 
 1528                         bitmap_idx = ch_idx / 8;
 1529                         if (bitmap_idx >= bitmap_n_entries)
 1530                                 return;
 1531 
 1532                         ch_idx = ch_idx % 8;
 1533                         ch_bitmap[bitmap_idx] |= BIT(ch_idx);
 1534 
 1535                         return;
 1536                 }
 1537         }
 1538 }
 1539 
 1540 static u32 iwl_mvm_scan_ch_n_aps_flag(enum nl80211_iftype vif_type, u8 ch_id)
 1541 {
 1542         int i;
 1543         u32 flags = 0;
 1544 
 1545         if (vif_type != NL80211_IFTYPE_P2P_DEVICE)
 1546                 goto out;
 1547 
 1548         for (i = 0; i < ARRAY_SIZE(p2p_go_friendly_chs); i++) {
 1549                 if (p2p_go_friendly_chs[i] == ch_id) {
 1550                         flags |= IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY_BIT;
 1551                         break;
 1552                 }
 1553         }
 1554 
 1555         if (flags)
 1556                 goto out;
 1557 
 1558         for (i = 0; i < ARRAY_SIZE(social_chs); i++) {
 1559                 if (social_chs[i] == ch_id) {
 1560                         flags |= IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS_BIT;
 1561                         break;
 1562                 }
 1563         }
 1564 
 1565 out:
 1566         return flags;
 1567 }
 1568 
 1569 static void
 1570 iwl_mvm_umac_scan_cfg_channels(struct iwl_mvm *mvm,
 1571                                struct ieee80211_channel **channels,
 1572                                int n_channels, u32 flags,
 1573                                struct iwl_scan_channel_cfg_umac *channel_cfg)
 1574 {
 1575         int i;
 1576 
 1577         for (i = 0; i < n_channels; i++) {
 1578                 channel_cfg[i].flags = cpu_to_le32(flags);
 1579                 channel_cfg[i].v1.channel_num = channels[i]->hw_value;
 1580                 if (iwl_mvm_is_scan_ext_chan_supported(mvm)) {
 1581                         enum nl80211_band band = channels[i]->band;
 1582 
 1583                         channel_cfg[i].v2.band =
 1584                                 iwl_mvm_phy_band_from_nl80211(band);
 1585                         channel_cfg[i].v2.iter_count = 1;
 1586                         channel_cfg[i].v2.iter_interval = 0;
 1587                 } else {
 1588                         channel_cfg[i].v1.iter_count = 1;
 1589                         channel_cfg[i].v1.iter_interval = 0;
 1590                 }
 1591         }
 1592 }
 1593 
 1594 static void
 1595 iwl_mvm_umac_scan_cfg_channels_v4(struct iwl_mvm *mvm,
 1596                                   struct ieee80211_channel **channels,
 1597                                   struct iwl_scan_channel_params_v4 *cp,
 1598                                   int n_channels, u32 flags,
 1599                                   enum nl80211_iftype vif_type)
 1600 {
 1601         u8 *bitmap = cp->adwell_ch_override_bitmap;
 1602         size_t bitmap_n_entries = ARRAY_SIZE(cp->adwell_ch_override_bitmap);
 1603         int i;
 1604 
 1605         for (i = 0; i < n_channels; i++) {
 1606                 enum nl80211_band band = channels[i]->band;
 1607                 struct iwl_scan_channel_cfg_umac *cfg =
 1608                         &cp->channel_config[i];
 1609 
 1610                 cfg->flags = cpu_to_le32(flags);
 1611                 cfg->v2.channel_num = channels[i]->hw_value;
 1612                 cfg->v2.band = iwl_mvm_phy_band_from_nl80211(band);
 1613                 cfg->v2.iter_count = 1;
 1614                 cfg->v2.iter_interval = 0;
 1615 
 1616                 iwl_mvm_scan_ch_add_n_aps_override(vif_type,
 1617                                                    cfg->v2.channel_num,
 1618                                                    cfg->v2.band, bitmap,
 1619                                                    bitmap_n_entries);
 1620         }
 1621 }
 1622 
 1623 static void
 1624 iwl_mvm_umac_scan_cfg_channels_v6(struct iwl_mvm *mvm,
 1625                                   struct ieee80211_channel **channels,
 1626                                   struct iwl_scan_channel_params_v6 *cp,
 1627                                   int n_channels, u32 flags,
 1628                                   enum nl80211_iftype vif_type)
 1629 {
 1630         int i;
 1631 
 1632         for (i = 0; i < n_channels; i++) {
 1633                 enum nl80211_band band = channels[i]->band;
 1634                 struct iwl_scan_channel_cfg_umac *cfg = &cp->channel_config[i];
 1635                 u32 n_aps_flag =
 1636                         iwl_mvm_scan_ch_n_aps_flag(vif_type,
 1637                                                    channels[i]->hw_value);
 1638 
 1639                 cfg->flags = cpu_to_le32(flags | n_aps_flag);
 1640                 cfg->v2.channel_num = channels[i]->hw_value;
 1641                 cfg->v2.band = iwl_mvm_phy_band_from_nl80211(band);
 1642                 if (cfg80211_channel_is_psc(channels[i]))
 1643                         cfg->flags = 0;
 1644                 cfg->v2.iter_count = 1;
 1645                 cfg->v2.iter_interval = 0;
 1646         }
 1647 }
 1648 
 1649 static void
 1650 iwl_mvm_umac_scan_fill_6g_chan_list(struct iwl_mvm *mvm,
 1651                                     struct iwl_mvm_scan_params *params,
 1652                                      struct iwl_scan_probe_params_v4 *pp)
 1653 {
 1654         int j, idex_s = 0, idex_b = 0;
 1655         struct cfg80211_scan_6ghz_params *scan_6ghz_params =
 1656                 params->scan_6ghz_params;
 1657         bool hidden_supported = fw_has_capa(&mvm->fw->ucode_capa,
 1658                                             IWL_UCODE_TLV_CAPA_HIDDEN_6GHZ_SCAN);
 1659 
 1660         for (j = 0; j < params->n_ssids && idex_s < SCAN_SHORT_SSID_MAX_SIZE;
 1661              j++) {
 1662                 if (!params->ssids[j].ssid_len)
 1663                         continue;
 1664 
 1665                 pp->short_ssid[idex_s] =
 1666                         cpu_to_le32(~crc32_le(~0, params->ssids[j].ssid,
 1667                                               params->ssids[j].ssid_len));
 1668 
 1669                 if (hidden_supported) {
 1670                         pp->direct_scan[idex_s].id = WLAN_EID_SSID;
 1671                         pp->direct_scan[idex_s].len = params->ssids[j].ssid_len;
 1672                         memcpy(pp->direct_scan[idex_s].ssid, params->ssids[j].ssid,
 1673                                params->ssids[j].ssid_len);
 1674                 }
 1675                 idex_s++;
 1676         }
 1677 
 1678         /*
 1679          * Populate the arrays of the short SSIDs and the BSSIDs using the 6GHz
 1680          * collocated parameters. This might not be optimal, as this processing
 1681          * does not (yet) correspond to the actual channels, so it is possible
 1682          * that some entries would be left out.
 1683          *
 1684          * TODO: improve this logic.
 1685          */
 1686         for (j = 0; j < params->n_6ghz_params; j++) {
 1687                 int k;
 1688 
 1689                 /* First, try to place the short SSID */
 1690                 if (scan_6ghz_params[j].short_ssid_valid) {
 1691                         for (k = 0; k < idex_s; k++) {
 1692                                 if (pp->short_ssid[k] ==
 1693                                     cpu_to_le32(scan_6ghz_params[j].short_ssid))
 1694                                         break;
 1695                         }
 1696 
 1697                         if (k == idex_s && idex_s < SCAN_SHORT_SSID_MAX_SIZE) {
 1698                                 pp->short_ssid[idex_s++] =
 1699                                         cpu_to_le32(scan_6ghz_params[j].short_ssid);
 1700                         }
 1701                 }
 1702 
 1703                 /* try to place BSSID for the same entry */
 1704                 for (k = 0; k < idex_b; k++) {
 1705                         if (!memcmp(&pp->bssid_array[k],
 1706                                     scan_6ghz_params[j].bssid, ETH_ALEN))
 1707                                 break;
 1708                 }
 1709 
 1710                 if (k == idex_b && idex_b < SCAN_BSSID_MAX_SIZE) {
 1711                         memcpy(&pp->bssid_array[idex_b++],
 1712                                scan_6ghz_params[j].bssid, ETH_ALEN);
 1713                 }
 1714         }
 1715 
 1716         pp->short_ssid_num = idex_s;
 1717         pp->bssid_num = idex_b;
 1718 }
 1719 
 1720 /* TODO: this function can be merged with iwl_mvm_scan_umac_fill_ch_p_v6 */
 1721 static u32
 1722 iwl_mvm_umac_scan_cfg_channels_v6_6g(struct iwl_mvm *mvm,
 1723                                      struct iwl_mvm_scan_params *params,
 1724                                      u32 n_channels,
 1725                                      struct iwl_scan_probe_params_v4 *pp,
 1726                                      struct iwl_scan_channel_params_v6 *cp,
 1727                                      enum nl80211_iftype vif_type)
 1728 {
 1729         int i;
 1730         struct cfg80211_scan_6ghz_params *scan_6ghz_params =
 1731                 params->scan_6ghz_params;
 1732         u32 ch_cnt;
 1733 
 1734         for (i = 0, ch_cnt = 0; i < params->n_channels; i++) {
 1735                 struct iwl_scan_channel_cfg_umac *cfg =
 1736                         &cp->channel_config[ch_cnt];
 1737 
 1738                 u32 s_ssid_bitmap = 0, bssid_bitmap = 0, flags = 0;
 1739                 u8 j, k, s_max = 0, b_max = 0, n_used_bssid_entries;
 1740                 bool force_passive, found = false, allow_passive = true,
 1741                      unsolicited_probe_on_chan = false, psc_no_listen = false;
 1742 
 1743                 /*
 1744                  * Avoid performing passive scan on non PSC channels unless the
 1745                  * scan is specifically a passive scan, i.e., no SSIDs
 1746                  * configured in the scan command.
 1747                  */
 1748                 if (!cfg80211_channel_is_psc(params->channels[i]) &&
 1749                     !params->n_6ghz_params && params->n_ssids)
 1750                         continue;
 1751 
 1752                 cfg->v1.channel_num = params->channels[i]->hw_value;
 1753                 cfg->v2.band = 2;
 1754                 cfg->v2.iter_count = 1;
 1755                 cfg->v2.iter_interval = 0;
 1756 
 1757                 /*
 1758                  * The optimize the scan time, i.e., reduce the scan dwell time
 1759                  * on each channel, the below logic tries to set 3 direct BSSID
 1760                  * probe requests for each broadcast probe request with a short
 1761                  * SSID.
 1762                  * TODO: improve this logic
 1763                  */
 1764                 n_used_bssid_entries = 3;
 1765                 for (j = 0; j < params->n_6ghz_params; j++) {
 1766                         if (!(scan_6ghz_params[j].channel_idx == i))
 1767                                 continue;
 1768 
 1769                         found = false;
 1770                         unsolicited_probe_on_chan |=
 1771                                 scan_6ghz_params[j].unsolicited_probe;
 1772                         psc_no_listen |= scan_6ghz_params[j].psc_no_listen;
 1773 
 1774                         for (k = 0; k < pp->short_ssid_num; k++) {
 1775                                 if (!scan_6ghz_params[j].unsolicited_probe &&
 1776                                     le32_to_cpu(pp->short_ssid[k]) ==
 1777                                     scan_6ghz_params[j].short_ssid) {
 1778                                         /* Relevant short SSID bit set */
 1779                                         if (s_ssid_bitmap & BIT(k)) {
 1780                                                 found = true;
 1781                                                 break;
 1782                                         }
 1783 
 1784                                         /*
 1785                                          * Use short SSID only to create a new
 1786                                          * iteration during channel dwell or in
 1787                                          * case that the short SSID has a
 1788                                          * matching SSID, i.e., scan for hidden
 1789                                          * APs.
 1790                                          */
 1791                                         if (n_used_bssid_entries >= 3) {
 1792                                                 s_ssid_bitmap |= BIT(k);
 1793                                                 s_max++;
 1794                                                 n_used_bssid_entries -= 3;
 1795                                                 found = true;
 1796                                                 break;
 1797                                         } else if (pp->direct_scan[k].len) {
 1798                                                 s_ssid_bitmap |= BIT(k);
 1799                                                 s_max++;
 1800                                                 found = true;
 1801                                                 allow_passive = false;
 1802                                                 break;
 1803                                         }
 1804                                 }
 1805                         }
 1806 
 1807                         if (found)
 1808                                 continue;
 1809 
 1810                         for (k = 0; k < pp->bssid_num; k++) {
 1811                                 if (!memcmp(&pp->bssid_array[k],
 1812                                             scan_6ghz_params[j].bssid,
 1813                                             ETH_ALEN)) {
 1814                                         if (!(bssid_bitmap & BIT(k))) {
 1815                                                 bssid_bitmap |= BIT(k);
 1816                                                 b_max++;
 1817                                                 n_used_bssid_entries++;
 1818                                         }
 1819                                         break;
 1820                                 }
 1821                         }
 1822                 }
 1823 
 1824                 if (cfg80211_channel_is_psc(params->channels[i]) &&
 1825                     psc_no_listen)
 1826                         flags |= IWL_UHB_CHAN_CFG_FLAG_PSC_CHAN_NO_LISTEN;
 1827 
 1828                 if (unsolicited_probe_on_chan)
 1829                         flags |= IWL_UHB_CHAN_CFG_FLAG_UNSOLICITED_PROBE_RES;
 1830 
 1831                 /*
 1832                  * In the following cases apply passive scan:
 1833                  * 1. Non fragmented scan:
 1834                  *      - PSC channel with NO_LISTEN_FLAG on should be treated
 1835                  *        like non PSC channel
 1836                  *      - Non PSC channel with more than 3 short SSIDs or more
 1837                  *        than 9 BSSIDs.
 1838                  *      - Non PSC Channel with unsolicited probe response and
 1839                  *        more than 2 short SSIDs or more than 6 BSSIDs.
 1840                  *      - PSC channel with more than 2 short SSIDs or more than
 1841                  *        6 BSSIDs.
 1842                  * 3. Fragmented scan:
 1843                  *      - PSC channel with more than 1 SSID or 3 BSSIDs.
 1844                  *      - Non PSC channel with more than 2 SSIDs or 6 BSSIDs.
 1845                  *      - Non PSC channel with unsolicited probe response and
 1846                  *        more than 1 SSID or more than 3 BSSIDs.
 1847                  */
 1848                 if (!iwl_mvm_is_scan_fragmented(params->type)) {
 1849                         if (!cfg80211_channel_is_psc(params->channels[i]) ||
 1850                             flags & IWL_UHB_CHAN_CFG_FLAG_PSC_CHAN_NO_LISTEN) {
 1851                                 force_passive = (s_max > 3 || b_max > 9);
 1852                                 force_passive |= (unsolicited_probe_on_chan &&
 1853                                                   (s_max > 2 || b_max > 6));
 1854                         } else {
 1855                                 force_passive = (s_max > 2 || b_max > 6);
 1856                         }
 1857                 } else if (cfg80211_channel_is_psc(params->channels[i])) {
 1858                         force_passive = (s_max > 1 || b_max > 3);
 1859                 } else {
 1860                         force_passive = (s_max > 2 || b_max > 6);
 1861                         force_passive |= (unsolicited_probe_on_chan &&
 1862                                           (s_max > 1 || b_max > 3));
 1863                 }
 1864                 if ((allow_passive && force_passive) ||
 1865                     (!(bssid_bitmap | s_ssid_bitmap) &&
 1866                      !cfg80211_channel_is_psc(params->channels[i])))
 1867                         flags |= IWL_UHB_CHAN_CFG_FLAG_FORCE_PASSIVE;
 1868                 else
 1869                         flags |= bssid_bitmap | (s_ssid_bitmap << 16);
 1870 
 1871                 cfg->flags |= cpu_to_le32(flags);
 1872                 ch_cnt++;
 1873         }
 1874 
 1875         if (params->n_channels > ch_cnt)
 1876                 IWL_DEBUG_SCAN(mvm,
 1877                                "6GHz: reducing number channels: (%u->%u)\n",
 1878                                params->n_channels, ch_cnt);
 1879 
 1880         return ch_cnt;
 1881 }
 1882 
 1883 static u8 iwl_mvm_scan_umac_chan_flags_v2(struct iwl_mvm *mvm,
 1884                                           struct iwl_mvm_scan_params *params,
 1885                                           struct ieee80211_vif *vif)
 1886 {
 1887         u8 flags = 0;
 1888 
 1889         flags |= IWL_SCAN_CHANNEL_FLAG_ENABLE_CHAN_ORDER;
 1890 
 1891         if (iwl_mvm_scan_use_ebs(mvm, vif))
 1892                 flags |= IWL_SCAN_CHANNEL_FLAG_EBS |
 1893                         IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
 1894                         IWL_SCAN_CHANNEL_FLAG_CACHE_ADD;
 1895 
 1896         /* set fragmented ebs for fragmented scan on HB channels */
 1897         if ((!iwl_mvm_is_cdb_supported(mvm) &&
 1898              iwl_mvm_is_scan_fragmented(params->type)) ||
 1899             (iwl_mvm_is_cdb_supported(mvm) &&
 1900              iwl_mvm_is_scan_fragmented(params->hb_type)))
 1901                 flags |= IWL_SCAN_CHANNEL_FLAG_EBS_FRAG;
 1902 
 1903         /*
 1904          * force EBS in case the scan is a fragmented and there is a need to take P2P
 1905          * GO operation into consideration during scan operation.
 1906          */
 1907         if ((!iwl_mvm_is_cdb_supported(mvm) &&
 1908              iwl_mvm_is_scan_fragmented(params->type) && params->respect_p2p_go) ||
 1909             (iwl_mvm_is_cdb_supported(mvm) &&
 1910              iwl_mvm_is_scan_fragmented(params->hb_type) &&
 1911              params->respect_p2p_go_hb)) {
 1912                 IWL_DEBUG_SCAN(mvm, "Respect P2P GO. Force EBS\n");
 1913                 flags |= IWL_SCAN_CHANNEL_FLAG_FORCE_EBS;
 1914         }
 1915 
 1916         return flags;
 1917 }
 1918 
 1919 static void iwl_mvm_scan_6ghz_passive_scan(struct iwl_mvm *mvm,
 1920                                            struct iwl_mvm_scan_params *params,
 1921                                            struct ieee80211_vif *vif)
 1922 {
 1923         struct ieee80211_supported_band *sband =
 1924                 &mvm->nvm_data->bands[NL80211_BAND_6GHZ];
 1925         u32 n_disabled, i;
 1926 
 1927         params->enable_6ghz_passive = false;
 1928 
 1929         if (params->scan_6ghz)
 1930                 return;
 1931 
 1932         if (!fw_has_capa(&mvm->fw->ucode_capa,
 1933                          IWL_UCODE_TLV_CAPA_PASSIVE_6GHZ_SCAN)) {
 1934                 IWL_DEBUG_SCAN(mvm,
 1935                                "6GHz passive scan: Not supported by FW\n");
 1936                 return;
 1937         }
 1938 
 1939         /* 6GHz passive scan allowed only on station interface  */
 1940         if (vif->type != NL80211_IFTYPE_STATION) {
 1941                 IWL_DEBUG_SCAN(mvm,
 1942                                "6GHz passive scan: not station interface\n");
 1943                 return;
 1944         }
 1945 
 1946         /*
 1947          * 6GHz passive scan is allowed in a defined time interval following HW
 1948          * reset or resume flow, or while not associated and a large interval
 1949          * has passed since the last 6GHz passive scan.
 1950          */
 1951         if ((vif->bss_conf.assoc ||
 1952              time_after(mvm->last_6ghz_passive_scan_jiffies +
 1953                         (IWL_MVM_6GHZ_PASSIVE_SCAN_TIMEOUT * HZ), jiffies)) &&
 1954             (time_before(mvm->last_reset_or_resume_time_jiffies +
 1955                          (IWL_MVM_6GHZ_PASSIVE_SCAN_ASSOC_TIMEOUT * HZ),
 1956                          jiffies))) {
 1957                 IWL_DEBUG_SCAN(mvm, "6GHz passive scan: %s\n",
 1958                                vif->bss_conf.assoc ? "associated" :
 1959                                "timeout did not expire");
 1960                 return;
 1961         }
 1962 
 1963         /* not enough channels in the regular scan request */
 1964         if (params->n_channels < IWL_MVM_6GHZ_PASSIVE_SCAN_MIN_CHANS) {
 1965                 IWL_DEBUG_SCAN(mvm,
 1966                                "6GHz passive scan: not enough channels\n");
 1967                 return;
 1968         }
 1969 
 1970         for (i = 0; i < params->n_ssids; i++) {
 1971                 if (!params->ssids[i].ssid_len)
 1972                         break;
 1973         }
 1974 
 1975         /* not a wildcard scan, so cannot enable passive 6GHz scan */
 1976         if (i == params->n_ssids) {
 1977                 IWL_DEBUG_SCAN(mvm,
 1978                                "6GHz passive scan: no wildcard SSID\n");
 1979                 return;
 1980         }
 1981 
 1982         if (!sband || !sband->n_channels) {
 1983                 IWL_DEBUG_SCAN(mvm,
 1984                                "6GHz passive scan: no 6GHz channels\n");
 1985                 return;
 1986         }
 1987 
 1988         for (i = 0, n_disabled = 0; i < sband->n_channels; i++) {
 1989                 if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED))
 1990                         n_disabled++;
 1991         }
 1992 
 1993         /*
 1994          * Not all the 6GHz channels are disabled, so no need for 6GHz passive
 1995          * scan
 1996          */
 1997         if (n_disabled != sband->n_channels) {
 1998                 IWL_DEBUG_SCAN(mvm,
 1999                                "6GHz passive scan: 6GHz channels enabled\n");
 2000                 return;
 2001         }
 2002 
 2003         /* all conditions to enable 6ghz passive scan are satisfied */
 2004         IWL_DEBUG_SCAN(mvm, "6GHz passive scan: can be enabled\n");
 2005         params->enable_6ghz_passive = true;
 2006 }
 2007 
 2008 static u16 iwl_mvm_scan_umac_flags_v2(struct iwl_mvm *mvm,
 2009                                       struct iwl_mvm_scan_params *params,
 2010                                       struct ieee80211_vif *vif,
 2011                                       int type)
 2012 {
 2013         u16 flags = 0;
 2014 
 2015         /*
 2016          * If no direct SSIDs are provided perform a passive scan. Otherwise,
 2017          * if there is a single SSID which is not the broadcast SSID, assume
 2018          * that the scan is intended for roaming purposes and thus enable Rx on
 2019          * all chains to improve chances of hearing the beacons/probe responses.
 2020          */
 2021         if (params->n_ssids == 0)
 2022                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_FORCE_PASSIVE;
 2023         else if (params->n_ssids == 1 && params->ssids[0].ssid_len)
 2024                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_USE_ALL_RX_CHAINS;
 2025 
 2026         if (iwl_mvm_is_scan_fragmented(params->type))
 2027                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC1;
 2028 
 2029         if (iwl_mvm_is_scan_fragmented(params->hb_type))
 2030                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC2;
 2031 
 2032         if (params->pass_all)
 2033                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_PASS_ALL;
 2034         else
 2035                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_MATCH;
 2036 
 2037         if (!iwl_mvm_is_regular_scan(params))
 2038                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_PERIODIC;
 2039 
 2040         if (params->iter_notif ||
 2041             mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_ENABLED)
 2042                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_NTFY_ITER_COMPLETE;
 2043 
 2044         if (IWL_MVM_ADWELL_ENABLE)
 2045                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_ADAPTIVE_DWELL;
 2046 
 2047         if (type == IWL_MVM_SCAN_SCHED || type == IWL_MVM_SCAN_NETDETECT)
 2048                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_PREEMPTIVE;
 2049 
 2050         if ((type == IWL_MVM_SCAN_SCHED || type == IWL_MVM_SCAN_NETDETECT) &&
 2051             params->flags & NL80211_SCAN_FLAG_COLOCATED_6GHZ)
 2052                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_TRIGGER_UHB_SCAN;
 2053 
 2054         if (params->enable_6ghz_passive)
 2055                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_6GHZ_PASSIVE_SCAN;
 2056 
 2057         if (iwl_mvm_is_oce_supported(mvm) &&
 2058             (params->flags & (NL80211_SCAN_FLAG_ACCEPT_BCAST_PROBE_RESP |
 2059                               NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE |
 2060                               NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME)))
 2061                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_V2_OCE;
 2062 
 2063         return flags;
 2064 }
 2065 
 2066 static u8 iwl_mvm_scan_umac_flags2(struct iwl_mvm *mvm,
 2067                                    struct iwl_mvm_scan_params *params,
 2068                                    struct ieee80211_vif *vif, int type)
 2069 {
 2070         u8 flags = 0;
 2071 
 2072         if (iwl_mvm_is_cdb_supported(mvm)) {
 2073                 if (params->respect_p2p_go)
 2074                         flags |= IWL_UMAC_SCAN_GEN_PARAMS_FLAGS2_RESPECT_P2P_GO_LB;
 2075                 if (params->respect_p2p_go_hb)
 2076                         flags |= IWL_UMAC_SCAN_GEN_PARAMS_FLAGS2_RESPECT_P2P_GO_HB;
 2077         } else {
 2078                 if (params->respect_p2p_go)
 2079                         flags = IWL_UMAC_SCAN_GEN_PARAMS_FLAGS2_RESPECT_P2P_GO_LB |
 2080                                 IWL_UMAC_SCAN_GEN_PARAMS_FLAGS2_RESPECT_P2P_GO_HB;
 2081         }
 2082 
 2083         return flags;
 2084 }
 2085 
 2086 static u16 iwl_mvm_scan_umac_flags(struct iwl_mvm *mvm,
 2087                                    struct iwl_mvm_scan_params *params,
 2088                                    struct ieee80211_vif *vif)
 2089 {
 2090         u16 flags = 0;
 2091 
 2092         if (params->n_ssids == 0)
 2093                 flags = IWL_UMAC_SCAN_GEN_FLAGS_PASSIVE;
 2094 
 2095         if (params->n_ssids == 1 && params->ssids[0].ssid_len != 0)
 2096                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_PRE_CONNECT;
 2097 
 2098         if (iwl_mvm_is_scan_fragmented(params->type))
 2099                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_FRAGMENTED;
 2100 
 2101         if (iwl_mvm_is_cdb_supported(mvm) &&
 2102             iwl_mvm_is_scan_fragmented(params->hb_type))
 2103                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_LMAC2_FRAGMENTED;
 2104 
 2105         if (iwl_mvm_rrm_scan_needed(mvm) &&
 2106             fw_has_capa(&mvm->fw->ucode_capa,
 2107                         IWL_UCODE_TLV_CAPA_WFA_TPC_REP_IE_SUPPORT))
 2108                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_RRM_ENABLED;
 2109 
 2110         if (params->pass_all)
 2111                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_PASS_ALL;
 2112         else
 2113                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_MATCH;
 2114 
 2115         if (!iwl_mvm_is_regular_scan(params))
 2116                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_PERIODIC;
 2117 
 2118         if (params->iter_notif)
 2119                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE;
 2120 
 2121 #ifdef CONFIG_IWLWIFI_DEBUGFS
 2122         if (mvm->scan_iter_notif_enabled)
 2123                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE;
 2124 #endif
 2125 
 2126         if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_ENABLED)
 2127                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_ITER_COMPLETE;
 2128 
 2129         if (iwl_mvm_is_adaptive_dwell_supported(mvm) && IWL_MVM_ADWELL_ENABLE)
 2130                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_ADAPTIVE_DWELL;
 2131 
 2132         /*
 2133          * Extended dwell is relevant only for low band to start with, as it is
 2134          * being used for social channles only (1, 6, 11), so we can check
 2135          * only scan type on low band also for CDB.
 2136          */
 2137         if (iwl_mvm_is_regular_scan(params) &&
 2138             vif->type != NL80211_IFTYPE_P2P_DEVICE &&
 2139             !iwl_mvm_is_scan_fragmented(params->type) &&
 2140             !iwl_mvm_is_adaptive_dwell_supported(mvm) &&
 2141             !iwl_mvm_is_oce_supported(mvm))
 2142                 flags |= IWL_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL;
 2143 
 2144         if (iwl_mvm_is_oce_supported(mvm)) {
 2145                 if ((params->flags &
 2146                      NL80211_SCAN_FLAG_OCE_PROBE_REQ_HIGH_TX_RATE))
 2147                         flags |= IWL_UMAC_SCAN_GEN_FLAGS_PROB_REQ_HIGH_TX_RATE;
 2148                 /* Since IWL_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL and
 2149                  * NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION shares
 2150                  * the same bit, we need to make sure that we use this bit here
 2151                  * only when IWL_UMAC_SCAN_GEN_FLAGS_EXTENDED_DWELL cannot be
 2152                  * used. */
 2153                 if ((params->flags &
 2154                      NL80211_SCAN_FLAG_OCE_PROBE_REQ_DEFERRAL_SUPPRESSION) &&
 2155                      !WARN_ON_ONCE(!iwl_mvm_is_adaptive_dwell_supported(mvm)))
 2156                         flags |= IWL_UMAC_SCAN_GEN_FLAGS_PROB_REQ_DEFER_SUPP;
 2157                 if ((params->flags & NL80211_SCAN_FLAG_FILS_MAX_CHANNEL_TIME))
 2158                         flags |= IWL_UMAC_SCAN_GEN_FLAGS_MAX_CHNL_TIME;
 2159         }
 2160 
 2161         return flags;
 2162 }
 2163 
 2164 static int
 2165 iwl_mvm_fill_scan_sched_params(struct iwl_mvm_scan_params *params,
 2166                                struct iwl_scan_umac_schedule *schedule,
 2167                                __le16 *delay)
 2168 {
 2169         int i;
 2170         if (WARN_ON(!params->n_scan_plans ||
 2171                     params->n_scan_plans > IWL_MAX_SCHED_SCAN_PLANS))
 2172                 return -EINVAL;
 2173 
 2174         for (i = 0; i < params->n_scan_plans; i++) {
 2175                 struct cfg80211_sched_scan_plan *scan_plan =
 2176                         &params->scan_plans[i];
 2177 
 2178                 schedule[i].iter_count = scan_plan->iterations;
 2179                 schedule[i].interval =
 2180                         cpu_to_le16(scan_plan->interval);
 2181         }
 2182 
 2183         /*
 2184          * If the number of iterations of the last scan plan is set to
 2185          * zero, it should run infinitely. However, this is not always the case.
 2186          * For example, when regular scan is requested the driver sets one scan
 2187          * plan with one iteration.
 2188          */
 2189         if (!schedule[params->n_scan_plans - 1].iter_count)
 2190                 schedule[params->n_scan_plans - 1].iter_count = 0xff;
 2191 
 2192         *delay = cpu_to_le16(params->delay);
 2193 
 2194         return 0;
 2195 }
 2196 
 2197 static int iwl_mvm_scan_umac(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 2198                              struct iwl_mvm_scan_params *params,
 2199                              int type, int uid)
 2200 {
 2201         struct iwl_scan_req_umac *cmd = mvm->scan_cmd;
 2202         struct iwl_scan_umac_chan_param *chan_param;
 2203         void *cmd_data = iwl_mvm_get_scan_req_umac_data(mvm);
 2204         void *sec_part = (u8 *)cmd_data + sizeof(struct iwl_scan_channel_cfg_umac) *
 2205                 mvm->fw->ucode_capa.n_scan_channels;
 2206         struct iwl_scan_req_umac_tail_v2 *tail_v2 =
 2207                 (struct iwl_scan_req_umac_tail_v2 *)sec_part;
 2208         struct iwl_scan_req_umac_tail_v1 *tail_v1;
 2209         struct iwl_ssid_ie *direct_scan;
 2210         int ret = 0;
 2211         u32 ssid_bitmap = 0;
 2212         u8 channel_flags = 0;
 2213         u16 gen_flags;
 2214         struct iwl_mvm_vif *scan_vif = iwl_mvm_vif_from_mac80211(vif);
 2215 
 2216         chan_param = iwl_mvm_get_scan_req_umac_channel(mvm);
 2217 
 2218         iwl_mvm_scan_umac_dwell(mvm, cmd, params);
 2219 
 2220         mvm->scan_uid_status[uid] = type;
 2221 
 2222         cmd->uid = cpu_to_le32(uid);
 2223         gen_flags = iwl_mvm_scan_umac_flags(mvm, params, vif);
 2224         cmd->general_flags = cpu_to_le16(gen_flags);
 2225         if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm)) {
 2226                 if (gen_flags & IWL_UMAC_SCAN_GEN_FLAGS_FRAGMENTED)
 2227                         cmd->v8.num_of_fragments[SCAN_LB_LMAC_IDX] =
 2228                                                         IWL_SCAN_NUM_OF_FRAGS;
 2229                 if (gen_flags & IWL_UMAC_SCAN_GEN_FLAGS_LMAC2_FRAGMENTED)
 2230                         cmd->v8.num_of_fragments[SCAN_HB_LMAC_IDX] =
 2231                                                         IWL_SCAN_NUM_OF_FRAGS;
 2232 
 2233                 cmd->v8.general_flags2 =
 2234                         IWL_UMAC_SCAN_GEN_FLAGS2_ALLOW_CHNL_REORDER;
 2235         }
 2236 
 2237         cmd->scan_start_mac_id = scan_vif->id;
 2238 
 2239         if (type == IWL_MVM_SCAN_SCHED || type == IWL_MVM_SCAN_NETDETECT)
 2240                 cmd->flags = cpu_to_le32(IWL_UMAC_SCAN_FLAG_PREEMPTIVE);
 2241 
 2242         if (iwl_mvm_scan_use_ebs(mvm, vif)) {
 2243                 channel_flags = IWL_SCAN_CHANNEL_FLAG_EBS |
 2244                                 IWL_SCAN_CHANNEL_FLAG_EBS_ACCURATE |
 2245                                 IWL_SCAN_CHANNEL_FLAG_CACHE_ADD;
 2246 
 2247                 /* set fragmented ebs for fragmented scan on HB channels */
 2248                 if (iwl_mvm_is_frag_ebs_supported(mvm)) {
 2249                         if (gen_flags &
 2250                             IWL_UMAC_SCAN_GEN_FLAGS_LMAC2_FRAGMENTED ||
 2251                             (!iwl_mvm_is_cdb_supported(mvm) &&
 2252                              gen_flags & IWL_UMAC_SCAN_GEN_FLAGS_FRAGMENTED))
 2253                                 channel_flags |= IWL_SCAN_CHANNEL_FLAG_EBS_FRAG;
 2254                 }
 2255         }
 2256 
 2257         chan_param->flags = channel_flags;
 2258         chan_param->count = params->n_channels;
 2259 
 2260         ret = iwl_mvm_fill_scan_sched_params(params, tail_v2->schedule,
 2261                                              &tail_v2->delay);
 2262         if (ret) {
 2263                 mvm->scan_uid_status[uid] = 0;
 2264                 return ret;
 2265         }
 2266 
 2267         if (iwl_mvm_is_scan_ext_chan_supported(mvm)) {
 2268                 tail_v2->preq = params->preq;
 2269                 direct_scan = tail_v2->direct_scan;
 2270         } else {
 2271                 tail_v1 = (struct iwl_scan_req_umac_tail_v1 *)sec_part;
 2272                 iwl_mvm_scan_set_legacy_probe_req(&tail_v1->preq,
 2273                                                   &params->preq);
 2274                 direct_scan = tail_v1->direct_scan;
 2275         }
 2276         iwl_scan_build_ssids(params, direct_scan, &ssid_bitmap);
 2277         iwl_mvm_umac_scan_cfg_channels(mvm, params->channels,
 2278                                        params->n_channels, ssid_bitmap,
 2279                                        cmd_data);
 2280         return 0;
 2281 }
 2282 
 2283 static void
 2284 iwl_mvm_scan_umac_fill_general_p_v11(struct iwl_mvm *mvm,
 2285                                      struct iwl_mvm_scan_params *params,
 2286                                      struct ieee80211_vif *vif,
 2287                                      struct iwl_scan_general_params_v11 *gp,
 2288                                      u16 gen_flags, u8 gen_flags2)
 2289 {
 2290         struct iwl_mvm_vif *scan_vif = iwl_mvm_vif_from_mac80211(vif);
 2291 
 2292         iwl_mvm_scan_umac_dwell_v11(mvm, gp, params);
 2293 
 2294         IWL_DEBUG_SCAN(mvm, "Gerenal: flags=0x%x, flags2=0x%x\n",
 2295                        gen_flags, gen_flags2);
 2296 
 2297         gp->flags = cpu_to_le16(gen_flags);
 2298         gp->flags2 = gen_flags2;
 2299 
 2300         if (gen_flags & IWL_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC1)
 2301                 gp->num_of_fragments[SCAN_LB_LMAC_IDX] = IWL_SCAN_NUM_OF_FRAGS;
 2302         if (gen_flags & IWL_UMAC_SCAN_GEN_FLAGS_V2_FRAGMENTED_LMAC2)
 2303                 gp->num_of_fragments[SCAN_HB_LMAC_IDX] = IWL_SCAN_NUM_OF_FRAGS;
 2304 
 2305         gp->scan_start_mac_id = scan_vif->id;
 2306 }
 2307 
 2308 static void
 2309 iwl_mvm_scan_umac_fill_probe_p_v3(struct iwl_mvm_scan_params *params,
 2310                                   struct iwl_scan_probe_params_v3 *pp)
 2311 {
 2312         pp->preq = params->preq;
 2313         pp->ssid_num = params->n_ssids;
 2314         iwl_scan_build_ssids(params, pp->direct_scan, NULL);
 2315 }
 2316 
 2317 static void
 2318 iwl_mvm_scan_umac_fill_probe_p_v4(struct iwl_mvm_scan_params *params,
 2319                                   struct iwl_scan_probe_params_v4 *pp,
 2320                                   u32 *bitmap_ssid)
 2321 {
 2322         pp->preq = params->preq;
 2323         iwl_scan_build_ssids(params, pp->direct_scan, bitmap_ssid);
 2324 }
 2325 
 2326 static void
 2327 iwl_mvm_scan_umac_fill_ch_p_v4(struct iwl_mvm *mvm,
 2328                                struct iwl_mvm_scan_params *params,
 2329                                struct ieee80211_vif *vif,
 2330                                struct iwl_scan_channel_params_v4 *cp,
 2331                                u32 channel_cfg_flags)
 2332 {
 2333         cp->flags = iwl_mvm_scan_umac_chan_flags_v2(mvm, params, vif);
 2334         cp->count = params->n_channels;
 2335         cp->num_of_aps_override = IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY;
 2336 
 2337         iwl_mvm_umac_scan_cfg_channels_v4(mvm, params->channels, cp,
 2338                                           params->n_channels,
 2339                                           channel_cfg_flags,
 2340                                           vif->type);
 2341 }
 2342 
 2343 static void
 2344 iwl_mvm_scan_umac_fill_ch_p_v6(struct iwl_mvm *mvm,
 2345                                struct iwl_mvm_scan_params *params,
 2346                                struct ieee80211_vif *vif,
 2347                                struct iwl_scan_channel_params_v6 *cp,
 2348                                u32 channel_cfg_flags)
 2349 {
 2350         cp->flags = iwl_mvm_scan_umac_chan_flags_v2(mvm, params, vif);
 2351         cp->count = params->n_channels;
 2352         cp->n_aps_override[0] = IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY;
 2353         cp->n_aps_override[1] = IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS;
 2354 
 2355         iwl_mvm_umac_scan_cfg_channels_v6(mvm, params->channels, cp,
 2356                                           params->n_channels,
 2357                                           channel_cfg_flags,
 2358                                           vif->type);
 2359 
 2360         if (params->enable_6ghz_passive) {
 2361                 struct ieee80211_supported_band *sband =
 2362                         &mvm->nvm_data->bands[NL80211_BAND_6GHZ];
 2363                 u32 i;
 2364 
 2365                 for (i = 0; i < sband->n_channels; i++) {
 2366                         struct ieee80211_channel *channel =
 2367                                 &sband->channels[i];
 2368 
 2369                         struct iwl_scan_channel_cfg_umac *cfg =
 2370                                 &cp->channel_config[cp->count];
 2371 
 2372                         if (!cfg80211_channel_is_psc(channel))
 2373                                 continue;
 2374 
 2375                         cfg->flags = 0;
 2376                         cfg->v2.channel_num = channel->hw_value;
 2377                         cfg->v2.band = PHY_BAND_6;
 2378                         cfg->v2.iter_count = 1;
 2379                         cfg->v2.iter_interval = 0;
 2380                         cp->count++;
 2381                 }
 2382         }
 2383 }
 2384 
 2385 static int iwl_mvm_scan_umac_v12(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 2386                                  struct iwl_mvm_scan_params *params, int type,
 2387                                  int uid)
 2388 {
 2389         struct iwl_scan_req_umac_v12 *cmd = mvm->scan_cmd;
 2390         struct iwl_scan_req_params_v12 *scan_p = &cmd->scan_params;
 2391         int ret;
 2392         u16 gen_flags;
 2393 
 2394         mvm->scan_uid_status[uid] = type;
 2395 
 2396         cmd->ooc_priority = cpu_to_le32(iwl_mvm_scan_umac_ooc_priority(params));
 2397         cmd->uid = cpu_to_le32(uid);
 2398 
 2399         gen_flags = iwl_mvm_scan_umac_flags_v2(mvm, params, vif, type);
 2400         iwl_mvm_scan_umac_fill_general_p_v11(mvm, params, vif,
 2401                                              &scan_p->general_params,
 2402                                              gen_flags, 0);
 2403 
 2404         ret = iwl_mvm_fill_scan_sched_params(params,
 2405                                              scan_p->periodic_params.schedule,
 2406                                              &scan_p->periodic_params.delay);
 2407         if (ret)
 2408                 return ret;
 2409 
 2410         iwl_mvm_scan_umac_fill_probe_p_v3(params, &scan_p->probe_params);
 2411         iwl_mvm_scan_umac_fill_ch_p_v4(mvm, params, vif,
 2412                                        &scan_p->channel_params, 0);
 2413 
 2414         return 0;
 2415 }
 2416 
 2417 static int iwl_mvm_scan_umac_v14_and_above(struct iwl_mvm *mvm,
 2418                                            struct ieee80211_vif *vif,
 2419                                            struct iwl_mvm_scan_params *params,
 2420                                            int type, int uid, u32 version)
 2421 {
 2422         struct iwl_scan_req_umac_v15 *cmd = mvm->scan_cmd;
 2423         struct iwl_scan_req_params_v15 *scan_p = &cmd->scan_params;
 2424         struct iwl_scan_channel_params_v6 *cp = &scan_p->channel_params;
 2425         struct iwl_scan_probe_params_v4 *pb = &scan_p->probe_params;
 2426         int ret;
 2427         u16 gen_flags;
 2428         u8 gen_flags2;
 2429         u32 bitmap_ssid = 0;
 2430 
 2431         mvm->scan_uid_status[uid] = type;
 2432 
 2433         cmd->ooc_priority = cpu_to_le32(iwl_mvm_scan_umac_ooc_priority(params));
 2434         cmd->uid = cpu_to_le32(uid);
 2435 
 2436         gen_flags = iwl_mvm_scan_umac_flags_v2(mvm, params, vif, type);
 2437 
 2438         if (version >= 15)
 2439                 gen_flags2 = iwl_mvm_scan_umac_flags2(mvm, params, vif, type);
 2440         else
 2441                 gen_flags2 = 0;
 2442 
 2443         iwl_mvm_scan_umac_fill_general_p_v11(mvm, params, vif,
 2444                                              &scan_p->general_params,
 2445                                              gen_flags, gen_flags2);
 2446 
 2447         ret = iwl_mvm_fill_scan_sched_params(params,
 2448                                              scan_p->periodic_params.schedule,
 2449                                              &scan_p->periodic_params.delay);
 2450         if (ret)
 2451                 return ret;
 2452 
 2453         if (!params->scan_6ghz) {
 2454                 iwl_mvm_scan_umac_fill_probe_p_v4(params, &scan_p->probe_params,
 2455                                           &bitmap_ssid);
 2456                 iwl_mvm_scan_umac_fill_ch_p_v6(mvm, params, vif,
 2457                                        &scan_p->channel_params, bitmap_ssid);
 2458 
 2459                 return 0;
 2460         } else {
 2461                 pb->preq = params->preq;
 2462         }
 2463 
 2464         cp->flags = iwl_mvm_scan_umac_chan_flags_v2(mvm, params, vif);
 2465         cp->n_aps_override[0] = IWL_SCAN_ADWELL_N_APS_GO_FRIENDLY;
 2466         cp->n_aps_override[1] = IWL_SCAN_ADWELL_N_APS_SOCIAL_CHS;
 2467 
 2468         iwl_mvm_umac_scan_fill_6g_chan_list(mvm, params, pb);
 2469 
 2470         cp->count = iwl_mvm_umac_scan_cfg_channels_v6_6g(mvm, params,
 2471                                                          params->n_channels,
 2472                                                          pb, cp, vif->type);
 2473         if (!cp->count) {
 2474                 mvm->scan_uid_status[uid] = 0;
 2475                 return -EINVAL;
 2476         }
 2477 
 2478         if (!params->n_ssids ||
 2479             (params->n_ssids == 1 && !params->ssids[0].ssid_len))
 2480                 cp->flags |= IWL_SCAN_CHANNEL_FLAG_6G_PSC_NO_FILTER;
 2481 
 2482         return 0;
 2483 }
 2484 
 2485 static int iwl_mvm_scan_umac_v14(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 2486                                  struct iwl_mvm_scan_params *params, int type,
 2487                                  int uid)
 2488 {
 2489         return iwl_mvm_scan_umac_v14_and_above(mvm, vif, params, type, uid, 14);
 2490 }
 2491 
 2492 static int iwl_mvm_scan_umac_v15(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 2493                                  struct iwl_mvm_scan_params *params, int type,
 2494                                  int uid)
 2495 {
 2496         return iwl_mvm_scan_umac_v14_and_above(mvm, vif, params, type, uid, 15);
 2497 }
 2498 
 2499 static int iwl_mvm_num_scans(struct iwl_mvm *mvm)
 2500 {
 2501         return hweight32(mvm->scan_status & IWL_MVM_SCAN_MASK);
 2502 }
 2503 
 2504 static int iwl_mvm_check_running_scans(struct iwl_mvm *mvm, int type)
 2505 {
 2506         bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
 2507                                          IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
 2508 
 2509         /* This looks a bit arbitrary, but the idea is that if we run
 2510          * out of possible simultaneous scans and the userspace is
 2511          * trying to run a scan type that is already running, we
 2512          * return -EBUSY.  But if the userspace wants to start a
 2513          * different type of scan, we stop the opposite type to make
 2514          * space for the new request.  The reason is backwards
 2515          * compatibility with old wpa_supplicant that wouldn't stop a
 2516          * scheduled scan before starting a normal scan.
 2517          */
 2518 
 2519         /* FW supports only a single periodic scan */
 2520         if ((type == IWL_MVM_SCAN_SCHED || type == IWL_MVM_SCAN_NETDETECT) &&
 2521             mvm->scan_status & (IWL_MVM_SCAN_SCHED | IWL_MVM_SCAN_NETDETECT))
 2522                 return -EBUSY;
 2523 
 2524         if (iwl_mvm_num_scans(mvm) < mvm->max_scans)
 2525                 return 0;
 2526 
 2527         /* Use a switch, even though this is a bitmask, so that more
 2528          * than one bits set will fall in default and we will warn.
 2529          */
 2530         switch (type) {
 2531         case IWL_MVM_SCAN_REGULAR:
 2532                 if (mvm->scan_status & IWL_MVM_SCAN_REGULAR_MASK)
 2533                         return -EBUSY;
 2534                 return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED, true);
 2535         case IWL_MVM_SCAN_SCHED:
 2536                 if (mvm->scan_status & IWL_MVM_SCAN_SCHED_MASK)
 2537                         return -EBUSY;
 2538                 return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_REGULAR, true);
 2539         case IWL_MVM_SCAN_NETDETECT:
 2540                 /* For non-unified images, there's no need to stop
 2541                  * anything for net-detect since the firmware is
 2542                  * restarted anyway.  This way, any sched scans that
 2543                  * were running will be restarted when we resume.
 2544                  */
 2545                 if (!unified_image)
 2546                         return 0;
 2547 
 2548                 /* If this is a unified image and we ran out of scans,
 2549                  * we need to stop something.  Prefer stopping regular
 2550                  * scans, because the results are useless at this
 2551                  * point, and we should be able to keep running
 2552                  * another scheduled scan while suspended.
 2553                  */
 2554                 if (mvm->scan_status & IWL_MVM_SCAN_REGULAR_MASK)
 2555                         return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_REGULAR,
 2556                                                  true);
 2557                 if (mvm->scan_status & IWL_MVM_SCAN_SCHED_MASK)
 2558                         return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED,
 2559                                                  true);
 2560                 /* Something is wrong if no scan was running but we
 2561                  * ran out of scans.
 2562                  */
 2563                 fallthrough;
 2564         default:
 2565                 WARN_ON(1);
 2566                 break;
 2567         }
 2568 
 2569         return -EIO;
 2570 }
 2571 
 2572 #define SCAN_TIMEOUT 30000
 2573 
 2574 void iwl_mvm_scan_timeout_wk(struct work_struct *work)
 2575 {
 2576         struct delayed_work *delayed_work = to_delayed_work(work);
 2577         struct iwl_mvm *mvm = container_of(delayed_work, struct iwl_mvm,
 2578                                            scan_timeout_dwork);
 2579 
 2580         IWL_ERR(mvm, "regular scan timed out\n");
 2581 
 2582         iwl_force_nmi(mvm->trans);
 2583 }
 2584 
 2585 static void iwl_mvm_fill_scan_type(struct iwl_mvm *mvm,
 2586                                    struct iwl_mvm_scan_params *params,
 2587                                    struct ieee80211_vif *vif)
 2588 {
 2589         if (iwl_mvm_is_cdb_supported(mvm)) {
 2590                 params->type =
 2591                         iwl_mvm_get_scan_type_band(mvm, vif,
 2592                                                    NL80211_BAND_2GHZ);
 2593                 params->hb_type =
 2594                         iwl_mvm_get_scan_type_band(mvm, vif,
 2595                                                    NL80211_BAND_5GHZ);
 2596         } else {
 2597                 params->type = iwl_mvm_get_scan_type(mvm, vif);
 2598         }
 2599 }
 2600 
 2601 struct iwl_scan_umac_handler {
 2602         u8 version;
 2603         int (*handler)(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 2604                        struct iwl_mvm_scan_params *params, int type, int uid);
 2605 };
 2606 
 2607 #define IWL_SCAN_UMAC_HANDLER(_ver) {           \
 2608         .version = _ver,                        \
 2609         .handler = iwl_mvm_scan_umac_v##_ver,   \
 2610 }
 2611 
 2612 static const struct iwl_scan_umac_handler iwl_scan_umac_handlers[] = {
 2613         /* set the newest version first to shorten the list traverse time */
 2614         IWL_SCAN_UMAC_HANDLER(15),
 2615         IWL_SCAN_UMAC_HANDLER(14),
 2616         IWL_SCAN_UMAC_HANDLER(12),
 2617 };
 2618 
 2619 static int iwl_mvm_build_scan_cmd(struct iwl_mvm *mvm,
 2620                                   struct ieee80211_vif *vif,
 2621                                   struct iwl_host_cmd *hcmd,
 2622                                   struct iwl_mvm_scan_params *params,
 2623                                   int type)
 2624 {
 2625         int uid, i, err;
 2626         u8 scan_ver;
 2627 
 2628         lockdep_assert_held(&mvm->mutex);
 2629         memset(mvm->scan_cmd, 0, ksize(mvm->scan_cmd));
 2630 
 2631         if (!fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
 2632                 hcmd->id = SCAN_OFFLOAD_REQUEST_CMD;
 2633 
 2634                 return iwl_mvm_scan_lmac(mvm, vif, params);
 2635         }
 2636 
 2637         uid = iwl_mvm_scan_uid_by_status(mvm, 0);
 2638         if (uid < 0)
 2639                 return uid;
 2640 
 2641         hcmd->id = WIDE_ID(IWL_ALWAYS_LONG_GROUP, SCAN_REQ_UMAC);
 2642 
 2643         scan_ver = iwl_fw_lookup_cmd_ver(mvm->fw, SCAN_REQ_UMAC,
 2644                                          IWL_FW_CMD_VER_UNKNOWN);
 2645 
 2646         for (i = 0; i < ARRAY_SIZE(iwl_scan_umac_handlers); i++) {
 2647                 const struct iwl_scan_umac_handler *ver_handler =
 2648                         &iwl_scan_umac_handlers[i];
 2649 
 2650                 if (ver_handler->version != scan_ver)
 2651                         continue;
 2652 
 2653                 return ver_handler->handler(mvm, vif, params, type, uid);
 2654         }
 2655 
 2656         err = iwl_mvm_scan_umac(mvm, vif, params, type, uid);
 2657         if (err)
 2658                 return err;
 2659 
 2660         return uid;
 2661 }
 2662 
 2663 struct iwl_mvm_scan_respect_p2p_go_iter_data {
 2664         struct ieee80211_vif *current_vif;
 2665         bool p2p_go;
 2666         enum nl80211_band band;
 2667 };
 2668 
 2669 static void iwl_mvm_scan_respect_p2p_go_iter(void *_data, u8 *mac,
 2670                                              struct ieee80211_vif *vif)
 2671 {
 2672         struct iwl_mvm_scan_respect_p2p_go_iter_data *data = _data;
 2673         struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 2674 
 2675         /* exclude the given vif */
 2676         if (vif == data->current_vif)
 2677                 return;
 2678 
 2679         if (vif->type == NL80211_IFTYPE_AP && vif->p2p &&
 2680             mvmvif->phy_ctxt->id < NUM_PHY_CTX &&
 2681             (data->band == NUM_NL80211_BANDS ||
 2682              mvmvif->phy_ctxt->channel->band == data->band))
 2683                 data->p2p_go = true;
 2684 }
 2685 
 2686 static bool _iwl_mvm_get_respect_p2p_go(struct iwl_mvm *mvm,
 2687                                         struct ieee80211_vif *vif,
 2688                                         bool low_latency,
 2689                                         enum nl80211_band band)
 2690 {
 2691         struct iwl_mvm_scan_respect_p2p_go_iter_data data = {
 2692                 .current_vif = vif,
 2693                 .p2p_go = false,
 2694                 .band = band,
 2695         };
 2696 
 2697         if (!low_latency)
 2698                 return false;
 2699 
 2700         ieee80211_iterate_active_interfaces_atomic(mvm->hw,
 2701                                                    IEEE80211_IFACE_ITER_NORMAL,
 2702                                                    iwl_mvm_scan_respect_p2p_go_iter,
 2703                                                    &data);
 2704 
 2705         return data.p2p_go;
 2706 }
 2707 
 2708 static bool iwl_mvm_get_respect_p2p_go_band(struct iwl_mvm *mvm,
 2709                                             struct ieee80211_vif *vif,
 2710                                             enum nl80211_band band)
 2711 {
 2712         bool low_latency = iwl_mvm_low_latency_band(mvm, band);
 2713 
 2714         return _iwl_mvm_get_respect_p2p_go(mvm, vif, low_latency, band);
 2715 }
 2716 
 2717 static bool iwl_mvm_get_respect_p2p_go(struct iwl_mvm *mvm,
 2718                                        struct ieee80211_vif *vif)
 2719 {
 2720         bool low_latency = iwl_mvm_low_latency(mvm);
 2721 
 2722         return _iwl_mvm_get_respect_p2p_go(mvm, vif, low_latency,
 2723                                            NUM_NL80211_BANDS);
 2724 }
 2725 
 2726 static void iwl_mvm_fill_respect_p2p_go(struct iwl_mvm *mvm,
 2727                                         struct iwl_mvm_scan_params *params,
 2728                                         struct ieee80211_vif *vif)
 2729 {
 2730         if (iwl_mvm_is_cdb_supported(mvm)) {
 2731                 params->respect_p2p_go =
 2732                         iwl_mvm_get_respect_p2p_go_band(mvm, vif,
 2733                                                         NL80211_BAND_2GHZ);
 2734                 params->respect_p2p_go_hb =
 2735                         iwl_mvm_get_respect_p2p_go_band(mvm, vif,
 2736                                                         NL80211_BAND_5GHZ);
 2737         } else {
 2738                 params->respect_p2p_go = iwl_mvm_get_respect_p2p_go(mvm, vif);
 2739         }
 2740 }
 2741 
 2742 int iwl_mvm_reg_scan_start(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
 2743                            struct cfg80211_scan_request *req,
 2744                            struct ieee80211_scan_ies *ies)
 2745 {
 2746         struct iwl_host_cmd hcmd = {
 2747                 .len = { iwl_mvm_scan_size(mvm), },
 2748                 .data = { mvm->scan_cmd, },
 2749                 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
 2750         };
 2751         struct iwl_mvm_scan_params params = {};
 2752         int ret, uid;
 2753         struct cfg80211_sched_scan_plan scan_plan = { .iterations = 1 };
 2754 
 2755         lockdep_assert_held(&mvm->mutex);
 2756 
 2757         if (iwl_mvm_is_lar_supported(mvm) && !mvm->lar_regdom_set) {
 2758                 IWL_ERR(mvm, "scan while LAR regdomain is not set\n");
 2759                 return -EBUSY;
 2760         }
 2761 
 2762         ret = iwl_mvm_check_running_scans(mvm, IWL_MVM_SCAN_REGULAR);
 2763         if (ret)
 2764                 return ret;
 2765 
 2766         /* we should have failed registration if scan_cmd was NULL */
 2767         if (WARN_ON(!mvm->scan_cmd))
 2768                 return -ENOMEM;
 2769 
 2770         if (!iwl_mvm_scan_fits(mvm, req->n_ssids, ies, req->n_channels))
 2771                 return -ENOBUFS;
 2772 
 2773         params.n_ssids = req->n_ssids;
 2774         params.flags = req->flags;
 2775         params.n_channels = req->n_channels;
 2776         params.delay = 0;
 2777         params.ssids = req->ssids;
 2778         params.channels = req->channels;
 2779         params.mac_addr = req->mac_addr;
 2780         params.mac_addr_mask = req->mac_addr_mask;
 2781         params.no_cck = req->no_cck;
 2782         params.pass_all = true;
 2783         params.n_match_sets = 0;
 2784         params.match_sets = NULL;
 2785 
 2786         params.scan_plans = &scan_plan;
 2787         params.n_scan_plans = 1;
 2788 
 2789         params.n_6ghz_params = req->n_6ghz_params;
 2790         params.scan_6ghz_params = req->scan_6ghz_params;
 2791         params.scan_6ghz = req->scan_6ghz;
 2792         iwl_mvm_fill_scan_type(mvm, &params, vif);
 2793         iwl_mvm_fill_respect_p2p_go(mvm, &params, vif);
 2794 
 2795         if (req->duration)
 2796                 params.iter_notif = true;
 2797 
 2798         iwl_mvm_build_scan_probe(mvm, vif, ies, &params);
 2799 
 2800         iwl_mvm_scan_6ghz_passive_scan(mvm, &params, vif);
 2801 
 2802         uid = iwl_mvm_build_scan_cmd(mvm, vif, &hcmd, &params,
 2803                                      IWL_MVM_SCAN_REGULAR);
 2804 
 2805         if (uid < 0)
 2806                 return uid;
 2807 
 2808         iwl_mvm_pause_tcm(mvm, false);
 2809 
 2810         ret = iwl_mvm_send_cmd(mvm, &hcmd);
 2811         if (ret) {
 2812                 /* If the scan failed, it usually means that the FW was unable
 2813                  * to allocate the time events. Warn on it, but maybe we
 2814                  * should try to send the command again with different params.
 2815                  */
 2816                 IWL_ERR(mvm, "Scan failed! ret %d\n", ret);
 2817                 iwl_mvm_resume_tcm(mvm);
 2818                 mvm->scan_uid_status[uid] = 0;
 2819                 return ret;
 2820         }
 2821 
 2822         IWL_DEBUG_SCAN(mvm, "Scan request was sent successfully\n");
 2823         mvm->scan_status |= IWL_MVM_SCAN_REGULAR;
 2824         mvm->scan_vif = iwl_mvm_vif_from_mac80211(vif);
 2825 
 2826         if (params.enable_6ghz_passive)
 2827                 mvm->last_6ghz_passive_scan_jiffies = jiffies;
 2828 
 2829         schedule_delayed_work(&mvm->scan_timeout_dwork,
 2830                               msecs_to_jiffies(SCAN_TIMEOUT));
 2831 
 2832         return 0;
 2833 }
 2834 
 2835 int iwl_mvm_sched_scan_start(struct iwl_mvm *mvm,
 2836                              struct ieee80211_vif *vif,
 2837                              struct cfg80211_sched_scan_request *req,
 2838                              struct ieee80211_scan_ies *ies,
 2839                              int type)
 2840 {
 2841         struct iwl_host_cmd hcmd = {
 2842                 .len = { iwl_mvm_scan_size(mvm), },
 2843                 .data = { mvm->scan_cmd, },
 2844                 .dataflags = { IWL_HCMD_DFL_NOCOPY, },
 2845         };
 2846         struct iwl_mvm_scan_params params = {};
 2847         int ret, uid;
 2848         int i, j;
 2849         bool non_psc_included = false;
 2850 
 2851         lockdep_assert_held(&mvm->mutex);
 2852 
 2853         if (iwl_mvm_is_lar_supported(mvm) && !mvm->lar_regdom_set) {
 2854                 IWL_ERR(mvm, "sched-scan while LAR regdomain is not set\n");
 2855                 return -EBUSY;
 2856         }
 2857 
 2858         ret = iwl_mvm_check_running_scans(mvm, type);
 2859         if (ret)
 2860                 return ret;
 2861 
 2862         /* we should have failed registration if scan_cmd was NULL */
 2863         if (WARN_ON(!mvm->scan_cmd))
 2864                 return -ENOMEM;
 2865 
 2866 
 2867         params.n_ssids = req->n_ssids;
 2868         params.flags = req->flags;
 2869         params.n_channels = req->n_channels;
 2870         params.ssids = req->ssids;
 2871         params.channels = req->channels;
 2872         params.mac_addr = req->mac_addr;
 2873         params.mac_addr_mask = req->mac_addr_mask;
 2874         params.no_cck = false;
 2875         params.pass_all =  iwl_mvm_scan_pass_all(mvm, req);
 2876         params.n_match_sets = req->n_match_sets;
 2877         params.match_sets = req->match_sets;
 2878         if (!req->n_scan_plans)
 2879                 return -EINVAL;
 2880 
 2881         params.n_scan_plans = req->n_scan_plans;
 2882         params.scan_plans = req->scan_plans;
 2883 
 2884         iwl_mvm_fill_scan_type(mvm, &params, vif);
 2885         iwl_mvm_fill_respect_p2p_go(mvm, &params, vif);
 2886 
 2887         /* In theory, LMAC scans can handle a 32-bit delay, but since
 2888          * waiting for over 18 hours to start the scan is a bit silly
 2889          * and to keep it aligned with UMAC scans (which only support
 2890          * 16-bit delays), trim it down to 16-bits.
 2891          */
 2892         if (req->delay > U16_MAX) {
 2893                 IWL_DEBUG_SCAN(mvm,
 2894                                "delay value is > 16-bits, set to max possible\n");
 2895                 params.delay = U16_MAX;
 2896         } else {
 2897                 params.delay = req->delay;
 2898         }
 2899 
 2900         ret = iwl_mvm_config_sched_scan_profiles(mvm, req);
 2901         if (ret)
 2902                 return ret;
 2903 
 2904         iwl_mvm_build_scan_probe(mvm, vif, ies, &params);
 2905 
 2906         /* for 6 GHZ band only PSC channels need to be added */
 2907         for (i = 0; i < params.n_channels; i++) {
 2908                 struct ieee80211_channel *channel = params.channels[i];
 2909 
 2910                 if (channel->band == NL80211_BAND_6GHZ &&
 2911                     !cfg80211_channel_is_psc(channel)) {
 2912                         non_psc_included = true;
 2913                         break;
 2914                 }
 2915         }
 2916 
 2917         if (non_psc_included) {
 2918                 params.channels = kmemdup(params.channels,
 2919                                           sizeof(params.channels[0]) *
 2920                                           params.n_channels,
 2921                                           GFP_KERNEL);
 2922                 if (!params.channels)
 2923                         return -ENOMEM;
 2924 
 2925                 for (i = j = 0; i < params.n_channels; i++) {
 2926                         if (params.channels[i]->band == NL80211_BAND_6GHZ &&
 2927                             !cfg80211_channel_is_psc(params.channels[i]))
 2928                                 continue;
 2929                         params.channels[j++] = params.channels[i];
 2930                 }
 2931                 params.n_channels = j;
 2932         }
 2933 
 2934         if (non_psc_included &&
 2935             !iwl_mvm_scan_fits(mvm, req->n_ssids, ies, params.n_channels)) {
 2936                 kfree(params.channels);
 2937                 return -ENOBUFS;
 2938         }
 2939 
 2940         uid = iwl_mvm_build_scan_cmd(mvm, vif, &hcmd, &params, type);
 2941 
 2942         if (non_psc_included)
 2943                 kfree(params.channels);
 2944         if (uid < 0)
 2945                 return uid;
 2946 
 2947         ret = iwl_mvm_send_cmd(mvm, &hcmd);
 2948         if (!ret) {
 2949                 IWL_DEBUG_SCAN(mvm,
 2950                                "Sched scan request was sent successfully\n");
 2951                 mvm->scan_status |= type;
 2952         } else {
 2953                 /* If the scan failed, it usually means that the FW was unable
 2954                  * to allocate the time events. Warn on it, but maybe we
 2955                  * should try to send the command again with different params.
 2956                  */
 2957                 IWL_ERR(mvm, "Sched scan failed! ret %d\n", ret);
 2958                 mvm->scan_uid_status[uid] = 0;
 2959                 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
 2960         }
 2961 
 2962         return ret;
 2963 }
 2964 
 2965 void iwl_mvm_rx_umac_scan_complete_notif(struct iwl_mvm *mvm,
 2966                                          struct iwl_rx_cmd_buffer *rxb)
 2967 {
 2968         struct iwl_rx_packet *pkt = rxb_addr(rxb);
 2969         struct iwl_umac_scan_complete *notif = (void *)pkt->data;
 2970         u32 uid = __le32_to_cpu(notif->uid);
 2971         bool aborted = (notif->status == IWL_SCAN_OFFLOAD_ABORTED);
 2972 
 2973         if (WARN_ON(!(mvm->scan_uid_status[uid] & mvm->scan_status)))
 2974                 return;
 2975 
 2976         /* if the scan is already stopping, we don't need to notify mac80211 */
 2977         if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_REGULAR) {
 2978                 struct cfg80211_scan_info info = {
 2979                         .aborted = aborted,
 2980                         .scan_start_tsf = mvm->scan_start,
 2981                 };
 2982 
 2983                 memcpy(info.tsf_bssid, mvm->scan_vif->bssid, ETH_ALEN);
 2984                 ieee80211_scan_completed(mvm->hw, &info);
 2985                 mvm->scan_vif = NULL;
 2986                 cancel_delayed_work(&mvm->scan_timeout_dwork);
 2987                 iwl_mvm_resume_tcm(mvm);
 2988         } else if (mvm->scan_uid_status[uid] == IWL_MVM_SCAN_SCHED) {
 2989                 ieee80211_sched_scan_stopped(mvm->hw);
 2990                 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
 2991         }
 2992 
 2993         mvm->scan_status &= ~mvm->scan_uid_status[uid];
 2994         IWL_DEBUG_SCAN(mvm,
 2995                        "Scan completed, uid %u type %u, status %s, EBS status %s\n",
 2996                        uid, mvm->scan_uid_status[uid],
 2997                        notif->status == IWL_SCAN_OFFLOAD_COMPLETED ?
 2998                                 "completed" : "aborted",
 2999                        iwl_mvm_ebs_status_str(notif->ebs_status));
 3000         IWL_DEBUG_SCAN(mvm,
 3001                        "Last line %d, Last iteration %d, Time from last iteration %d\n",
 3002                        notif->last_schedule, notif->last_iter,
 3003                        __le32_to_cpu(notif->time_from_last_iter));
 3004 
 3005         if (notif->ebs_status != IWL_SCAN_EBS_SUCCESS &&
 3006             notif->ebs_status != IWL_SCAN_EBS_INACTIVE)
 3007                 mvm->last_ebs_successful = false;
 3008 
 3009         mvm->scan_uid_status[uid] = 0;
 3010 }
 3011 
 3012 void iwl_mvm_rx_umac_scan_iter_complete_notif(struct iwl_mvm *mvm,
 3013                                               struct iwl_rx_cmd_buffer *rxb)
 3014 {
 3015         struct iwl_rx_packet *pkt = rxb_addr(rxb);
 3016         struct iwl_umac_scan_iter_complete_notif *notif = (void *)pkt->data;
 3017 
 3018         mvm->scan_start = le64_to_cpu(notif->start_tsf);
 3019 
 3020         IWL_DEBUG_SCAN(mvm,
 3021                        "UMAC Scan iteration complete: status=0x%x scanned_channels=%d\n",
 3022                        notif->status, notif->scanned_channels);
 3023 
 3024         if (mvm->sched_scan_pass_all == SCHED_SCAN_PASS_ALL_FOUND) {
 3025                 IWL_DEBUG_SCAN(mvm, "Pass all scheduled scan results found\n");
 3026                 ieee80211_sched_scan_results(mvm->hw);
 3027                 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_ENABLED;
 3028         }
 3029 
 3030         IWL_DEBUG_SCAN(mvm,
 3031                        "UMAC Scan iteration complete: scan started at %llu (TSF)\n",
 3032                        mvm->scan_start);
 3033 }
 3034 
 3035 static int iwl_mvm_umac_scan_abort(struct iwl_mvm *mvm, int type)
 3036 {
 3037         struct iwl_umac_scan_abort cmd = {};
 3038         int uid, ret;
 3039 
 3040         lockdep_assert_held(&mvm->mutex);
 3041 
 3042         /* We should always get a valid index here, because we already
 3043          * checked that this type of scan was running in the generic
 3044          * code.
 3045          */
 3046         uid = iwl_mvm_scan_uid_by_status(mvm, type);
 3047         if (WARN_ON_ONCE(uid < 0))
 3048                 return uid;
 3049 
 3050         cmd.uid = cpu_to_le32(uid);
 3051 
 3052         IWL_DEBUG_SCAN(mvm, "Sending scan abort, uid %u\n", uid);
 3053 
 3054         ret = iwl_mvm_send_cmd_pdu(mvm,
 3055                                    WIDE_ID(IWL_ALWAYS_LONG_GROUP, SCAN_ABORT_UMAC),
 3056                                    0, sizeof(cmd), &cmd);
 3057         if (!ret)
 3058                 mvm->scan_uid_status[uid] = type << IWL_MVM_SCAN_STOPPING_SHIFT;
 3059 
 3060         return ret;
 3061 }
 3062 
 3063 static int iwl_mvm_scan_stop_wait(struct iwl_mvm *mvm, int type)
 3064 {
 3065         struct iwl_notification_wait wait_scan_done;
 3066         static const u16 scan_done_notif[] = { SCAN_COMPLETE_UMAC,
 3067                                               SCAN_OFFLOAD_COMPLETE, };
 3068         int ret;
 3069 
 3070         lockdep_assert_held(&mvm->mutex);
 3071 
 3072         iwl_init_notification_wait(&mvm->notif_wait, &wait_scan_done,
 3073                                    scan_done_notif,
 3074                                    ARRAY_SIZE(scan_done_notif),
 3075                                    NULL, NULL);
 3076 
 3077         IWL_DEBUG_SCAN(mvm, "Preparing to stop scan, type %x\n", type);
 3078 
 3079         if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN))
 3080                 ret = iwl_mvm_umac_scan_abort(mvm, type);
 3081         else
 3082                 ret = iwl_mvm_lmac_scan_abort(mvm);
 3083 
 3084         if (ret) {
 3085                 IWL_DEBUG_SCAN(mvm, "couldn't stop scan type %d\n", type);
 3086                 iwl_remove_notification(&mvm->notif_wait, &wait_scan_done);
 3087                 return ret;
 3088         }
 3089 
 3090         return iwl_wait_notification(&mvm->notif_wait, &wait_scan_done,
 3091                                      1 * HZ);
 3092 }
 3093 
 3094 static int iwl_scan_req_umac_get_size(u8 scan_ver)
 3095 {
 3096         switch (scan_ver) {
 3097         case 12:
 3098                 return sizeof(struct iwl_scan_req_umac_v12);
 3099         case 14:
 3100         case 15:
 3101                 return sizeof(struct iwl_scan_req_umac_v15);
 3102         }
 3103 
 3104         return 0;
 3105 }
 3106 
 3107 int iwl_mvm_scan_size(struct iwl_mvm *mvm)
 3108 {
 3109         int base_size, tail_size;
 3110         u8 scan_ver = iwl_fw_lookup_cmd_ver(mvm->fw, SCAN_REQ_UMAC,
 3111                                             IWL_FW_CMD_VER_UNKNOWN);
 3112 
 3113         base_size = iwl_scan_req_umac_get_size(scan_ver);
 3114         if (base_size)
 3115                 return base_size;
 3116 
 3117 
 3118         if (iwl_mvm_is_adaptive_dwell_v2_supported(mvm))
 3119                 base_size = IWL_SCAN_REQ_UMAC_SIZE_V8;
 3120         else if (iwl_mvm_is_adaptive_dwell_supported(mvm))
 3121                 base_size = IWL_SCAN_REQ_UMAC_SIZE_V7;
 3122         else if (iwl_mvm_cdb_scan_api(mvm))
 3123                 base_size = IWL_SCAN_REQ_UMAC_SIZE_V6;
 3124         else
 3125                 base_size = IWL_SCAN_REQ_UMAC_SIZE_V1;
 3126 
 3127         if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
 3128                 if (iwl_mvm_is_scan_ext_chan_supported(mvm))
 3129                         tail_size = sizeof(struct iwl_scan_req_umac_tail_v2);
 3130                 else
 3131                         tail_size = sizeof(struct iwl_scan_req_umac_tail_v1);
 3132 
 3133                 return base_size +
 3134                         sizeof(struct iwl_scan_channel_cfg_umac) *
 3135                                 mvm->fw->ucode_capa.n_scan_channels +
 3136                         tail_size;
 3137         }
 3138         return sizeof(struct iwl_scan_req_lmac) +
 3139                 sizeof(struct iwl_scan_channel_cfg_lmac) *
 3140                 mvm->fw->ucode_capa.n_scan_channels +
 3141                 sizeof(struct iwl_scan_probe_req_v1);
 3142 }
 3143 
 3144 /*
 3145  * This function is used in nic restart flow, to inform mac80211 about scans
 3146  * that was aborted by restart flow or by an assert.
 3147  */
 3148 void iwl_mvm_report_scan_aborted(struct iwl_mvm *mvm)
 3149 {
 3150         if (fw_has_capa(&mvm->fw->ucode_capa, IWL_UCODE_TLV_CAPA_UMAC_SCAN)) {
 3151                 int uid, i;
 3152 
 3153                 uid = iwl_mvm_scan_uid_by_status(mvm, IWL_MVM_SCAN_REGULAR);
 3154                 if (uid >= 0) {
 3155                         struct cfg80211_scan_info info = {
 3156                                 .aborted = true,
 3157                         };
 3158 
 3159                         cancel_delayed_work(&mvm->scan_timeout_dwork);
 3160 
 3161                         ieee80211_scan_completed(mvm->hw, &info);
 3162                         mvm->scan_uid_status[uid] = 0;
 3163                 }
 3164                 uid = iwl_mvm_scan_uid_by_status(mvm, IWL_MVM_SCAN_SCHED);
 3165                 if (uid >= 0) {
 3166                         /* Sched scan will be restarted by mac80211 in
 3167                          * restart_hw, so do not report if FW is about to be
 3168                          * restarted.
 3169                          */
 3170                         if (!mvm->fw_restart)
 3171                                 ieee80211_sched_scan_stopped(mvm->hw);
 3172                         mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
 3173                         mvm->scan_uid_status[uid] = 0;
 3174                 }
 3175                 uid = iwl_mvm_scan_uid_by_status(mvm,
 3176                                                  IWL_MVM_SCAN_STOPPING_REGULAR);
 3177                 if (uid >= 0)
 3178                         mvm->scan_uid_status[uid] = 0;
 3179 
 3180                 uid = iwl_mvm_scan_uid_by_status(mvm,
 3181                                                  IWL_MVM_SCAN_STOPPING_SCHED);
 3182                 if (uid >= 0)
 3183                         mvm->scan_uid_status[uid] = 0;
 3184 
 3185                 /* We shouldn't have any UIDs still set.  Loop over all the
 3186                  * UIDs to make sure there's nothing left there and warn if
 3187                  * any is found.
 3188                  */
 3189                 for (i = 0; i < mvm->max_scans; i++) {
 3190                         if (WARN_ONCE(mvm->scan_uid_status[i],
 3191                                       "UMAC scan UID %d status was not cleaned\n",
 3192                                       i))
 3193                                 mvm->scan_uid_status[i] = 0;
 3194                 }
 3195         } else {
 3196                 if (mvm->scan_status & IWL_MVM_SCAN_REGULAR) {
 3197                         struct cfg80211_scan_info info = {
 3198                                 .aborted = true,
 3199                         };
 3200 
 3201                         cancel_delayed_work(&mvm->scan_timeout_dwork);
 3202                         ieee80211_scan_completed(mvm->hw, &info);
 3203                 }
 3204 
 3205                 /* Sched scan will be restarted by mac80211 in
 3206                  * restart_hw, so do not report if FW is about to be
 3207                  * restarted.
 3208                  */
 3209                 if ((mvm->scan_status & IWL_MVM_SCAN_SCHED) &&
 3210                     !mvm->fw_restart) {
 3211                         ieee80211_sched_scan_stopped(mvm->hw);
 3212                         mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
 3213                 }
 3214         }
 3215 }
 3216 
 3217 int iwl_mvm_scan_stop(struct iwl_mvm *mvm, int type, bool notify)
 3218 {
 3219         int ret;
 3220 
 3221         if (!(mvm->scan_status & type))
 3222                 return 0;
 3223 
 3224         if (iwl_mvm_is_radio_killed(mvm)) {
 3225                 ret = 0;
 3226                 goto out;
 3227         }
 3228 
 3229         ret = iwl_mvm_scan_stop_wait(mvm, type);
 3230         if (!ret)
 3231                 mvm->scan_status |= type << IWL_MVM_SCAN_STOPPING_SHIFT;
 3232 out:
 3233         /* Clear the scan status so the next scan requests will
 3234          * succeed and mark the scan as stopping, so that the Rx
 3235          * handler doesn't do anything, as the scan was stopped from
 3236          * above.
 3237          */
 3238         mvm->scan_status &= ~type;
 3239 
 3240         if (type == IWL_MVM_SCAN_REGULAR) {
 3241                 cancel_delayed_work(&mvm->scan_timeout_dwork);
 3242                 if (notify) {
 3243                         struct cfg80211_scan_info info = {
 3244                                 .aborted = true,
 3245                         };
 3246 
 3247                         ieee80211_scan_completed(mvm->hw, &info);
 3248                 }
 3249         } else if (notify) {
 3250                 ieee80211_sched_scan_stopped(mvm->hw);
 3251                 mvm->sched_scan_pass_all = SCHED_SCAN_PASS_ALL_DISABLED;
 3252         }
 3253 
 3254         return ret;
 3255 }

Cache object: f992815c0727be9165b168b93ea49ce8


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.