linux/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * This file is provided under a dual BSD/GPLv2 license.  When using or
   4 * redistributing this file, you may do so under either license.
   5 *
   6 * GPL LICENSE SUMMARY
   7 *
   8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
   9 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  10 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
  11 *
  12 * This program is free software; you can redistribute it and/or modify
  13 * it under the terms of version 2 of the GNU General Public License as
  14 * published by the Free Software Foundation.
  15 *
  16 * This program is distributed in the hope that it will be useful, but
  17 * WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  19 * General Public License for more details.
  20 *
  21 * You should have received a copy of the GNU General Public License
  22 * along with this program; if not, write to the Free Software
  23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
  24 * USA
  25 *
  26 * The full GNU General Public License is included in this distribution
  27 * in the file called COPYING.
  28 *
  29 * Contact Information:
  30 *  Intel Linux Wireless <linuxwifi@intel.com>
  31 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  32 *
  33 * BSD LICENSE
  34 *
  35 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
  36 * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  37 * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
  38 * All rights reserved.
  39 *
  40 * Redistribution and use in source and binary forms, with or without
  41 * modification, are permitted provided that the following conditions
  42 * are met:
  43 *
  44 *  * Redistributions of source code must retain the above copyright
  45 *    notice, this list of conditions and the following disclaimer.
  46 *  * Redistributions in binary form must reproduce the above copyright
  47 *    notice, this list of conditions and the following disclaimer in
  48 *    the documentation and/or other materials provided with the
  49 *    distribution.
  50 *  * Neither the name Intel Corporation nor the names of its
  51 *    contributors may be used to endorse or promote products derived
  52 *    from this software without specific prior written permission.
  53 *
  54 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  55 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  56 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  57 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  58 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  59 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  60 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  61 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  62 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  63 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  64 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  65 *****************************************************************************/
  66#include <linux/types.h>
  67#include <linux/slab.h>
  68#include <linux/export.h>
  69#include <linux/etherdevice.h>
  70#include <linux/pci.h>
  71#include <linux/acpi.h>
  72#include "iwl-drv.h"
  73#include "iwl-modparams.h"
  74#include "iwl-nvm-parse.h"
  75#include "iwl-prph.h"
  76#include "iwl-io.h"
  77#include "iwl-csr.h"
  78
  79/* NVM offsets (in words) definitions */
  80enum wkp_nvm_offsets {
  81        /* NVM HW-Section offset (in words) definitions */
  82        HW_ADDR = 0x15,
  83
  84        /* NVM SW-Section offset (in words) definitions */
  85        NVM_SW_SECTION = 0x1C0,
  86        NVM_VERSION = 0,
  87        RADIO_CFG = 1,
  88        SKU = 2,
  89        N_HW_ADDRS = 3,
  90        NVM_CHANNELS = 0x1E0 - NVM_SW_SECTION,
  91
  92        /* NVM calibration section offset (in words) definitions */
  93        NVM_CALIB_SECTION = 0x2B8,
  94        XTAL_CALIB = 0x316 - NVM_CALIB_SECTION
  95};
  96
  97enum family_8000_nvm_offsets {
  98        /* NVM HW-Section offset (in words) definitions */
  99        HW_ADDR0_WFPM_FAMILY_8000 = 0x12,
 100        HW_ADDR1_WFPM_FAMILY_8000 = 0x16,
 101        HW_ADDR0_PCIE_FAMILY_8000 = 0x8A,
 102        HW_ADDR1_PCIE_FAMILY_8000 = 0x8E,
 103        MAC_ADDRESS_OVERRIDE_FAMILY_8000 = 1,
 104
 105        /* NVM SW-Section offset (in words) definitions */
 106        NVM_SW_SECTION_FAMILY_8000 = 0x1C0,
 107        NVM_VERSION_FAMILY_8000 = 0,
 108        RADIO_CFG_FAMILY_8000 = 0,
 109        SKU_FAMILY_8000 = 2,
 110        N_HW_ADDRS_FAMILY_8000 = 3,
 111
 112        /* NVM REGULATORY -Section offset (in words) definitions */
 113        NVM_CHANNELS_FAMILY_8000 = 0,
 114        NVM_LAR_OFFSET_FAMILY_8000_OLD = 0x4C7,
 115        NVM_LAR_OFFSET_FAMILY_8000 = 0x507,
 116        NVM_LAR_ENABLED_FAMILY_8000 = 0x7,
 117
 118        /* NVM calibration section offset (in words) definitions */
 119        NVM_CALIB_SECTION_FAMILY_8000 = 0x2B8,
 120        XTAL_CALIB_FAMILY_8000 = 0x316 - NVM_CALIB_SECTION_FAMILY_8000
 121};
 122
 123/* SKU Capabilities (actual values from NVM definition) */
 124enum nvm_sku_bits {
 125        NVM_SKU_CAP_BAND_24GHZ          = BIT(0),
 126        NVM_SKU_CAP_BAND_52GHZ          = BIT(1),
 127        NVM_SKU_CAP_11N_ENABLE          = BIT(2),
 128        NVM_SKU_CAP_11AC_ENABLE         = BIT(3),
 129        NVM_SKU_CAP_MIMO_DISABLE        = BIT(5),
 130};
 131
 132/*
 133 * These are the channel numbers in the order that they are stored in the NVM
 134 */
 135static const u8 iwl_nvm_channels[] = {
 136        /* 2.4 GHz */
 137        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
 138        /* 5 GHz */
 139        36, 40, 44 , 48, 52, 56, 60, 64,
 140        100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
 141        149, 153, 157, 161, 165
 142};
 143
 144static const u8 iwl_nvm_channels_family_8000[] = {
 145        /* 2.4 GHz */
 146        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
 147        /* 5 GHz */
 148        36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92,
 149        96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
 150        149, 153, 157, 161, 165, 169, 173, 177, 181
 151};
 152
 153#define IWL_NUM_CHANNELS                ARRAY_SIZE(iwl_nvm_channels)
 154#define IWL_NUM_CHANNELS_FAMILY_8000    ARRAY_SIZE(iwl_nvm_channels_family_8000)
 155#define NUM_2GHZ_CHANNELS               14
 156#define NUM_2GHZ_CHANNELS_FAMILY_8000   14
 157#define FIRST_2GHZ_HT_MINUS             5
 158#define LAST_2GHZ_HT_PLUS               9
 159#define LAST_5GHZ_HT                    165
 160#define LAST_5GHZ_HT_FAMILY_8000        181
 161#define N_HW_ADDR_MASK                  0xF
 162
 163/* rate data (static) */
 164static struct ieee80211_rate iwl_cfg80211_rates[] = {
 165        { .bitrate = 1 * 10, .hw_value = 0, .hw_value_short = 0, },
 166        { .bitrate = 2 * 10, .hw_value = 1, .hw_value_short = 1,
 167          .flags = IEEE80211_RATE_SHORT_PREAMBLE, },
 168        { .bitrate = 5.5 * 10, .hw_value = 2, .hw_value_short = 2,
 169          .flags = IEEE80211_RATE_SHORT_PREAMBLE, },
 170        { .bitrate = 11 * 10, .hw_value = 3, .hw_value_short = 3,
 171          .flags = IEEE80211_RATE_SHORT_PREAMBLE, },
 172        { .bitrate = 6 * 10, .hw_value = 4, .hw_value_short = 4, },
 173        { .bitrate = 9 * 10, .hw_value = 5, .hw_value_short = 5, },
 174        { .bitrate = 12 * 10, .hw_value = 6, .hw_value_short = 6, },
 175        { .bitrate = 18 * 10, .hw_value = 7, .hw_value_short = 7, },
 176        { .bitrate = 24 * 10, .hw_value = 8, .hw_value_short = 8, },
 177        { .bitrate = 36 * 10, .hw_value = 9, .hw_value_short = 9, },
 178        { .bitrate = 48 * 10, .hw_value = 10, .hw_value_short = 10, },
 179        { .bitrate = 54 * 10, .hw_value = 11, .hw_value_short = 11, },
 180};
 181#define RATES_24_OFFS   0
 182#define N_RATES_24      ARRAY_SIZE(iwl_cfg80211_rates)
 183#define RATES_52_OFFS   4
 184#define N_RATES_52      (N_RATES_24 - RATES_52_OFFS)
 185
 186/**
 187 * enum iwl_nvm_channel_flags - channel flags in NVM
 188 * @NVM_CHANNEL_VALID: channel is usable for this SKU/geo
 189 * @NVM_CHANNEL_IBSS: usable as an IBSS channel
 190 * @NVM_CHANNEL_ACTIVE: active scanning allowed
 191 * @NVM_CHANNEL_RADAR: radar detection required
 192 * @NVM_CHANNEL_INDOOR_ONLY: only indoor use is allowed
 193 * @NVM_CHANNEL_GO_CONCURRENT: GO operation is allowed when connected to BSS
 194 *      on same channel on 2.4 or same UNII band on 5.2
 195 * @NVM_CHANNEL_WIDE: 20 MHz channel okay (?)
 196 * @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?)
 197 * @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?)
 198 * @NVM_CHANNEL_160MHZ: 160 MHz channel okay (?)
 199 */
 200enum iwl_nvm_channel_flags {
 201        NVM_CHANNEL_VALID = BIT(0),
 202        NVM_CHANNEL_IBSS = BIT(1),
 203        NVM_CHANNEL_ACTIVE = BIT(3),
 204        NVM_CHANNEL_RADAR = BIT(4),
 205        NVM_CHANNEL_INDOOR_ONLY = BIT(5),
 206        NVM_CHANNEL_GO_CONCURRENT = BIT(6),
 207        NVM_CHANNEL_WIDE = BIT(8),
 208        NVM_CHANNEL_40MHZ = BIT(9),
 209        NVM_CHANNEL_80MHZ = BIT(10),
 210        NVM_CHANNEL_160MHZ = BIT(11),
 211};
 212
 213#define CHECK_AND_PRINT_I(x)    \
 214        ((ch_flags & NVM_CHANNEL_##x) ? # x " " : "")
 215
 216static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz,
 217                                 u16 nvm_flags, const struct iwl_cfg *cfg)
 218{
 219        u32 flags = IEEE80211_CHAN_NO_HT40;
 220        u32 last_5ghz_ht = LAST_5GHZ_HT;
 221
 222        if (cfg->device_family == IWL_DEVICE_FAMILY_8000)
 223                last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000;
 224
 225        if (!is_5ghz && (nvm_flags & NVM_CHANNEL_40MHZ)) {
 226                if (ch_num <= LAST_2GHZ_HT_PLUS)
 227                        flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
 228                if (ch_num >= FIRST_2GHZ_HT_MINUS)
 229                        flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
 230        } else if (ch_num <= last_5ghz_ht && (nvm_flags & NVM_CHANNEL_40MHZ)) {
 231                if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
 232                        flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
 233                else
 234                        flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
 235        }
 236        if (!(nvm_flags & NVM_CHANNEL_80MHZ))
 237                flags |= IEEE80211_CHAN_NO_80MHZ;
 238        if (!(nvm_flags & NVM_CHANNEL_160MHZ))
 239                flags |= IEEE80211_CHAN_NO_160MHZ;
 240
 241        if (!(nvm_flags & NVM_CHANNEL_IBSS))
 242                flags |= IEEE80211_CHAN_NO_IR;
 243
 244        if (!(nvm_flags & NVM_CHANNEL_ACTIVE))
 245                flags |= IEEE80211_CHAN_NO_IR;
 246
 247        if (nvm_flags & NVM_CHANNEL_RADAR)
 248                flags |= IEEE80211_CHAN_RADAR;
 249
 250        if (nvm_flags & NVM_CHANNEL_INDOOR_ONLY)
 251                flags |= IEEE80211_CHAN_INDOOR_ONLY;
 252
 253        /* Set the GO concurrent flag only in case that NO_IR is set.
 254         * Otherwise it is meaningless
 255         */
 256        if ((nvm_flags & NVM_CHANNEL_GO_CONCURRENT) &&
 257            (flags & IEEE80211_CHAN_NO_IR))
 258                flags |= IEEE80211_CHAN_IR_CONCURRENT;
 259
 260        return flags;
 261}
 262
 263static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
 264                                struct iwl_nvm_data *data,
 265                                const __le16 * const nvm_ch_flags,
 266                                bool lar_supported)
 267{
 268        int ch_idx;
 269        int n_channels = 0;
 270        struct ieee80211_channel *channel;
 271        u16 ch_flags;
 272        bool is_5ghz;
 273        int num_of_ch, num_2ghz_channels;
 274        const u8 *nvm_chan;
 275
 276        if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
 277                num_of_ch = IWL_NUM_CHANNELS;
 278                nvm_chan = &iwl_nvm_channels[0];
 279                num_2ghz_channels = NUM_2GHZ_CHANNELS;
 280        } else {
 281                num_of_ch = IWL_NUM_CHANNELS_FAMILY_8000;
 282                nvm_chan = &iwl_nvm_channels_family_8000[0];
 283                num_2ghz_channels = NUM_2GHZ_CHANNELS_FAMILY_8000;
 284        }
 285
 286        for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
 287                ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
 288
 289                if (ch_idx >= num_2ghz_channels &&
 290                    !data->sku_cap_band_52GHz_enable)
 291                        continue;
 292
 293                if (ch_flags & NVM_CHANNEL_160MHZ)
 294                        data->vht160_supported = true;
 295
 296                if (!lar_supported && !(ch_flags & NVM_CHANNEL_VALID)) {
 297                        /*
 298                         * Channels might become valid later if lar is
 299                         * supported, hence we still want to add them to
 300                         * the list of supported channels to cfg80211.
 301                         */
 302                        IWL_DEBUG_EEPROM(dev,
 303                                         "Ch. %d Flags %x [%sGHz] - No traffic\n",
 304                                         nvm_chan[ch_idx],
 305                                         ch_flags,
 306                                         (ch_idx >= num_2ghz_channels) ?
 307                                         "5.2" : "2.4");
 308                        continue;
 309                }
 310
 311                channel = &data->channels[n_channels];
 312                n_channels++;
 313
 314                channel->hw_value = nvm_chan[ch_idx];
 315                channel->band = (ch_idx < num_2ghz_channels) ?
 316                                NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
 317                channel->center_freq =
 318                        ieee80211_channel_to_frequency(
 319                                channel->hw_value, channel->band);
 320
 321                /* Initialize regulatory-based run-time data */
 322
 323                /*
 324                 * Default value - highest tx power value.  max_power
 325                 * is not used in mvm, and is used for backwards compatibility
 326                 */
 327                channel->max_power = IWL_DEFAULT_MAX_TX_POWER;
 328                is_5ghz = channel->band == NL80211_BAND_5GHZ;
 329
 330                /* don't put limitations in case we're using LAR */
 331                if (!lar_supported)
 332                        channel->flags = iwl_get_channel_flags(nvm_chan[ch_idx],
 333                                                               ch_idx, is_5ghz,
 334                                                               ch_flags, cfg);
 335                else
 336                        channel->flags = 0;
 337
 338                IWL_DEBUG_EEPROM(dev,
 339                                 "Ch. %d [%sGHz] flags 0x%x %s%s%s%s%s%s%s%s%s%s(%ddBm): Ad-Hoc %ssupported\n",
 340                                 channel->hw_value,
 341                                 is_5ghz ? "5.2" : "2.4",
 342                                 ch_flags,
 343                                 CHECK_AND_PRINT_I(VALID),
 344                                 CHECK_AND_PRINT_I(IBSS),
 345                                 CHECK_AND_PRINT_I(ACTIVE),
 346                                 CHECK_AND_PRINT_I(RADAR),
 347                                 CHECK_AND_PRINT_I(INDOOR_ONLY),
 348                                 CHECK_AND_PRINT_I(GO_CONCURRENT),
 349                                 CHECK_AND_PRINT_I(WIDE),
 350                                 CHECK_AND_PRINT_I(40MHZ),
 351                                 CHECK_AND_PRINT_I(80MHZ),
 352                                 CHECK_AND_PRINT_I(160MHZ),
 353                                 channel->max_power,
 354                                 ((ch_flags & NVM_CHANNEL_IBSS) &&
 355                                  !(ch_flags & NVM_CHANNEL_RADAR))
 356                                        ? "" : "not ");
 357        }
 358
 359        return n_channels;
 360}
 361
 362static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
 363                                  struct iwl_nvm_data *data,
 364                                  struct ieee80211_sta_vht_cap *vht_cap,
 365                                  u8 tx_chains, u8 rx_chains)
 366{
 367        int num_rx_ants = num_of_ant(rx_chains);
 368        int num_tx_ants = num_of_ant(tx_chains);
 369        unsigned int max_ampdu_exponent = (cfg->max_vht_ampdu_exponent ?:
 370                                           IEEE80211_VHT_MAX_AMPDU_1024K);
 371
 372        vht_cap->vht_supported = true;
 373
 374        vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 |
 375                       IEEE80211_VHT_CAP_RXSTBC_1 |
 376                       IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
 377                       3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT |
 378                       max_ampdu_exponent <<
 379                       IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
 380
 381        if (data->vht160_supported)
 382                vht_cap->cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
 383                                IEEE80211_VHT_CAP_SHORT_GI_160;
 384
 385        if (cfg->vht_mu_mimo_supported)
 386                vht_cap->cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
 387
 388        if (cfg->ht_params->ldpc)
 389                vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC;
 390
 391        if (data->sku_cap_mimo_disabled) {
 392                num_rx_ants = 1;
 393                num_tx_ants = 1;
 394        }
 395
 396        if (num_tx_ants > 1)
 397                vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC;
 398        else
 399                vht_cap->cap |= IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
 400
 401        switch (iwlwifi_mod_params.amsdu_size) {
 402        case IWL_AMSDU_DEF:
 403                if (cfg->mq_rx_supported)
 404                        vht_cap->cap |=
 405                                IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
 406                else
 407                        vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
 408                break;
 409        case IWL_AMSDU_4K:
 410                vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
 411                break;
 412        case IWL_AMSDU_8K:
 413                vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
 414                break;
 415        case IWL_AMSDU_12K:
 416                vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
 417                break;
 418        default:
 419                break;
 420        }
 421
 422        vht_cap->vht_mcs.rx_mcs_map =
 423                cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |
 424                            IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 |
 425                            IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 |
 426                            IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 |
 427                            IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 |
 428                            IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 |
 429                            IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
 430                            IEEE80211_VHT_MCS_NOT_SUPPORTED << 14);
 431
 432        if (num_rx_ants == 1 || cfg->rx_with_siso_diversity) {
 433                vht_cap->cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN;
 434                /* this works because NOT_SUPPORTED == 3 */
 435                vht_cap->vht_mcs.rx_mcs_map |=
 436                        cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << 2);
 437        }
 438
 439        vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map;
 440}
 441
 442void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
 443                     struct iwl_nvm_data *data, const __le16 *nvm_ch_flags,
 444                     u8 tx_chains, u8 rx_chains, bool lar_supported)
 445{
 446        int n_channels;
 447        int n_used = 0;
 448        struct ieee80211_supported_band *sband;
 449
 450        n_channels = iwl_init_channel_map(dev, cfg, data, nvm_ch_flags,
 451                                          lar_supported);
 452        sband = &data->bands[NL80211_BAND_2GHZ];
 453        sband->band = NL80211_BAND_2GHZ;
 454        sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS];
 455        sband->n_bitrates = N_RATES_24;
 456        n_used += iwl_init_sband_channels(data, sband, n_channels,
 457                                          NL80211_BAND_2GHZ);
 458        iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, NL80211_BAND_2GHZ,
 459                             tx_chains, rx_chains);
 460
 461        sband = &data->bands[NL80211_BAND_5GHZ];
 462        sband->band = NL80211_BAND_5GHZ;
 463        sband->bitrates = &iwl_cfg80211_rates[RATES_52_OFFS];
 464        sband->n_bitrates = N_RATES_52;
 465        n_used += iwl_init_sband_channels(data, sband, n_channels,
 466                                          NL80211_BAND_5GHZ);
 467        iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, NL80211_BAND_5GHZ,
 468                             tx_chains, rx_chains);
 469        if (data->sku_cap_11ac_enable && !iwlwifi_mod_params.disable_11ac)
 470                iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap,
 471                                      tx_chains, rx_chains);
 472
 473        if (n_channels != n_used)
 474                IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n",
 475                            n_used, n_channels);
 476}
 477IWL_EXPORT_SYMBOL(iwl_init_sbands);
 478
 479static int iwl_get_sku(const struct iwl_cfg *cfg, const __le16 *nvm_sw,
 480                       const __le16 *phy_sku)
 481{
 482        if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
 483                return le16_to_cpup(nvm_sw + SKU);
 484
 485        return le32_to_cpup((__le32 *)(phy_sku + SKU_FAMILY_8000));
 486}
 487
 488static int iwl_get_nvm_version(const struct iwl_cfg *cfg, const __le16 *nvm_sw)
 489{
 490        if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
 491                return le16_to_cpup(nvm_sw + NVM_VERSION);
 492        else
 493                return le32_to_cpup((__le32 *)(nvm_sw +
 494                                               NVM_VERSION_FAMILY_8000));
 495}
 496
 497static int iwl_get_radio_cfg(const struct iwl_cfg *cfg, const __le16 *nvm_sw,
 498                             const __le16 *phy_sku)
 499{
 500        if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
 501                return le16_to_cpup(nvm_sw + RADIO_CFG);
 502
 503        return le32_to_cpup((__le32 *)(phy_sku + RADIO_CFG_FAMILY_8000));
 504
 505}
 506
 507static int iwl_get_n_hw_addrs(const struct iwl_cfg *cfg, const __le16 *nvm_sw)
 508{
 509        int n_hw_addr;
 510
 511        if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
 512                return le16_to_cpup(nvm_sw + N_HW_ADDRS);
 513
 514        n_hw_addr = le32_to_cpup((__le32 *)(nvm_sw + N_HW_ADDRS_FAMILY_8000));
 515
 516        return n_hw_addr & N_HW_ADDR_MASK;
 517}
 518
 519static void iwl_set_radio_cfg(const struct iwl_cfg *cfg,
 520                              struct iwl_nvm_data *data,
 521                              u32 radio_cfg)
 522{
 523        if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
 524                data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK(radio_cfg);
 525                data->radio_cfg_step = NVM_RF_CFG_STEP_MSK(radio_cfg);
 526                data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK(radio_cfg);
 527                data->radio_cfg_pnum = NVM_RF_CFG_PNUM_MSK(radio_cfg);
 528                return;
 529        }
 530
 531        /* set the radio configuration for family 8000 */
 532        data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK_FAMILY_8000(radio_cfg);
 533        data->radio_cfg_step = NVM_RF_CFG_STEP_MSK_FAMILY_8000(radio_cfg);
 534        data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK_FAMILY_8000(radio_cfg);
 535        data->radio_cfg_pnum = NVM_RF_CFG_FLAVOR_MSK_FAMILY_8000(radio_cfg);
 536        data->valid_tx_ant = NVM_RF_CFG_TX_ANT_MSK_FAMILY_8000(radio_cfg);
 537        data->valid_rx_ant = NVM_RF_CFG_RX_ANT_MSK_FAMILY_8000(radio_cfg);
 538}
 539
 540static void iwl_flip_hw_address(__le32 mac_addr0, __le32 mac_addr1, u8 *dest)
 541{
 542        const u8 *hw_addr;
 543
 544        hw_addr = (const u8 *)&mac_addr0;
 545        dest[0] = hw_addr[3];
 546        dest[1] = hw_addr[2];
 547        dest[2] = hw_addr[1];
 548        dest[3] = hw_addr[0];
 549
 550        hw_addr = (const u8 *)&mac_addr1;
 551        dest[4] = hw_addr[1];
 552        dest[5] = hw_addr[0];
 553}
 554
 555void iwl_set_hw_address_from_csr(struct iwl_trans *trans,
 556                                 struct iwl_nvm_data *data)
 557{
 558        __le32 mac_addr0 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR0_STRAP));
 559        __le32 mac_addr1 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR1_STRAP));
 560
 561        iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
 562        /*
 563         * If the OEM fused a valid address, use it instead of the one in the
 564         * OTP
 565         */
 566        if (is_valid_ether_addr(data->hw_addr))
 567                return;
 568
 569        mac_addr0 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR0_OTP));
 570        mac_addr1 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR1_OTP));
 571
 572        iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
 573}
 574IWL_EXPORT_SYMBOL(iwl_set_hw_address_from_csr);
 575
 576static void iwl_set_hw_address_family_8000(struct iwl_trans *trans,
 577                                           const struct iwl_cfg *cfg,
 578                                           struct iwl_nvm_data *data,
 579                                           const __le16 *mac_override,
 580                                           const __le16 *nvm_hw)
 581{
 582        const u8 *hw_addr;
 583
 584        if (mac_override) {
 585                static const u8 reserved_mac[] = {
 586                        0x02, 0xcc, 0xaa, 0xff, 0xee, 0x00
 587                };
 588
 589                hw_addr = (const u8 *)(mac_override +
 590                                 MAC_ADDRESS_OVERRIDE_FAMILY_8000);
 591
 592                /*
 593                 * Store the MAC address from MAO section.
 594                 * No byte swapping is required in MAO section
 595                 */
 596                memcpy(data->hw_addr, hw_addr, ETH_ALEN);
 597
 598                /*
 599                 * Force the use of the OTP MAC address in case of reserved MAC
 600                 * address in the NVM, or if address is given but invalid.
 601                 */
 602                if (is_valid_ether_addr(data->hw_addr) &&
 603                    memcmp(reserved_mac, hw_addr, ETH_ALEN) != 0)
 604                        return;
 605
 606                IWL_ERR(trans,
 607                        "mac address from nvm override section is not valid\n");
 608        }
 609
 610        if (nvm_hw) {
 611                /* read the mac address from WFMP registers */
 612                __le32 mac_addr0 = cpu_to_le32(iwl_trans_read_prph(trans,
 613                                                WFMP_MAC_ADDR_0));
 614                __le32 mac_addr1 = cpu_to_le32(iwl_trans_read_prph(trans,
 615                                                WFMP_MAC_ADDR_1));
 616
 617                iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
 618
 619                return;
 620        }
 621
 622        IWL_ERR(trans, "mac address is not found\n");
 623}
 624
 625static int iwl_set_hw_address(struct iwl_trans *trans,
 626                              const struct iwl_cfg *cfg,
 627                              struct iwl_nvm_data *data, const __le16 *nvm_hw,
 628                              const __le16 *mac_override)
 629{
 630        if (cfg->mac_addr_from_csr) {
 631                iwl_set_hw_address_from_csr(trans, data);
 632        } else if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
 633                const u8 *hw_addr = (const u8 *)(nvm_hw + HW_ADDR);
 634
 635                /* The byte order is little endian 16 bit, meaning 214365 */
 636                data->hw_addr[0] = hw_addr[1];
 637                data->hw_addr[1] = hw_addr[0];
 638                data->hw_addr[2] = hw_addr[3];
 639                data->hw_addr[3] = hw_addr[2];
 640                data->hw_addr[4] = hw_addr[5];
 641                data->hw_addr[5] = hw_addr[4];
 642        } else {
 643                iwl_set_hw_address_family_8000(trans, cfg, data,
 644                                               mac_override, nvm_hw);
 645        }
 646
 647        if (!is_valid_ether_addr(data->hw_addr)) {
 648                IWL_ERR(trans, "no valid mac address was found\n");
 649                return -EINVAL;
 650        }
 651
 652        return 0;
 653}
 654
 655struct iwl_nvm_data *
 656iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
 657                   const __le16 *nvm_hw, const __le16 *nvm_sw,
 658                   const __le16 *nvm_calib, const __le16 *regulatory,
 659                   const __le16 *mac_override, const __le16 *phy_sku,
 660                   u8 tx_chains, u8 rx_chains, bool lar_fw_supported)
 661{
 662        struct device *dev = trans->dev;
 663        struct iwl_nvm_data *data;
 664        bool lar_enabled;
 665        u32 sku, radio_cfg;
 666        u16 lar_config;
 667        const __le16 *ch_section;
 668
 669        if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
 670                data = kzalloc(sizeof(*data) +
 671                               sizeof(struct ieee80211_channel) *
 672                               IWL_NUM_CHANNELS,
 673                               GFP_KERNEL);
 674        else
 675                data = kzalloc(sizeof(*data) +
 676                               sizeof(struct ieee80211_channel) *
 677                               IWL_NUM_CHANNELS_FAMILY_8000,
 678                               GFP_KERNEL);
 679        if (!data)
 680                return NULL;
 681
 682        data->nvm_version = iwl_get_nvm_version(cfg, nvm_sw);
 683
 684        radio_cfg = iwl_get_radio_cfg(cfg, nvm_sw, phy_sku);
 685        iwl_set_radio_cfg(cfg, data, radio_cfg);
 686        if (data->valid_tx_ant)
 687                tx_chains &= data->valid_tx_ant;
 688        if (data->valid_rx_ant)
 689                rx_chains &= data->valid_rx_ant;
 690
 691        sku = iwl_get_sku(cfg, nvm_sw, phy_sku);
 692        data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ;
 693        data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ;
 694        data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE;
 695        if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
 696                data->sku_cap_11n_enable = false;
 697        data->sku_cap_11ac_enable = data->sku_cap_11n_enable &&
 698                                    (sku & NVM_SKU_CAP_11AC_ENABLE);
 699        data->sku_cap_mimo_disabled = sku & NVM_SKU_CAP_MIMO_DISABLE;
 700
 701        data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw);
 702
 703        if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
 704                /* Checking for required sections */
 705                if (!nvm_calib) {
 706                        IWL_ERR(trans,
 707                                "Can't parse empty Calib NVM sections\n");
 708                        kfree(data);
 709                        return NULL;
 710                }
 711                /* in family 8000 Xtal calibration values moved to OTP */
 712                data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB);
 713                data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1);
 714                lar_enabled = true;
 715                ch_section = &nvm_sw[NVM_CHANNELS];
 716        } else {
 717                u16 lar_offset = data->nvm_version < 0xE39 ?
 718                                 NVM_LAR_OFFSET_FAMILY_8000_OLD :
 719                                 NVM_LAR_OFFSET_FAMILY_8000;
 720
 721                lar_config = le16_to_cpup(regulatory + lar_offset);
 722                data->lar_enabled = !!(lar_config &
 723                                       NVM_LAR_ENABLED_FAMILY_8000);
 724                lar_enabled = data->lar_enabled;
 725                ch_section = &regulatory[NVM_CHANNELS_FAMILY_8000];
 726        }
 727
 728        /* If no valid mac address was found - bail out */
 729        if (iwl_set_hw_address(trans, cfg, data, nvm_hw, mac_override)) {
 730                kfree(data);
 731                return NULL;
 732        }
 733
 734        iwl_init_sbands(dev, cfg, data, ch_section, tx_chains, rx_chains,
 735                        lar_fw_supported && lar_enabled);
 736        data->calib_version = 255;
 737
 738        return data;
 739}
 740IWL_EXPORT_SYMBOL(iwl_parse_nvm_data);
 741
 742static u32 iwl_nvm_get_regdom_bw_flags(const u8 *nvm_chan,
 743                                       int ch_idx, u16 nvm_flags,
 744                                       const struct iwl_cfg *cfg)
 745{
 746        u32 flags = NL80211_RRF_NO_HT40;
 747        u32 last_5ghz_ht = LAST_5GHZ_HT;
 748
 749        if (cfg->device_family == IWL_DEVICE_FAMILY_8000)
 750                last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000;
 751
 752        if (ch_idx < NUM_2GHZ_CHANNELS &&
 753            (nvm_flags & NVM_CHANNEL_40MHZ)) {
 754                if (nvm_chan[ch_idx] <= LAST_2GHZ_HT_PLUS)
 755                        flags &= ~NL80211_RRF_NO_HT40PLUS;
 756                if (nvm_chan[ch_idx] >= FIRST_2GHZ_HT_MINUS)
 757                        flags &= ~NL80211_RRF_NO_HT40MINUS;
 758        } else if (nvm_chan[ch_idx] <= last_5ghz_ht &&
 759                   (nvm_flags & NVM_CHANNEL_40MHZ)) {
 760                if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
 761                        flags &= ~NL80211_RRF_NO_HT40PLUS;
 762                else
 763                        flags &= ~NL80211_RRF_NO_HT40MINUS;
 764        }
 765
 766        if (!(nvm_flags & NVM_CHANNEL_80MHZ))
 767                flags |= NL80211_RRF_NO_80MHZ;
 768        if (!(nvm_flags & NVM_CHANNEL_160MHZ))
 769                flags |= NL80211_RRF_NO_160MHZ;
 770
 771        if (!(nvm_flags & NVM_CHANNEL_ACTIVE))
 772                flags |= NL80211_RRF_NO_IR;
 773
 774        if (nvm_flags & NVM_CHANNEL_RADAR)
 775                flags |= NL80211_RRF_DFS;
 776
 777        if (nvm_flags & NVM_CHANNEL_INDOOR_ONLY)
 778                flags |= NL80211_RRF_NO_OUTDOOR;
 779
 780        /* Set the GO concurrent flag only in case that NO_IR is set.
 781         * Otherwise it is meaningless
 782         */
 783        if ((nvm_flags & NVM_CHANNEL_GO_CONCURRENT) &&
 784            (flags & NL80211_RRF_NO_IR))
 785                flags |= NL80211_RRF_GO_CONCURRENT;
 786
 787        return flags;
 788}
 789
 790struct ieee80211_regdomain *
 791iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
 792                       int num_of_ch, __le32 *channels, u16 fw_mcc)
 793{
 794        int ch_idx;
 795        u16 ch_flags, prev_ch_flags = 0;
 796        const u8 *nvm_chan = cfg->device_family == IWL_DEVICE_FAMILY_8000 ?
 797                             iwl_nvm_channels_family_8000 : iwl_nvm_channels;
 798        struct ieee80211_regdomain *regd;
 799        int size_of_regd;
 800        struct ieee80211_reg_rule *rule;
 801        enum nl80211_band band;
 802        int center_freq, prev_center_freq = 0;
 803        int valid_rules = 0;
 804        bool new_rule;
 805        int max_num_ch = cfg->device_family == IWL_DEVICE_FAMILY_8000 ?
 806                         IWL_NUM_CHANNELS_FAMILY_8000 : IWL_NUM_CHANNELS;
 807
 808        if (WARN_ON_ONCE(num_of_ch > NL80211_MAX_SUPP_REG_RULES))
 809                return ERR_PTR(-EINVAL);
 810
 811        if (WARN_ON(num_of_ch > max_num_ch))
 812                num_of_ch = max_num_ch;
 813
 814        IWL_DEBUG_DEV(dev, IWL_DL_LAR, "building regdom for %d channels\n",
 815                      num_of_ch);
 816
 817        /* build a regdomain rule for every valid channel */
 818        size_of_regd =
 819                sizeof(struct ieee80211_regdomain) +
 820                num_of_ch * sizeof(struct ieee80211_reg_rule);
 821
 822        regd = kzalloc(size_of_regd, GFP_KERNEL);
 823        if (!regd)
 824                return ERR_PTR(-ENOMEM);
 825
 826        for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
 827                ch_flags = (u16)__le32_to_cpup(channels + ch_idx);
 828                band = (ch_idx < NUM_2GHZ_CHANNELS) ?
 829                       NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
 830                center_freq = ieee80211_channel_to_frequency(nvm_chan[ch_idx],
 831                                                             band);
 832                new_rule = false;
 833
 834                if (!(ch_flags & NVM_CHANNEL_VALID)) {
 835                        IWL_DEBUG_DEV(dev, IWL_DL_LAR,
 836                                      "Ch. %d Flags %x [%sGHz] - No traffic\n",
 837                                      nvm_chan[ch_idx],
 838                                      ch_flags,
 839                                      (ch_idx >= NUM_2GHZ_CHANNELS) ?
 840                                      "5.2" : "2.4");
 841                        continue;
 842                }
 843
 844                /* we can't continue the same rule */
 845                if (ch_idx == 0 || prev_ch_flags != ch_flags ||
 846                    center_freq - prev_center_freq > 20) {
 847                        valid_rules++;
 848                        new_rule = true;
 849                }
 850
 851                rule = &regd->reg_rules[valid_rules - 1];
 852
 853                if (new_rule)
 854                        rule->freq_range.start_freq_khz =
 855                                                MHZ_TO_KHZ(center_freq - 10);
 856
 857                rule->freq_range.end_freq_khz = MHZ_TO_KHZ(center_freq + 10);
 858
 859                /* this doesn't matter - not used by FW */
 860                rule->power_rule.max_antenna_gain = DBI_TO_MBI(6);
 861                rule->power_rule.max_eirp =
 862                        DBM_TO_MBM(IWL_DEFAULT_MAX_TX_POWER);
 863
 864                rule->flags = iwl_nvm_get_regdom_bw_flags(nvm_chan, ch_idx,
 865                                                          ch_flags, cfg);
 866
 867                /* rely on auto-calculation to merge BW of contiguous chans */
 868                rule->flags |= NL80211_RRF_AUTO_BW;
 869                rule->freq_range.max_bandwidth_khz = 0;
 870
 871                prev_ch_flags = ch_flags;
 872                prev_center_freq = center_freq;
 873
 874                IWL_DEBUG_DEV(dev, IWL_DL_LAR,
 875                              "Ch. %d [%sGHz] %s%s%s%s%s%s%s%s%s(0x%02x): Ad-Hoc %ssupported\n",
 876                              center_freq,
 877                              band == NL80211_BAND_5GHZ ? "5.2" : "2.4",
 878                              CHECK_AND_PRINT_I(VALID),
 879                              CHECK_AND_PRINT_I(ACTIVE),
 880                              CHECK_AND_PRINT_I(RADAR),
 881                              CHECK_AND_PRINT_I(WIDE),
 882                              CHECK_AND_PRINT_I(40MHZ),
 883                              CHECK_AND_PRINT_I(80MHZ),
 884                              CHECK_AND_PRINT_I(160MHZ),
 885                              CHECK_AND_PRINT_I(INDOOR_ONLY),
 886                              CHECK_AND_PRINT_I(GO_CONCURRENT),
 887                              ch_flags,
 888                              ((ch_flags & NVM_CHANNEL_ACTIVE) &&
 889                               !(ch_flags & NVM_CHANNEL_RADAR))
 890                                         ? "" : "not ");
 891        }
 892
 893        regd->n_reg_rules = valid_rules;
 894
 895        /* set alpha2 from FW. */
 896        regd->alpha2[0] = fw_mcc >> 8;
 897        regd->alpha2[1] = fw_mcc & 0xff;
 898
 899        return regd;
 900}
 901IWL_EXPORT_SYMBOL(iwl_parse_nvm_mcc_info);
 902
 903#ifdef CONFIG_ACPI
 904#define WRDD_METHOD             "WRDD"
 905#define WRDD_WIFI               (0x07)
 906#define WRDD_WIGIG              (0x10)
 907
 908static u32 iwl_wrdd_get_mcc(struct device *dev, union acpi_object *wrdd)
 909{
 910        union acpi_object *mcc_pkg, *domain_type, *mcc_value;
 911        u32 i;
 912
 913        if (wrdd->type != ACPI_TYPE_PACKAGE ||
 914            wrdd->package.count < 2 ||
 915            wrdd->package.elements[0].type != ACPI_TYPE_INTEGER ||
 916            wrdd->package.elements[0].integer.value != 0) {
 917                IWL_DEBUG_EEPROM(dev, "Unsupported wrdd structure\n");
 918                return 0;
 919        }
 920
 921        for (i = 1 ; i < wrdd->package.count ; ++i) {
 922                mcc_pkg = &wrdd->package.elements[i];
 923
 924                if (mcc_pkg->type != ACPI_TYPE_PACKAGE ||
 925                    mcc_pkg->package.count < 2 ||
 926                    mcc_pkg->package.elements[0].type != ACPI_TYPE_INTEGER ||
 927                    mcc_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) {
 928                        mcc_pkg = NULL;
 929                        continue;
 930                }
 931
 932                domain_type = &mcc_pkg->package.elements[0];
 933                if (domain_type->integer.value == WRDD_WIFI)
 934                        break;
 935
 936                mcc_pkg = NULL;
 937        }
 938
 939        if (mcc_pkg) {
 940                mcc_value = &mcc_pkg->package.elements[1];
 941                return mcc_value->integer.value;
 942        }
 943
 944        return 0;
 945}
 946
 947int iwl_get_bios_mcc(struct device *dev, char *mcc)
 948{
 949        acpi_handle root_handle;
 950        acpi_handle handle;
 951        struct acpi_buffer wrdd = {ACPI_ALLOCATE_BUFFER, NULL};
 952        acpi_status status;
 953        u32 mcc_val;
 954
 955        root_handle = ACPI_HANDLE(dev);
 956        if (!root_handle) {
 957                IWL_DEBUG_EEPROM(dev,
 958                                 "Could not retrieve root port ACPI handle\n");
 959                return -ENOENT;
 960        }
 961
 962        /* Get the method's handle */
 963        status = acpi_get_handle(root_handle, (acpi_string)WRDD_METHOD,
 964                                 &handle);
 965        if (ACPI_FAILURE(status)) {
 966                IWL_DEBUG_EEPROM(dev, "WRD method not found\n");
 967                return -ENOENT;
 968        }
 969
 970        /* Call WRDD with no arguments */
 971        status = acpi_evaluate_object(handle, NULL, NULL, &wrdd);
 972        if (ACPI_FAILURE(status)) {
 973                IWL_DEBUG_EEPROM(dev, "WRDC invocation failed (0x%x)\n",
 974                                 status);
 975                return -ENOENT;
 976        }
 977
 978        mcc_val = iwl_wrdd_get_mcc(dev, wrdd.pointer);
 979        kfree(wrdd.pointer);
 980        if (!mcc_val)
 981                return -ENOENT;
 982
 983        mcc[0] = (mcc_val >> 8) & 0xff;
 984        mcc[1] = mcc_val & 0xff;
 985        mcc[2] = '\0';
 986        return 0;
 987}
 988IWL_EXPORT_SYMBOL(iwl_get_bios_mcc);
 989#endif
 990