iwlwifi: mvm: reset Thermal Throttling's SMPS request upon disassociation
[deliverable/linux.git] / drivers / net / wireless / iwlwifi / iwl-nvm-parse.c
CommitLineData
b1e1adfa
JB
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 *
51368bf7 8 * Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved.
b1e1adfa
JB
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
410dc5aa 25 * in the file called COPYING.
b1e1adfa
JB
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 *
51368bf7 33 * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
b1e1adfa
JB
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>
48e29340 65#include "iwl-drv.h"
b1e1adfa
JB
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
87/* SKU Capabilities (actual values from NVM definition) */
88enum nvm_sku_bits {
89 NVM_SKU_CAP_BAND_24GHZ = BIT(0),
90 NVM_SKU_CAP_BAND_52GHZ = BIT(1),
91 NVM_SKU_CAP_11N_ENABLE = BIT(2),
bfc824b0 92 NVM_SKU_CAP_11AC_ENABLE = BIT(3),
b1e1adfa
JB
93};
94
95/* radio config bits (actual values from NVM definition) */
96#define NVM_RF_CFG_DASH_MSK(x) (x & 0x3) /* bits 0-1 */
97#define NVM_RF_CFG_STEP_MSK(x) ((x >> 2) & 0x3) /* bits 2-3 */
98#define NVM_RF_CFG_TYPE_MSK(x) ((x >> 4) & 0x3) /* bits 4-5 */
99#define NVM_RF_CFG_PNUM_MSK(x) ((x >> 6) & 0x3) /* bits 6-7 */
100#define NVM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */
101#define NVM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */
102
103/*
104 * These are the channel numbers in the order that they are stored in the NVM
105 */
106static const u8 iwl_nvm_channels[] = {
107 /* 2.4 GHz */
108 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
109 /* 5 GHz */
110 36, 40, 44 , 48, 52, 56, 60, 64,
111 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
112 149, 153, 157, 161, 165
113};
114
115#define IWL_NUM_CHANNELS ARRAY_SIZE(iwl_nvm_channels)
116#define NUM_2GHZ_CHANNELS 14
117#define FIRST_2GHZ_HT_MINUS 5
118#define LAST_2GHZ_HT_PLUS 9
119#define LAST_5GHZ_HT 161
120
88f2fd73 121#define DEFAULT_MAX_TX_POWER 16
b1e1adfa
JB
122
123/* rate data (static) */
124static struct ieee80211_rate iwl_cfg80211_rates[] = {
125 { .bitrate = 1 * 10, .hw_value = 0, .hw_value_short = 0, },
126 { .bitrate = 2 * 10, .hw_value = 1, .hw_value_short = 1,
127 .flags = IEEE80211_RATE_SHORT_PREAMBLE, },
128 { .bitrate = 5.5 * 10, .hw_value = 2, .hw_value_short = 2,
129 .flags = IEEE80211_RATE_SHORT_PREAMBLE, },
130 { .bitrate = 11 * 10, .hw_value = 3, .hw_value_short = 3,
131 .flags = IEEE80211_RATE_SHORT_PREAMBLE, },
132 { .bitrate = 6 * 10, .hw_value = 4, .hw_value_short = 4, },
133 { .bitrate = 9 * 10, .hw_value = 5, .hw_value_short = 5, },
134 { .bitrate = 12 * 10, .hw_value = 6, .hw_value_short = 6, },
135 { .bitrate = 18 * 10, .hw_value = 7, .hw_value_short = 7, },
136 { .bitrate = 24 * 10, .hw_value = 8, .hw_value_short = 8, },
137 { .bitrate = 36 * 10, .hw_value = 9, .hw_value_short = 9, },
138 { .bitrate = 48 * 10, .hw_value = 10, .hw_value_short = 10, },
139 { .bitrate = 54 * 10, .hw_value = 11, .hw_value_short = 11, },
140};
141#define RATES_24_OFFS 0
142#define N_RATES_24 ARRAY_SIZE(iwl_cfg80211_rates)
143#define RATES_52_OFFS 4
144#define N_RATES_52 (N_RATES_24 - RATES_52_OFFS)
145
146/**
147 * enum iwl_nvm_channel_flags - channel flags in NVM
148 * @NVM_CHANNEL_VALID: channel is usable for this SKU/geo
149 * @NVM_CHANNEL_IBSS: usable as an IBSS channel
150 * @NVM_CHANNEL_ACTIVE: active scanning allowed
151 * @NVM_CHANNEL_RADAR: radar detection required
152 * @NVM_CHANNEL_DFS: dynamic freq selection candidate
153 * @NVM_CHANNEL_WIDE: 20 MHz channel okay (?)
154 * @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?)
33158fef
EL
155 * @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?)
156 * @NVM_CHANNEL_160MHZ: 160 MHz channel okay (?)
b1e1adfa
JB
157 */
158enum iwl_nvm_channel_flags {
159 NVM_CHANNEL_VALID = BIT(0),
160 NVM_CHANNEL_IBSS = BIT(1),
161 NVM_CHANNEL_ACTIVE = BIT(3),
162 NVM_CHANNEL_RADAR = BIT(4),
163 NVM_CHANNEL_DFS = BIT(7),
164 NVM_CHANNEL_WIDE = BIT(8),
165 NVM_CHANNEL_40MHZ = BIT(9),
33158fef
EL
166 NVM_CHANNEL_80MHZ = BIT(10),
167 NVM_CHANNEL_160MHZ = BIT(11),
b1e1adfa
JB
168};
169
170#define CHECK_AND_PRINT_I(x) \
171 ((ch_flags & NVM_CHANNEL_##x) ? # x " " : "")
172
173static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
174 struct iwl_nvm_data *data,
175 const __le16 * const nvm_ch_flags)
176{
177 int ch_idx;
178 int n_channels = 0;
179 struct ieee80211_channel *channel;
180 u16 ch_flags;
181 bool is_5ghz;
182
183 for (ch_idx = 0; ch_idx < IWL_NUM_CHANNELS; ch_idx++) {
184 ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
185 if (!(ch_flags & NVM_CHANNEL_VALID)) {
186 IWL_DEBUG_EEPROM(dev,
187 "Ch. %d Flags %x [%sGHz] - No traffic\n",
188 iwl_nvm_channels[ch_idx],
189 ch_flags,
190 (ch_idx >= NUM_2GHZ_CHANNELS) ?
191 "5.2" : "2.4");
192 continue;
193 }
194
195 channel = &data->channels[n_channels];
196 n_channels++;
197
198 channel->hw_value = iwl_nvm_channels[ch_idx];
199 channel->band = (ch_idx < NUM_2GHZ_CHANNELS) ?
200 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
201 channel->center_freq =
202 ieee80211_channel_to_frequency(
203 channel->hw_value, channel->band);
204
205 /* TODO: Need to be dependent to the NVM */
206 channel->flags = IEEE80211_CHAN_NO_HT40;
207 if (ch_idx < NUM_2GHZ_CHANNELS &&
208 (ch_flags & NVM_CHANNEL_40MHZ)) {
209 if (iwl_nvm_channels[ch_idx] <= LAST_2GHZ_HT_PLUS)
210 channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
211 if (iwl_nvm_channels[ch_idx] >= FIRST_2GHZ_HT_MINUS)
212 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
213 } else if (iwl_nvm_channels[ch_idx] <= LAST_5GHZ_HT &&
214 (ch_flags & NVM_CHANNEL_40MHZ)) {
215 if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
216 channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
217 else
218 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
219 }
33158fef
EL
220 if (!(ch_flags & NVM_CHANNEL_80MHZ))
221 channel->flags |= IEEE80211_CHAN_NO_80MHZ;
222 if (!(ch_flags & NVM_CHANNEL_160MHZ))
223 channel->flags |= IEEE80211_CHAN_NO_160MHZ;
b1e1adfa
JB
224
225 if (!(ch_flags & NVM_CHANNEL_IBSS))
8fe02e16 226 channel->flags |= IEEE80211_CHAN_NO_IR;
b1e1adfa
JB
227
228 if (!(ch_flags & NVM_CHANNEL_ACTIVE))
8fe02e16 229 channel->flags |= IEEE80211_CHAN_NO_IR;
b1e1adfa
JB
230
231 if (ch_flags & NVM_CHANNEL_RADAR)
232 channel->flags |= IEEE80211_CHAN_RADAR;
233
234 /* Initialize regulatory-based run-time data */
235
88f2fd73
MG
236 /*
237 * Default value - highest tx power value. max_power
238 * is not used in mvm, and is used for backwards compatibility
239 */
240 channel->max_power = DEFAULT_MAX_TX_POWER;
b1e1adfa
JB
241 is_5ghz = channel->band == IEEE80211_BAND_5GHZ;
242 IWL_DEBUG_EEPROM(dev,
243 "Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported\n",
244 channel->hw_value,
245 is_5ghz ? "5.2" : "2.4",
246 CHECK_AND_PRINT_I(VALID),
247 CHECK_AND_PRINT_I(IBSS),
248 CHECK_AND_PRINT_I(ACTIVE),
249 CHECK_AND_PRINT_I(RADAR),
250 CHECK_AND_PRINT_I(WIDE),
251 CHECK_AND_PRINT_I(DFS),
252 ch_flags,
253 channel->max_power,
254 ((ch_flags & NVM_CHANNEL_IBSS) &&
255 !(ch_flags & NVM_CHANNEL_RADAR))
256 ? "" : "not ");
257 }
258
259 return n_channels;
260}
261
33158fef
EL
262static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
263 struct iwl_nvm_data *data,
264 struct ieee80211_sta_vht_cap *vht_cap)
265{
5f7a6f9b
ES
266 int num_ants = num_of_ant(data->valid_rx_ant);
267 int bf_sts_cap = num_ants - 1;
48e6de61 268
33158fef
EL
269 vht_cap->vht_supported = true;
270
271 vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 |
272 IEEE80211_VHT_CAP_RXSTBC_1 |
273 IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
48e6de61 274 bf_sts_cap << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT |
33158fef
EL
275 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
276
5f7a6f9b
ES
277 if (num_ants > 1)
278 vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC;
279
33158fef
EL
280 if (iwlwifi_mod_params.amsdu_size_8K)
281 vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
282
283 vht_cap->vht_mcs.rx_mcs_map =
284 cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |
285 IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 |
286 IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 |
287 IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 |
288 IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 |
289 IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 |
290 IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
291 IEEE80211_VHT_MCS_NOT_SUPPORTED << 14);
292
65732208
ES
293 /* Max rate for Long GI NSS=2 80Mhz is 780Mbps */
294 vht_cap->vht_mcs.rx_highest = cpu_to_le16(780);
295
5f7a6f9b 296 if (num_ants == 1 ||
a7b8b2ca 297 cfg->rx_with_siso_diversity) {
33158fef
EL
298 vht_cap->cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
299 IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
300 /* this works because NOT_SUPPORTED == 3 */
301 vht_cap->vht_mcs.rx_mcs_map |=
302 cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << 2);
65732208
ES
303 /* Max rate for Long GI NSS=1 80Mhz is 390Mbps */
304 vht_cap->vht_mcs.rx_highest = cpu_to_le16(390);
33158fef
EL
305 }
306
307 vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map;
65732208 308 vht_cap->vht_mcs.tx_highest = vht_cap->vht_mcs.rx_highest;
33158fef
EL
309}
310
b1e1adfa 311static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
bfc824b0 312 struct iwl_nvm_data *data, const __le16 *nvm_sw,
9ce4fa72 313 bool enable_vht, u8 tx_chains, u8 rx_chains)
b1e1adfa
JB
314{
315 int n_channels = iwl_init_channel_map(dev, cfg, data,
316 &nvm_sw[NVM_CHANNELS]);
317 int n_used = 0;
318 struct ieee80211_supported_band *sband;
319
320 sband = &data->bands[IEEE80211_BAND_2GHZ];
321 sband->band = IEEE80211_BAND_2GHZ;
322 sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS];
323 sband->n_bitrates = N_RATES_24;
324 n_used += iwl_init_sband_channels(data, sband, n_channels,
325 IEEE80211_BAND_2GHZ);
9ce4fa72
EG
326 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ,
327 tx_chains, rx_chains);
b1e1adfa
JB
328
329 sband = &data->bands[IEEE80211_BAND_5GHZ];
330 sband->band = IEEE80211_BAND_5GHZ;
331 sband->bitrates = &iwl_cfg80211_rates[RATES_52_OFFS];
332 sband->n_bitrates = N_RATES_52;
333 n_used += iwl_init_sband_channels(data, sband, n_channels,
334 IEEE80211_BAND_5GHZ);
9ce4fa72
EG
335 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ,
336 tx_chains, rx_chains);
bfc824b0
JB
337 if (enable_vht)
338 iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap);
b1e1adfa
JB
339
340 if (n_channels != n_used)
341 IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n",
342 n_used, n_channels);
343}
344
345struct iwl_nvm_data *
346iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
347 const __le16 *nvm_hw, const __le16 *nvm_sw,
9ce4fa72 348 const __le16 *nvm_calib, u8 tx_chains, u8 rx_chains)
b1e1adfa
JB
349{
350 struct iwl_nvm_data *data;
351 u8 hw_addr[ETH_ALEN];
352 u16 radio_cfg, sku;
353
354 data = kzalloc(sizeof(*data) +
355 sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS,
356 GFP_KERNEL);
357 if (!data)
358 return NULL;
359
360 data->nvm_version = le16_to_cpup(nvm_sw + NVM_VERSION);
361
362 radio_cfg = le16_to_cpup(nvm_sw + RADIO_CFG);
363 data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK(radio_cfg);
364 data->radio_cfg_step = NVM_RF_CFG_STEP_MSK(radio_cfg);
365 data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK(radio_cfg);
366 data->radio_cfg_pnum = NVM_RF_CFG_PNUM_MSK(radio_cfg);
367 data->valid_tx_ant = NVM_RF_CFG_TX_ANT_MSK(radio_cfg);
368 data->valid_rx_ant = NVM_RF_CFG_RX_ANT_MSK(radio_cfg);
369
370 sku = le16_to_cpup(nvm_sw + SKU);
371 data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ;
372 data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ;
373 data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE;
374 if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
375 data->sku_cap_11n_enable = false;
376
377 /* check overrides (some devices have wrong NVM) */
378 if (cfg->valid_tx_ant)
379 data->valid_tx_ant = cfg->valid_tx_ant;
380 if (cfg->valid_rx_ant)
381 data->valid_rx_ant = cfg->valid_rx_ant;
382
383 if (!data->valid_tx_ant || !data->valid_rx_ant) {
384 IWL_ERR_DEV(dev, "invalid antennas (0x%x, 0x%x)\n",
385 data->valid_tx_ant, data->valid_rx_ant);
386 kfree(data);
387 return NULL;
388 }
389
390 data->n_hw_addrs = le16_to_cpup(nvm_sw + N_HW_ADDRS);
391
392 data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB);
393 data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1);
394
395 /* The byte order is little endian 16 bit, meaning 214365 */
396 memcpy(hw_addr, nvm_hw + HW_ADDR, ETH_ALEN);
397 data->hw_addr[0] = hw_addr[1];
398 data->hw_addr[1] = hw_addr[0];
399 data->hw_addr[2] = hw_addr[3];
400 data->hw_addr[3] = hw_addr[2];
401 data->hw_addr[4] = hw_addr[5];
402 data->hw_addr[5] = hw_addr[4];
403
9ce4fa72
EG
404 iwl_init_sbands(dev, cfg, data, nvm_sw, sku & NVM_SKU_CAP_11AC_ENABLE,
405 tx_chains, rx_chains);
b1e1adfa
JB
406
407 data->calib_version = 255; /* TODO:
408 this value will prevent some checks from
409 failing, we need to check if this
410 field is still needed, and if it does,
411 where is it in the NVM*/
412
413 return data;
414}
48e29340 415IWL_EXPORT_SYMBOL(iwl_parse_nvm_data);
This page took 0.163594 seconds and 5 git commands to generate.