1 /******************************************************************************
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.
8 * Copyright(c) 2008 - 2013 Intel Corporation. All rights reserved.
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.
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.
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,
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
33 * Copyright(c) 2005 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
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
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.
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>
66 #include "iwl-modparams.h"
67 #include "iwl-nvm-parse.h"
69 /* NVM offsets (in words) definitions */
70 enum wkp_nvm_offsets {
71 /* NVM HW-Section offset (in words) definitions */
74 /* NVM SW-Section offset (in words) definitions */
75 NVM_SW_SECTION = 0x1C0,
80 NVM_CHANNELS = 0x1E0 - NVM_SW_SECTION,
82 /* NVM calibration section offset (in words) definitions */
83 NVM_CALIB_SECTION = 0x2B8,
84 XTAL_CALIB = 0x316 - NVM_CALIB_SECTION
87 /* SKU Capabilities (actual values from NVM definition) */
89 NVM_SKU_CAP_BAND_24GHZ = BIT(0),
90 NVM_SKU_CAP_BAND_52GHZ = BIT(1),
91 NVM_SKU_CAP_11N_ENABLE = BIT(2),
94 /* radio config bits (actual values from NVM definition) */
95 #define NVM_RF_CFG_DASH_MSK(x) (x & 0x3) /* bits 0-1 */
96 #define NVM_RF_CFG_STEP_MSK(x) ((x >> 2) & 0x3) /* bits 2-3 */
97 #define NVM_RF_CFG_TYPE_MSK(x) ((x >> 4) & 0x3) /* bits 4-5 */
98 #define NVM_RF_CFG_PNUM_MSK(x) ((x >> 6) & 0x3) /* bits 6-7 */
99 #define NVM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */
100 #define NVM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */
103 * These are the channel numbers in the order that they are stored in the NVM
105 static const u8 iwl_nvm_channels[] = {
107 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
109 36, 40, 44 , 48, 52, 56, 60, 64,
110 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
111 149, 153, 157, 161, 165
114 #define IWL_NUM_CHANNELS ARRAY_SIZE(iwl_nvm_channels)
115 #define NUM_2GHZ_CHANNELS 14
116 #define FIRST_2GHZ_HT_MINUS 5
117 #define LAST_2GHZ_HT_PLUS 9
118 #define LAST_5GHZ_HT 161
121 /* rate data (static) */
122 static struct ieee80211_rate iwl_cfg80211_rates[] = {
123 { .bitrate = 1 * 10, .hw_value = 0, .hw_value_short = 0, },
124 { .bitrate = 2 * 10, .hw_value = 1, .hw_value_short = 1,
125 .flags = IEEE80211_RATE_SHORT_PREAMBLE, },
126 { .bitrate = 5.5 * 10, .hw_value = 2, .hw_value_short = 2,
127 .flags = IEEE80211_RATE_SHORT_PREAMBLE, },
128 { .bitrate = 11 * 10, .hw_value = 3, .hw_value_short = 3,
129 .flags = IEEE80211_RATE_SHORT_PREAMBLE, },
130 { .bitrate = 6 * 10, .hw_value = 4, .hw_value_short = 4, },
131 { .bitrate = 9 * 10, .hw_value = 5, .hw_value_short = 5, },
132 { .bitrate = 12 * 10, .hw_value = 6, .hw_value_short = 6, },
133 { .bitrate = 18 * 10, .hw_value = 7, .hw_value_short = 7, },
134 { .bitrate = 24 * 10, .hw_value = 8, .hw_value_short = 8, },
135 { .bitrate = 36 * 10, .hw_value = 9, .hw_value_short = 9, },
136 { .bitrate = 48 * 10, .hw_value = 10, .hw_value_short = 10, },
137 { .bitrate = 54 * 10, .hw_value = 11, .hw_value_short = 11, },
139 #define RATES_24_OFFS 0
140 #define N_RATES_24 ARRAY_SIZE(iwl_cfg80211_rates)
141 #define RATES_52_OFFS 4
142 #define N_RATES_52 (N_RATES_24 - RATES_52_OFFS)
145 * enum iwl_nvm_channel_flags - channel flags in NVM
146 * @NVM_CHANNEL_VALID: channel is usable for this SKU/geo
147 * @NVM_CHANNEL_IBSS: usable as an IBSS channel
148 * @NVM_CHANNEL_ACTIVE: active scanning allowed
149 * @NVM_CHANNEL_RADAR: radar detection required
150 * @NVM_CHANNEL_DFS: dynamic freq selection candidate
151 * @NVM_CHANNEL_WIDE: 20 MHz channel okay (?)
152 * @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?)
153 * @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?)
154 * @NVM_CHANNEL_160MHZ: 160 MHz channel okay (?)
156 enum iwl_nvm_channel_flags {
157 NVM_CHANNEL_VALID = BIT(0),
158 NVM_CHANNEL_IBSS = BIT(1),
159 NVM_CHANNEL_ACTIVE = BIT(3),
160 NVM_CHANNEL_RADAR = BIT(4),
161 NVM_CHANNEL_DFS = BIT(7),
162 NVM_CHANNEL_WIDE = BIT(8),
163 NVM_CHANNEL_40MHZ = BIT(9),
164 NVM_CHANNEL_80MHZ = BIT(10),
165 NVM_CHANNEL_160MHZ = BIT(11),
168 #define CHECK_AND_PRINT_I(x) \
169 ((ch_flags & NVM_CHANNEL_##x) ? # x " " : "")
171 static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
172 struct iwl_nvm_data *data,
173 const __le16 * const nvm_ch_flags)
177 struct ieee80211_channel *channel;
181 for (ch_idx = 0; ch_idx < IWL_NUM_CHANNELS; ch_idx++) {
182 ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
184 if (ch_idx >= NUM_2GHZ_CHANNELS &&
185 !data->sku_cap_band_52GHz_enable)
186 ch_flags &= ~NVM_CHANNEL_VALID;
188 if (!(ch_flags & NVM_CHANNEL_VALID)) {
189 IWL_DEBUG_EEPROM(dev,
190 "Ch. %d Flags %x [%sGHz] - No traffic\n",
191 iwl_nvm_channels[ch_idx],
193 (ch_idx >= NUM_2GHZ_CHANNELS) ?
198 channel = &data->channels[n_channels];
201 channel->hw_value = iwl_nvm_channels[ch_idx];
202 channel->band = (ch_idx < NUM_2GHZ_CHANNELS) ?
203 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
204 channel->center_freq =
205 ieee80211_channel_to_frequency(
206 channel->hw_value, channel->band);
208 /* TODO: Need to be dependent to the NVM */
209 channel->flags = IEEE80211_CHAN_NO_HT40;
210 if (ch_idx < NUM_2GHZ_CHANNELS &&
211 (ch_flags & NVM_CHANNEL_40MHZ)) {
212 if (iwl_nvm_channels[ch_idx] <= LAST_2GHZ_HT_PLUS)
213 channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
214 if (iwl_nvm_channels[ch_idx] >= FIRST_2GHZ_HT_MINUS)
215 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
216 } else if (iwl_nvm_channels[ch_idx] <= LAST_5GHZ_HT &&
217 (ch_flags & NVM_CHANNEL_40MHZ)) {
218 if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
219 channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
221 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
223 if (!(ch_flags & NVM_CHANNEL_80MHZ))
224 channel->flags |= IEEE80211_CHAN_NO_80MHZ;
225 if (!(ch_flags & NVM_CHANNEL_160MHZ))
226 channel->flags |= IEEE80211_CHAN_NO_160MHZ;
228 if (!(ch_flags & NVM_CHANNEL_IBSS))
229 channel->flags |= IEEE80211_CHAN_NO_IBSS;
231 if (!(ch_flags & NVM_CHANNEL_ACTIVE))
232 channel->flags |= IEEE80211_CHAN_PASSIVE_SCAN;
234 if (ch_flags & NVM_CHANNEL_RADAR)
235 channel->flags |= IEEE80211_CHAN_RADAR;
237 /* Initialize regulatory-based run-time data */
239 /* TODO: read the real value from the NVM */
240 channel->max_power = 0;
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",
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),
254 ((ch_flags & NVM_CHANNEL_IBSS) &&
255 !(ch_flags & NVM_CHANNEL_RADAR))
262 static 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)
266 /* For now, assume new devices with NVM are VHT capable */
268 vht_cap->vht_supported = true;
270 vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 |
271 IEEE80211_VHT_CAP_RXSTBC_1 |
272 IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
273 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
275 if (iwlwifi_mod_params.amsdu_size_8K)
276 vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
278 vht_cap->vht_mcs.rx_mcs_map =
279 cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |
280 IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 |
281 IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 |
282 IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 |
283 IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 |
284 IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 |
285 IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
286 IEEE80211_VHT_MCS_NOT_SUPPORTED << 14);
288 if (data->valid_rx_ant == 1 || cfg->rx_with_siso_diversity) {
289 vht_cap->cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
290 IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
291 /* this works because NOT_SUPPORTED == 3 */
292 vht_cap->vht_mcs.rx_mcs_map |=
293 cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << 2);
296 vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map;
299 static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
300 struct iwl_nvm_data *data, const __le16 *nvm_sw)
302 int n_channels = iwl_init_channel_map(dev, cfg, data,
303 &nvm_sw[NVM_CHANNELS]);
305 struct ieee80211_supported_band *sband;
307 sband = &data->bands[IEEE80211_BAND_2GHZ];
308 sband->band = IEEE80211_BAND_2GHZ;
309 sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS];
310 sband->n_bitrates = N_RATES_24;
311 n_used += iwl_init_sband_channels(data, sband, n_channels,
312 IEEE80211_BAND_2GHZ);
313 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ);
315 sband = &data->bands[IEEE80211_BAND_5GHZ];
316 sband->band = IEEE80211_BAND_5GHZ;
317 sband->bitrates = &iwl_cfg80211_rates[RATES_52_OFFS];
318 sband->n_bitrates = N_RATES_52;
319 n_used += iwl_init_sband_channels(data, sband, n_channels,
320 IEEE80211_BAND_5GHZ);
321 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ);
322 iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap);
324 if (n_channels != n_used)
325 IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n",
329 struct iwl_nvm_data *
330 iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
331 const __le16 *nvm_hw, const __le16 *nvm_sw,
332 const __le16 *nvm_calib)
334 struct iwl_nvm_data *data;
335 u8 hw_addr[ETH_ALEN];
338 data = kzalloc(sizeof(*data) +
339 sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS,
344 data->nvm_version = le16_to_cpup(nvm_sw + NVM_VERSION);
346 radio_cfg = le16_to_cpup(nvm_sw + RADIO_CFG);
347 data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK(radio_cfg);
348 data->radio_cfg_step = NVM_RF_CFG_STEP_MSK(radio_cfg);
349 data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK(radio_cfg);
350 data->radio_cfg_pnum = NVM_RF_CFG_PNUM_MSK(radio_cfg);
351 data->valid_tx_ant = NVM_RF_CFG_TX_ANT_MSK(radio_cfg);
352 data->valid_rx_ant = NVM_RF_CFG_RX_ANT_MSK(radio_cfg);
354 sku = le16_to_cpup(nvm_sw + SKU);
355 data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ;
356 data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ;
357 data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE;
358 if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
359 data->sku_cap_11n_enable = false;
361 /* check overrides (some devices have wrong NVM) */
362 if (cfg->valid_tx_ant)
363 data->valid_tx_ant = cfg->valid_tx_ant;
364 if (cfg->valid_rx_ant)
365 data->valid_rx_ant = cfg->valid_rx_ant;
367 if (!data->valid_tx_ant || !data->valid_rx_ant) {
368 IWL_ERR_DEV(dev, "invalid antennas (0x%x, 0x%x)\n",
369 data->valid_tx_ant, data->valid_rx_ant);
374 data->n_hw_addrs = le16_to_cpup(nvm_sw + N_HW_ADDRS);
376 data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB);
377 data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1);
379 /* The byte order is little endian 16 bit, meaning 214365 */
380 memcpy(hw_addr, nvm_hw + HW_ADDR, ETH_ALEN);
381 data->hw_addr[0] = hw_addr[1];
382 data->hw_addr[1] = hw_addr[0];
383 data->hw_addr[2] = hw_addr[3];
384 data->hw_addr[3] = hw_addr[2];
385 data->hw_addr[4] = hw_addr[5];
386 data->hw_addr[5] = hw_addr[4];
388 iwl_init_sbands(dev, cfg, data, nvm_sw);
390 data->calib_version = 255; /* TODO:
391 this value will prevent some checks from
392 failing, we need to check if this
393 field is still needed, and if it does,
394 where is it in the NVM*/
398 IWL_EXPORT_SYMBOL(iwl_parse_nvm_data);