iwlwifi: mvm: advertise VHT capabilities
[firefly-linux-kernel-4.4.55.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-modparams.h"
66 #include "iwl-nvm-parse.h"
67
68 /* NVM offsets (in words) definitions */
69 enum wkp_nvm_offsets {
70         /* NVM HW-Section offset (in words) definitions */
71         HW_ADDR = 0x15,
72
73 /* NVM SW-Section offset (in words) definitions */
74         NVM_SW_SECTION = 0x1C0,
75         NVM_VERSION = 0,
76         RADIO_CFG = 1,
77         SKU = 2,
78         N_HW_ADDRS = 3,
79         NVM_CHANNELS = 0x1E0 - NVM_SW_SECTION,
80
81 /* NVM calibration section offset (in words) definitions */
82         NVM_CALIB_SECTION = 0x2B8,
83         XTAL_CALIB = 0x316 - NVM_CALIB_SECTION
84 };
85
86 /* SKU Capabilities (actual values from NVM definition) */
87 enum nvm_sku_bits {
88         NVM_SKU_CAP_BAND_24GHZ  = BIT(0),
89         NVM_SKU_CAP_BAND_52GHZ  = BIT(1),
90         NVM_SKU_CAP_11N_ENABLE  = BIT(2),
91 };
92
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 */
100
101 /*
102  * These are the channel numbers in the order that they are stored in the NVM
103  */
104 static const u8 iwl_nvm_channels[] = {
105         /* 2.4 GHz */
106         1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
107         /* 5 GHz */
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
111 };
112
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
118
119
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, },
137 };
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)
142
143 /**
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 (?)
152  * @NVM_CHANNEL_80MHZ: 80 MHz channel okay (?)
153  * @NVM_CHANNEL_160MHZ: 160 MHz channel okay (?)
154  */
155 enum iwl_nvm_channel_flags {
156         NVM_CHANNEL_VALID = BIT(0),
157         NVM_CHANNEL_IBSS = BIT(1),
158         NVM_CHANNEL_ACTIVE = BIT(3),
159         NVM_CHANNEL_RADAR = BIT(4),
160         NVM_CHANNEL_DFS = BIT(7),
161         NVM_CHANNEL_WIDE = BIT(8),
162         NVM_CHANNEL_40MHZ = BIT(9),
163         NVM_CHANNEL_80MHZ = BIT(10),
164         NVM_CHANNEL_160MHZ = BIT(11),
165 };
166
167 #define CHECK_AND_PRINT_I(x)    \
168         ((ch_flags & NVM_CHANNEL_##x) ? # x " " : "")
169
170 static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
171                                 struct iwl_nvm_data *data,
172                                 const __le16 * const nvm_ch_flags)
173 {
174         int ch_idx;
175         int n_channels = 0;
176         struct ieee80211_channel *channel;
177         u16 ch_flags;
178         bool is_5ghz;
179
180         for (ch_idx = 0; ch_idx < IWL_NUM_CHANNELS; ch_idx++) {
181                 ch_flags = __le16_to_cpup(nvm_ch_flags + ch_idx);
182                 if (!(ch_flags & NVM_CHANNEL_VALID)) {
183                         IWL_DEBUG_EEPROM(dev,
184                                          "Ch. %d Flags %x [%sGHz] - No traffic\n",
185                                          iwl_nvm_channels[ch_idx],
186                                          ch_flags,
187                                          (ch_idx >= NUM_2GHZ_CHANNELS) ?
188                                          "5.2" : "2.4");
189                         continue;
190                 }
191
192                 channel = &data->channels[n_channels];
193                 n_channels++;
194
195                 channel->hw_value = iwl_nvm_channels[ch_idx];
196                 channel->band = (ch_idx < NUM_2GHZ_CHANNELS) ?
197                                 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
198                 channel->center_freq =
199                         ieee80211_channel_to_frequency(
200                                 channel->hw_value, channel->band);
201
202                 /* TODO: Need to be dependent to the NVM */
203                 channel->flags = IEEE80211_CHAN_NO_HT40;
204                 if (ch_idx < NUM_2GHZ_CHANNELS &&
205                     (ch_flags & NVM_CHANNEL_40MHZ)) {
206                         if (iwl_nvm_channels[ch_idx] <= LAST_2GHZ_HT_PLUS)
207                                 channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
208                         if (iwl_nvm_channels[ch_idx] >= FIRST_2GHZ_HT_MINUS)
209                                 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
210                 } else if (iwl_nvm_channels[ch_idx] <= LAST_5GHZ_HT &&
211                            (ch_flags & NVM_CHANNEL_40MHZ)) {
212                         if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
213                                 channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
214                         else
215                                 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
216                 }
217                 if (!(ch_flags & NVM_CHANNEL_80MHZ))
218                         channel->flags |= IEEE80211_CHAN_NO_80MHZ;
219                 if (!(ch_flags & NVM_CHANNEL_160MHZ))
220                         channel->flags |= IEEE80211_CHAN_NO_160MHZ;
221
222                 if (!(ch_flags & NVM_CHANNEL_IBSS))
223                         channel->flags |= IEEE80211_CHAN_NO_IBSS;
224
225                 if (!(ch_flags & NVM_CHANNEL_ACTIVE))
226                         channel->flags |= IEEE80211_CHAN_PASSIVE_SCAN;
227
228                 if (ch_flags & NVM_CHANNEL_RADAR)
229                         channel->flags |= IEEE80211_CHAN_RADAR;
230
231                 /* Initialize regulatory-based run-time data */
232
233                 /* TODO: read the real value from the NVM */
234                 channel->max_power = 0;
235                 is_5ghz = channel->band == IEEE80211_BAND_5GHZ;
236                 IWL_DEBUG_EEPROM(dev,
237                                  "Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported\n",
238                                  channel->hw_value,
239                                  is_5ghz ? "5.2" : "2.4",
240                                  CHECK_AND_PRINT_I(VALID),
241                                  CHECK_AND_PRINT_I(IBSS),
242                                  CHECK_AND_PRINT_I(ACTIVE),
243                                  CHECK_AND_PRINT_I(RADAR),
244                                  CHECK_AND_PRINT_I(WIDE),
245                                  CHECK_AND_PRINT_I(DFS),
246                                  ch_flags,
247                                  channel->max_power,
248                                  ((ch_flags & NVM_CHANNEL_IBSS) &&
249                                   !(ch_flags & NVM_CHANNEL_RADAR))
250                                         ? "" : "not ");
251         }
252
253         return n_channels;
254 }
255
256 static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
257                                   struct iwl_nvm_data *data,
258                                   struct ieee80211_sta_vht_cap *vht_cap)
259 {
260         /* For now, assume new devices with NVM are VHT capable */
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 {
296         int n_channels = iwl_init_channel_map(dev, cfg, data,
297                         &nvm_sw[NVM_CHANNELS]);
298         int n_used = 0;
299         struct ieee80211_supported_band *sband;
300
301         sband = &data->bands[IEEE80211_BAND_2GHZ];
302         sband->band = IEEE80211_BAND_2GHZ;
303         sband->bitrates = &iwl_cfg80211_rates[RATES_24_OFFS];
304         sband->n_bitrates = N_RATES_24;
305         n_used += iwl_init_sband_channels(data, sband, n_channels,
306                                           IEEE80211_BAND_2GHZ);
307         iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_2GHZ);
308
309         sband = &data->bands[IEEE80211_BAND_5GHZ];
310         sband->band = IEEE80211_BAND_5GHZ;
311         sband->bitrates = &iwl_cfg80211_rates[RATES_52_OFFS];
312         sband->n_bitrates = N_RATES_52;
313         n_used += iwl_init_sband_channels(data, sband, n_channels,
314                                           IEEE80211_BAND_5GHZ);
315         iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ);
316         iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap);
317
318         if (n_channels != n_used)
319                 IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n",
320                             n_used, n_channels);
321 }
322
323 struct iwl_nvm_data *
324 iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
325                    const __le16 *nvm_hw, const __le16 *nvm_sw,
326                    const __le16 *nvm_calib)
327 {
328         struct iwl_nvm_data *data;
329         u8 hw_addr[ETH_ALEN];
330         u16 radio_cfg, sku;
331
332         data = kzalloc(sizeof(*data) +
333                        sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS,
334                        GFP_KERNEL);
335         if (!data)
336                 return NULL;
337
338         data->nvm_version = le16_to_cpup(nvm_sw + NVM_VERSION);
339
340         radio_cfg = le16_to_cpup(nvm_sw + RADIO_CFG);
341         data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK(radio_cfg);
342         data->radio_cfg_step = NVM_RF_CFG_STEP_MSK(radio_cfg);
343         data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK(radio_cfg);
344         data->radio_cfg_pnum = NVM_RF_CFG_PNUM_MSK(radio_cfg);
345         data->valid_tx_ant = NVM_RF_CFG_TX_ANT_MSK(radio_cfg);
346         data->valid_rx_ant = NVM_RF_CFG_RX_ANT_MSK(radio_cfg);
347
348         sku = le16_to_cpup(nvm_sw + SKU);
349         data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ;
350         data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ;
351         data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE;
352         if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
353                 data->sku_cap_11n_enable = false;
354
355         /* check overrides (some devices have wrong NVM) */
356         if (cfg->valid_tx_ant)
357                 data->valid_tx_ant = cfg->valid_tx_ant;
358         if (cfg->valid_rx_ant)
359                 data->valid_rx_ant = cfg->valid_rx_ant;
360
361         if (!data->valid_tx_ant || !data->valid_rx_ant) {
362                 IWL_ERR_DEV(dev, "invalid antennas (0x%x, 0x%x)\n",
363                             data->valid_tx_ant, data->valid_rx_ant);
364                 kfree(data);
365                 return NULL;
366         }
367
368         data->n_hw_addrs = le16_to_cpup(nvm_sw + N_HW_ADDRS);
369
370         data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB);
371         data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1);
372
373         /* The byte order is little endian 16 bit, meaning 214365 */
374         memcpy(hw_addr, nvm_hw + HW_ADDR, ETH_ALEN);
375         data->hw_addr[0] = hw_addr[1];
376         data->hw_addr[1] = hw_addr[0];
377         data->hw_addr[2] = hw_addr[3];
378         data->hw_addr[3] = hw_addr[2];
379         data->hw_addr[4] = hw_addr[5];
380         data->hw_addr[5] = hw_addr[4];
381
382         iwl_init_sbands(dev, cfg, data, nvm_sw);
383
384         data->calib_version = 255;   /* TODO:
385                                         this value will prevent some checks from
386                                         failing, we need to check if this
387                                         field is still needed, and if it does,
388                                         where is it in the NVM*/
389
390         return data;
391 }
392 EXPORT_SYMBOL_GPL(iwl_parse_nvm_data);