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 LICENSE.GPL.
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>
65 #include "iwl-modparams.h"
66 #include "iwl-nvm-parse.h"
68 /* NVM offsets (in words) definitions */
69 enum wkp_nvm_offsets
{
70 /* NVM HW-Section offset (in words) definitions */
73 /* NVM SW-Section offset (in words) definitions */
74 NVM_SW_SECTION
= 0x1C0,
79 NVM_CHANNELS
= 0x1E0 - NVM_SW_SECTION
,
81 /* NVM calibration section offset (in words) definitions */
82 NVM_CALIB_SECTION
= 0x2B8,
83 XTAL_CALIB
= 0x316 - NVM_CALIB_SECTION
86 /* SKU Capabilities (actual values from NVM definition) */
88 NVM_SKU_CAP_BAND_24GHZ
= BIT(0),
89 NVM_SKU_CAP_BAND_52GHZ
= BIT(1),
90 NVM_SKU_CAP_11N_ENABLE
= BIT(2),
93 /* radio config bits (actual values from NVM definition) */
94 #define NVM_RF_CFG_DASH_MSK(x) (x & 0x3) /* bits 0-1 */
95 #define NVM_RF_CFG_STEP_MSK(x) ((x >> 2) & 0x3) /* bits 2-3 */
96 #define NVM_RF_CFG_TYPE_MSK(x) ((x >> 4) & 0x3) /* bits 4-5 */
97 #define NVM_RF_CFG_PNUM_MSK(x) ((x >> 6) & 0x3) /* bits 6-7 */
98 #define NVM_RF_CFG_TX_ANT_MSK(x) ((x >> 8) & 0xF) /* bits 8-11 */
99 #define NVM_RF_CFG_RX_ANT_MSK(x) ((x >> 12) & 0xF) /* bits 12-15 */
102 * These are the channel numbers in the order that they are stored in the NVM
104 static const u8 iwl_nvm_channels
[] = {
106 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
108 36, 40, 44 , 48, 52, 56, 60, 64,
109 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144,
110 149, 153, 157, 161, 165
113 #define IWL_NUM_CHANNELS ARRAY_SIZE(iwl_nvm_channels)
114 #define NUM_2GHZ_CHANNELS 14
115 #define FIRST_2GHZ_HT_MINUS 5
116 #define LAST_2GHZ_HT_PLUS 9
117 #define LAST_5GHZ_HT 161
120 /* rate data (static) */
121 static struct ieee80211_rate iwl_cfg80211_rates
[] = {
122 { .bitrate
= 1 * 10, .hw_value
= 0, .hw_value_short
= 0, },
123 { .bitrate
= 2 * 10, .hw_value
= 1, .hw_value_short
= 1,
124 .flags
= IEEE80211_RATE_SHORT_PREAMBLE
, },
125 { .bitrate
= 5.5 * 10, .hw_value
= 2, .hw_value_short
= 2,
126 .flags
= IEEE80211_RATE_SHORT_PREAMBLE
, },
127 { .bitrate
= 11 * 10, .hw_value
= 3, .hw_value_short
= 3,
128 .flags
= IEEE80211_RATE_SHORT_PREAMBLE
, },
129 { .bitrate
= 6 * 10, .hw_value
= 4, .hw_value_short
= 4, },
130 { .bitrate
= 9 * 10, .hw_value
= 5, .hw_value_short
= 5, },
131 { .bitrate
= 12 * 10, .hw_value
= 6, .hw_value_short
= 6, },
132 { .bitrate
= 18 * 10, .hw_value
= 7, .hw_value_short
= 7, },
133 { .bitrate
= 24 * 10, .hw_value
= 8, .hw_value_short
= 8, },
134 { .bitrate
= 36 * 10, .hw_value
= 9, .hw_value_short
= 9, },
135 { .bitrate
= 48 * 10, .hw_value
= 10, .hw_value_short
= 10, },
136 { .bitrate
= 54 * 10, .hw_value
= 11, .hw_value_short
= 11, },
138 #define RATES_24_OFFS 0
139 #define N_RATES_24 ARRAY_SIZE(iwl_cfg80211_rates)
140 #define RATES_52_OFFS 4
141 #define N_RATES_52 (N_RATES_24 - RATES_52_OFFS)
144 * enum iwl_nvm_channel_flags - channel flags in NVM
145 * @NVM_CHANNEL_VALID: channel is usable for this SKU/geo
146 * @NVM_CHANNEL_IBSS: usable as an IBSS channel
147 * @NVM_CHANNEL_ACTIVE: active scanning allowed
148 * @NVM_CHANNEL_RADAR: radar detection required
149 * @NVM_CHANNEL_DFS: dynamic freq selection candidate
150 * @NVM_CHANNEL_WIDE: 20 MHz channel okay (?)
151 * @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?)
153 enum iwl_nvm_channel_flags
{
154 NVM_CHANNEL_VALID
= BIT(0),
155 NVM_CHANNEL_IBSS
= BIT(1),
156 NVM_CHANNEL_ACTIVE
= BIT(3),
157 NVM_CHANNEL_RADAR
= BIT(4),
158 NVM_CHANNEL_DFS
= BIT(7),
159 NVM_CHANNEL_WIDE
= BIT(8),
160 NVM_CHANNEL_40MHZ
= BIT(9),
163 #define CHECK_AND_PRINT_I(x) \
164 ((ch_flags & NVM_CHANNEL_##x) ? # x " " : "")
166 static int iwl_init_channel_map(struct device
*dev
, const struct iwl_cfg
*cfg
,
167 struct iwl_nvm_data
*data
,
168 const __le16
* const nvm_ch_flags
)
172 struct ieee80211_channel
*channel
;
176 for (ch_idx
= 0; ch_idx
< IWL_NUM_CHANNELS
; ch_idx
++) {
177 ch_flags
= __le16_to_cpup(nvm_ch_flags
+ ch_idx
);
178 if (!(ch_flags
& NVM_CHANNEL_VALID
)) {
179 IWL_DEBUG_EEPROM(dev
,
180 "Ch. %d Flags %x [%sGHz] - No traffic\n",
181 iwl_nvm_channels
[ch_idx
],
183 (ch_idx
>= NUM_2GHZ_CHANNELS
) ?
188 channel
= &data
->channels
[n_channels
];
191 channel
->hw_value
= iwl_nvm_channels
[ch_idx
];
192 channel
->band
= (ch_idx
< NUM_2GHZ_CHANNELS
) ?
193 IEEE80211_BAND_2GHZ
: IEEE80211_BAND_5GHZ
;
194 channel
->center_freq
=
195 ieee80211_channel_to_frequency(
196 channel
->hw_value
, channel
->band
);
198 /* TODO: Need to be dependent to the NVM */
199 channel
->flags
= IEEE80211_CHAN_NO_HT40
;
200 if (ch_idx
< NUM_2GHZ_CHANNELS
&&
201 (ch_flags
& NVM_CHANNEL_40MHZ
)) {
202 if (iwl_nvm_channels
[ch_idx
] <= LAST_2GHZ_HT_PLUS
)
203 channel
->flags
&= ~IEEE80211_CHAN_NO_HT40PLUS
;
204 if (iwl_nvm_channels
[ch_idx
] >= FIRST_2GHZ_HT_MINUS
)
205 channel
->flags
&= ~IEEE80211_CHAN_NO_HT40MINUS
;
206 } else if (iwl_nvm_channels
[ch_idx
] <= LAST_5GHZ_HT
&&
207 (ch_flags
& NVM_CHANNEL_40MHZ
)) {
208 if ((ch_idx
- NUM_2GHZ_CHANNELS
) % 2 == 0)
209 channel
->flags
&= ~IEEE80211_CHAN_NO_HT40PLUS
;
211 channel
->flags
&= ~IEEE80211_CHAN_NO_HT40MINUS
;
214 if (!(ch_flags
& NVM_CHANNEL_IBSS
))
215 channel
->flags
|= IEEE80211_CHAN_NO_IBSS
;
217 if (!(ch_flags
& NVM_CHANNEL_ACTIVE
))
218 channel
->flags
|= IEEE80211_CHAN_PASSIVE_SCAN
;
220 if (ch_flags
& NVM_CHANNEL_RADAR
)
221 channel
->flags
|= IEEE80211_CHAN_RADAR
;
223 /* Initialize regulatory-based run-time data */
225 /* TODO: read the real value from the NVM */
226 channel
->max_power
= 0;
227 is_5ghz
= channel
->band
== IEEE80211_BAND_5GHZ
;
228 IWL_DEBUG_EEPROM(dev
,
229 "Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported\n",
231 is_5ghz
? "5.2" : "2.4",
232 CHECK_AND_PRINT_I(VALID
),
233 CHECK_AND_PRINT_I(IBSS
),
234 CHECK_AND_PRINT_I(ACTIVE
),
235 CHECK_AND_PRINT_I(RADAR
),
236 CHECK_AND_PRINT_I(WIDE
),
237 CHECK_AND_PRINT_I(DFS
),
240 ((ch_flags
& NVM_CHANNEL_IBSS
) &&
241 !(ch_flags
& NVM_CHANNEL_RADAR
))
248 static void iwl_init_sbands(struct device
*dev
, const struct iwl_cfg
*cfg
,
249 struct iwl_nvm_data
*data
, const __le16
*nvm_sw
)
251 int n_channels
= iwl_init_channel_map(dev
, cfg
, data
,
252 &nvm_sw
[NVM_CHANNELS
]);
254 struct ieee80211_supported_band
*sband
;
256 sband
= &data
->bands
[IEEE80211_BAND_2GHZ
];
257 sband
->band
= IEEE80211_BAND_2GHZ
;
258 sband
->bitrates
= &iwl_cfg80211_rates
[RATES_24_OFFS
];
259 sband
->n_bitrates
= N_RATES_24
;
260 n_used
+= iwl_init_sband_channels(data
, sband
, n_channels
,
261 IEEE80211_BAND_2GHZ
);
262 iwl_init_ht_hw_capab(cfg
, data
, &sband
->ht_cap
, IEEE80211_BAND_2GHZ
);
264 sband
= &data
->bands
[IEEE80211_BAND_5GHZ
];
265 sband
->band
= IEEE80211_BAND_5GHZ
;
266 sband
->bitrates
= &iwl_cfg80211_rates
[RATES_52_OFFS
];
267 sband
->n_bitrates
= N_RATES_52
;
268 n_used
+= iwl_init_sband_channels(data
, sband
, n_channels
,
269 IEEE80211_BAND_5GHZ
);
270 iwl_init_ht_hw_capab(cfg
, data
, &sband
->ht_cap
, IEEE80211_BAND_5GHZ
);
272 if (n_channels
!= n_used
)
273 IWL_ERR_DEV(dev
, "NVM: used only %d of %d channels\n",
277 struct iwl_nvm_data
*
278 iwl_parse_nvm_data(struct device
*dev
, const struct iwl_cfg
*cfg
,
279 const __le16
*nvm_hw
, const __le16
*nvm_sw
,
280 const __le16
*nvm_calib
)
282 struct iwl_nvm_data
*data
;
283 u8 hw_addr
[ETH_ALEN
];
286 data
= kzalloc(sizeof(*data
) +
287 sizeof(struct ieee80211_channel
) * IWL_NUM_CHANNELS
,
292 data
->nvm_version
= le16_to_cpup(nvm_sw
+ NVM_VERSION
);
294 radio_cfg
= le16_to_cpup(nvm_sw
+ RADIO_CFG
);
295 data
->radio_cfg_type
= NVM_RF_CFG_TYPE_MSK(radio_cfg
);
296 data
->radio_cfg_step
= NVM_RF_CFG_STEP_MSK(radio_cfg
);
297 data
->radio_cfg_dash
= NVM_RF_CFG_DASH_MSK(radio_cfg
);
298 data
->radio_cfg_pnum
= NVM_RF_CFG_PNUM_MSK(radio_cfg
);
299 data
->valid_tx_ant
= NVM_RF_CFG_TX_ANT_MSK(radio_cfg
);
300 data
->valid_rx_ant
= NVM_RF_CFG_RX_ANT_MSK(radio_cfg
);
302 sku
= le16_to_cpup(nvm_sw
+ SKU
);
303 data
->sku_cap_band_24GHz_enable
= sku
& NVM_SKU_CAP_BAND_24GHZ
;
304 data
->sku_cap_band_52GHz_enable
= sku
& NVM_SKU_CAP_BAND_52GHZ
;
305 data
->sku_cap_11n_enable
= sku
& NVM_SKU_CAP_11N_ENABLE
;
306 if (iwlwifi_mod_params
.disable_11n
& IWL_DISABLE_HT_ALL
)
307 data
->sku_cap_11n_enable
= false;
309 /* check overrides (some devices have wrong NVM) */
310 if (cfg
->valid_tx_ant
)
311 data
->valid_tx_ant
= cfg
->valid_tx_ant
;
312 if (cfg
->valid_rx_ant
)
313 data
->valid_rx_ant
= cfg
->valid_rx_ant
;
315 if (!data
->valid_tx_ant
|| !data
->valid_rx_ant
) {
316 IWL_ERR_DEV(dev
, "invalid antennas (0x%x, 0x%x)\n",
317 data
->valid_tx_ant
, data
->valid_rx_ant
);
322 data
->n_hw_addrs
= le16_to_cpup(nvm_sw
+ N_HW_ADDRS
);
324 data
->xtal_calib
[0] = *(nvm_calib
+ XTAL_CALIB
);
325 data
->xtal_calib
[1] = *(nvm_calib
+ XTAL_CALIB
+ 1);
327 /* The byte order is little endian 16 bit, meaning 214365 */
328 memcpy(hw_addr
, nvm_hw
+ HW_ADDR
, ETH_ALEN
);
329 data
->hw_addr
[0] = hw_addr
[1];
330 data
->hw_addr
[1] = hw_addr
[0];
331 data
->hw_addr
[2] = hw_addr
[3];
332 data
->hw_addr
[3] = hw_addr
[2];
333 data
->hw_addr
[4] = hw_addr
[5];
334 data
->hw_addr
[5] = hw_addr
[4];
336 iwl_init_sbands(dev
, cfg
, data
, nvm_sw
);
338 data
->calib_version
= 255; /* TODO:
339 this value will prevent some checks from
340 failing, we need to check if this
341 field is still needed, and if it does,
342 where is it in the NVM*/
346 EXPORT_SYMBOL_GPL(iwl_parse_nvm_data
);