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