rtlwifi: cleanup 8723be ant_sel definition
[platform/kernel/linux-starfive.git] / drivers / net / wireless / intel / iwlwifi / iwl-nvm-parse.c
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
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 #include "fw/acpi.h"
79 #include "fw/api/nvm-reg.h"
80
81 /* NVM offsets (in words) definitions */
82 enum nvm_offsets {
83         /* NVM HW-Section offset (in words) definitions */
84         SUBSYSTEM_ID = 0x0A,
85         HW_ADDR = 0x15,
86
87         /* NVM SW-Section offset (in words) definitions */
88         NVM_SW_SECTION = 0x1C0,
89         NVM_VERSION = 0,
90         RADIO_CFG = 1,
91         SKU = 2,
92         N_HW_ADDRS = 3,
93         NVM_CHANNELS = 0x1E0 - NVM_SW_SECTION,
94
95         /* NVM calibration section offset (in words) definitions */
96         NVM_CALIB_SECTION = 0x2B8,
97         XTAL_CALIB = 0x316 - NVM_CALIB_SECTION,
98
99         /* NVM REGULATORY -Section offset (in words) definitions */
100         NVM_CHANNELS_SDP = 0,
101 };
102
103 enum ext_nvm_offsets {
104         /* NVM HW-Section offset (in words) definitions */
105         MAC_ADDRESS_OVERRIDE_EXT_NVM = 1,
106
107         /* NVM SW-Section offset (in words) definitions */
108         NVM_VERSION_EXT_NVM = 0,
109         RADIO_CFG_FAMILY_EXT_NVM = 0,
110         SKU_FAMILY_8000 = 2,
111         N_HW_ADDRS_FAMILY_8000 = 3,
112
113         /* NVM REGULATORY -Section offset (in words) definitions */
114         NVM_CHANNELS_EXTENDED = 0,
115         NVM_LAR_OFFSET_OLD = 0x4C7,
116         NVM_LAR_OFFSET = 0x507,
117         NVM_LAR_ENABLED = 0x7,
118 };
119
120 /* SKU Capabilities (actual values from NVM definition) */
121 enum nvm_sku_bits {
122         NVM_SKU_CAP_BAND_24GHZ          = BIT(0),
123         NVM_SKU_CAP_BAND_52GHZ          = BIT(1),
124         NVM_SKU_CAP_11N_ENABLE          = BIT(2),
125         NVM_SKU_CAP_11AC_ENABLE         = BIT(3),
126         NVM_SKU_CAP_MIMO_DISABLE        = BIT(5),
127 };
128
129 /*
130  * These are the channel numbers in the order that they are stored in the NVM
131  */
132 static const u8 iwl_nvm_channels[] = {
133         /* 2.4 GHz */
134         1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
135         /* 5 GHz */
136         36, 40, 44 , 48, 52, 56, 60, 64,
137         100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
138         149, 153, 157, 161, 165
139 };
140
141 static const u8 iwl_ext_nvm_channels[] = {
142         /* 2.4 GHz */
143         1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
144         /* 5 GHz */
145         36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92,
146         96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
147         149, 153, 157, 161, 165, 169, 173, 177, 181
148 };
149
150 #define IWL_NVM_NUM_CHANNELS            ARRAY_SIZE(iwl_nvm_channels)
151 #define IWL_NVM_NUM_CHANNELS_EXT        ARRAY_SIZE(iwl_ext_nvm_channels)
152 #define NUM_2GHZ_CHANNELS               14
153 #define NUM_2GHZ_CHANNELS_EXT   14
154 #define FIRST_2GHZ_HT_MINUS             5
155 #define LAST_2GHZ_HT_PLUS               9
156 #define LAST_5GHZ_HT                    165
157 #define LAST_5GHZ_HT_FAMILY_8000        181
158 #define N_HW_ADDR_MASK                  0xF
159
160 /* rate data (static) */
161 static struct ieee80211_rate iwl_cfg80211_rates[] = {
162         { .bitrate = 1 * 10, .hw_value = 0, .hw_value_short = 0, },
163         { .bitrate = 2 * 10, .hw_value = 1, .hw_value_short = 1,
164           .flags = IEEE80211_RATE_SHORT_PREAMBLE, },
165         { .bitrate = 5.5 * 10, .hw_value = 2, .hw_value_short = 2,
166           .flags = IEEE80211_RATE_SHORT_PREAMBLE, },
167         { .bitrate = 11 * 10, .hw_value = 3, .hw_value_short = 3,
168           .flags = IEEE80211_RATE_SHORT_PREAMBLE, },
169         { .bitrate = 6 * 10, .hw_value = 4, .hw_value_short = 4, },
170         { .bitrate = 9 * 10, .hw_value = 5, .hw_value_short = 5, },
171         { .bitrate = 12 * 10, .hw_value = 6, .hw_value_short = 6, },
172         { .bitrate = 18 * 10, .hw_value = 7, .hw_value_short = 7, },
173         { .bitrate = 24 * 10, .hw_value = 8, .hw_value_short = 8, },
174         { .bitrate = 36 * 10, .hw_value = 9, .hw_value_short = 9, },
175         { .bitrate = 48 * 10, .hw_value = 10, .hw_value_short = 10, },
176         { .bitrate = 54 * 10, .hw_value = 11, .hw_value_short = 11, },
177 };
178 #define RATES_24_OFFS   0
179 #define N_RATES_24      ARRAY_SIZE(iwl_cfg80211_rates)
180 #define RATES_52_OFFS   4
181 #define N_RATES_52      (N_RATES_24 - RATES_52_OFFS)
182
183 /**
184  * enum iwl_nvm_channel_flags - channel flags in NVM
185  * @NVM_CHANNEL_VALID: channel is usable for this SKU/geo
186  * @NVM_CHANNEL_IBSS: usable as an IBSS channel
187  * @NVM_CHANNEL_ACTIVE: active scanning allowed
188  * @NVM_CHANNEL_RADAR: radar detection required
189  * @NVM_CHANNEL_INDOOR_ONLY: only indoor use is allowed
190  * @NVM_CHANNEL_GO_CONCURRENT: GO operation is allowed when connected to BSS
191  *      on same channel on 2.4 or same UNII band on 5.2
192  * @NVM_CHANNEL_UNIFORM: uniform spreading required
193  * @NVM_CHANNEL_20MHZ: 20 MHz channel okay
194  * @NVM_CHANNEL_40MHZ: 40 MHz channel okay
195  * @NVM_CHANNEL_80MHZ: 80 MHz channel okay
196  * @NVM_CHANNEL_160MHZ: 160 MHz channel okay
197  * @NVM_CHANNEL_DC_HIGH: DC HIGH required/allowed (?)
198  */
199 enum 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_UNIFORM             = BIT(7),
207         NVM_CHANNEL_20MHZ               = BIT(8),
208         NVM_CHANNEL_40MHZ               = BIT(9),
209         NVM_CHANNEL_80MHZ               = BIT(10),
210         NVM_CHANNEL_160MHZ              = BIT(11),
211         NVM_CHANNEL_DC_HIGH             = BIT(12),
212 };
213
214 static inline void iwl_nvm_print_channel_flags(struct device *dev, u32 level,
215                                                int chan, u16 flags)
216 {
217 #define CHECK_AND_PRINT_I(x)    \
218         ((flags & NVM_CHANNEL_##x) ? " " #x : "")
219
220         if (!(flags & NVM_CHANNEL_VALID)) {
221                 IWL_DEBUG_DEV(dev, level, "Ch. %d: 0x%x: No traffic\n",
222                               chan, flags);
223                 return;
224         }
225
226         /* Note: already can print up to 101 characters, 110 is the limit! */
227         IWL_DEBUG_DEV(dev, level,
228                       "Ch. %d: 0x%x:%s%s%s%s%s%s%s%s%s%s%s%s\n",
229                       chan, flags,
230                       CHECK_AND_PRINT_I(VALID),
231                       CHECK_AND_PRINT_I(IBSS),
232                       CHECK_AND_PRINT_I(ACTIVE),
233                       CHECK_AND_PRINT_I(RADAR),
234                       CHECK_AND_PRINT_I(INDOOR_ONLY),
235                       CHECK_AND_PRINT_I(GO_CONCURRENT),
236                       CHECK_AND_PRINT_I(UNIFORM),
237                       CHECK_AND_PRINT_I(20MHZ),
238                       CHECK_AND_PRINT_I(40MHZ),
239                       CHECK_AND_PRINT_I(80MHZ),
240                       CHECK_AND_PRINT_I(160MHZ),
241                       CHECK_AND_PRINT_I(DC_HIGH));
242 #undef CHECK_AND_PRINT_I
243 }
244
245 static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz,
246                                  u16 nvm_flags, const struct iwl_cfg *cfg)
247 {
248         u32 flags = IEEE80211_CHAN_NO_HT40;
249         u32 last_5ghz_ht = LAST_5GHZ_HT;
250
251         if (cfg->nvm_type == IWL_NVM_EXT)
252                 last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000;
253
254         if (!is_5ghz && (nvm_flags & NVM_CHANNEL_40MHZ)) {
255                 if (ch_num <= LAST_2GHZ_HT_PLUS)
256                         flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
257                 if (ch_num >= FIRST_2GHZ_HT_MINUS)
258                         flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
259         } else if (ch_num <= last_5ghz_ht && (nvm_flags & NVM_CHANNEL_40MHZ)) {
260                 if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
261                         flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
262                 else
263                         flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
264         }
265         if (!(nvm_flags & NVM_CHANNEL_80MHZ))
266                 flags |= IEEE80211_CHAN_NO_80MHZ;
267         if (!(nvm_flags & NVM_CHANNEL_160MHZ))
268                 flags |= IEEE80211_CHAN_NO_160MHZ;
269
270         if (!(nvm_flags & NVM_CHANNEL_IBSS))
271                 flags |= IEEE80211_CHAN_NO_IR;
272
273         if (!(nvm_flags & NVM_CHANNEL_ACTIVE))
274                 flags |= IEEE80211_CHAN_NO_IR;
275
276         if (nvm_flags & NVM_CHANNEL_RADAR)
277                 flags |= IEEE80211_CHAN_RADAR;
278
279         if (nvm_flags & NVM_CHANNEL_INDOOR_ONLY)
280                 flags |= IEEE80211_CHAN_INDOOR_ONLY;
281
282         /* Set the GO concurrent flag only in case that NO_IR is set.
283          * Otherwise it is meaningless
284          */
285         if ((nvm_flags & NVM_CHANNEL_GO_CONCURRENT) &&
286             (flags & IEEE80211_CHAN_NO_IR))
287                 flags |= IEEE80211_CHAN_IR_CONCURRENT;
288
289         return flags;
290 }
291
292 static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
293                                 struct iwl_nvm_data *data,
294                                 const __le16 * const nvm_ch_flags,
295                                 bool lar_supported, bool no_wide_in_5ghz)
296 {
297         int ch_idx;
298         int n_channels = 0;
299         struct ieee80211_channel *channel;
300         u16 ch_flags;
301         int num_of_ch, num_2ghz_channels;
302         const u8 *nvm_chan;
303
304         if (cfg->nvm_type != IWL_NVM_EXT) {
305                 num_of_ch = IWL_NVM_NUM_CHANNELS;
306                 nvm_chan = &iwl_nvm_channels[0];
307                 num_2ghz_channels = NUM_2GHZ_CHANNELS;
308         } else {
309                 num_of_ch = IWL_NVM_NUM_CHANNELS_EXT;
310                 nvm_chan = &iwl_ext_nvm_channels[0];
311                 num_2ghz_channels = NUM_2GHZ_CHANNELS_EXT;
312         }
313
314         for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
315                 bool is_5ghz = (ch_idx >= num_2ghz_channels);
316
317                 ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
318
319                 if (is_5ghz && !data->sku_cap_band_52GHz_enable)
320                         continue;
321
322                 /* workaround to disable wide channels in 5GHz */
323                 if (no_wide_in_5ghz && is_5ghz) {
324                         ch_flags &= ~(NVM_CHANNEL_40MHZ |
325                                      NVM_CHANNEL_80MHZ |
326                                      NVM_CHANNEL_160MHZ);
327                 }
328
329                 if (ch_flags & NVM_CHANNEL_160MHZ)
330                         data->vht160_supported = true;
331
332                 if (!lar_supported && !(ch_flags & NVM_CHANNEL_VALID)) {
333                         /*
334                          * Channels might become valid later if lar is
335                          * supported, hence we still want to add them to
336                          * the list of supported channels to cfg80211.
337                          */
338                         iwl_nvm_print_channel_flags(dev, IWL_DL_EEPROM,
339                                                     nvm_chan[ch_idx], ch_flags);
340                         continue;
341                 }
342
343                 channel = &data->channels[n_channels];
344                 n_channels++;
345
346                 channel->hw_value = nvm_chan[ch_idx];
347                 channel->band = is_5ghz ?
348                                 NL80211_BAND_5GHZ : NL80211_BAND_2GHZ;
349                 channel->center_freq =
350                         ieee80211_channel_to_frequency(
351                                 channel->hw_value, channel->band);
352
353                 /* Initialize regulatory-based run-time data */
354
355                 /*
356                  * Default value - highest tx power value.  max_power
357                  * is not used in mvm, and is used for backwards compatibility
358                  */
359                 channel->max_power = IWL_DEFAULT_MAX_TX_POWER;
360
361                 /* don't put limitations in case we're using LAR */
362                 if (!lar_supported)
363                         channel->flags = iwl_get_channel_flags(nvm_chan[ch_idx],
364                                                                ch_idx, is_5ghz,
365                                                                ch_flags, cfg);
366                 else
367                         channel->flags = 0;
368
369                 iwl_nvm_print_channel_flags(dev, IWL_DL_EEPROM,
370                                             channel->hw_value, ch_flags);
371                 IWL_DEBUG_EEPROM(dev, "Ch. %d: %ddBm\n",
372                                  channel->hw_value, channel->max_power);
373         }
374
375         return n_channels;
376 }
377
378 static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
379                                   struct iwl_nvm_data *data,
380                                   struct ieee80211_sta_vht_cap *vht_cap,
381                                   u8 tx_chains, u8 rx_chains)
382 {
383         int num_rx_ants = num_of_ant(rx_chains);
384         int num_tx_ants = num_of_ant(tx_chains);
385         unsigned int max_ampdu_exponent = (cfg->max_vht_ampdu_exponent ?:
386                                            IEEE80211_VHT_MAX_AMPDU_1024K);
387
388         vht_cap->vht_supported = true;
389
390         vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 |
391                        IEEE80211_VHT_CAP_RXSTBC_1 |
392                        IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
393                        3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT |
394                        max_ampdu_exponent <<
395                        IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
396
397         if (data->vht160_supported)
398                 vht_cap->cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
399                                 IEEE80211_VHT_CAP_SHORT_GI_160;
400
401         if (cfg->vht_mu_mimo_supported)
402                 vht_cap->cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
403
404         if (cfg->ht_params->ldpc)
405                 vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC;
406
407         if (data->sku_cap_mimo_disabled) {
408                 num_rx_ants = 1;
409                 num_tx_ants = 1;
410         }
411
412         if (num_tx_ants > 1)
413                 vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC;
414         else
415                 vht_cap->cap |= IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
416
417         switch (iwlwifi_mod_params.amsdu_size) {
418         case IWL_AMSDU_DEF:
419                 if (cfg->mq_rx_supported)
420                         vht_cap->cap |=
421                                 IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
422                 else
423                         vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
424                 break;
425         case IWL_AMSDU_4K:
426                 vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_3895;
427                 break;
428         case IWL_AMSDU_8K:
429                 vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
430                 break;
431         case IWL_AMSDU_12K:
432                 vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454;
433                 break;
434         default:
435                 break;
436         }
437
438         vht_cap->vht_mcs.rx_mcs_map =
439                 cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |
440                             IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 |
441                             IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 |
442                             IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 |
443                             IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 |
444                             IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 |
445                             IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
446                             IEEE80211_VHT_MCS_NOT_SUPPORTED << 14);
447
448         if (num_rx_ants == 1 || cfg->rx_with_siso_diversity) {
449                 vht_cap->cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN;
450                 /* this works because NOT_SUPPORTED == 3 */
451                 vht_cap->vht_mcs.rx_mcs_map |=
452                         cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << 2);
453         }
454
455         vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map;
456 }
457
458 void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
459                      struct iwl_nvm_data *data, const __le16 *nvm_ch_flags,
460                      u8 tx_chains, u8 rx_chains, bool lar_supported,
461                      bool no_wide_in_5ghz)
462 {
463         int n_channels;
464         int n_used = 0;
465         struct ieee80211_supported_band *sband;
466
467         n_channels = iwl_init_channel_map(dev, cfg, data, nvm_ch_flags,
468                                           lar_supported, no_wide_in_5ghz);
469         sband = &data->bands[NL80211_BAND_2GHZ];
470         sband->band = NL80211_BAND_2GHZ;
471         sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS];
472         sband->n_bitrates = N_RATES_24;
473         n_used += iwl_init_sband_channels(data, sband, n_channels,
474                                           NL80211_BAND_2GHZ);
475         iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, NL80211_BAND_2GHZ,
476                              tx_chains, rx_chains);
477
478         sband = &data->bands[NL80211_BAND_5GHZ];
479         sband->band = NL80211_BAND_5GHZ;
480         sband->bitrates = &iwl_cfg80211_rates[RATES_52_OFFS];
481         sband->n_bitrates = N_RATES_52;
482         n_used += iwl_init_sband_channels(data, sband, n_channels,
483                                           NL80211_BAND_5GHZ);
484         iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, NL80211_BAND_5GHZ,
485                              tx_chains, rx_chains);
486         if (data->sku_cap_11ac_enable && !iwlwifi_mod_params.disable_11ac)
487                 iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap,
488                                       tx_chains, rx_chains);
489
490         if (n_channels != n_used)
491                 IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n",
492                             n_used, n_channels);
493 }
494 IWL_EXPORT_SYMBOL(iwl_init_sbands);
495
496 static int iwl_get_sku(const struct iwl_cfg *cfg, const __le16 *nvm_sw,
497                        const __le16 *phy_sku)
498 {
499         if (cfg->nvm_type != IWL_NVM_EXT)
500                 return le16_to_cpup(nvm_sw + SKU);
501
502         return le32_to_cpup((__le32 *)(phy_sku + SKU_FAMILY_8000));
503 }
504
505 static int iwl_get_nvm_version(const struct iwl_cfg *cfg, const __le16 *nvm_sw)
506 {
507         if (cfg->nvm_type != IWL_NVM_EXT)
508                 return le16_to_cpup(nvm_sw + NVM_VERSION);
509         else
510                 return le32_to_cpup((__le32 *)(nvm_sw +
511                                                NVM_VERSION_EXT_NVM));
512 }
513
514 static int iwl_get_radio_cfg(const struct iwl_cfg *cfg, const __le16 *nvm_sw,
515                              const __le16 *phy_sku)
516 {
517         if (cfg->nvm_type != IWL_NVM_EXT)
518                 return le16_to_cpup(nvm_sw + RADIO_CFG);
519
520         return le32_to_cpup((__le32 *)(phy_sku + RADIO_CFG_FAMILY_EXT_NVM));
521
522 }
523
524 static int iwl_get_n_hw_addrs(const struct iwl_cfg *cfg, const __le16 *nvm_sw)
525 {
526         int n_hw_addr;
527
528         if (cfg->nvm_type != IWL_NVM_EXT)
529                 return le16_to_cpup(nvm_sw + N_HW_ADDRS);
530
531         n_hw_addr = le32_to_cpup((__le32 *)(nvm_sw + N_HW_ADDRS_FAMILY_8000));
532
533         return n_hw_addr & N_HW_ADDR_MASK;
534 }
535
536 static void iwl_set_radio_cfg(const struct iwl_cfg *cfg,
537                               struct iwl_nvm_data *data,
538                               u32 radio_cfg)
539 {
540         if (cfg->nvm_type != IWL_NVM_EXT) {
541                 data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK(radio_cfg);
542                 data->radio_cfg_step = NVM_RF_CFG_STEP_MSK(radio_cfg);
543                 data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK(radio_cfg);
544                 data->radio_cfg_pnum = NVM_RF_CFG_PNUM_MSK(radio_cfg);
545                 return;
546         }
547
548         /* set the radio configuration for family 8000 */
549         data->radio_cfg_type = EXT_NVM_RF_CFG_TYPE_MSK(radio_cfg);
550         data->radio_cfg_step = EXT_NVM_RF_CFG_STEP_MSK(radio_cfg);
551         data->radio_cfg_dash = EXT_NVM_RF_CFG_DASH_MSK(radio_cfg);
552         data->radio_cfg_pnum = EXT_NVM_RF_CFG_FLAVOR_MSK(radio_cfg);
553         data->valid_tx_ant = EXT_NVM_RF_CFG_TX_ANT_MSK(radio_cfg);
554         data->valid_rx_ant = EXT_NVM_RF_CFG_RX_ANT_MSK(radio_cfg);
555 }
556
557 static void iwl_flip_hw_address(__le32 mac_addr0, __le32 mac_addr1, u8 *dest)
558 {
559         const u8 *hw_addr;
560
561         hw_addr = (const u8 *)&mac_addr0;
562         dest[0] = hw_addr[3];
563         dest[1] = hw_addr[2];
564         dest[2] = hw_addr[1];
565         dest[3] = hw_addr[0];
566
567         hw_addr = (const u8 *)&mac_addr1;
568         dest[4] = hw_addr[1];
569         dest[5] = hw_addr[0];
570 }
571
572 void iwl_set_hw_address_from_csr(struct iwl_trans *trans,
573                                  struct iwl_nvm_data *data)
574 {
575         __le32 mac_addr0 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR0_STRAP));
576         __le32 mac_addr1 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR1_STRAP));
577
578         iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
579         /*
580          * If the OEM fused a valid address, use it instead of the one in the
581          * OTP
582          */
583         if (is_valid_ether_addr(data->hw_addr))
584                 return;
585
586         mac_addr0 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR0_OTP));
587         mac_addr1 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR1_OTP));
588
589         iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
590 }
591 IWL_EXPORT_SYMBOL(iwl_set_hw_address_from_csr);
592
593 static void iwl_set_hw_address_family_8000(struct iwl_trans *trans,
594                                            const struct iwl_cfg *cfg,
595                                            struct iwl_nvm_data *data,
596                                            const __le16 *mac_override,
597                                            const __be16 *nvm_hw)
598 {
599         const u8 *hw_addr;
600
601         if (mac_override) {
602                 static const u8 reserved_mac[] = {
603                         0x02, 0xcc, 0xaa, 0xff, 0xee, 0x00
604                 };
605
606                 hw_addr = (const u8 *)(mac_override +
607                                  MAC_ADDRESS_OVERRIDE_EXT_NVM);
608
609                 /*
610                  * Store the MAC address from MAO section.
611                  * No byte swapping is required in MAO section
612                  */
613                 memcpy(data->hw_addr, hw_addr, ETH_ALEN);
614
615                 /*
616                  * Force the use of the OTP MAC address in case of reserved MAC
617                  * address in the NVM, or if address is given but invalid.
618                  */
619                 if (is_valid_ether_addr(data->hw_addr) &&
620                     memcmp(reserved_mac, hw_addr, ETH_ALEN) != 0)
621                         return;
622
623                 IWL_ERR(trans,
624                         "mac address from nvm override section is not valid\n");
625         }
626
627         if (nvm_hw) {
628                 /* read the mac address from WFMP registers */
629                 __le32 mac_addr0 = cpu_to_le32(iwl_trans_read_prph(trans,
630                                                 WFMP_MAC_ADDR_0));
631                 __le32 mac_addr1 = cpu_to_le32(iwl_trans_read_prph(trans,
632                                                 WFMP_MAC_ADDR_1));
633
634                 iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
635
636                 return;
637         }
638
639         IWL_ERR(trans, "mac address is not found\n");
640 }
641
642 static int iwl_set_hw_address(struct iwl_trans *trans,
643                               const struct iwl_cfg *cfg,
644                               struct iwl_nvm_data *data, const __be16 *nvm_hw,
645                               const __le16 *mac_override)
646 {
647         if (cfg->mac_addr_from_csr) {
648                 iwl_set_hw_address_from_csr(trans, data);
649         } else if (cfg->nvm_type != IWL_NVM_EXT) {
650                 const u8 *hw_addr = (const u8 *)(nvm_hw + HW_ADDR);
651
652                 /* The byte order is little endian 16 bit, meaning 214365 */
653                 data->hw_addr[0] = hw_addr[1];
654                 data->hw_addr[1] = hw_addr[0];
655                 data->hw_addr[2] = hw_addr[3];
656                 data->hw_addr[3] = hw_addr[2];
657                 data->hw_addr[4] = hw_addr[5];
658                 data->hw_addr[5] = hw_addr[4];
659         } else {
660                 iwl_set_hw_address_family_8000(trans, cfg, data,
661                                                mac_override, nvm_hw);
662         }
663
664         if (!is_valid_ether_addr(data->hw_addr)) {
665                 IWL_ERR(trans, "no valid mac address was found\n");
666                 return -EINVAL;
667         }
668
669         IWL_INFO(trans, "base HW address: %pM\n", data->hw_addr);
670
671         return 0;
672 }
673
674 static bool
675 iwl_nvm_no_wide_in_5ghz(struct device *dev, const struct iwl_cfg *cfg,
676                         const __be16 *nvm_hw)
677 {
678         /*
679          * Workaround a bug in Indonesia SKUs where the regulatory in
680          * some 7000-family OTPs erroneously allow wide channels in
681          * 5GHz.  To check for Indonesia, we take the SKU value from
682          * bits 1-4 in the subsystem ID and check if it is either 5 or
683          * 9.  In those cases, we need to force-disable wide channels
684          * in 5GHz otherwise the FW will throw a sysassert when we try
685          * to use them.
686          */
687         if (cfg->device_family == IWL_DEVICE_FAMILY_7000) {
688                 /*
689                  * Unlike the other sections in the NVM, the hw
690                  * section uses big-endian.
691                  */
692                 u16 subsystem_id = be16_to_cpup(nvm_hw + SUBSYSTEM_ID);
693                 u8 sku = (subsystem_id & 0x1e) >> 1;
694
695                 if (sku == 5 || sku == 9) {
696                         IWL_DEBUG_EEPROM(dev,
697                                          "disabling wide channels in 5GHz (0x%0x %d)\n",
698                                          subsystem_id, sku);
699                         return true;
700                 }
701         }
702
703         return false;
704 }
705
706 struct iwl_nvm_data *
707 iwl_parse_nvm_data(struct iwl_trans *trans, const struct iwl_cfg *cfg,
708                    const __be16 *nvm_hw, const __le16 *nvm_sw,
709                    const __le16 *nvm_calib, const __le16 *regulatory,
710                    const __le16 *mac_override, const __le16 *phy_sku,
711                    u8 tx_chains, u8 rx_chains, bool lar_fw_supported)
712 {
713         struct device *dev = trans->dev;
714         struct iwl_nvm_data *data;
715         bool lar_enabled;
716         bool no_wide_in_5ghz = iwl_nvm_no_wide_in_5ghz(dev, cfg, nvm_hw);
717         u32 sku, radio_cfg;
718         u16 lar_config;
719         const __le16 *ch_section;
720
721         if (cfg->nvm_type != IWL_NVM_EXT)
722                 data = kzalloc(sizeof(*data) +
723                                sizeof(struct ieee80211_channel) *
724                                IWL_NVM_NUM_CHANNELS,
725                                GFP_KERNEL);
726         else
727                 data = kzalloc(sizeof(*data) +
728                                sizeof(struct ieee80211_channel) *
729                                IWL_NVM_NUM_CHANNELS_EXT,
730                                GFP_KERNEL);
731         if (!data)
732                 return NULL;
733
734         data->nvm_version = iwl_get_nvm_version(cfg, nvm_sw);
735
736         radio_cfg = iwl_get_radio_cfg(cfg, nvm_sw, phy_sku);
737         iwl_set_radio_cfg(cfg, data, radio_cfg);
738         if (data->valid_tx_ant)
739                 tx_chains &= data->valid_tx_ant;
740         if (data->valid_rx_ant)
741                 rx_chains &= data->valid_rx_ant;
742
743         sku = iwl_get_sku(cfg, nvm_sw, phy_sku);
744         data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ;
745         data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ;
746         data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE;
747         if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
748                 data->sku_cap_11n_enable = false;
749         data->sku_cap_11ac_enable = data->sku_cap_11n_enable &&
750                                     (sku & NVM_SKU_CAP_11AC_ENABLE);
751         data->sku_cap_mimo_disabled = sku & NVM_SKU_CAP_MIMO_DISABLE;
752
753         data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw);
754
755         if (cfg->nvm_type != IWL_NVM_EXT) {
756                 /* Checking for required sections */
757                 if (!nvm_calib) {
758                         IWL_ERR(trans,
759                                 "Can't parse empty Calib NVM sections\n");
760                         kfree(data);
761                         return NULL;
762                 }
763
764                 ch_section = cfg->nvm_type == IWL_NVM_SDP ?
765                              &regulatory[NVM_CHANNELS_SDP] :
766                              &nvm_sw[NVM_CHANNELS];
767
768                 /* in family 8000 Xtal calibration values moved to OTP */
769                 data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB);
770                 data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1);
771                 lar_enabled = true;
772         } else {
773                 u16 lar_offset = data->nvm_version < 0xE39 ?
774                                  NVM_LAR_OFFSET_OLD :
775                                  NVM_LAR_OFFSET;
776
777                 lar_config = le16_to_cpup(regulatory + lar_offset);
778                 data->lar_enabled = !!(lar_config &
779                                        NVM_LAR_ENABLED);
780                 lar_enabled = data->lar_enabled;
781                 ch_section = &regulatory[NVM_CHANNELS_EXTENDED];
782         }
783
784         /* If no valid mac address was found - bail out */
785         if (iwl_set_hw_address(trans, cfg, data, nvm_hw, mac_override)) {
786                 kfree(data);
787                 return NULL;
788         }
789
790         iwl_init_sbands(dev, cfg, data, ch_section, tx_chains, rx_chains,
791                         lar_fw_supported && lar_enabled, no_wide_in_5ghz);
792         data->calib_version = 255;
793
794         return data;
795 }
796 IWL_EXPORT_SYMBOL(iwl_parse_nvm_data);
797
798 static u32 iwl_nvm_get_regdom_bw_flags(const u8 *nvm_chan,
799                                        int ch_idx, u16 nvm_flags,
800                                        const struct iwl_cfg *cfg)
801 {
802         u32 flags = NL80211_RRF_NO_HT40;
803         u32 last_5ghz_ht = LAST_5GHZ_HT;
804
805         if (cfg->nvm_type == IWL_NVM_EXT)
806                 last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000;
807
808         if (ch_idx < NUM_2GHZ_CHANNELS &&
809             (nvm_flags & NVM_CHANNEL_40MHZ)) {
810                 if (nvm_chan[ch_idx] <= LAST_2GHZ_HT_PLUS)
811                         flags &= ~NL80211_RRF_NO_HT40PLUS;
812                 if (nvm_chan[ch_idx] >= FIRST_2GHZ_HT_MINUS)
813                         flags &= ~NL80211_RRF_NO_HT40MINUS;
814         } else if (nvm_chan[ch_idx] <= last_5ghz_ht &&
815                    (nvm_flags & NVM_CHANNEL_40MHZ)) {
816                 if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
817                         flags &= ~NL80211_RRF_NO_HT40PLUS;
818                 else
819                         flags &= ~NL80211_RRF_NO_HT40MINUS;
820         }
821
822         if (!(nvm_flags & NVM_CHANNEL_80MHZ))
823                 flags |= NL80211_RRF_NO_80MHZ;
824         if (!(nvm_flags & NVM_CHANNEL_160MHZ))
825                 flags |= NL80211_RRF_NO_160MHZ;
826
827         if (!(nvm_flags & NVM_CHANNEL_ACTIVE))
828                 flags |= NL80211_RRF_NO_IR;
829
830         if (nvm_flags & NVM_CHANNEL_RADAR)
831                 flags |= NL80211_RRF_DFS;
832
833         if (nvm_flags & NVM_CHANNEL_INDOOR_ONLY)
834                 flags |= NL80211_RRF_NO_OUTDOOR;
835
836         /* Set the GO concurrent flag only in case that NO_IR is set.
837          * Otherwise it is meaningless
838          */
839         if ((nvm_flags & NVM_CHANNEL_GO_CONCURRENT) &&
840             (flags & NL80211_RRF_NO_IR))
841                 flags |= NL80211_RRF_GO_CONCURRENT;
842
843         return flags;
844 }
845
846 struct regdb_ptrs {
847         struct ieee80211_wmm_rule *rule;
848         u32 token;
849 };
850
851 struct ieee80211_regdomain *
852 iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
853                        int num_of_ch, __le32 *channels, u16 fw_mcc,
854                        u16 geo_info)
855 {
856         int ch_idx;
857         u16 ch_flags;
858         u32 reg_rule_flags, prev_reg_rule_flags = 0;
859         const u8 *nvm_chan = cfg->nvm_type == IWL_NVM_EXT ?
860                              iwl_ext_nvm_channels : iwl_nvm_channels;
861         struct ieee80211_regdomain *regd, *copy_rd;
862         int size_of_regd, regd_to_copy, wmms_to_copy;
863         int size_of_wmms = 0;
864         struct ieee80211_reg_rule *rule;
865         struct ieee80211_wmm_rule *wmm_rule, *d_wmm, *s_wmm;
866         struct regdb_ptrs *regdb_ptrs;
867         enum nl80211_band band;
868         int center_freq, prev_center_freq = 0;
869         int valid_rules = 0, n_wmms = 0;
870         int i;
871         bool new_rule;
872         int max_num_ch = cfg->nvm_type == IWL_NVM_EXT ?
873                          IWL_NVM_NUM_CHANNELS_EXT : IWL_NVM_NUM_CHANNELS;
874
875         if (WARN_ON_ONCE(num_of_ch > NL80211_MAX_SUPP_REG_RULES))
876                 return ERR_PTR(-EINVAL);
877
878         if (WARN_ON(num_of_ch > max_num_ch))
879                 num_of_ch = max_num_ch;
880
881         IWL_DEBUG_DEV(dev, IWL_DL_LAR, "building regdom for %d channels\n",
882                       num_of_ch);
883
884         /* build a regdomain rule for every valid channel */
885         size_of_regd =
886                 sizeof(struct ieee80211_regdomain) +
887                 num_of_ch * sizeof(struct ieee80211_reg_rule);
888
889         if (geo_info & GEO_WMM_ETSI_5GHZ_INFO)
890                 size_of_wmms =
891                         num_of_ch * sizeof(struct ieee80211_wmm_rule);
892
893         regd = kzalloc(size_of_regd + size_of_wmms, GFP_KERNEL);
894         if (!regd)
895                 return ERR_PTR(-ENOMEM);
896
897         regdb_ptrs = kcalloc(num_of_ch, sizeof(*regdb_ptrs), GFP_KERNEL);
898         if (!regdb_ptrs) {
899                 copy_rd = ERR_PTR(-ENOMEM);
900                 goto out;
901         }
902
903         /* set alpha2 from FW. */
904         regd->alpha2[0] = fw_mcc >> 8;
905         regd->alpha2[1] = fw_mcc & 0xff;
906
907         wmm_rule = (struct ieee80211_wmm_rule *)((u8 *)regd + size_of_regd);
908
909         for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
910                 ch_flags = (u16)__le32_to_cpup(channels + ch_idx);
911                 band = (ch_idx < NUM_2GHZ_CHANNELS) ?
912                        NL80211_BAND_2GHZ : NL80211_BAND_5GHZ;
913                 center_freq = ieee80211_channel_to_frequency(nvm_chan[ch_idx],
914                                                              band);
915                 new_rule = false;
916
917                 if (!(ch_flags & NVM_CHANNEL_VALID)) {
918                         iwl_nvm_print_channel_flags(dev, IWL_DL_LAR,
919                                                     nvm_chan[ch_idx], ch_flags);
920                         continue;
921                 }
922
923                 reg_rule_flags = iwl_nvm_get_regdom_bw_flags(nvm_chan, ch_idx,
924                                                              ch_flags, cfg);
925
926                 /* we can't continue the same rule */
927                 if (ch_idx == 0 || prev_reg_rule_flags != reg_rule_flags ||
928                     center_freq - prev_center_freq > 20) {
929                         valid_rules++;
930                         new_rule = true;
931                 }
932
933                 rule = &regd->reg_rules[valid_rules - 1];
934
935                 if (new_rule)
936                         rule->freq_range.start_freq_khz =
937                                                 MHZ_TO_KHZ(center_freq - 10);
938
939                 rule->freq_range.end_freq_khz = MHZ_TO_KHZ(center_freq + 10);
940
941                 /* this doesn't matter - not used by FW */
942                 rule->power_rule.max_antenna_gain = DBI_TO_MBI(6);
943                 rule->power_rule.max_eirp =
944                         DBM_TO_MBM(IWL_DEFAULT_MAX_TX_POWER);
945
946                 rule->flags = reg_rule_flags;
947
948                 /* rely on auto-calculation to merge BW of contiguous chans */
949                 rule->flags |= NL80211_RRF_AUTO_BW;
950                 rule->freq_range.max_bandwidth_khz = 0;
951
952                 prev_center_freq = center_freq;
953                 prev_reg_rule_flags = reg_rule_flags;
954
955                 iwl_nvm_print_channel_flags(dev, IWL_DL_LAR,
956                                             nvm_chan[ch_idx], ch_flags);
957
958                 if (!(geo_info & GEO_WMM_ETSI_5GHZ_INFO) ||
959                     band == NL80211_BAND_2GHZ)
960                         continue;
961
962                 if (!reg_query_regdb_wmm(regd->alpha2, center_freq,
963                                          &regdb_ptrs[n_wmms].token, wmm_rule)) {
964                         /* Add only new rules */
965                         for (i = 0; i < n_wmms; i++) {
966                                 if (regdb_ptrs[i].token ==
967                                     regdb_ptrs[n_wmms].token) {
968                                         rule->wmm_rule = regdb_ptrs[i].rule;
969                                         break;
970                                 }
971                         }
972                         if (i == n_wmms) {
973                                 rule->wmm_rule = wmm_rule;
974                                 regdb_ptrs[n_wmms++].rule = wmm_rule;
975                                 wmm_rule++;
976                         }
977                 }
978         }
979
980         regd->n_reg_rules = valid_rules;
981         regd->n_wmm_rules = n_wmms;
982
983         /*
984          * Narrow down regdom for unused regulatory rules to prevent hole
985          * between reg rules to wmm rules.
986          */
987         regd_to_copy = sizeof(struct ieee80211_regdomain) +
988                 valid_rules * sizeof(struct ieee80211_reg_rule);
989
990         wmms_to_copy = sizeof(struct ieee80211_wmm_rule) * n_wmms;
991
992         copy_rd = kzalloc(regd_to_copy + wmms_to_copy, GFP_KERNEL);
993         if (!copy_rd) {
994                 copy_rd = ERR_PTR(-ENOMEM);
995                 goto out;
996         }
997
998         memcpy(copy_rd, regd, regd_to_copy);
999         memcpy((u8 *)copy_rd + regd_to_copy, (u8 *)regd + size_of_regd,
1000                wmms_to_copy);
1001
1002         d_wmm = (struct ieee80211_wmm_rule *)((u8 *)copy_rd + regd_to_copy);
1003         s_wmm = (struct ieee80211_wmm_rule *)((u8 *)regd + size_of_regd);
1004
1005         for (i = 0; i < regd->n_reg_rules; i++) {
1006                 if (!regd->reg_rules[i].wmm_rule)
1007                         continue;
1008
1009                 copy_rd->reg_rules[i].wmm_rule = d_wmm +
1010                         (regd->reg_rules[i].wmm_rule - s_wmm) /
1011                         sizeof(struct ieee80211_wmm_rule);
1012         }
1013
1014 out:
1015         kfree(regdb_ptrs);
1016         kfree(regd);
1017         return copy_rd;
1018 }
1019 IWL_EXPORT_SYMBOL(iwl_parse_nvm_mcc_info);