1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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
70enum wkp_nvm_offsets {
71
72 HW_ADDR = 0x15,
73
74
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
83 NVM_CALIB_SECTION = 0x2B8,
84 XTAL_CALIB = 0x316 - NVM_CALIB_SECTION
85};
86
87enum family_8000_nvm_offsets {
88
89 HW_ADDR0_FAMILY_8000 = 0x12,
90 HW_ADDR1_FAMILY_8000 = 0x16,
91 MAC_ADDRESS_OVERRIDE_FAMILY_8000 = 1,
92
93
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
101 NVM_CHANNELS_FAMILY_8000 = 0,
102
103
104 NVM_CALIB_SECTION_FAMILY_8000 = 0x2B8,
105 XTAL_CALIB_FAMILY_8000 = 0x316 - NVM_CALIB_SECTION_FAMILY_8000
106};
107
108
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
118
119static const u8 iwl_nvm_channels[] = {
120
121 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
122
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
130 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
131
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
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
171
172
173
174
175
176
177
178
179
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
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
273
274
275
276
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
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
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
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
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
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
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