• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 - 2013 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 - 2013 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 */
70 enum 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) */
88 enum 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),
92 };
93 
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 */
101 
102 /*
103  * These are the channel numbers in the order that they are stored in the NVM
104  */
105 static const u8 iwl_nvm_channels[] = {
106 	/* 2.4 GHz */
107 	1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
108 	/* 5 GHz */
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
112 };
113 
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
119 
120 
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, },
138 };
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)
143 
144 /**
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 (?)
155  */
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),
166 };
167 
168 #define CHECK_AND_PRINT_I(x)	\
169 	((ch_flags & NVM_CHANNEL_##x) ? # x " " : "")
170 
iwl_init_channel_map(struct device * dev,const struct iwl_cfg * cfg,struct iwl_nvm_data * data,const __le16 * const nvm_ch_flags)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)
174 {
175 	int ch_idx;
176 	int n_channels = 0;
177 	struct ieee80211_channel *channel;
178 	u16 ch_flags;
179 	bool is_5ghz;
180 
181 	for (ch_idx = 0; ch_idx < IWL_NUM_CHANNELS; ch_idx++) {
182 		ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
183 		if (!(ch_flags & NVM_CHANNEL_VALID)) {
184 			IWL_DEBUG_EEPROM(dev,
185 					 "Ch. %d Flags %x [%sGHz] - No traffic\n",
186 					 iwl_nvm_channels[ch_idx],
187 					 ch_flags,
188 					 (ch_idx >= NUM_2GHZ_CHANNELS) ?
189 					 "5.2" : "2.4");
190 			continue;
191 		}
192 
193 		channel = &data->channels[n_channels];
194 		n_channels++;
195 
196 		channel->hw_value = iwl_nvm_channels[ch_idx];
197 		channel->band = (ch_idx < NUM_2GHZ_CHANNELS) ?
198 				IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
199 		channel->center_freq =
200 			ieee80211_channel_to_frequency(
201 				channel->hw_value, channel->band);
202 
203 		/* TODO: Need to be dependent to the NVM */
204 		channel->flags = IEEE80211_CHAN_NO_HT40;
205 		if (ch_idx < NUM_2GHZ_CHANNELS &&
206 		    (ch_flags & NVM_CHANNEL_40MHZ)) {
207 			if (iwl_nvm_channels[ch_idx] <= LAST_2GHZ_HT_PLUS)
208 				channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
209 			if (iwl_nvm_channels[ch_idx] >= FIRST_2GHZ_HT_MINUS)
210 				channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
211 		} else if (iwl_nvm_channels[ch_idx] <= LAST_5GHZ_HT &&
212 			   (ch_flags & NVM_CHANNEL_40MHZ)) {
213 			if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
214 				channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
215 			else
216 				channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
217 		}
218 		if (!(ch_flags & NVM_CHANNEL_80MHZ))
219 			channel->flags |= IEEE80211_CHAN_NO_80MHZ;
220 		if (!(ch_flags & NVM_CHANNEL_160MHZ))
221 			channel->flags |= IEEE80211_CHAN_NO_160MHZ;
222 
223 		if (!(ch_flags & NVM_CHANNEL_IBSS))
224 			channel->flags |= IEEE80211_CHAN_NO_IBSS;
225 
226 		if (!(ch_flags & NVM_CHANNEL_ACTIVE))
227 			channel->flags |= IEEE80211_CHAN_PASSIVE_SCAN;
228 
229 		if (ch_flags & NVM_CHANNEL_RADAR)
230 			channel->flags |= IEEE80211_CHAN_RADAR;
231 
232 		/* Initialize regulatory-based run-time data */
233 
234 		/* TODO: read the real value from the NVM */
235 		channel->max_power = 0;
236 		is_5ghz = channel->band == IEEE80211_BAND_5GHZ;
237 		IWL_DEBUG_EEPROM(dev,
238 				 "Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported\n",
239 				 channel->hw_value,
240 				 is_5ghz ? "5.2" : "2.4",
241 				 CHECK_AND_PRINT_I(VALID),
242 				 CHECK_AND_PRINT_I(IBSS),
243 				 CHECK_AND_PRINT_I(ACTIVE),
244 				 CHECK_AND_PRINT_I(RADAR),
245 				 CHECK_AND_PRINT_I(WIDE),
246 				 CHECK_AND_PRINT_I(DFS),
247 				 ch_flags,
248 				 channel->max_power,
249 				 ((ch_flags & NVM_CHANNEL_IBSS) &&
250 				  !(ch_flags & NVM_CHANNEL_RADAR))
251 					? "" : "not ");
252 	}
253 
254 	return n_channels;
255 }
256 
iwl_init_vht_hw_capab(const struct iwl_cfg * cfg,struct iwl_nvm_data * data,struct ieee80211_sta_vht_cap * vht_cap)257 static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
258 				  struct iwl_nvm_data *data,
259 				  struct ieee80211_sta_vht_cap *vht_cap)
260 {
261 	/* For now, assume new devices with NVM are VHT capable */
262 
263 	vht_cap->vht_supported = true;
264 
265 	vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 |
266 		       IEEE80211_VHT_CAP_RXSTBC_1 |
267 		       IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
268 		       7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
269 
270 	if (iwlwifi_mod_params.amsdu_size_8K)
271 		vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
272 
273 	vht_cap->vht_mcs.rx_mcs_map =
274 		cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |
275 			    IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 |
276 			    IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 |
277 			    IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 |
278 			    IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 |
279 			    IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 |
280 			    IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
281 			    IEEE80211_VHT_MCS_NOT_SUPPORTED << 14);
282 
283 	if (data->valid_rx_ant == 1 || cfg->rx_with_siso_diversity) {
284 		vht_cap->cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
285 				IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
286 		/* this works because NOT_SUPPORTED == 3 */
287 		vht_cap->vht_mcs.rx_mcs_map |=
288 			cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << 2);
289 	}
290 
291 	vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map;
292 }
293 
iwl_init_sbands(struct device * dev,const struct iwl_cfg * cfg,struct iwl_nvm_data * data,const __le16 * nvm_sw)294 static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
295 			    struct iwl_nvm_data *data, const __le16 *nvm_sw)
296 {
297 	int n_channels = iwl_init_channel_map(dev, cfg, data,
298 			&nvm_sw[NVM_CHANNELS]);
299 	int n_used = 0;
300 	struct ieee80211_supported_band *sband;
301 
302 	sband = &data->bands[IEEE80211_BAND_2GHZ];
303 	sband->band = IEEE80211_BAND_2GHZ;
304 	sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS];
305 	sband->n_bitrates = N_RATES_24;
306 	n_used += iwl_init_sband_channels(data, sband, n_channels,
307 					  IEEE80211_BAND_2GHZ);
308 	iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ);
309 
310 	sband = &data->bands[IEEE80211_BAND_5GHZ];
311 	sband->band = IEEE80211_BAND_5GHZ;
312 	sband->bitrates = &iwl_cfg80211_rates[RATES_52_OFFS];
313 	sband->n_bitrates = N_RATES_52;
314 	n_used += iwl_init_sband_channels(data, sband, n_channels,
315 					  IEEE80211_BAND_5GHZ);
316 	iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ);
317 	iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap);
318 
319 	if (n_channels != n_used)
320 		IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n",
321 			    n_used, n_channels);
322 }
323 
324 struct iwl_nvm_data *
iwl_parse_nvm_data(struct device * dev,const struct iwl_cfg * cfg,const __le16 * nvm_hw,const __le16 * nvm_sw,const __le16 * nvm_calib)325 iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
326 		   const __le16 *nvm_hw, const __le16 *nvm_sw,
327 		   const __le16 *nvm_calib)
328 {
329 	struct iwl_nvm_data *data;
330 	u8 hw_addr[ETH_ALEN];
331 	u16 radio_cfg, sku;
332 
333 	data = kzalloc(sizeof(*data) +
334 		       sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS,
335 		       GFP_KERNEL);
336 	if (!data)
337 		return NULL;
338 
339 	data->nvm_version = le16_to_cpup(nvm_sw + NVM_VERSION);
340 
341 	radio_cfg = le16_to_cpup(nvm_sw + RADIO_CFG);
342 	data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK(radio_cfg);
343 	data->radio_cfg_step = NVM_RF_CFG_STEP_MSK(radio_cfg);
344 	data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK(radio_cfg);
345 	data->radio_cfg_pnum = NVM_RF_CFG_PNUM_MSK(radio_cfg);
346 	data->valid_tx_ant = NVM_RF_CFG_TX_ANT_MSK(radio_cfg);
347 	data->valid_rx_ant = NVM_RF_CFG_RX_ANT_MSK(radio_cfg);
348 
349 	sku = le16_to_cpup(nvm_sw + SKU);
350 	data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ;
351 	data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ;
352 	data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE;
353 	if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
354 		data->sku_cap_11n_enable = false;
355 
356 	/* check overrides (some devices have wrong NVM) */
357 	if (cfg->valid_tx_ant)
358 		data->valid_tx_ant = cfg->valid_tx_ant;
359 	if (cfg->valid_rx_ant)
360 		data->valid_rx_ant = cfg->valid_rx_ant;
361 
362 	if (!data->valid_tx_ant || !data->valid_rx_ant) {
363 		IWL_ERR_DEV(dev, "invalid antennas (0x%x, 0x%x)\n",
364 			    data->valid_tx_ant, data->valid_rx_ant);
365 		kfree(data);
366 		return NULL;
367 	}
368 
369 	data->n_hw_addrs = le16_to_cpup(nvm_sw + N_HW_ADDRS);
370 
371 	data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB);
372 	data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1);
373 
374 	/* The byte order is little endian 16 bit, meaning 214365 */
375 	memcpy(hw_addr, nvm_hw + HW_ADDR, ETH_ALEN);
376 	data->hw_addr[0] = hw_addr[1];
377 	data->hw_addr[1] = hw_addr[0];
378 	data->hw_addr[2] = hw_addr[3];
379 	data->hw_addr[3] = hw_addr[2];
380 	data->hw_addr[4] = hw_addr[5];
381 	data->hw_addr[5] = hw_addr[4];
382 
383 	iwl_init_sbands(dev, cfg, data, nvm_sw);
384 
385 	data->calib_version = 255;   /* TODO:
386 					this value will prevent some checks from
387 					failing, we need to check if this
388 					field is still needed, and if it does,
389 					where is it in the NVM*/
390 
391 	return data;
392 }
393 IWL_EXPORT_SYMBOL(iwl_parse_nvm_data);
394