linux/drivers/net/wireless/mwifiex/scan.c
<<
>>
Prefs
   1/*
   2 * Marvell Wireless LAN device driver: scan ioctl and command handling
   3 *
   4 * Copyright (C) 2011, Marvell International Ltd.
   5 *
   6 * This software file (the "File") is distributed by Marvell International
   7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
   8 * (the "License").  You may use, redistribute and/or modify this File in
   9 * accordance with the terms and conditions of the License, a copy of which
  10 * is available by writing to the Free Software Foundation, Inc.,
  11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
  12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
  13 *
  14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
  15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
  16 * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
  17 * this warranty disclaimer.
  18 */
  19
  20#include "decl.h"
  21#include "ioctl.h"
  22#include "util.h"
  23#include "fw.h"
  24#include "main.h"
  25#include "11n.h"
  26#include "cfg80211.h"
  27
  28/* The maximum number of channels the firmware can scan per command */
  29#define MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN   14
  30
  31#define MWIFIEX_DEF_CHANNELS_PER_SCAN_CMD       4
  32#define MWIFIEX_LIMIT_1_CHANNEL_PER_SCAN_CMD    15
  33#define MWIFIEX_LIMIT_2_CHANNELS_PER_SCAN_CMD   27
  34#define MWIFIEX_LIMIT_3_CHANNELS_PER_SCAN_CMD   35
  35
  36/* Memory needed to store a max sized Channel List TLV for a firmware scan */
  37#define CHAN_TLV_MAX_SIZE  (sizeof(struct mwifiex_ie_types_header)         \
  38                                + (MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN     \
  39                                *sizeof(struct mwifiex_chan_scan_param_set)))
  40
  41/* Memory needed to store supported rate */
  42#define RATE_TLV_MAX_SIZE   (sizeof(struct mwifiex_ie_types_rates_param_set) \
  43                                + HOSTCMD_SUPPORTED_RATES)
  44
  45/* Memory needed to store a max number/size WildCard SSID TLV for a firmware
  46        scan */
  47#define WILDCARD_SSID_TLV_MAX_SIZE  \
  48        (MWIFIEX_MAX_SSID_LIST_LENGTH *                                 \
  49                (sizeof(struct mwifiex_ie_types_wildcard_ssid_params)   \
  50                        + IEEE80211_MAX_SSID_LEN))
  51
  52/* Maximum memory needed for a mwifiex_scan_cmd_config with all TLVs at max */
  53#define MAX_SCAN_CFG_ALLOC (sizeof(struct mwifiex_scan_cmd_config)        \
  54                                + sizeof(struct mwifiex_ie_types_num_probes)   \
  55                                + sizeof(struct mwifiex_ie_types_htcap)       \
  56                                + CHAN_TLV_MAX_SIZE                 \
  57                                + RATE_TLV_MAX_SIZE                 \
  58                                + WILDCARD_SSID_TLV_MAX_SIZE)
  59
  60
  61union mwifiex_scan_cmd_config_tlv {
  62        /* Scan configuration (variable length) */
  63        struct mwifiex_scan_cmd_config config;
  64        /* Max allocated block */
  65        u8 config_alloc_buf[MAX_SCAN_CFG_ALLOC];
  66};
  67
  68enum cipher_suite {
  69        CIPHER_SUITE_TKIP,
  70        CIPHER_SUITE_CCMP,
  71        CIPHER_SUITE_MAX
  72};
  73static u8 mwifiex_wpa_oui[CIPHER_SUITE_MAX][4] = {
  74        { 0x00, 0x50, 0xf2, 0x02 },     /* TKIP */
  75        { 0x00, 0x50, 0xf2, 0x04 },     /* AES  */
  76};
  77static u8 mwifiex_rsn_oui[CIPHER_SUITE_MAX][4] = {
  78        { 0x00, 0x0f, 0xac, 0x02 },     /* TKIP */
  79        { 0x00, 0x0f, 0xac, 0x04 },     /* AES  */
  80};
  81
  82/*
  83 * This function parses a given IE for a given OUI.
  84 *
  85 * This is used to parse a WPA/RSN IE to find if it has
  86 * a given oui in PTK.
  87 */
  88static u8
  89mwifiex_search_oui_in_ie(struct ie_body *iebody, u8 *oui)
  90{
  91        u8 count;
  92
  93        count = iebody->ptk_cnt[0];
  94
  95        /* There could be multiple OUIs for PTK hence
  96           1) Take the length.
  97           2) Check all the OUIs for AES.
  98           3) If one of them is AES then pass success. */
  99        while (count) {
 100                if (!memcmp(iebody->ptk_body, oui, sizeof(iebody->ptk_body)))
 101                        return MWIFIEX_OUI_PRESENT;
 102
 103                --count;
 104                if (count)
 105                        iebody = (struct ie_body *) ((u8 *) iebody +
 106                                                sizeof(iebody->ptk_body));
 107        }
 108
 109        pr_debug("info: %s: OUI is not found in PTK\n", __func__);
 110        return MWIFIEX_OUI_NOT_PRESENT;
 111}
 112
 113/*
 114 * This function checks if a given OUI is present in a RSN IE.
 115 *
 116 * The function first checks if a RSN IE is present or not in the
 117 * BSS descriptor. It tries to locate the OUI only if such an IE is
 118 * present.
 119 */
 120static u8
 121mwifiex_is_rsn_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
 122{
 123        u8 *oui;
 124        struct ie_body *iebody;
 125        u8 ret = MWIFIEX_OUI_NOT_PRESENT;
 126
 127        if (((bss_desc->bcn_rsn_ie) && ((*(bss_desc->bcn_rsn_ie)).
 128                                        ieee_hdr.element_id == WLAN_EID_RSN))) {
 129                iebody = (struct ie_body *)
 130                         (((u8 *) bss_desc->bcn_rsn_ie->data) +
 131                          RSN_GTK_OUI_OFFSET);
 132                oui = &mwifiex_rsn_oui[cipher][0];
 133                ret = mwifiex_search_oui_in_ie(iebody, oui);
 134                if (ret)
 135                        return ret;
 136        }
 137        return ret;
 138}
 139
 140/*
 141 * This function checks if a given OUI is present in a WPA IE.
 142 *
 143 * The function first checks if a WPA IE is present or not in the
 144 * BSS descriptor. It tries to locate the OUI only if such an IE is
 145 * present.
 146 */
 147static u8
 148mwifiex_is_wpa_oui_present(struct mwifiex_bssdescriptor *bss_desc, u32 cipher)
 149{
 150        u8 *oui;
 151        struct ie_body *iebody;
 152        u8 ret = MWIFIEX_OUI_NOT_PRESENT;
 153
 154        if (((bss_desc->bcn_wpa_ie) &&
 155             ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id ==
 156              WLAN_EID_VENDOR_SPECIFIC))) {
 157                iebody = (struct ie_body *) bss_desc->bcn_wpa_ie->data;
 158                oui = &mwifiex_wpa_oui[cipher][0];
 159                ret = mwifiex_search_oui_in_ie(iebody, oui);
 160                if (ret)
 161                        return ret;
 162        }
 163        return ret;
 164}
 165
 166/*
 167 * This function compares two SSIDs and checks if they match.
 168 */
 169s32
 170mwifiex_ssid_cmp(struct cfg80211_ssid *ssid1, struct cfg80211_ssid *ssid2)
 171{
 172        if (!ssid1 || !ssid2 || (ssid1->ssid_len != ssid2->ssid_len))
 173                return -1;
 174        return memcmp(ssid1->ssid, ssid2->ssid, ssid1->ssid_len);
 175}
 176
 177/*
 178 * This function checks if wapi is enabled in driver and scanned network is
 179 * compatible with it.
 180 */
 181static bool
 182mwifiex_is_bss_wapi(struct mwifiex_private *priv,
 183                    struct mwifiex_bssdescriptor *bss_desc)
 184{
 185        if (priv->sec_info.wapi_enabled &&
 186            (bss_desc->bcn_wapi_ie &&
 187             ((*(bss_desc->bcn_wapi_ie)).ieee_hdr.element_id ==
 188                        WLAN_EID_BSS_AC_ACCESS_DELAY))) {
 189                return true;
 190        }
 191        return false;
 192}
 193
 194/*
 195 * This function checks if driver is configured with no security mode and
 196 * scanned network is compatible with it.
 197 */
 198static bool
 199mwifiex_is_bss_no_sec(struct mwifiex_private *priv,
 200                      struct mwifiex_bssdescriptor *bss_desc)
 201{
 202        if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
 203            !priv->sec_info.wpa2_enabled && ((!bss_desc->bcn_wpa_ie) ||
 204                ((*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id !=
 205                 WLAN_EID_VENDOR_SPECIFIC)) &&
 206            ((!bss_desc->bcn_rsn_ie) ||
 207                ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id !=
 208                 WLAN_EID_RSN)) &&
 209            !priv->sec_info.encryption_mode && !bss_desc->privacy) {
 210                return true;
 211        }
 212        return false;
 213}
 214
 215/*
 216 * This function checks if static WEP is enabled in driver and scanned network
 217 * is compatible with it.
 218 */
 219static bool
 220mwifiex_is_bss_static_wep(struct mwifiex_private *priv,
 221                          struct mwifiex_bssdescriptor *bss_desc)
 222{
 223        if (priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
 224            !priv->sec_info.wpa2_enabled && bss_desc->privacy) {
 225                return true;
 226        }
 227        return false;
 228}
 229
 230/*
 231 * This function checks if wpa is enabled in driver and scanned network is
 232 * compatible with it.
 233 */
 234static bool
 235mwifiex_is_bss_wpa(struct mwifiex_private *priv,
 236                   struct mwifiex_bssdescriptor *bss_desc)
 237{
 238        if (!priv->sec_info.wep_enabled && priv->sec_info.wpa_enabled &&
 239            !priv->sec_info.wpa2_enabled && ((bss_desc->bcn_wpa_ie) &&
 240            ((*(bss_desc->bcn_wpa_ie)).
 241             vend_hdr.element_id == WLAN_EID_VENDOR_SPECIFIC))
 242           /*
 243            * Privacy bit may NOT be set in some APs like
 244            * LinkSys WRT54G && bss_desc->privacy
 245            */
 246         ) {
 247                dev_dbg(priv->adapter->dev, "info: %s: WPA:"
 248                        " wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
 249                        "EncMode=%#x privacy=%#x\n", __func__,
 250                        (bss_desc->bcn_wpa_ie) ?
 251                        (*(bss_desc->bcn_wpa_ie)).
 252                        vend_hdr.element_id : 0,
 253                        (bss_desc->bcn_rsn_ie) ?
 254                        (*(bss_desc->bcn_rsn_ie)).
 255                        ieee_hdr.element_id : 0,
 256                        (priv->sec_info.wep_enabled) ? "e" : "d",
 257                        (priv->sec_info.wpa_enabled) ? "e" : "d",
 258                        (priv->sec_info.wpa2_enabled) ? "e" : "d",
 259                        priv->sec_info.encryption_mode,
 260                        bss_desc->privacy);
 261                return true;
 262        }
 263        return false;
 264}
 265
 266/*
 267 * This function checks if wpa2 is enabled in driver and scanned network is
 268 * compatible with it.
 269 */
 270static bool
 271mwifiex_is_bss_wpa2(struct mwifiex_private *priv,
 272                    struct mwifiex_bssdescriptor *bss_desc)
 273{
 274        if (!priv->sec_info.wep_enabled &&
 275            !priv->sec_info.wpa_enabled &&
 276            priv->sec_info.wpa2_enabled &&
 277            ((bss_desc->bcn_rsn_ie) &&
 278             ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id == WLAN_EID_RSN))) {
 279                /*
 280                 * Privacy bit may NOT be set in some APs like
 281                 * LinkSys WRT54G && bss_desc->privacy
 282                 */
 283                dev_dbg(priv->adapter->dev, "info: %s: WPA2: "
 284                        " wpa_ie=%#x wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
 285                        "EncMode=%#x privacy=%#x\n", __func__,
 286                        (bss_desc->bcn_wpa_ie) ?
 287                        (*(bss_desc->bcn_wpa_ie)).
 288                        vend_hdr.element_id : 0,
 289                        (bss_desc->bcn_rsn_ie) ?
 290                        (*(bss_desc->bcn_rsn_ie)).
 291                        ieee_hdr.element_id : 0,
 292                        (priv->sec_info.wep_enabled) ? "e" : "d",
 293                        (priv->sec_info.wpa_enabled) ? "e" : "d",
 294                        (priv->sec_info.wpa2_enabled) ? "e" : "d",
 295                        priv->sec_info.encryption_mode,
 296                        bss_desc->privacy);
 297                return true;
 298        }
 299        return false;
 300}
 301
 302/*
 303 * This function checks if adhoc AES is enabled in driver and scanned network is
 304 * compatible with it.
 305 */
 306static bool
 307mwifiex_is_bss_adhoc_aes(struct mwifiex_private *priv,
 308                         struct mwifiex_bssdescriptor *bss_desc)
 309{
 310        if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
 311            !priv->sec_info.wpa2_enabled &&
 312            ((!bss_desc->bcn_wpa_ie) ||
 313             ((*(bss_desc->bcn_wpa_ie)).
 314              vend_hdr.element_id != WLAN_EID_VENDOR_SPECIFIC)) &&
 315            ((!bss_desc->bcn_rsn_ie) ||
 316             ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) &&
 317            !priv->sec_info.encryption_mode && bss_desc->privacy) {
 318                return true;
 319        }
 320        return false;
 321}
 322
 323/*
 324 * This function checks if dynamic WEP is enabled in driver and scanned network
 325 * is compatible with it.
 326 */
 327static bool
 328mwifiex_is_bss_dynamic_wep(struct mwifiex_private *priv,
 329                           struct mwifiex_bssdescriptor *bss_desc)
 330{
 331        if (!priv->sec_info.wep_enabled && !priv->sec_info.wpa_enabled &&
 332            !priv->sec_info.wpa2_enabled &&
 333            ((!bss_desc->bcn_wpa_ie) ||
 334             ((*(bss_desc->bcn_wpa_ie)).
 335              vend_hdr.element_id != WLAN_EID_VENDOR_SPECIFIC)) &&
 336            ((!bss_desc->bcn_rsn_ie) ||
 337             ((*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id != WLAN_EID_RSN)) &&
 338            priv->sec_info.encryption_mode && bss_desc->privacy) {
 339                dev_dbg(priv->adapter->dev, "info: %s: dynamic "
 340                        "WEP: wpa_ie=%#x wpa2_ie=%#x "
 341                        "EncMode=%#x privacy=%#x\n",
 342                        __func__,
 343                        (bss_desc->bcn_wpa_ie) ?
 344                        (*(bss_desc->bcn_wpa_ie)).
 345                        vend_hdr.element_id : 0,
 346                        (bss_desc->bcn_rsn_ie) ?
 347                        (*(bss_desc->bcn_rsn_ie)).
 348                        ieee_hdr.element_id : 0,
 349                        priv->sec_info.encryption_mode,
 350                        bss_desc->privacy);
 351                return true;
 352        }
 353        return false;
 354}
 355
 356/*
 357 * This function checks if a scanned network is compatible with the driver
 358 * settings.
 359 *
 360 *   WEP     WPA    WPA2   ad-hoc encrypt                  Network
 361 * enabled enabled enabled  AES    mode   Privacy WPA WPA2 Compatible
 362 *    0       0       0      0     NONE      0     0   0   yes No security
 363 *    0       1       0      0      x        1x    1   x   yes WPA (disable
 364 *                                                         HT if no AES)
 365 *    0       0       1      0      x        1x    x   1   yes WPA2 (disable
 366 *                                                         HT if no AES)
 367 *    0       0       0      1     NONE      1     0   0   yes Ad-hoc AES
 368 *    1       0       0      0     NONE      1     0   0   yes Static WEP
 369 *                                                         (disable HT)
 370 *    0       0       0      0    !=NONE     1     0   0   yes Dynamic WEP
 371 *
 372 * Compatibility is not matched while roaming, except for mode.
 373 */
 374static s32
 375mwifiex_is_network_compatible(struct mwifiex_private *priv,
 376                              struct mwifiex_bssdescriptor *bss_desc, u32 mode)
 377{
 378        struct mwifiex_adapter *adapter = priv->adapter;
 379
 380        bss_desc->disable_11n = false;
 381
 382        /* Don't check for compatibility if roaming */
 383        if (priv->media_connected &&
 384            (priv->bss_mode == NL80211_IFTYPE_STATION) &&
 385            (bss_desc->bss_mode == NL80211_IFTYPE_STATION))
 386                return 0;
 387
 388        if (priv->wps.session_enable) {
 389                dev_dbg(adapter->dev,
 390                        "info: return success directly in WPS period\n");
 391                return 0;
 392        }
 393
 394        if (bss_desc->chan_sw_ie_present) {
 395                dev_err(adapter->dev,
 396                        "Don't connect to AP with WLAN_EID_CHANNEL_SWITCH\n");
 397                return -1;
 398        }
 399
 400        if (mwifiex_is_bss_wapi(priv, bss_desc)) {
 401                dev_dbg(adapter->dev, "info: return success for WAPI AP\n");
 402                return 0;
 403        }
 404
 405        if (bss_desc->bss_mode == mode) {
 406                if (mwifiex_is_bss_no_sec(priv, bss_desc)) {
 407                        /* No security */
 408                        return 0;
 409                } else if (mwifiex_is_bss_static_wep(priv, bss_desc)) {
 410                        /* Static WEP enabled */
 411                        dev_dbg(adapter->dev, "info: Disable 11n in WEP mode.\n");
 412                        bss_desc->disable_11n = true;
 413                        return 0;
 414                } else if (mwifiex_is_bss_wpa(priv, bss_desc)) {
 415                        /* WPA enabled */
 416                        if (((priv->adapter->config_bands & BAND_GN ||
 417                              priv->adapter->config_bands & BAND_AN) &&
 418                             bss_desc->bcn_ht_cap) &&
 419                            !mwifiex_is_wpa_oui_present(bss_desc,
 420                                                         CIPHER_SUITE_CCMP)) {
 421
 422                                if (mwifiex_is_wpa_oui_present
 423                                                (bss_desc, CIPHER_SUITE_TKIP)) {
 424                                        dev_dbg(adapter->dev,
 425                                                "info: Disable 11n if AES "
 426                                                "is not supported by AP\n");
 427                                        bss_desc->disable_11n = true;
 428                                } else {
 429                                        return -1;
 430                                }
 431                        }
 432                        return 0;
 433                } else if (mwifiex_is_bss_wpa2(priv, bss_desc)) {
 434                        /* WPA2 enabled */
 435                        if (((priv->adapter->config_bands & BAND_GN ||
 436                              priv->adapter->config_bands & BAND_AN) &&
 437                             bss_desc->bcn_ht_cap) &&
 438                            !mwifiex_is_rsn_oui_present(bss_desc,
 439                                                        CIPHER_SUITE_CCMP)) {
 440
 441                                if (mwifiex_is_rsn_oui_present
 442                                                (bss_desc, CIPHER_SUITE_TKIP)) {
 443                                        dev_dbg(adapter->dev,
 444                                                "info: Disable 11n if AES "
 445                                                "is not supported by AP\n");
 446                                        bss_desc->disable_11n = true;
 447                                } else {
 448                                        return -1;
 449                                }
 450                        }
 451                        return 0;
 452                } else if (mwifiex_is_bss_adhoc_aes(priv, bss_desc)) {
 453                        /* Ad-hoc AES enabled */
 454                        return 0;
 455                } else if (mwifiex_is_bss_dynamic_wep(priv, bss_desc)) {
 456                        /* Dynamic WEP enabled */
 457                        return 0;
 458                }
 459
 460                /* Security doesn't match */
 461                dev_dbg(adapter->dev,
 462                        "info: %s: failed: wpa_ie=%#x wpa2_ie=%#x WEP=%s "
 463                        "WPA=%s WPA2=%s EncMode=%#x privacy=%#x\n", __func__,
 464                        (bss_desc->bcn_wpa_ie) ?
 465                        (*(bss_desc->bcn_wpa_ie)).vend_hdr.element_id : 0,
 466                        (bss_desc->bcn_rsn_ie) ?
 467                        (*(bss_desc->bcn_rsn_ie)).ieee_hdr.element_id : 0,
 468                        (priv->sec_info.wep_enabled) ? "e" : "d",
 469                        (priv->sec_info.wpa_enabled) ? "e" : "d",
 470                        (priv->sec_info.wpa2_enabled) ? "e" : "d",
 471                        priv->sec_info.encryption_mode, bss_desc->privacy);
 472                return -1;
 473        }
 474
 475        /* Mode doesn't match */
 476        return -1;
 477}
 478
 479/*
 480 * This function creates a channel list for the driver to scan, based
 481 * on region/band information.
 482 *
 483 * This routine is used for any scan that is not provided with a
 484 * specific channel list to scan.
 485 */
 486static int
 487mwifiex_scan_create_channel_list(struct mwifiex_private *priv,
 488                                 const struct mwifiex_user_scan_cfg
 489                                                        *user_scan_in,
 490                                 struct mwifiex_chan_scan_param_set
 491                                                        *scan_chan_list,
 492                                 u8 filtered_scan)
 493{
 494        enum ieee80211_band band;
 495        struct ieee80211_supported_band *sband;
 496        struct ieee80211_channel *ch;
 497        struct mwifiex_adapter *adapter = priv->adapter;
 498        int chan_idx = 0, i;
 499
 500        for (band = 0; (band < IEEE80211_NUM_BANDS) ; band++) {
 501
 502                if (!priv->wdev->wiphy->bands[band])
 503                        continue;
 504
 505                sband = priv->wdev->wiphy->bands[band];
 506
 507                for (i = 0; (i < sband->n_channels) ; i++) {
 508                        ch = &sband->channels[i];
 509                        if (ch->flags & IEEE80211_CHAN_DISABLED)
 510                                continue;
 511                        scan_chan_list[chan_idx].radio_type = band;
 512
 513                        if (user_scan_in &&
 514                            user_scan_in->chan_list[0].scan_time)
 515                                scan_chan_list[chan_idx].max_scan_time =
 516                                        cpu_to_le16((u16) user_scan_in->
 517                                        chan_list[0].scan_time);
 518                        else if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
 519                                scan_chan_list[chan_idx].max_scan_time =
 520                                        cpu_to_le16(adapter->passive_scan_time);
 521                        else
 522                                scan_chan_list[chan_idx].max_scan_time =
 523                                        cpu_to_le16(adapter->active_scan_time);
 524
 525                        if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
 526                                scan_chan_list[chan_idx].chan_scan_mode_bitmap
 527                                        |= MWIFIEX_PASSIVE_SCAN;
 528                        else
 529                                scan_chan_list[chan_idx].chan_scan_mode_bitmap
 530                                        &= ~MWIFIEX_PASSIVE_SCAN;
 531                        scan_chan_list[chan_idx].chan_number =
 532                                                        (u32) ch->hw_value;
 533                        if (filtered_scan) {
 534                                scan_chan_list[chan_idx].max_scan_time =
 535                                cpu_to_le16(adapter->specific_scan_time);
 536                                scan_chan_list[chan_idx].chan_scan_mode_bitmap
 537                                        |= MWIFIEX_DISABLE_CHAN_FILT;
 538                        }
 539                        chan_idx++;
 540                }
 541
 542        }
 543        return chan_idx;
 544}
 545
 546/* This function appends rate TLV to scan config command. */
 547static int
 548mwifiex_append_rate_tlv(struct mwifiex_private *priv,
 549                        struct mwifiex_scan_cmd_config *scan_cfg_out,
 550                        u8 radio)
 551{
 552        struct mwifiex_ie_types_rates_param_set *rates_tlv;
 553        u8 rates[MWIFIEX_SUPPORTED_RATES], *tlv_pos;
 554        u32 rates_size;
 555
 556        memset(rates, 0, sizeof(rates));
 557
 558        tlv_pos = (u8 *)scan_cfg_out->tlv_buf + scan_cfg_out->tlv_buf_len;
 559
 560        if (priv->scan_request)
 561                rates_size = mwifiex_get_rates_from_cfg80211(priv, rates,
 562                                                             radio);
 563        else
 564                rates_size = mwifiex_get_supported_rates(priv, rates);
 565
 566        dev_dbg(priv->adapter->dev, "info: SCAN_CMD: Rates size = %d\n",
 567                rates_size);
 568        rates_tlv = (struct mwifiex_ie_types_rates_param_set *)tlv_pos;
 569        rates_tlv->header.type = cpu_to_le16(WLAN_EID_SUPP_RATES);
 570        rates_tlv->header.len = cpu_to_le16((u16) rates_size);
 571        memcpy(rates_tlv->rates, rates, rates_size);
 572        scan_cfg_out->tlv_buf_len += sizeof(rates_tlv->header) + rates_size;
 573
 574        return rates_size;
 575}
 576
 577/*
 578 * This function constructs and sends multiple scan config commands to
 579 * the firmware.
 580 *
 581 * Previous routines in the code flow have created a scan command configuration
 582 * with any requested TLVs.  This function splits the channel TLV into maximum
 583 * channels supported per scan lists and sends the portion of the channel TLV,
 584 * along with the other TLVs, to the firmware.
 585 */
 586static int
 587mwifiex_scan_channel_list(struct mwifiex_private *priv,
 588                          u32 max_chan_per_scan, u8 filtered_scan,
 589                          struct mwifiex_scan_cmd_config *scan_cfg_out,
 590                          struct mwifiex_ie_types_chan_list_param_set
 591                          *chan_tlv_out,
 592                          struct mwifiex_chan_scan_param_set *scan_chan_list)
 593{
 594        int ret = 0;
 595        struct mwifiex_chan_scan_param_set *tmp_chan_list;
 596        struct mwifiex_chan_scan_param_set *start_chan;
 597
 598        u32 tlv_idx, rates_size;
 599        u32 total_scan_time;
 600        u32 done_early;
 601        u8 radio_type;
 602
 603        if (!scan_cfg_out || !chan_tlv_out || !scan_chan_list) {
 604                dev_dbg(priv->adapter->dev,
 605                        "info: Scan: Null detect: %p, %p, %p\n",
 606                       scan_cfg_out, chan_tlv_out, scan_chan_list);
 607                return -1;
 608        }
 609
 610        /* Check csa channel expiry before preparing scan list */
 611        mwifiex_11h_get_csa_closed_channel(priv);
 612
 613        chan_tlv_out->header.type = cpu_to_le16(TLV_TYPE_CHANLIST);
 614
 615        /* Set the temp channel struct pointer to the start of the desired
 616           list */
 617        tmp_chan_list = scan_chan_list;
 618
 619        /* Loop through the desired channel list, sending a new firmware scan
 620           commands for each max_chan_per_scan channels (or for 1,6,11
 621           individually if configured accordingly) */
 622        while (tmp_chan_list->chan_number) {
 623
 624                tlv_idx = 0;
 625                total_scan_time = 0;
 626                radio_type = 0;
 627                chan_tlv_out->header.len = 0;
 628                start_chan = tmp_chan_list;
 629                done_early = false;
 630
 631                /*
 632                 * Construct the Channel TLV for the scan command.  Continue to
 633                 * insert channel TLVs until:
 634                 *   - the tlv_idx hits the maximum configured per scan command
 635                 *   - the next channel to insert is 0 (end of desired channel
 636                 *     list)
 637                 *   - done_early is set (controlling individual scanning of
 638                 *     1,6,11)
 639                 */
 640                while (tlv_idx < max_chan_per_scan &&
 641                       tmp_chan_list->chan_number && !done_early) {
 642
 643                        if (tmp_chan_list->chan_number == priv->csa_chan) {
 644                                tmp_chan_list++;
 645                                continue;
 646                        }
 647
 648                        radio_type = tmp_chan_list->radio_type;
 649                        dev_dbg(priv->adapter->dev,
 650                                "info: Scan: Chan(%3d), Radio(%d),"
 651                                " Mode(%d, %d), Dur(%d)\n",
 652                                tmp_chan_list->chan_number,
 653                                tmp_chan_list->radio_type,
 654                                tmp_chan_list->chan_scan_mode_bitmap
 655                                & MWIFIEX_PASSIVE_SCAN,
 656                                (tmp_chan_list->chan_scan_mode_bitmap
 657                                 & MWIFIEX_DISABLE_CHAN_FILT) >> 1,
 658                                le16_to_cpu(tmp_chan_list->max_scan_time));
 659
 660                        /* Copy the current channel TLV to the command being
 661                           prepared */
 662                        memcpy(chan_tlv_out->chan_scan_param + tlv_idx,
 663                               tmp_chan_list,
 664                               sizeof(chan_tlv_out->chan_scan_param));
 665
 666                        /* Increment the TLV header length by the size
 667                           appended */
 668                        le16_add_cpu(&chan_tlv_out->header.len,
 669                                     sizeof(chan_tlv_out->chan_scan_param));
 670
 671                        /*
 672                         * The tlv buffer length is set to the number of bytes
 673                         * of the between the channel tlv pointer and the start
 674                         * of the tlv buffer.  This compensates for any TLVs
 675                         * that were appended before the channel list.
 676                         */
 677                        scan_cfg_out->tlv_buf_len = (u32) ((u8 *) chan_tlv_out -
 678                                                        scan_cfg_out->tlv_buf);
 679
 680                        /* Add the size of the channel tlv header and the data
 681                           length */
 682                        scan_cfg_out->tlv_buf_len +=
 683                                (sizeof(chan_tlv_out->header)
 684                                 + le16_to_cpu(chan_tlv_out->header.len));
 685
 686                        /* Increment the index to the channel tlv we are
 687                           constructing */
 688                        tlv_idx++;
 689
 690                        /* Count the total scan time per command */
 691                        total_scan_time +=
 692                                le16_to_cpu(tmp_chan_list->max_scan_time);
 693
 694                        done_early = false;
 695
 696                        /* Stop the loop if the *current* channel is in the
 697                           1,6,11 set and we are not filtering on a BSSID
 698                           or SSID. */
 699                        if (!filtered_scan &&
 700                            (tmp_chan_list->chan_number == 1 ||
 701                             tmp_chan_list->chan_number == 6 ||
 702                             tmp_chan_list->chan_number == 11))
 703                                done_early = true;
 704
 705                        /* Increment the tmp pointer to the next channel to
 706                           be scanned */
 707                        tmp_chan_list++;
 708
 709                        /* Stop the loop if the *next* channel is in the 1,6,11
 710                           set.  This will cause it to be the only channel
 711                           scanned on the next interation */
 712                        if (!filtered_scan &&
 713                            (tmp_chan_list->chan_number == 1 ||
 714                             tmp_chan_list->chan_number == 6 ||
 715                             tmp_chan_list->chan_number == 11))
 716                                done_early = true;
 717                }
 718
 719                /* The total scan time should be less than scan command timeout
 720                   value */
 721                if (total_scan_time > MWIFIEX_MAX_TOTAL_SCAN_TIME) {
 722                        dev_err(priv->adapter->dev, "total scan time %dms"
 723                                " is over limit (%dms), scan skipped\n",
 724                                total_scan_time, MWIFIEX_MAX_TOTAL_SCAN_TIME);
 725                        ret = -1;
 726                        break;
 727                }
 728
 729                rates_size = mwifiex_append_rate_tlv(priv, scan_cfg_out,
 730                                                     radio_type);
 731
 732                priv->adapter->scan_channels = start_chan;
 733
 734                /* Send the scan command to the firmware with the specified
 735                   cfg */
 736                ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11_SCAN,
 737                                             HostCmd_ACT_GEN_SET, 0,
 738                                             scan_cfg_out);
 739
 740                /* rate IE is updated per scan command but same starting
 741                 * pointer is used each time so that rate IE from earlier
 742                 * scan_cfg_out->buf is overwritten with new one.
 743                 */
 744                scan_cfg_out->tlv_buf_len -=
 745                            sizeof(struct mwifiex_ie_types_header) + rates_size;
 746
 747                if (ret)
 748                        break;
 749        }
 750
 751        if (ret)
 752                return -1;
 753
 754        return 0;
 755}
 756
 757/*
 758 * This function constructs a scan command configuration structure to use
 759 * in scan commands.
 760 *
 761 * Application layer or other functions can invoke network scanning
 762 * with a scan configuration supplied in a user scan configuration structure.
 763 * This structure is used as the basis of one or many scan command configuration
 764 * commands that are sent to the command processing module and eventually to the
 765 * firmware.
 766 *
 767 * This function creates a scan command configuration structure  based on the
 768 * following user supplied parameters (if present):
 769 *      - SSID filter
 770 *      - BSSID filter
 771 *      - Number of Probes to be sent
 772 *      - Channel list
 773 *
 774 * If the SSID or BSSID filter is not present, the filter is disabled/cleared.
 775 * If the number of probes is not set, adapter default setting is used.
 776 */
 777static void
 778mwifiex_config_scan(struct mwifiex_private *priv,
 779                    const struct mwifiex_user_scan_cfg *user_scan_in,
 780                    struct mwifiex_scan_cmd_config *scan_cfg_out,
 781                    struct mwifiex_ie_types_chan_list_param_set **chan_list_out,
 782                    struct mwifiex_chan_scan_param_set *scan_chan_list,
 783                    u8 *max_chan_per_scan, u8 *filtered_scan,
 784                    u8 *scan_current_only)
 785{
 786        struct mwifiex_adapter *adapter = priv->adapter;
 787        struct mwifiex_ie_types_num_probes *num_probes_tlv;
 788        struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv;
 789        u8 *tlv_pos;
 790        u32 num_probes;
 791        u32 ssid_len;
 792        u32 chan_idx;
 793        u32 chan_num;
 794        u32 scan_type;
 795        u16 scan_dur;
 796        u8 channel;
 797        u8 radio_type;
 798        int i;
 799        u8 ssid_filter;
 800        struct mwifiex_ie_types_htcap *ht_cap;
 801
 802        /* The tlv_buf_len is calculated for each scan command.  The TLVs added
 803           in this routine will be preserved since the routine that sends the
 804           command will append channelTLVs at *chan_list_out.  The difference
 805           between the *chan_list_out and the tlv_buf start will be used to
 806           calculate the size of anything we add in this routine. */
 807        scan_cfg_out->tlv_buf_len = 0;
 808
 809        /* Running tlv pointer.  Assigned to chan_list_out at end of function
 810           so later routines know where channels can be added to the command
 811           buf */
 812        tlv_pos = scan_cfg_out->tlv_buf;
 813
 814        /* Initialize the scan as un-filtered; the flag is later set to TRUE
 815           below if a SSID or BSSID filter is sent in the command */
 816        *filtered_scan = false;
 817
 818        /* Initialize the scan as not being only on the current channel.  If
 819           the channel list is customized, only contains one channel, and is
 820           the active channel, this is set true and data flow is not halted. */
 821        *scan_current_only = false;
 822
 823        if (user_scan_in) {
 824
 825                /* Default the ssid_filter flag to TRUE, set false under
 826                   certain wildcard conditions and qualified by the existence
 827                   of an SSID list before marking the scan as filtered */
 828                ssid_filter = true;
 829
 830                /* Set the BSS type scan filter, use Adapter setting if
 831                   unset */
 832                scan_cfg_out->bss_mode =
 833                        (user_scan_in->bss_mode ? (u8) user_scan_in->
 834                         bss_mode : (u8) adapter->scan_mode);
 835
 836                /* Set the number of probes to send, use Adapter setting
 837                   if unset */
 838                num_probes =
 839                        (user_scan_in->num_probes ? user_scan_in->
 840                         num_probes : adapter->scan_probes);
 841
 842                /*
 843                 * Set the BSSID filter to the incoming configuration,
 844                 * if non-zero.  If not set, it will remain disabled
 845                 * (all zeros).
 846                 */
 847                memcpy(scan_cfg_out->specific_bssid,
 848                       user_scan_in->specific_bssid,
 849                       sizeof(scan_cfg_out->specific_bssid));
 850
 851                for (i = 0; i < user_scan_in->num_ssids; i++) {
 852                        ssid_len = user_scan_in->ssid_list[i].ssid_len;
 853
 854                        wildcard_ssid_tlv =
 855                                (struct mwifiex_ie_types_wildcard_ssid_params *)
 856                                tlv_pos;
 857                        wildcard_ssid_tlv->header.type =
 858                                cpu_to_le16(TLV_TYPE_WILDCARDSSID);
 859                        wildcard_ssid_tlv->header.len = cpu_to_le16(
 860                                (u16) (ssid_len + sizeof(wildcard_ssid_tlv->
 861                                                         max_ssid_length)));
 862
 863                        /*
 864                         * max_ssid_length = 0 tells firmware to perform
 865                         * specific scan for the SSID filled, whereas
 866                         * max_ssid_length = IEEE80211_MAX_SSID_LEN is for
 867                         * wildcard scan.
 868                         */
 869                        if (ssid_len)
 870                                wildcard_ssid_tlv->max_ssid_length = 0;
 871                        else
 872                                wildcard_ssid_tlv->max_ssid_length =
 873                                                        IEEE80211_MAX_SSID_LEN;
 874
 875                        memcpy(wildcard_ssid_tlv->ssid,
 876                               user_scan_in->ssid_list[i].ssid, ssid_len);
 877
 878                        tlv_pos += (sizeof(wildcard_ssid_tlv->header)
 879                                + le16_to_cpu(wildcard_ssid_tlv->header.len));
 880
 881                        dev_dbg(adapter->dev, "info: scan: ssid[%d]: %s, %d\n",
 882                                i, wildcard_ssid_tlv->ssid,
 883                                wildcard_ssid_tlv->max_ssid_length);
 884
 885                        /* Empty wildcard ssid with a maxlen will match many or
 886                           potentially all SSIDs (maxlen == 32), therefore do
 887                           not treat the scan as
 888                           filtered. */
 889                        if (!ssid_len && wildcard_ssid_tlv->max_ssid_length)
 890                                ssid_filter = false;
 891                }
 892
 893                /*
 894                 *  The default number of channels sent in the command is low to
 895                 *  ensure the response buffer from the firmware does not
 896                 *  truncate scan results.  That is not an issue with an SSID
 897                 *  or BSSID filter applied to the scan results in the firmware.
 898                 */
 899                if ((i && ssid_filter) ||
 900                    !is_zero_ether_addr(scan_cfg_out->specific_bssid))
 901                        *filtered_scan = true;
 902        } else {
 903                scan_cfg_out->bss_mode = (u8) adapter->scan_mode;
 904                num_probes = adapter->scan_probes;
 905        }
 906
 907        /*
 908         *  If a specific BSSID or SSID is used, the number of channels in the
 909         *  scan command will be increased to the absolute maximum.
 910         */
 911        if (*filtered_scan)
 912                *max_chan_per_scan = MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN;
 913        else
 914                *max_chan_per_scan = MWIFIEX_DEF_CHANNELS_PER_SCAN_CMD;
 915
 916        /* If the input config or adapter has the number of Probes set,
 917           add tlv */
 918        if (num_probes) {
 919
 920                dev_dbg(adapter->dev, "info: scan: num_probes = %d\n",
 921                        num_probes);
 922
 923                num_probes_tlv = (struct mwifiex_ie_types_num_probes *) tlv_pos;
 924                num_probes_tlv->header.type = cpu_to_le16(TLV_TYPE_NUMPROBES);
 925                num_probes_tlv->header.len =
 926                        cpu_to_le16(sizeof(num_probes_tlv->num_probes));
 927                num_probes_tlv->num_probes = cpu_to_le16((u16) num_probes);
 928
 929                tlv_pos += sizeof(num_probes_tlv->header) +
 930                        le16_to_cpu(num_probes_tlv->header.len);
 931
 932        }
 933
 934        if (ISSUPP_11NENABLED(priv->adapter->fw_cap_info) &&
 935            (priv->adapter->config_bands & BAND_GN ||
 936             priv->adapter->config_bands & BAND_AN)) {
 937                ht_cap = (struct mwifiex_ie_types_htcap *) tlv_pos;
 938                memset(ht_cap, 0, sizeof(struct mwifiex_ie_types_htcap));
 939                ht_cap->header.type = cpu_to_le16(WLAN_EID_HT_CAPABILITY);
 940                ht_cap->header.len =
 941                                cpu_to_le16(sizeof(struct ieee80211_ht_cap));
 942                radio_type =
 943                        mwifiex_band_to_radio_type(priv->adapter->config_bands);
 944                mwifiex_fill_cap_info(priv, radio_type, ht_cap);
 945                tlv_pos += sizeof(struct mwifiex_ie_types_htcap);
 946        }
 947
 948        /* Append vendor specific IE TLV */
 949        mwifiex_cmd_append_vsie_tlv(priv, MWIFIEX_VSIE_MASK_SCAN, &tlv_pos);
 950
 951        /*
 952         * Set the output for the channel TLV to the address in the tlv buffer
 953         *   past any TLVs that were added in this function (SSID, num_probes).
 954         *   Channel TLVs will be added past this for each scan command,
 955         *   preserving the TLVs that were previously added.
 956         */
 957        *chan_list_out =
 958                (struct mwifiex_ie_types_chan_list_param_set *) tlv_pos;
 959
 960        if (user_scan_in && user_scan_in->chan_list[0].chan_number) {
 961
 962                dev_dbg(adapter->dev, "info: Scan: Using supplied channel list\n");
 963
 964                for (chan_idx = 0;
 965                     chan_idx < MWIFIEX_USER_SCAN_CHAN_MAX &&
 966                     user_scan_in->chan_list[chan_idx].chan_number;
 967                     chan_idx++) {
 968
 969                        channel = user_scan_in->chan_list[chan_idx].chan_number;
 970                        (scan_chan_list + chan_idx)->chan_number = channel;
 971
 972                        radio_type =
 973                                user_scan_in->chan_list[chan_idx].radio_type;
 974                        (scan_chan_list + chan_idx)->radio_type = radio_type;
 975
 976                        scan_type = user_scan_in->chan_list[chan_idx].scan_type;
 977
 978                        if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE)
 979                                (scan_chan_list +
 980                                 chan_idx)->chan_scan_mode_bitmap
 981                                        |= MWIFIEX_PASSIVE_SCAN;
 982                        else
 983                                (scan_chan_list +
 984                                 chan_idx)->chan_scan_mode_bitmap
 985                                        &= ~MWIFIEX_PASSIVE_SCAN;
 986
 987                        if (*filtered_scan)
 988                                (scan_chan_list +
 989                                 chan_idx)->chan_scan_mode_bitmap
 990                                        |= MWIFIEX_DISABLE_CHAN_FILT;
 991
 992                        if (user_scan_in->chan_list[chan_idx].scan_time) {
 993                                scan_dur = (u16) user_scan_in->
 994                                        chan_list[chan_idx].scan_time;
 995                        } else {
 996                                if (scan_type == MWIFIEX_SCAN_TYPE_PASSIVE)
 997                                        scan_dur = adapter->passive_scan_time;
 998                                else if (*filtered_scan)
 999                                        scan_dur = adapter->specific_scan_time;
1000                                else
1001                                        scan_dur = adapter->active_scan_time;
1002                        }
1003
1004                        (scan_chan_list + chan_idx)->min_scan_time =
1005                                cpu_to_le16(scan_dur);
1006                        (scan_chan_list + chan_idx)->max_scan_time =
1007                                cpu_to_le16(scan_dur);
1008                }
1009
1010                /* Check if we are only scanning the current channel */
1011                if ((chan_idx == 1) &&
1012                    (user_scan_in->chan_list[0].chan_number ==
1013                     priv->curr_bss_params.bss_descriptor.channel)) {
1014                        *scan_current_only = true;
1015                        dev_dbg(adapter->dev,
1016                                "info: Scan: Scanning current channel only\n");
1017                }
1018                chan_num = chan_idx;
1019        } else {
1020                dev_dbg(adapter->dev,
1021                        "info: Scan: Creating full region channel list\n");
1022                chan_num = mwifiex_scan_create_channel_list(priv, user_scan_in,
1023                                                            scan_chan_list,
1024                                                            *filtered_scan);
1025        }
1026
1027        /*
1028         * In associated state we will reduce the number of channels scanned per
1029         * scan command to avoid any traffic delay/loss. This number is decided
1030         * based on total number of channels to be scanned due to constraints
1031         * of command buffers.
1032         */
1033        if (priv->media_connected) {
1034                if (chan_num < MWIFIEX_LIMIT_1_CHANNEL_PER_SCAN_CMD)
1035                        *max_chan_per_scan = 1;
1036                else if (chan_num < MWIFIEX_LIMIT_2_CHANNELS_PER_SCAN_CMD)
1037                        *max_chan_per_scan = 2;
1038                else if (chan_num < MWIFIEX_LIMIT_3_CHANNELS_PER_SCAN_CMD)
1039                        *max_chan_per_scan = 3;
1040                else
1041                        *max_chan_per_scan = 4;
1042        }
1043}
1044
1045/*
1046 * This function inspects the scan response buffer for pointers to
1047 * expected TLVs.
1048 *
1049 * TLVs can be included at the end of the scan response BSS information.
1050 *
1051 * Data in the buffer is parsed pointers to TLVs that can potentially
1052 * be passed back in the response.
1053 */
1054static void
1055mwifiex_ret_802_11_scan_get_tlv_ptrs(struct mwifiex_adapter *adapter,
1056                                     struct mwifiex_ie_types_data *tlv,
1057                                     u32 tlv_buf_size, u32 req_tlv_type,
1058                                     struct mwifiex_ie_types_data **tlv_data)
1059{
1060        struct mwifiex_ie_types_data *current_tlv;
1061        u32 tlv_buf_left;
1062        u32 tlv_type;
1063        u32 tlv_len;
1064
1065        current_tlv = tlv;
1066        tlv_buf_left = tlv_buf_size;
1067        *tlv_data = NULL;
1068
1069        dev_dbg(adapter->dev, "info: SCAN_RESP: tlv_buf_size = %d\n",
1070                tlv_buf_size);
1071
1072        while (tlv_buf_left >= sizeof(struct mwifiex_ie_types_header)) {
1073
1074                tlv_type = le16_to_cpu(current_tlv->header.type);
1075                tlv_len = le16_to_cpu(current_tlv->header.len);
1076
1077                if (sizeof(tlv->header) + tlv_len > tlv_buf_left) {
1078                        dev_err(adapter->dev, "SCAN_RESP: TLV buffer corrupt\n");
1079                        break;
1080                }
1081
1082                if (req_tlv_type == tlv_type) {
1083                        switch (tlv_type) {
1084                        case TLV_TYPE_TSFTIMESTAMP:
1085                                dev_dbg(adapter->dev, "info: SCAN_RESP: TSF "
1086                                        "timestamp TLV, len = %d\n", tlv_len);
1087                                *tlv_data = current_tlv;
1088                                break;
1089                        case TLV_TYPE_CHANNELBANDLIST:
1090                                dev_dbg(adapter->dev, "info: SCAN_RESP: channel"
1091                                        " band list TLV, len = %d\n", tlv_len);
1092                                *tlv_data = current_tlv;
1093                                break;
1094                        default:
1095                                dev_err(adapter->dev,
1096                                        "SCAN_RESP: unhandled TLV = %d\n",
1097                                       tlv_type);
1098                                /* Give up, this seems corrupted */
1099                                return;
1100                        }
1101                }
1102
1103                if (*tlv_data)
1104                        break;
1105
1106
1107                tlv_buf_left -= (sizeof(tlv->header) + tlv_len);
1108                current_tlv =
1109                        (struct mwifiex_ie_types_data *) (current_tlv->data +
1110                                                          tlv_len);
1111
1112        }                       /* while */
1113}
1114
1115/*
1116 * This function parses provided beacon buffer and updates
1117 * respective fields in bss descriptor structure.
1118 */
1119int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
1120                                    struct mwifiex_bssdescriptor *bss_entry)
1121{
1122        int ret = 0;
1123        u8 element_id;
1124        struct ieee_types_fh_param_set *fh_param_set;
1125        struct ieee_types_ds_param_set *ds_param_set;
1126        struct ieee_types_cf_param_set *cf_param_set;
1127        struct ieee_types_ibss_param_set *ibss_param_set;
1128        u8 *current_ptr;
1129        u8 *rate;
1130        u8 element_len;
1131        u16 total_ie_len;
1132        u8 bytes_to_copy;
1133        u8 rate_size;
1134        u8 found_data_rate_ie;
1135        u32 bytes_left;
1136        struct ieee_types_vendor_specific *vendor_ie;
1137        const u8 wpa_oui[4] = { 0x00, 0x50, 0xf2, 0x01 };
1138        const u8 wmm_oui[4] = { 0x00, 0x50, 0xf2, 0x02 };
1139
1140        found_data_rate_ie = false;
1141        rate_size = 0;
1142        current_ptr = bss_entry->beacon_buf;
1143        bytes_left = bss_entry->beacon_buf_size;
1144
1145        /* Process variable IE */
1146        while (bytes_left >= 2) {
1147                element_id = *current_ptr;
1148                element_len = *(current_ptr + 1);
1149                total_ie_len = element_len + sizeof(struct ieee_types_header);
1150
1151                if (bytes_left < total_ie_len) {
1152                        dev_err(adapter->dev, "err: InterpretIE: in processing"
1153                                " IE, bytes left < IE length\n");
1154                        return -1;
1155                }
1156                switch (element_id) {
1157                case WLAN_EID_SSID:
1158                        bss_entry->ssid.ssid_len = element_len;
1159                        memcpy(bss_entry->ssid.ssid, (current_ptr + 2),
1160                               element_len);
1161                        dev_dbg(adapter->dev,
1162                                "info: InterpretIE: ssid: %-32s\n",
1163                                bss_entry->ssid.ssid);
1164                        break;
1165
1166                case WLAN_EID_SUPP_RATES:
1167                        memcpy(bss_entry->data_rates, current_ptr + 2,
1168                               element_len);
1169                        memcpy(bss_entry->supported_rates, current_ptr + 2,
1170                               element_len);
1171                        rate_size = element_len;
1172                        found_data_rate_ie = true;
1173                        break;
1174
1175                case WLAN_EID_FH_PARAMS:
1176                        fh_param_set =
1177                                (struct ieee_types_fh_param_set *) current_ptr;
1178                        memcpy(&bss_entry->phy_param_set.fh_param_set,
1179                               fh_param_set,
1180                               sizeof(struct ieee_types_fh_param_set));
1181                        break;
1182
1183                case WLAN_EID_DS_PARAMS:
1184                        ds_param_set =
1185                                (struct ieee_types_ds_param_set *) current_ptr;
1186
1187                        bss_entry->channel = ds_param_set->current_chan;
1188
1189                        memcpy(&bss_entry->phy_param_set.ds_param_set,
1190                               ds_param_set,
1191                               sizeof(struct ieee_types_ds_param_set));
1192                        break;
1193
1194                case WLAN_EID_CF_PARAMS:
1195                        cf_param_set =
1196                                (struct ieee_types_cf_param_set *) current_ptr;
1197                        memcpy(&bss_entry->ss_param_set.cf_param_set,
1198                               cf_param_set,
1199                               sizeof(struct ieee_types_cf_param_set));
1200                        break;
1201
1202                case WLAN_EID_IBSS_PARAMS:
1203                        ibss_param_set =
1204                                (struct ieee_types_ibss_param_set *)
1205                                current_ptr;
1206                        memcpy(&bss_entry->ss_param_set.ibss_param_set,
1207                               ibss_param_set,
1208                               sizeof(struct ieee_types_ibss_param_set));
1209                        break;
1210
1211                case WLAN_EID_ERP_INFO:
1212                        bss_entry->erp_flags = *(current_ptr + 2);
1213                        break;
1214
1215                case WLAN_EID_PWR_CONSTRAINT:
1216                        bss_entry->local_constraint = *(current_ptr + 2);
1217                        bss_entry->sensed_11h = true;
1218                        break;
1219
1220                case WLAN_EID_CHANNEL_SWITCH:
1221                        bss_entry->chan_sw_ie_present = true;
1222                case WLAN_EID_PWR_CAPABILITY:
1223                case WLAN_EID_TPC_REPORT:
1224                case WLAN_EID_QUIET:
1225                        bss_entry->sensed_11h = true;
1226                    break;
1227
1228                case WLAN_EID_EXT_SUPP_RATES:
1229                        /*
1230                         * Only process extended supported rate
1231                         * if data rate is already found.
1232                         * Data rate IE should come before
1233                         * extended supported rate IE
1234                         */
1235                        if (found_data_rate_ie) {
1236                                if ((element_len + rate_size) >
1237                                    MWIFIEX_SUPPORTED_RATES)
1238                                        bytes_to_copy =
1239                                                (MWIFIEX_SUPPORTED_RATES -
1240                                                 rate_size);
1241                                else
1242                                        bytes_to_copy = element_len;
1243
1244                                rate = (u8 *) bss_entry->data_rates;
1245                                rate += rate_size;
1246                                memcpy(rate, current_ptr + 2, bytes_to_copy);
1247
1248                                rate = (u8 *) bss_entry->supported_rates;
1249                                rate += rate_size;
1250                                memcpy(rate, current_ptr + 2, bytes_to_copy);
1251                        }
1252                        break;
1253
1254                case WLAN_EID_VENDOR_SPECIFIC:
1255                        vendor_ie = (struct ieee_types_vendor_specific *)
1256                                        current_ptr;
1257
1258                        if (!memcmp
1259                            (vendor_ie->vend_hdr.oui, wpa_oui,
1260                             sizeof(wpa_oui))) {
1261                                bss_entry->bcn_wpa_ie =
1262                                        (struct ieee_types_vendor_specific *)
1263                                        current_ptr;
1264                                bss_entry->wpa_offset = (u16)
1265                                        (current_ptr - bss_entry->beacon_buf);
1266                        } else if (!memcmp(vendor_ie->vend_hdr.oui, wmm_oui,
1267                                    sizeof(wmm_oui))) {
1268                                if (total_ie_len ==
1269                                    sizeof(struct ieee_types_wmm_parameter) ||
1270                                    total_ie_len ==
1271                                    sizeof(struct ieee_types_wmm_info))
1272                                        /*
1273                                         * Only accept and copy the WMM IE if
1274                                         * it matches the size expected for the
1275                                         * WMM Info IE or the WMM Parameter IE.
1276                                         */
1277                                        memcpy((u8 *) &bss_entry->wmm_ie,
1278                                               current_ptr, total_ie_len);
1279                        }
1280                        break;
1281                case WLAN_EID_RSN:
1282                        bss_entry->bcn_rsn_ie =
1283                                (struct ieee_types_generic *) current_ptr;
1284                        bss_entry->rsn_offset = (u16) (current_ptr -
1285                                                        bss_entry->beacon_buf);
1286                        break;
1287                case WLAN_EID_BSS_AC_ACCESS_DELAY:
1288                        bss_entry->bcn_wapi_ie =
1289                                (struct ieee_types_generic *) current_ptr;
1290                        bss_entry->wapi_offset = (u16) (current_ptr -
1291                                                        bss_entry->beacon_buf);
1292                        break;
1293                case WLAN_EID_HT_CAPABILITY:
1294                        bss_entry->bcn_ht_cap = (struct ieee80211_ht_cap *)
1295                                        (current_ptr +
1296                                        sizeof(struct ieee_types_header));
1297                        bss_entry->ht_cap_offset = (u16) (current_ptr +
1298                                        sizeof(struct ieee_types_header) -
1299                                        bss_entry->beacon_buf);
1300                        break;
1301                case WLAN_EID_HT_OPERATION:
1302                        bss_entry->bcn_ht_oper =
1303                                (struct ieee80211_ht_operation *)(current_ptr +
1304                                        sizeof(struct ieee_types_header));
1305                        bss_entry->ht_info_offset = (u16) (current_ptr +
1306                                        sizeof(struct ieee_types_header) -
1307                                        bss_entry->beacon_buf);
1308                        break;
1309                case WLAN_EID_VHT_CAPABILITY:
1310                        bss_entry->disable_11ac = false;
1311                        bss_entry->bcn_vht_cap =
1312                                (void *)(current_ptr +
1313                                         sizeof(struct ieee_types_header));
1314                        bss_entry->vht_cap_offset =
1315                                        (u16)((u8 *)bss_entry->bcn_vht_cap -
1316                                              bss_entry->beacon_buf);
1317                        break;
1318                case WLAN_EID_VHT_OPERATION:
1319                        bss_entry->bcn_vht_oper =
1320                                (void *)(current_ptr +
1321                                         sizeof(struct ieee_types_header));
1322                        bss_entry->vht_info_offset =
1323                                        (u16)((u8 *)bss_entry->bcn_vht_oper -
1324                                              bss_entry->beacon_buf);
1325                        break;
1326                case WLAN_EID_BSS_COEX_2040:
1327                        bss_entry->bcn_bss_co_2040 = current_ptr +
1328                                sizeof(struct ieee_types_header);
1329                        bss_entry->bss_co_2040_offset = (u16) (current_ptr +
1330                                        sizeof(struct ieee_types_header) -
1331                                                bss_entry->beacon_buf);
1332                        break;
1333                case WLAN_EID_EXT_CAPABILITY:
1334                        bss_entry->bcn_ext_cap = current_ptr +
1335                                sizeof(struct ieee_types_header);
1336                        bss_entry->ext_cap_offset = (u16) (current_ptr +
1337                                        sizeof(struct ieee_types_header) -
1338                                        bss_entry->beacon_buf);
1339                        break;
1340                case WLAN_EID_OPMODE_NOTIF:
1341                        bss_entry->oper_mode =
1342                                (void *)(current_ptr +
1343                                         sizeof(struct ieee_types_header));
1344                        bss_entry->oper_mode_offset =
1345                                        (u16)((u8 *)bss_entry->oper_mode -
1346                                              bss_entry->beacon_buf);
1347                        break;
1348                default:
1349                        break;
1350                }
1351
1352                current_ptr += element_len + 2;
1353
1354                /* Need to account for IE ID and IE Len */
1355                bytes_left -= (element_len + 2);
1356
1357        }       /* while (bytes_left > 2) */
1358        return ret;
1359}
1360
1361/*
1362 * This function converts radio type scan parameter to a band configuration
1363 * to be used in join command.
1364 */
1365static u8
1366mwifiex_radio_type_to_band(u8 radio_type)
1367{
1368        switch (radio_type) {
1369        case HostCmd_SCAN_RADIO_TYPE_A:
1370                return BAND_A;
1371        case HostCmd_SCAN_RADIO_TYPE_BG:
1372        default:
1373                return BAND_G;
1374        }
1375}
1376
1377/*
1378 * This is an internal function used to start a scan based on an input
1379 * configuration.
1380 *
1381 * This uses the input user scan configuration information when provided in
1382 * order to send the appropriate scan commands to firmware to populate or
1383 * update the internal driver scan table.
1384 */
1385int mwifiex_scan_networks(struct mwifiex_private *priv,
1386                          const struct mwifiex_user_scan_cfg *user_scan_in)
1387{
1388        int ret;
1389        struct mwifiex_adapter *adapter = priv->adapter;
1390        struct cmd_ctrl_node *cmd_node;
1391        union mwifiex_scan_cmd_config_tlv *scan_cfg_out;
1392        struct mwifiex_ie_types_chan_list_param_set *chan_list_out;
1393        struct mwifiex_chan_scan_param_set *scan_chan_list;
1394        u8 filtered_scan;
1395        u8 scan_current_chan_only;
1396        u8 max_chan_per_scan;
1397        unsigned long flags;
1398
1399        if (adapter->scan_processing) {
1400                dev_err(adapter->dev, "cmd: Scan already in process...\n");
1401                return -EBUSY;
1402        }
1403
1404        if (priv->scan_block) {
1405                dev_err(adapter->dev,
1406                        "cmd: Scan is blocked during association...\n");
1407                return -EBUSY;
1408        }
1409
1410        spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
1411        adapter->scan_processing = true;
1412        spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
1413
1414        scan_cfg_out = kzalloc(sizeof(union mwifiex_scan_cmd_config_tlv),
1415                               GFP_KERNEL);
1416        if (!scan_cfg_out) {
1417                ret = -ENOMEM;
1418                goto done;
1419        }
1420
1421        scan_chan_list = kcalloc(MWIFIEX_USER_SCAN_CHAN_MAX,
1422                                 sizeof(struct mwifiex_chan_scan_param_set),
1423                                 GFP_KERNEL);
1424        if (!scan_chan_list) {
1425                kfree(scan_cfg_out);
1426                ret = -ENOMEM;
1427                goto done;
1428        }
1429
1430        mwifiex_config_scan(priv, user_scan_in, &scan_cfg_out->config,
1431                            &chan_list_out, scan_chan_list, &max_chan_per_scan,
1432                            &filtered_scan, &scan_current_chan_only);
1433
1434        ret = mwifiex_scan_channel_list(priv, max_chan_per_scan, filtered_scan,
1435                                        &scan_cfg_out->config, chan_list_out,
1436                                        scan_chan_list);
1437
1438        /* Get scan command from scan_pending_q and put to cmd_pending_q */
1439        if (!ret) {
1440                spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
1441                if (!list_empty(&adapter->scan_pending_q)) {
1442                        cmd_node = list_first_entry(&adapter->scan_pending_q,
1443                                                    struct cmd_ctrl_node, list);
1444                        list_del(&cmd_node->list);
1445                        spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1446                                               flags);
1447                        mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
1448                                                        true);
1449                        queue_work(adapter->workqueue, &adapter->main_work);
1450
1451                        /* Perform internal scan synchronously */
1452                        if (!priv->scan_request) {
1453                                dev_dbg(adapter->dev, "wait internal scan\n");
1454                                mwifiex_wait_queue_complete(adapter, cmd_node);
1455                        }
1456                } else {
1457                        spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1458                                               flags);
1459                }
1460        }
1461
1462        kfree(scan_cfg_out);
1463        kfree(scan_chan_list);
1464done:
1465        if (ret) {
1466                spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
1467                adapter->scan_processing = false;
1468                spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
1469        }
1470        return ret;
1471}
1472
1473/*
1474 * This function prepares a scan command to be sent to the firmware.
1475 *
1476 * This uses the scan command configuration sent to the command processing
1477 * module in command preparation stage to configure a scan command structure
1478 * to send to firmware.
1479 *
1480 * The fixed fields specifying the BSS type and BSSID filters as well as a
1481 * variable number/length of TLVs are sent in the command to firmware.
1482 *
1483 * Preparation also includes -
1484 *      - Setting command ID, and proper size
1485 *      - Ensuring correct endian-ness
1486 */
1487int mwifiex_cmd_802_11_scan(struct host_cmd_ds_command *cmd,
1488                            struct mwifiex_scan_cmd_config *scan_cfg)
1489{
1490        struct host_cmd_ds_802_11_scan *scan_cmd = &cmd->params.scan;
1491
1492        /* Set fixed field variables in scan command */
1493        scan_cmd->bss_mode = scan_cfg->bss_mode;
1494        memcpy(scan_cmd->bssid, scan_cfg->specific_bssid,
1495               sizeof(scan_cmd->bssid));
1496        memcpy(scan_cmd->tlv_buffer, scan_cfg->tlv_buf, scan_cfg->tlv_buf_len);
1497
1498        cmd->command = cpu_to_le16(HostCmd_CMD_802_11_SCAN);
1499
1500        /* Size is equal to the sizeof(fixed portions) + the TLV len + header */
1501        cmd->size = cpu_to_le16((u16) (sizeof(scan_cmd->bss_mode)
1502                                          + sizeof(scan_cmd->bssid)
1503                                          + scan_cfg->tlv_buf_len + S_DS_GEN));
1504
1505        return 0;
1506}
1507
1508/*
1509 * This function checks compatibility of requested network with current
1510 * driver settings.
1511 */
1512int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
1513                                        struct mwifiex_bssdescriptor *bss_desc)
1514{
1515        int ret = -1;
1516
1517        if (!bss_desc)
1518                return -1;
1519
1520        if ((mwifiex_get_cfp(priv, (u8) bss_desc->bss_band,
1521                             (u16) bss_desc->channel, 0))) {
1522                switch (priv->bss_mode) {
1523                case NL80211_IFTYPE_STATION:
1524                case NL80211_IFTYPE_ADHOC:
1525                        ret = mwifiex_is_network_compatible(priv, bss_desc,
1526                                                            priv->bss_mode);
1527                        if (ret)
1528                                dev_err(priv->adapter->dev,
1529                                        "Incompatible network settings\n");
1530                        break;
1531                default:
1532                        ret = 0;
1533                }
1534        }
1535
1536        return ret;
1537}
1538
1539static int mwifiex_update_curr_bss_params(struct mwifiex_private *priv,
1540                                          struct cfg80211_bss *bss)
1541{
1542        struct mwifiex_bssdescriptor *bss_desc;
1543        int ret;
1544        unsigned long flags;
1545
1546        /* Allocate and fill new bss descriptor */
1547        bss_desc = kzalloc(sizeof(struct mwifiex_bssdescriptor), GFP_KERNEL);
1548        if (!bss_desc)
1549                return -ENOMEM;
1550
1551        ret = mwifiex_fill_new_bss_desc(priv, bss, bss_desc);
1552        if (ret)
1553                goto done;
1554
1555        ret = mwifiex_check_network_compatibility(priv, bss_desc);
1556        if (ret)
1557                goto done;
1558
1559        spin_lock_irqsave(&priv->curr_bcn_buf_lock, flags);
1560        /* Make a copy of current BSSID descriptor */
1561        memcpy(&priv->curr_bss_params.bss_descriptor, bss_desc,
1562               sizeof(priv->curr_bss_params.bss_descriptor));
1563
1564        /* The contents of beacon_ie will be copied to its own buffer
1565         * in mwifiex_save_curr_bcn()
1566         */
1567        mwifiex_save_curr_bcn(priv);
1568        spin_unlock_irqrestore(&priv->curr_bcn_buf_lock, flags);
1569
1570done:
1571        /* beacon_ie buffer was allocated in function
1572         * mwifiex_fill_new_bss_desc(). Free it now.
1573         */
1574        kfree(bss_desc->beacon_buf);
1575        kfree(bss_desc);
1576        return 0;
1577}
1578
1579/*
1580 * This function handles the command response of scan.
1581 *
1582 * The response buffer for the scan command has the following
1583 * memory layout:
1584 *
1585 *      .-------------------------------------------------------------.
1586 *      |  Header (4 * sizeof(t_u16)):  Standard command response hdr |
1587 *      .-------------------------------------------------------------.
1588 *      |  BufSize (t_u16) : sizeof the BSS Description data          |
1589 *      .-------------------------------------------------------------.
1590 *      |  NumOfSet (t_u8) : Number of BSS Descs returned             |
1591 *      .-------------------------------------------------------------.
1592 *      |  BSSDescription data (variable, size given in BufSize)      |
1593 *      .-------------------------------------------------------------.
1594 *      |  TLV data (variable, size calculated using Header->Size,    |
1595 *      |            BufSize and sizeof the fixed fields above)       |
1596 *      .-------------------------------------------------------------.
1597 */
1598int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
1599                            struct host_cmd_ds_command *resp)
1600{
1601        int ret = 0;
1602        struct mwifiex_adapter *adapter = priv->adapter;
1603        struct cmd_ctrl_node *cmd_node;
1604        struct host_cmd_ds_802_11_scan_rsp *scan_rsp;
1605        struct mwifiex_ie_types_data *tlv_data;
1606        struct mwifiex_ie_types_tsf_timestamp *tsf_tlv;
1607        u8 *bss_info;
1608        u32 scan_resp_size;
1609        u32 bytes_left;
1610        u32 idx;
1611        u32 tlv_buf_size;
1612        struct mwifiex_chan_freq_power *cfp;
1613        struct mwifiex_ie_types_chan_band_list_param_set *chan_band_tlv;
1614        struct chan_band_param_set *chan_band;
1615        u8 is_bgscan_resp;
1616        unsigned long flags;
1617        struct cfg80211_bss *bss;
1618
1619        is_bgscan_resp = (le16_to_cpu(resp->command)
1620                          == HostCmd_CMD_802_11_BG_SCAN_QUERY);
1621        if (is_bgscan_resp)
1622                scan_rsp = &resp->params.bg_scan_query_resp.scan_resp;
1623        else
1624                scan_rsp = &resp->params.scan_resp;
1625
1626
1627        if (scan_rsp->number_of_sets > MWIFIEX_MAX_AP) {
1628                dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n",
1629                        scan_rsp->number_of_sets);
1630                ret = -1;
1631                goto check_next_scan;
1632        }
1633
1634        /* Check csa channel expiry before parsing scan response */
1635        mwifiex_11h_get_csa_closed_channel(priv);
1636
1637        bytes_left = le16_to_cpu(scan_rsp->bss_descript_size);
1638        dev_dbg(adapter->dev, "info: SCAN_RESP: bss_descript_size %d\n",
1639                bytes_left);
1640
1641        scan_resp_size = le16_to_cpu(resp->size);
1642
1643        dev_dbg(adapter->dev,
1644                "info: SCAN_RESP: returned %d APs before parsing\n",
1645                scan_rsp->number_of_sets);
1646
1647        bss_info = scan_rsp->bss_desc_and_tlv_buffer;
1648
1649        /*
1650         * The size of the TLV buffer is equal to the entire command response
1651         *   size (scan_resp_size) minus the fixed fields (sizeof()'s), the
1652         *   BSS Descriptions (bss_descript_size as bytesLef) and the command
1653         *   response header (S_DS_GEN)
1654         */
1655        tlv_buf_size = scan_resp_size - (bytes_left
1656                                         + sizeof(scan_rsp->bss_descript_size)
1657                                         + sizeof(scan_rsp->number_of_sets)
1658                                         + S_DS_GEN);
1659
1660        tlv_data = (struct mwifiex_ie_types_data *) (scan_rsp->
1661                                                 bss_desc_and_tlv_buffer +
1662                                                 bytes_left);
1663
1664        /* Search the TLV buffer space in the scan response for any valid
1665           TLVs */
1666        mwifiex_ret_802_11_scan_get_tlv_ptrs(adapter, tlv_data, tlv_buf_size,
1667                                             TLV_TYPE_TSFTIMESTAMP,
1668                                             (struct mwifiex_ie_types_data **)
1669                                             &tsf_tlv);
1670
1671        /* Search the TLV buffer space in the scan response for any valid
1672           TLVs */
1673        mwifiex_ret_802_11_scan_get_tlv_ptrs(adapter, tlv_data, tlv_buf_size,
1674                                             TLV_TYPE_CHANNELBANDLIST,
1675                                             (struct mwifiex_ie_types_data **)
1676                                             &chan_band_tlv);
1677
1678        for (idx = 0; idx < scan_rsp->number_of_sets && bytes_left; idx++) {
1679                u8 bssid[ETH_ALEN];
1680                s32 rssi;
1681                const u8 *ie_buf;
1682                size_t ie_len;
1683                u16 channel = 0;
1684                u64 fw_tsf = 0;
1685                u16 beacon_size = 0;
1686                u32 curr_bcn_bytes;
1687                u32 freq;
1688                u16 beacon_period;
1689                u16 cap_info_bitmap;
1690                u8 *current_ptr;
1691                u64 timestamp;
1692                struct mwifiex_bcn_param *bcn_param;
1693                struct mwifiex_bss_priv *bss_priv;
1694
1695                if (bytes_left >= sizeof(beacon_size)) {
1696                        /* Extract & convert beacon size from command buffer */
1697                        memcpy(&beacon_size, bss_info, sizeof(beacon_size));
1698                        bytes_left -= sizeof(beacon_size);
1699                        bss_info += sizeof(beacon_size);
1700                }
1701
1702                if (!beacon_size || beacon_size > bytes_left) {
1703                        bss_info += bytes_left;
1704                        bytes_left = 0;
1705                        ret = -1;
1706                        goto check_next_scan;
1707                }
1708
1709                /* Initialize the current working beacon pointer for this BSS
1710                 * iteration */
1711                current_ptr = bss_info;
1712
1713                /* Advance the return beacon pointer past the current beacon */
1714                bss_info += beacon_size;
1715                bytes_left -= beacon_size;
1716
1717                curr_bcn_bytes = beacon_size;
1718
1719                /*
1720                 * First 5 fields are bssid, RSSI, time stamp, beacon interval,
1721                 *   and capability information
1722                 */
1723                if (curr_bcn_bytes < sizeof(struct mwifiex_bcn_param)) {
1724                        dev_err(adapter->dev,
1725                                "InterpretIE: not enough bytes left\n");
1726                        continue;
1727                }
1728                bcn_param = (struct mwifiex_bcn_param *)current_ptr;
1729                current_ptr += sizeof(*bcn_param);
1730                curr_bcn_bytes -= sizeof(*bcn_param);
1731
1732                memcpy(bssid, bcn_param->bssid, ETH_ALEN);
1733
1734                rssi = (s32) bcn_param->rssi;
1735                rssi = (-rssi) * 100;           /* Convert dBm to mBm */
1736                dev_dbg(adapter->dev, "info: InterpretIE: RSSI=%d\n", rssi);
1737
1738                timestamp = le64_to_cpu(bcn_param->timestamp);
1739                beacon_period = le16_to_cpu(bcn_param->beacon_period);
1740
1741                cap_info_bitmap = le16_to_cpu(bcn_param->cap_info_bitmap);
1742                dev_dbg(adapter->dev, "info: InterpretIE: capabilities=0x%X\n",
1743                        cap_info_bitmap);
1744
1745                /* Rest of the current buffer are IE's */
1746                ie_buf = current_ptr;
1747                ie_len = curr_bcn_bytes;
1748                dev_dbg(adapter->dev,
1749                        "info: InterpretIE: IELength for this AP = %d\n",
1750                        curr_bcn_bytes);
1751
1752                while (curr_bcn_bytes >= sizeof(struct ieee_types_header)) {
1753                        u8 element_id, element_len;
1754
1755                        element_id = *current_ptr;
1756                        element_len = *(current_ptr + 1);
1757                        if (curr_bcn_bytes < element_len +
1758                                        sizeof(struct ieee_types_header)) {
1759                                dev_err(priv->adapter->dev,
1760                                        "%s: bytes left < IE length\n",
1761                                        __func__);
1762                                goto check_next_scan;
1763                        }
1764                        if (element_id == WLAN_EID_DS_PARAMS) {
1765                                channel = *(current_ptr + sizeof(struct ieee_types_header));
1766                                break;
1767                        }
1768
1769                        current_ptr += element_len +
1770                                        sizeof(struct ieee_types_header);
1771                        curr_bcn_bytes -= element_len +
1772                                        sizeof(struct ieee_types_header);
1773                }
1774
1775                /*
1776                 * If the TSF TLV was appended to the scan results, save this
1777                 * entry's TSF value in the fw_tsf field. It is the firmware's
1778                 * TSF value at the time the beacon or probe response was
1779                 * received.
1780                 */
1781                if (tsf_tlv)
1782                        memcpy(&fw_tsf, &tsf_tlv->tsf_data[idx * TSF_DATA_SIZE],
1783                               sizeof(fw_tsf));
1784
1785                if (channel) {
1786                        struct ieee80211_channel *chan;
1787                        u8 band;
1788
1789                        /* Skip entry if on csa closed channel */
1790                        if (channel == priv->csa_chan) {
1791                                dev_dbg(adapter->dev,
1792                                        "Dropping entry on csa closed channel\n");
1793                                continue;
1794                        }
1795
1796                        band = BAND_G;
1797                        if (chan_band_tlv) {
1798                                chan_band =
1799                                        &chan_band_tlv->chan_band_param[idx];
1800                                band = mwifiex_radio_type_to_band(
1801                                                chan_band->radio_type
1802                                                & (BIT(0) | BIT(1)));
1803                        }
1804
1805                        cfp = mwifiex_get_cfp(priv, band, channel, 0);
1806
1807                        freq = cfp ? cfp->freq : 0;
1808
1809                        chan = ieee80211_get_channel(priv->wdev->wiphy, freq);
1810
1811                        if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) {
1812                                bss = cfg80211_inform_bss(priv->wdev->wiphy,
1813                                              chan, bssid, timestamp,
1814                                              cap_info_bitmap, beacon_period,
1815                                              ie_buf, ie_len, rssi, GFP_KERNEL);
1816                                bss_priv = (struct mwifiex_bss_priv *)bss->priv;
1817                                bss_priv->band = band;
1818                                bss_priv->fw_tsf = fw_tsf;
1819                                if (priv->media_connected &&
1820                                    !memcmp(bssid,
1821                                            priv->curr_bss_params.bss_descriptor
1822                                            .mac_address, ETH_ALEN))
1823                                        mwifiex_update_curr_bss_params(priv,
1824                                                                       bss);
1825                                cfg80211_put_bss(priv->wdev->wiphy, bss);
1826                        }
1827                } else {
1828                        dev_dbg(adapter->dev, "missing BSS channel IE\n");
1829                }
1830        }
1831
1832check_next_scan:
1833        spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
1834        if (list_empty(&adapter->scan_pending_q)) {
1835                spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
1836                spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
1837                adapter->scan_processing = false;
1838                spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
1839
1840                /* Need to indicate IOCTL complete */
1841                if (adapter->curr_cmd->wait_q_enabled) {
1842                        adapter->cmd_wait_q.status = 0;
1843                        if (!priv->scan_request) {
1844                                dev_dbg(adapter->dev,
1845                                        "complete internal scan\n");
1846                                mwifiex_complete_cmd(adapter,
1847                                                     adapter->curr_cmd);
1848                        }
1849                }
1850                if (priv->report_scan_result)
1851                        priv->report_scan_result = false;
1852
1853                if (priv->scan_request) {
1854                        dev_dbg(adapter->dev, "info: notifying scan done\n");
1855                        cfg80211_scan_done(priv->scan_request, 0);
1856                        priv->scan_request = NULL;
1857                } else {
1858                        priv->scan_aborting = false;
1859                        dev_dbg(adapter->dev, "info: scan already aborted\n");
1860                }
1861        } else {
1862                if ((priv->scan_aborting && !priv->scan_request) ||
1863                    priv->scan_block) {
1864                        spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1865                                               flags);
1866                        adapter->scan_delay_cnt = MWIFIEX_MAX_SCAN_DELAY_CNT;
1867                        mod_timer(&priv->scan_delay_timer, jiffies);
1868                        dev_dbg(priv->adapter->dev,
1869                                "info: %s: triggerring scan abort\n", __func__);
1870                } else if (!mwifiex_wmm_lists_empty(adapter) &&
1871                           (priv->scan_request && (priv->scan_request->flags &
1872                                            NL80211_SCAN_FLAG_LOW_PRIORITY))) {
1873                        spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1874                                               flags);
1875                        adapter->scan_delay_cnt = 1;
1876                        mod_timer(&priv->scan_delay_timer, jiffies +
1877                                  msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC));
1878                        dev_dbg(priv->adapter->dev,
1879                                "info: %s: deferring scan\n", __func__);
1880                } else {
1881                        /* Get scan command from scan_pending_q and put to
1882                           cmd_pending_q */
1883                        cmd_node = list_first_entry(&adapter->scan_pending_q,
1884                                                    struct cmd_ctrl_node, list);
1885                        list_del(&cmd_node->list);
1886                        spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1887                                               flags);
1888                        mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
1889                                                        true);
1890                }
1891        }
1892
1893        return ret;
1894}
1895
1896/*
1897 * This function prepares command for background scan query.
1898 *
1899 * Preparation includes -
1900 *      - Setting command ID and proper size
1901 *      - Setting background scan flush parameter
1902 *      - Ensuring correct endian-ness
1903 */
1904int mwifiex_cmd_802_11_bg_scan_query(struct host_cmd_ds_command *cmd)
1905{
1906        struct host_cmd_ds_802_11_bg_scan_query *bg_query =
1907                &cmd->params.bg_scan_query;
1908
1909        cmd->command = cpu_to_le16(HostCmd_CMD_802_11_BG_SCAN_QUERY);
1910        cmd->size = cpu_to_le16(sizeof(struct host_cmd_ds_802_11_bg_scan_query)
1911                                + S_DS_GEN);
1912
1913        bg_query->flush = 1;
1914
1915        return 0;
1916}
1917
1918/*
1919 * This function inserts scan command node to the scan pending queue.
1920 */
1921void
1922mwifiex_queue_scan_cmd(struct mwifiex_private *priv,
1923                       struct cmd_ctrl_node *cmd_node)
1924{
1925        struct mwifiex_adapter *adapter = priv->adapter;
1926        unsigned long flags;
1927
1928        cmd_node->wait_q_enabled = true;
1929        cmd_node->condition = &adapter->scan_wait_q_woken;
1930        spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
1931        list_add_tail(&cmd_node->list, &adapter->scan_pending_q);
1932        spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
1933}
1934
1935/*
1936 * This function sends a scan command for all available channels to the
1937 * firmware, filtered on a specific SSID.
1938 */
1939static int mwifiex_scan_specific_ssid(struct mwifiex_private *priv,
1940                                      struct cfg80211_ssid *req_ssid)
1941{
1942        struct mwifiex_adapter *adapter = priv->adapter;
1943        int ret;
1944        struct mwifiex_user_scan_cfg *scan_cfg;
1945
1946        if (adapter->scan_processing) {
1947                dev_err(adapter->dev, "cmd: Scan already in process...\n");
1948                return -EBUSY;
1949        }
1950
1951        if (priv->scan_block) {
1952                dev_err(adapter->dev,
1953                        "cmd: Scan is blocked during association...\n");
1954                return -EBUSY;
1955        }
1956
1957        scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg), GFP_KERNEL);
1958        if (!scan_cfg)
1959                return -ENOMEM;
1960
1961        scan_cfg->ssid_list = req_ssid;
1962        scan_cfg->num_ssids = 1;
1963
1964        ret = mwifiex_scan_networks(priv, scan_cfg);
1965
1966        kfree(scan_cfg);
1967        return ret;
1968}
1969
1970/*
1971 * Sends IOCTL request to start a scan.
1972 *
1973 * This function allocates the IOCTL request buffer, fills it
1974 * with requisite parameters and calls the IOCTL handler.
1975 *
1976 * Scan command can be issued for both normal scan and specific SSID
1977 * scan, depending upon whether an SSID is provided or not.
1978 */
1979int mwifiex_request_scan(struct mwifiex_private *priv,
1980                         struct cfg80211_ssid *req_ssid)
1981{
1982        int ret;
1983
1984        if (down_interruptible(&priv->async_sem)) {
1985                dev_err(priv->adapter->dev, "%s: acquire semaphore\n",
1986                        __func__);
1987                return -1;
1988        }
1989
1990        priv->adapter->scan_wait_q_woken = false;
1991
1992        if (req_ssid && req_ssid->ssid_len != 0)
1993                /* Specific SSID scan */
1994                ret = mwifiex_scan_specific_ssid(priv, req_ssid);
1995        else
1996                /* Normal scan */
1997                ret = mwifiex_scan_networks(priv, NULL);
1998
1999        up(&priv->async_sem);
2000
2001        return ret;
2002}
2003
2004/*
2005 * This function appends the vendor specific IE TLV to a buffer.
2006 */
2007int
2008mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv,
2009                            u16 vsie_mask, u8 **buffer)
2010{
2011        int id, ret_len = 0;
2012        struct mwifiex_ie_types_vendor_param_set *vs_param_set;
2013
2014        if (!buffer)
2015                return 0;
2016        if (!(*buffer))
2017                return 0;
2018
2019        /*
2020         * Traverse through the saved vendor specific IE array and append
2021         * the selected(scan/assoc/adhoc) IE as TLV to the command
2022         */
2023        for (id = 0; id < MWIFIEX_MAX_VSIE_NUM; id++) {
2024                if (priv->vs_ie[id].mask & vsie_mask) {
2025                        vs_param_set =
2026                                (struct mwifiex_ie_types_vendor_param_set *)
2027                                *buffer;
2028                        vs_param_set->header.type =
2029                                cpu_to_le16(TLV_TYPE_PASSTHROUGH);
2030                        vs_param_set->header.len =
2031                                cpu_to_le16((((u16) priv->vs_ie[id].ie[1])
2032                                & 0x00FF) + 2);
2033                        memcpy(vs_param_set->ie, priv->vs_ie[id].ie,
2034                               le16_to_cpu(vs_param_set->header.len));
2035                        *buffer += le16_to_cpu(vs_param_set->header.len) +
2036                                   sizeof(struct mwifiex_ie_types_header);
2037                        ret_len += le16_to_cpu(vs_param_set->header.len) +
2038                                   sizeof(struct mwifiex_ie_types_header);
2039                }
2040        }
2041        return ret_len;
2042}
2043
2044/*
2045 * This function saves a beacon buffer of the current BSS descriptor.
2046 *
2047 * The current beacon buffer is saved so that it can be restored in the
2048 * following cases that makes the beacon buffer not to contain the current
2049 * ssid's beacon buffer.
2050 *      - The current ssid was not found somehow in the last scan.
2051 *      - The current ssid was the last entry of the scan table and overloaded.
2052 */
2053void
2054mwifiex_save_curr_bcn(struct mwifiex_private *priv)
2055{
2056        struct mwifiex_bssdescriptor *curr_bss =
2057                &priv->curr_bss_params.bss_descriptor;
2058
2059        if (!curr_bss->beacon_buf_size)
2060                return;
2061
2062        /* allocate beacon buffer at 1st time; or if it's size has changed */
2063        if (!priv->curr_bcn_buf ||
2064            priv->curr_bcn_size != curr_bss->beacon_buf_size) {
2065                priv->curr_bcn_size = curr_bss->beacon_buf_size;
2066
2067                kfree(priv->curr_bcn_buf);
2068                priv->curr_bcn_buf = kmalloc(curr_bss->beacon_buf_size,
2069                                             GFP_ATOMIC);
2070                if (!priv->curr_bcn_buf)
2071                        return;
2072        }
2073
2074        memcpy(priv->curr_bcn_buf, curr_bss->beacon_buf,
2075               curr_bss->beacon_buf_size);
2076        dev_dbg(priv->adapter->dev, "info: current beacon saved %d\n",
2077                priv->curr_bcn_size);
2078
2079        curr_bss->beacon_buf = priv->curr_bcn_buf;
2080
2081        /* adjust the pointers in the current BSS descriptor */
2082        if (curr_bss->bcn_wpa_ie)
2083                curr_bss->bcn_wpa_ie =
2084                        (struct ieee_types_vendor_specific *)
2085                        (curr_bss->beacon_buf +
2086                         curr_bss->wpa_offset);
2087
2088        if (curr_bss->bcn_rsn_ie)
2089                curr_bss->bcn_rsn_ie = (struct ieee_types_generic *)
2090                        (curr_bss->beacon_buf +
2091                         curr_bss->rsn_offset);
2092
2093        if (curr_bss->bcn_ht_cap)
2094                curr_bss->bcn_ht_cap = (struct ieee80211_ht_cap *)
2095                        (curr_bss->beacon_buf +
2096                         curr_bss->ht_cap_offset);
2097
2098        if (curr_bss->bcn_ht_oper)
2099                curr_bss->bcn_ht_oper = (struct ieee80211_ht_operation *)
2100                        (curr_bss->beacon_buf +
2101                         curr_bss->ht_info_offset);
2102
2103        if (curr_bss->bcn_vht_cap)
2104                curr_bss->bcn_ht_cap = (void *)(curr_bss->beacon_buf +
2105                                                curr_bss->vht_cap_offset);
2106
2107        if (curr_bss->bcn_vht_oper)
2108                curr_bss->bcn_ht_oper = (void *)(curr_bss->beacon_buf +
2109                                                 curr_bss->vht_info_offset);
2110
2111        if (curr_bss->bcn_bss_co_2040)
2112                curr_bss->bcn_bss_co_2040 =
2113                        (curr_bss->beacon_buf + curr_bss->bss_co_2040_offset);
2114
2115        if (curr_bss->bcn_ext_cap)
2116                curr_bss->bcn_ext_cap = curr_bss->beacon_buf +
2117                        curr_bss->ext_cap_offset;
2118
2119        if (curr_bss->oper_mode)
2120                curr_bss->oper_mode = (void *)(curr_bss->beacon_buf +
2121                                               curr_bss->oper_mode_offset);
2122}
2123
2124/*
2125 * This function frees the current BSS descriptor beacon buffer.
2126 */
2127void
2128mwifiex_free_curr_bcn(struct mwifiex_private *priv)
2129{
2130        kfree(priv->curr_bcn_buf);
2131        priv->curr_bcn_buf = NULL;
2132}
2133