linux/drivers/net/wireless/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 *
  10 * This program is free software; you can redistribute it and/or modify
  11 * it under the terms of version 2 of the GNU General Public License as
  12 * published by the Free Software Foundation.
  13 *
  14 * This program is distributed in the hope that it will be useful, but
  15 * WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  17 * General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this program; if not, write to the Free Software
  21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
  22 * USA
  23 *
  24 * The full GNU General Public License is included in this distribution
  25 * in the file called COPYING.
  26 *
  27 * Contact Information:
  28 *  Intel Linux Wireless <ilw@linux.intel.com>
  29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
  30 *
  31 * BSD LICENSE
  32 *
  33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
  34 * All rights reserved.
  35 *
  36 * Redistribution and use in source and binary forms, with or without
  37 * modification, are permitted provided that the following conditions
  38 * are met:
  39 *
  40 *  * Redistributions of source code must retain the above copyright
  41 *    notice, this list of conditions and the following disclaimer.
  42 *  * Redistributions in binary form must reproduce the above copyright
  43 *    notice, this list of conditions and the following disclaimer in
  44 *    the documentation and/or other materials provided with the
  45 *    distribution.
  46 *  * Neither the name Intel Corporation nor the names of its
  47 *    contributors may be used to endorse or promote products derived
  48 *    from this software without specific prior written permission.
  49 *
  50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  61 *****************************************************************************/
  62#include <linux/types.h>
  63#include <linux/slab.h>
  64#include <linux/export.h>
  65#include "iwl-drv.h"
  66#include "iwl-modparams.h"
  67#include "iwl-nvm-parse.h"
  68
  69/* NVM offsets (in words) definitions */
  70enum wkp_nvm_offsets {
  71        /* NVM HW-Section offset (in words) definitions */
  72        HW_ADDR = 0x15,
  73
  74        /* NVM SW-Section offset (in words) definitions */
  75        NVM_SW_SECTION = 0x1C0,
  76        NVM_VERSION = 0,
  77        RADIO_CFG = 1,
  78        SKU = 2,
  79        N_HW_ADDRS = 3,
  80        NVM_CHANNELS = 0x1E0 - NVM_SW_SECTION,
  81
  82        /* NVM calibration section offset (in words) definitions */
  83        NVM_CALIB_SECTION = 0x2B8,
  84        XTAL_CALIB = 0x316 - NVM_CALIB_SECTION
  85};
  86
  87enum family_8000_nvm_offsets {
  88        /* NVM HW-Section offset (in words) definitions */
  89        HW_ADDR0_FAMILY_8000 = 0x12,
  90        HW_ADDR1_FAMILY_8000 = 0x16,
  91        MAC_ADDRESS_OVERRIDE_FAMILY_8000 = 1,
  92
  93        /* NVM SW-Section offset (in words) definitions */
  94        NVM_SW_SECTION_FAMILY_8000 = 0x1C0,
  95        NVM_VERSION_FAMILY_8000 = 0,
  96        RADIO_CFG_FAMILY_8000 = 2,
  97        SKU_FAMILY_8000 = 4,
  98        N_HW_ADDRS_FAMILY_8000 = 5,
  99
 100        /* NVM REGULATORY -Section offset (in words) definitions */
 101        NVM_CHANNELS_FAMILY_8000 = 0,
 102
 103        /* NVM calibration section offset (in words) definitions */
 104        NVM_CALIB_SECTION_FAMILY_8000 = 0x2B8,
 105        XTAL_CALIB_FAMILY_8000 = 0x316 - NVM_CALIB_SECTION_FAMILY_8000
 106};
 107
 108/* SKU Capabilities (actual values from NVM definition) */
 109enum nvm_sku_bits {
 110        NVM_SKU_CAP_BAND_24GHZ  = BIT(0),
 111        NVM_SKU_CAP_BAND_52GHZ  = BIT(1),
 112        NVM_SKU_CAP_11N_ENABLE  = BIT(2),
 113        NVM_SKU_CAP_11AC_ENABLE = BIT(3),
 114};
 115
 116/*
 117 * These are the channel numbers in the order that they are stored in the NVM
 118 */
 119static const u8 iwl_nvm_channels[] = {
 120        /* 2.4 GHz */
 121        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
 122        /* 5 GHz */
 123        36, 40, 44 , 48, 52, 56, 60, 64,
 124        100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
 125        149, 153, 157, 161, 165
 126};
 127
 128static const u8 iwl_nvm_channels_family_8000[] = {
 129        /* 2.4 GHz */
 130        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
 131        /* 5 GHz */
 132        36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92,
 133        96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
 134        149, 153, 157, 161, 165, 169, 173, 177, 181
 135};
 136
 137#define IWL_NUM_CHANNELS        ARRAY_SIZE(iwl_nvm_channels)
 138#define IWL_NUM_CHANNELS_FAMILY_8000    ARRAY_SIZE(iwl_nvm_channels_family_8000)
 139#define NUM_2GHZ_CHANNELS       14
 140#define FIRST_2GHZ_HT_MINUS     5
 141#define LAST_2GHZ_HT_PLUS       9
 142#define LAST_5GHZ_HT            161
 143
 144#define DEFAULT_MAX_TX_POWER 16
 145
 146/* rate data (static) */
 147static struct ieee80211_rate iwl_cfg80211_rates[] = {
 148        { .bitrate = 1 * 10, .hw_value = 0, .hw_value_short = 0, },
 149        { .bitrate = 2 * 10, .hw_value = 1, .hw_value_short = 1,
 150          .flags = IEEE80211_RATE_SHORT_PREAMBLE, },
 151        { .bitrate = 5.5 * 10, .hw_value = 2, .hw_value_short = 2,
 152          .flags = IEEE80211_RATE_SHORT_PREAMBLE, },
 153        { .bitrate = 11 * 10, .hw_value = 3, .hw_value_short = 3,
 154          .flags = IEEE80211_RATE_SHORT_PREAMBLE, },
 155        { .bitrate = 6 * 10, .hw_value = 4, .hw_value_short = 4, },
 156        { .bitrate = 9 * 10, .hw_value = 5, .hw_value_short = 5, },
 157        { .bitrate = 12 * 10, .hw_value = 6, .hw_value_short = 6, },
 158        { .bitrate = 18 * 10, .hw_value = 7, .hw_value_short = 7, },
 159        { .bitrate = 24 * 10, .hw_value = 8, .hw_value_short = 8, },
 160        { .bitrate = 36 * 10, .hw_value = 9, .hw_value_short = 9, },
 161        { .bitrate = 48 * 10, .hw_value = 10, .hw_value_short = 10, },
 162        { .bitrate = 54 * 10, .hw_value = 11, .hw_value_short = 11, },
 163};
 164#define RATES_24_OFFS   0
 165#define N_RATES_24      ARRAY_SIZE(iwl_cfg80211_rates)
 166#define RATES_52_OFFS   4
 167#define N_RATES_52      (N_RATES_24 - RATES_52_OFFS)
 168
 169/**
 170 * enum iwl_nvm_channel_flags - channel flags in NVM
 171 * @NVM_CHANNEL_VALID: channel is usable for this SKU/geo
 172 * @NVM_CHANNEL_IBSS: usable as an IBSS channel
 173 * @NVM_CHANNEL_ACTIVE: active scanning allowed
 174 * @NVM_CHANNEL_RADAR: radar detection required
 175 * @NVM_CHANNEL_DFS: dynamic freq selection candidate
 176 * @NVM_CHANNEL_WIDE: 20 MHz channel okay (?)
 177 * @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?)
 178 * @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?)
 179 * @NVM_CHANNEL_160MHZ: 160 MHz channel okay (?)
 180 */
 181enum iwl_nvm_channel_flags {
 182        NVM_CHANNEL_VALID = BIT(0),
 183        NVM_CHANNEL_IBSS = BIT(1),
 184        NVM_CHANNEL_ACTIVE = BIT(3),
 185        NVM_CHANNEL_RADAR = BIT(4),
 186        NVM_CHANNEL_DFS = BIT(7),
 187        NVM_CHANNEL_WIDE = BIT(8),
 188        NVM_CHANNEL_40MHZ = BIT(9),
 189        NVM_CHANNEL_80MHZ = BIT(10),
 190        NVM_CHANNEL_160MHZ = BIT(11),
 191};
 192
 193#define CHECK_AND_PRINT_I(x)    \
 194        ((ch_flags & NVM_CHANNEL_##x) ? # x " " : "")
 195
 196static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
 197                                struct iwl_nvm_data *data,
 198                                const __le16 * const nvm_ch_flags)
 199{
 200        int ch_idx;
 201        int n_channels = 0;
 202        struct ieee80211_channel *channel;
 203        u16 ch_flags;
 204        bool is_5ghz;
 205        int num_of_ch;
 206        const u8 *nvm_chan;
 207
 208        if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
 209                num_of_ch = IWL_NUM_CHANNELS;
 210                nvm_chan = &iwl_nvm_channels[0];
 211        } else {
 212                num_of_ch = IWL_NUM_CHANNELS_FAMILY_8000;
 213                nvm_chan = &iwl_nvm_channels_family_8000[0];
 214        }
 215
 216        for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
 217                ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
 218
 219                if (ch_idx >= NUM_2GHZ_CHANNELS &&
 220                    !data->sku_cap_band_52GHz_enable)
 221                        ch_flags &= ~NVM_CHANNEL_VALID;
 222
 223                if (!(ch_flags & NVM_CHANNEL_VALID)) {
 224                        IWL_DEBUG_EEPROM(dev,
 225                                         "Ch. %d Flags %x [%sGHz] - No traffic\n",
 226                                         nvm_chan[ch_idx],
 227                                         ch_flags,
 228                                         (ch_idx >= NUM_2GHZ_CHANNELS) ?
 229                                         "5.2" : "2.4");
 230                        continue;
 231                }
 232
 233                channel = &data->channels[n_channels];
 234                n_channels++;
 235
 236                channel->hw_value = nvm_chan[ch_idx];
 237                channel->band = (ch_idx < NUM_2GHZ_CHANNELS) ?
 238                                IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
 239                channel->center_freq =
 240                        ieee80211_channel_to_frequency(
 241                                channel->hw_value, channel->band);
 242
 243                /* TODO: Need to be dependent to the NVM */
 244                channel->flags = IEEE80211_CHAN_NO_HT40;
 245                if (ch_idx < NUM_2GHZ_CHANNELS &&
 246                    (ch_flags & NVM_CHANNEL_40MHZ)) {
 247                        if (nvm_chan[ch_idx] <= LAST_2GHZ_HT_PLUS)
 248                                channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
 249                        if (nvm_chan[ch_idx] >= FIRST_2GHZ_HT_MINUS)
 250                                channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
 251                } else if (nvm_chan[ch_idx] <= LAST_5GHZ_HT &&
 252                           (ch_flags & NVM_CHANNEL_40MHZ)) {
 253                        if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
 254                                channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
 255                        else
 256                                channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
 257                }
 258                if (!(ch_flags & NVM_CHANNEL_80MHZ))
 259                        channel->flags |= IEEE80211_CHAN_NO_80MHZ;
 260                if (!(ch_flags & NVM_CHANNEL_160MHZ))
 261                        channel->flags |= IEEE80211_CHAN_NO_160MHZ;
 262
 263                if (!(ch_flags & NVM_CHANNEL_IBSS))
 264                        channel->flags |= IEEE80211_CHAN_NO_IR;
 265
 266                if (!(ch_flags & NVM_CHANNEL_ACTIVE))
 267                        channel->flags |= IEEE80211_CHAN_NO_IR;
 268
 269                if (ch_flags & NVM_CHANNEL_RADAR)
 270                        channel->flags |= IEEE80211_CHAN_RADAR;
 271
 272                /* Initialize regulatory-based run-time data */
 273
 274                /*
 275                 * Default value - highest tx power value.  max_power
 276                 * is not used in mvm, and is used for backwards compatibility
 277                 */
 278                channel->max_power = DEFAULT_MAX_TX_POWER;
 279                is_5ghz = channel->band == IEEE80211_BAND_5GHZ;
 280                IWL_DEBUG_EEPROM(dev,
 281                                 "Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported\n",
 282                                 channel->hw_value,
 283                                 is_5ghz ? "5.2" : "2.4",
 284                                 CHECK_AND_PRINT_I(VALID),
 285                                 CHECK_AND_PRINT_I(IBSS),
 286                                 CHECK_AND_PRINT_I(ACTIVE),
 287                                 CHECK_AND_PRINT_I(RADAR),
 288                                 CHECK_AND_PRINT_I(WIDE),
 289                                 CHECK_AND_PRINT_I(DFS),
 290                                 ch_flags,
 291                                 channel->max_power,
 292                                 ((ch_flags & NVM_CHANNEL_IBSS) &&
 293                                  !(ch_flags & NVM_CHANNEL_RADAR))
 294                                        ? "" : "not ");
 295        }
 296
 297        return n_channels;
 298}
 299
 300static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
 301                                  struct iwl_nvm_data *data,
 302                                  struct ieee80211_sta_vht_cap *vht_cap,
 303                                  u8 tx_chains, u8 rx_chains)
 304{
 305        int num_rx_ants = num_of_ant(rx_chains);
 306        int num_tx_ants = num_of_ant(tx_chains);
 307
 308        vht_cap->vht_supported = true;
 309
 310        vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 |
 311                       IEEE80211_VHT_CAP_RXSTBC_1 |
 312                       IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
 313                       3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT |
 314                       7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
 315
 316        if (num_tx_ants > 1)
 317                vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC;
 318        else
 319                vht_cap->cap |= IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
 320
 321        if (iwlwifi_mod_params.amsdu_size_8K)
 322                vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
 323
 324        vht_cap->vht_mcs.rx_mcs_map =
 325                cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |
 326                            IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 |
 327                            IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 |
 328                            IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 |
 329                            IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 |
 330                            IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 |
 331                            IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
 332                            IEEE80211_VHT_MCS_NOT_SUPPORTED << 14);
 333
 334        if (num_rx_ants == 1 || cfg->rx_with_siso_diversity) {
 335                vht_cap->cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN;
 336                /* this works because NOT_SUPPORTED == 3 */
 337                vht_cap->vht_mcs.rx_mcs_map |=
 338                        cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << 2);
 339        }
 340
 341        vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map;
 342}
 343
 344static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
 345                            struct iwl_nvm_data *data,
 346                            const __le16 *ch_section, bool enable_vht,
 347                            u8 tx_chains, u8 rx_chains)
 348{
 349        int n_channels;
 350        int n_used = 0;
 351        struct ieee80211_supported_band *sband;
 352
 353        if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
 354                n_channels = iwl_init_channel_map(
 355                                dev, cfg, data,
 356                                &ch_section[NVM_CHANNELS]);
 357        else
 358                n_channels = iwl_init_channel_map(
 359                                dev, cfg, data,
 360                                &ch_section[NVM_CHANNELS_FAMILY_8000]);
 361
 362        sband = &data->bands[IEEE80211_BAND_2GHZ];
 363        sband->band = IEEE80211_BAND_2GHZ;
 364        sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS];
 365        sband->n_bitrates = N_RATES_24;
 366        n_used += iwl_init_sband_channels(data, sband, n_channels,
 367                                          IEEE80211_BAND_2GHZ);
 368        iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ,
 369                             tx_chains, rx_chains);
 370
 371        sband = &data->bands[IEEE80211_BAND_5GHZ];
 372        sband->band = IEEE80211_BAND_5GHZ;
 373        sband->bitrates = &iwl_cfg80211_rates[RATES_52_OFFS];
 374        sband->n_bitrates = N_RATES_52;
 375        n_used += iwl_init_sband_channels(data, sband, n_channels,
 376                                          IEEE80211_BAND_5GHZ);
 377        iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ,
 378                             tx_chains, rx_chains);
 379        if (enable_vht)
 380                iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap,
 381                                      tx_chains, rx_chains);
 382
 383        if (n_channels != n_used)
 384                IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n",
 385                            n_used, n_channels);
 386}
 387
 388static int iwl_get_sku(const struct iwl_cfg *cfg,
 389                       const __le16 *nvm_sw)
 390{
 391        if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
 392                return le16_to_cpup(nvm_sw + SKU);
 393        else
 394                return le32_to_cpup((__le32 *)(nvm_sw + SKU_FAMILY_8000));
 395}
 396
 397static int iwl_get_nvm_version(const struct iwl_cfg *cfg,
 398                               const __le16 *nvm_sw)
 399{
 400        if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
 401                return le16_to_cpup(nvm_sw + NVM_VERSION);
 402        else
 403                return le32_to_cpup((__le32 *)(nvm_sw +
 404                                               NVM_VERSION_FAMILY_8000));
 405}
 406
 407static int iwl_get_radio_cfg(const struct iwl_cfg *cfg,
 408                             const __le16 *nvm_sw)
 409{
 410        if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
 411                return le16_to_cpup(nvm_sw + RADIO_CFG);
 412        else
 413                return le32_to_cpup((__le32 *)(nvm_sw + RADIO_CFG_FAMILY_8000));
 414}
 415
 416#define N_HW_ADDRS_MASK_FAMILY_8000     0xF
 417static int iwl_get_n_hw_addrs(const struct iwl_cfg *cfg,
 418                              const __le16 *nvm_sw)
 419{
 420        if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
 421                return le16_to_cpup(nvm_sw + N_HW_ADDRS);
 422        else
 423                return le32_to_cpup((__le32 *)(nvm_sw + N_HW_ADDRS_FAMILY_8000))
 424                       & N_HW_ADDRS_MASK_FAMILY_8000;
 425}
 426
 427static void iwl_set_radio_cfg(const struct iwl_cfg *cfg,
 428                              struct iwl_nvm_data *data,
 429                              u32 radio_cfg)
 430{
 431        if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
 432                data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK(radio_cfg);
 433                data->radio_cfg_step = NVM_RF_CFG_STEP_MSK(radio_cfg);
 434                data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK(radio_cfg);
 435                data->radio_cfg_pnum = NVM_RF_CFG_PNUM_MSK(radio_cfg);
 436                return;
 437        }
 438
 439        /* set the radio configuration for family 8000 */
 440        data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK_FAMILY_8000(radio_cfg);
 441        data->radio_cfg_step = NVM_RF_CFG_STEP_MSK_FAMILY_8000(radio_cfg);
 442        data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK_FAMILY_8000(radio_cfg);
 443        data->radio_cfg_pnum = NVM_RF_CFG_FLAVOR_MSK_FAMILY_8000(radio_cfg);
 444}
 445
 446static void iwl_set_hw_address(const struct iwl_cfg *cfg,
 447                               struct iwl_nvm_data *data,
 448                               const __le16 *nvm_sec)
 449{
 450        u8 hw_addr[ETH_ALEN];
 451
 452        if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
 453                memcpy(hw_addr, nvm_sec + HW_ADDR, ETH_ALEN);
 454        else
 455                memcpy(hw_addr, nvm_sec + MAC_ADDRESS_OVERRIDE_FAMILY_8000,
 456                       ETH_ALEN);
 457
 458        /* The byte order is little endian 16 bit, meaning 214365 */
 459        data->hw_addr[0] = hw_addr[1];
 460        data->hw_addr[1] = hw_addr[0];
 461        data->hw_addr[2] = hw_addr[3];
 462        data->hw_addr[3] = hw_addr[2];
 463        data->hw_addr[4] = hw_addr[5];
 464        data->hw_addr[5] = hw_addr[4];
 465}
 466
 467struct iwl_nvm_data *
 468iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
 469                   const __le16 *nvm_hw, const __le16 *nvm_sw,
 470                   const __le16 *nvm_calib, const __le16 *regulatory,
 471                   const __le16 *mac_override, u8 tx_chains, u8 rx_chains)
 472{
 473        struct iwl_nvm_data *data;
 474        u32 sku;
 475        u32 radio_cfg;
 476
 477        if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
 478                data = kzalloc(sizeof(*data) +
 479                               sizeof(struct ieee80211_channel) *
 480                               IWL_NUM_CHANNELS,
 481                               GFP_KERNEL);
 482        else
 483                data = kzalloc(sizeof(*data) +
 484                               sizeof(struct ieee80211_channel) *
 485                               IWL_NUM_CHANNELS_FAMILY_8000,
 486                               GFP_KERNEL);
 487        if (!data)
 488                return NULL;
 489
 490        data->nvm_version = iwl_get_nvm_version(cfg, nvm_sw);
 491
 492        radio_cfg = iwl_get_radio_cfg(cfg, nvm_sw);
 493        iwl_set_radio_cfg(cfg, data, radio_cfg);
 494
 495        sku = iwl_get_sku(cfg, nvm_sw);
 496        data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ;
 497        data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ;
 498        data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE;
 499        data->sku_cap_11ac_enable = sku & NVM_SKU_CAP_11AC_ENABLE;
 500        if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
 501                data->sku_cap_11n_enable = false;
 502
 503        data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw);
 504
 505        if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
 506                /* Checking for required sections */
 507                if (!nvm_calib) {
 508                        IWL_ERR_DEV(dev,
 509                                    "Can't parse empty Calib NVM sections\n");
 510                        kfree(data);
 511                        return NULL;
 512                }
 513                /* in family 8000 Xtal calibration values moved to OTP */
 514                data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB);
 515                data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1);
 516        }
 517
 518        if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
 519                iwl_set_hw_address(cfg, data, nvm_hw);
 520
 521                iwl_init_sbands(dev, cfg, data, nvm_sw,
 522                                sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains,
 523                                rx_chains);
 524        } else {
 525                /* MAC address in family 8000 */
 526                iwl_set_hw_address(cfg, data, mac_override);
 527
 528                iwl_init_sbands(dev, cfg, data, regulatory,
 529                                sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains,
 530                                rx_chains);
 531        }
 532
 533        data->calib_version = 255;
 534
 535        return data;
 536}
 537IWL_EXPORT_SYMBOL(iwl_parse_nvm_data);
 538