]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
Merge branch 'for-3.11' of git://linux-nfs.org/~bfields/linux
[karo-tx-linux.git] / drivers / net / wireless / iwlwifi / iwl-nvm-parse.c
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         NVM_SKU_CAP_11AC_ENABLE = BIT(3),
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  */
106 static 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
121
122 /* rate data (static) */
123 static struct ieee80211_rate iwl_cfg80211_rates[] = {
124         { .bitrate = 1 * 10, .hw_value = 0, .hw_value_short = 0, },
125         { .bitrate = 2 * 10, .hw_value = 1, .hw_value_short = 1,
126           .flags = IEEE80211_RATE_SHORT_PREAMBLE, },
127         { .bitrate = 5.5 * 10, .hw_value = 2, .hw_value_short = 2,
128           .flags = IEEE80211_RATE_SHORT_PREAMBLE, },
129         { .bitrate = 11 * 10, .hw_value = 3, .hw_value_short = 3,
130           .flags = IEEE80211_RATE_SHORT_PREAMBLE, },
131         { .bitrate = 6 * 10, .hw_value = 4, .hw_value_short = 4, },
132         { .bitrate = 9 * 10, .hw_value = 5, .hw_value_short = 5, },
133         { .bitrate = 12 * 10, .hw_value = 6, .hw_value_short = 6, },
134         { .bitrate = 18 * 10, .hw_value = 7, .hw_value_short = 7, },
135         { .bitrate = 24 * 10, .hw_value = 8, .hw_value_short = 8, },
136         { .bitrate = 36 * 10, .hw_value = 9, .hw_value_short = 9, },
137         { .bitrate = 48 * 10, .hw_value = 10, .hw_value_short = 10, },
138         { .bitrate = 54 * 10, .hw_value = 11, .hw_value_short = 11, },
139 };
140 #define RATES_24_OFFS   0
141 #define N_RATES_24      ARRAY_SIZE(iwl_cfg80211_rates)
142 #define RATES_52_OFFS   4
143 #define N_RATES_52      (N_RATES_24 - RATES_52_OFFS)
144
145 /**
146  * enum iwl_nvm_channel_flags - channel flags in NVM
147  * @NVM_CHANNEL_VALID: channel is usable for this SKU/geo
148  * @NVM_CHANNEL_IBSS: usable as an IBSS channel
149  * @NVM_CHANNEL_ACTIVE: active scanning allowed
150  * @NVM_CHANNEL_RADAR: radar detection required
151  * @NVM_CHANNEL_DFS: dynamic freq selection candidate
152  * @NVM_CHANNEL_WIDE: 20 MHz channel okay (?)
153  * @NVM_CHANNEL_40MHZ: 40 MHz channel okay (?)
154  * @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?)
155  * @NVM_CHANNEL_160MHZ: 160 MHz channel okay (?)
156  */
157 enum iwl_nvm_channel_flags {
158         NVM_CHANNEL_VALID = BIT(0),
159         NVM_CHANNEL_IBSS = BIT(1),
160         NVM_CHANNEL_ACTIVE = BIT(3),
161         NVM_CHANNEL_RADAR = BIT(4),
162         NVM_CHANNEL_DFS = BIT(7),
163         NVM_CHANNEL_WIDE = BIT(8),
164         NVM_CHANNEL_40MHZ = BIT(9),
165         NVM_CHANNEL_80MHZ = BIT(10),
166         NVM_CHANNEL_160MHZ = BIT(11),
167 };
168
169 #define CHECK_AND_PRINT_I(x)    \
170         ((ch_flags & NVM_CHANNEL_##x) ? # x " " : "")
171
172 static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
173                                 struct iwl_nvm_data *data,
174                                 const __le16 * const nvm_ch_flags)
175 {
176         int ch_idx;
177         int n_channels = 0;
178         struct ieee80211_channel *channel;
179         u16 ch_flags;
180         bool is_5ghz;
181
182         for (ch_idx = 0; ch_idx < IWL_NUM_CHANNELS; ch_idx++) {
183                 ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
184                 if (!(ch_flags & NVM_CHANNEL_VALID)) {
185                         IWL_DEBUG_EEPROM(dev,
186                                          "Ch. %d Flags %x [%sGHz] - No traffic\n",
187                                          iwl_nvm_channels[ch_idx],
188                                          ch_flags,
189                                          (ch_idx >= NUM_2GHZ_CHANNELS) ?
190                                          "5.2" : "2.4");
191                         continue;
192                 }
193
194                 channel = &data->channels[n_channels];
195                 n_channels++;
196
197                 channel->hw_value = iwl_nvm_channels[ch_idx];
198                 channel->band = (ch_idx < NUM_2GHZ_CHANNELS) ?
199                                 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
200                 channel->center_freq =
201                         ieee80211_channel_to_frequency(
202                                 channel->hw_value, channel->band);
203
204                 /* TODO: Need to be dependent to the NVM */
205                 channel->flags = IEEE80211_CHAN_NO_HT40;
206                 if (ch_idx < NUM_2GHZ_CHANNELS &&
207                     (ch_flags & NVM_CHANNEL_40MHZ)) {
208                         if (iwl_nvm_channels[ch_idx] <= LAST_2GHZ_HT_PLUS)
209                                 channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
210                         if (iwl_nvm_channels[ch_idx] >= FIRST_2GHZ_HT_MINUS)
211                                 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
212                 } else if (iwl_nvm_channels[ch_idx] <= LAST_5GHZ_HT &&
213                            (ch_flags & NVM_CHANNEL_40MHZ)) {
214                         if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
215                                 channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
216                         else
217                                 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
218                 }
219                 if (!(ch_flags & NVM_CHANNEL_80MHZ))
220                         channel->flags |= IEEE80211_CHAN_NO_80MHZ;
221                 if (!(ch_flags & NVM_CHANNEL_160MHZ))
222                         channel->flags |= IEEE80211_CHAN_NO_160MHZ;
223
224                 if (!(ch_flags & NVM_CHANNEL_IBSS))
225                         channel->flags |= IEEE80211_CHAN_NO_IBSS;
226
227                 if (!(ch_flags & NVM_CHANNEL_ACTIVE))
228                         channel->flags |= IEEE80211_CHAN_PASSIVE_SCAN;
229
230                 if (ch_flags & NVM_CHANNEL_RADAR)
231                         channel->flags |= IEEE80211_CHAN_RADAR;
232
233                 /* Initialize regulatory-based run-time data */
234
235                 /* TODO: read the real value from the NVM */
236                 channel->max_power = 0;
237                 is_5ghz = channel->band == IEEE80211_BAND_5GHZ;
238                 IWL_DEBUG_EEPROM(dev,
239                                  "Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported\n",
240                                  channel->hw_value,
241                                  is_5ghz ? "5.2" : "2.4",
242                                  CHECK_AND_PRINT_I(VALID),
243                                  CHECK_AND_PRINT_I(IBSS),
244                                  CHECK_AND_PRINT_I(ACTIVE),
245                                  CHECK_AND_PRINT_I(RADAR),
246                                  CHECK_AND_PRINT_I(WIDE),
247                                  CHECK_AND_PRINT_I(DFS),
248                                  ch_flags,
249                                  channel->max_power,
250                                  ((ch_flags & NVM_CHANNEL_IBSS) &&
251                                   !(ch_flags & NVM_CHANNEL_RADAR))
252                                         ? "" : "not ");
253         }
254
255         return n_channels;
256 }
257
258 static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
259                                   struct iwl_nvm_data *data,
260                                   struct ieee80211_sta_vht_cap *vht_cap)
261 {
262         vht_cap->vht_supported = true;
263
264         vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 |
265                        IEEE80211_VHT_CAP_RXSTBC_1 |
266                        IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |
267                        7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
268
269         if (iwlwifi_mod_params.amsdu_size_8K)
270                 vht_cap->cap |= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_7991;
271
272         vht_cap->vht_mcs.rx_mcs_map =
273                 cpu_to_le16(IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 |
274                             IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 |
275                             IEEE80211_VHT_MCS_NOT_SUPPORTED << 4 |
276                             IEEE80211_VHT_MCS_NOT_SUPPORTED << 6 |
277                             IEEE80211_VHT_MCS_NOT_SUPPORTED << 8 |
278                             IEEE80211_VHT_MCS_NOT_SUPPORTED << 10 |
279                             IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |
280                             IEEE80211_VHT_MCS_NOT_SUPPORTED << 14);
281
282         if (data->valid_rx_ant == 1 || cfg->rx_with_siso_diversity) {
283                 vht_cap->cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |
284                                 IEEE80211_VHT_CAP_TX_ANTENNA_PATTERN;
285                 /* this works because NOT_SUPPORTED == 3 */
286                 vht_cap->vht_mcs.rx_mcs_map |=
287                         cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << 2);
288         }
289
290         vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map;
291 }
292
293 static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
294                             struct iwl_nvm_data *data, const __le16 *nvm_sw,
295                             bool enable_vht, u8 tx_chains, u8 rx_chains)
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                              tx_chains, rx_chains);
310
311         sband = &data->bands[IEEE80211_BAND_5GHZ];
312         sband->band = IEEE80211_BAND_5GHZ;
313         sband->bitrates = &iwl_cfg80211_rates[RATES_52_OFFS];
314         sband->n_bitrates = N_RATES_52;
315         n_used += iwl_init_sband_channels(data, sband, n_channels,
316                                           IEEE80211_BAND_5GHZ);
317         iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ,
318                              tx_chains, rx_chains);
319         if (enable_vht)
320                 iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap);
321
322         if (n_channels != n_used)
323                 IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n",
324                             n_used, n_channels);
325 }
326
327 struct iwl_nvm_data *
328 iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
329                    const __le16 *nvm_hw, const __le16 *nvm_sw,
330                    const __le16 *nvm_calib, u8 tx_chains, u8 rx_chains)
331 {
332         struct iwl_nvm_data *data;
333         u8 hw_addr[ETH_ALEN];
334         u16 radio_cfg, sku;
335
336         data = kzalloc(sizeof(*data) +
337                        sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS,
338                        GFP_KERNEL);
339         if (!data)
340                 return NULL;
341
342         data->nvm_version = le16_to_cpup(nvm_sw + NVM_VERSION);
343
344         radio_cfg = le16_to_cpup(nvm_sw + RADIO_CFG);
345         data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK(radio_cfg);
346         data->radio_cfg_step = NVM_RF_CFG_STEP_MSK(radio_cfg);
347         data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK(radio_cfg);
348         data->radio_cfg_pnum = NVM_RF_CFG_PNUM_MSK(radio_cfg);
349         data->valid_tx_ant = NVM_RF_CFG_TX_ANT_MSK(radio_cfg);
350         data->valid_rx_ant = NVM_RF_CFG_RX_ANT_MSK(radio_cfg);
351
352         sku = le16_to_cpup(nvm_sw + SKU);
353         data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ;
354         data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ;
355         data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE;
356         if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
357                 data->sku_cap_11n_enable = false;
358
359         /* check overrides (some devices have wrong NVM) */
360         if (cfg->valid_tx_ant)
361                 data->valid_tx_ant = cfg->valid_tx_ant;
362         if (cfg->valid_rx_ant)
363                 data->valid_rx_ant = cfg->valid_rx_ant;
364
365         if (!data->valid_tx_ant || !data->valid_rx_ant) {
366                 IWL_ERR_DEV(dev, "invalid antennas (0x%x, 0x%x)\n",
367                             data->valid_tx_ant, data->valid_rx_ant);
368                 kfree(data);
369                 return NULL;
370         }
371
372         data->n_hw_addrs = le16_to_cpup(nvm_sw + N_HW_ADDRS);
373
374         data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB);
375         data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1);
376
377         /* The byte order is little endian 16 bit, meaning 214365 */
378         memcpy(hw_addr, nvm_hw + HW_ADDR, ETH_ALEN);
379         data->hw_addr[0] = hw_addr[1];
380         data->hw_addr[1] = hw_addr[0];
381         data->hw_addr[2] = hw_addr[3];
382         data->hw_addr[3] = hw_addr[2];
383         data->hw_addr[4] = hw_addr[5];
384         data->hw_addr[5] = hw_addr[4];
385
386         iwl_init_sbands(dev, cfg, data, nvm_sw, sku & NVM_SKU_CAP_11AC_ENABLE,
387                         tx_chains, rx_chains);
388
389         data->calib_version = 255;   /* TODO:
390                                         this value will prevent some checks from
391                                         failing, we need to check if this
392                                         field is still needed, and if it does,
393                                         where is it in the NVM*/
394
395         return data;
396 }
397 IWL_EXPORT_SYMBOL(iwl_parse_nvm_data);