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