aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-01-24 08:14:22 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-01-30 15:41:32 -0500
commitb1e1adfa7d30cd0e8ad9a5c6a89e8c45ebe084f4 (patch)
tree43b0ae0d3e4b6ffbfd31d652a2b982e9956cb373
parentaa2b17708380ca48946a9ad97907f54032cf48fc (diff)
iwlwifi: add NVM and PHY DB code for new MVM driver
The new MVM (multi-virtual MAC) firmware driver requires NVM (non-volatile memory) parsing code and some PHY information database code. Add this separately. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c346
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.h80
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-phy-db.c514
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-phy-db.h82
7 files changed, 1039 insertions, 7 deletions
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index 98cb8e826834..2d4d47a6ef14 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -5,6 +5,7 @@ iwlwifi-objs += iwl-drv.o
5iwlwifi-objs += iwl-debug.o 5iwlwifi-objs += iwl-debug.o
6iwlwifi-objs += iwl-notif-wait.o 6iwlwifi-objs += iwl-notif-wait.o
7iwlwifi-objs += iwl-eeprom-read.o iwl-eeprom-parse.o 7iwlwifi-objs += iwl-eeprom-read.o iwl-eeprom-parse.o
8iwlwifi-objs += iwl-phy-db.o iwl-nvm-parse.o
8iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o 9iwlwifi-objs += pcie/drv.o pcie/rx.o pcie/tx.o pcie/trans.o
9iwlwifi-objs += pcie/1000.o pcie/2000.o pcie/5000.o pcie/6000.o 10iwlwifi-objs += pcie/1000.o pcie/2000.o pcie/5000.o pcie/6000.o
10iwlwifi-objs += pcie/7000.o 11iwlwifi-objs += pcie/7000.o
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
index 1ece4c06e45c..034f2ff4f43d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
@@ -703,9 +703,9 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
703 return n_channels; 703 return n_channels;
704} 704}
705 705
706static int iwl_init_sband_channels(struct iwl_nvm_data *data, 706int iwl_init_sband_channels(struct iwl_nvm_data *data,
707 struct ieee80211_supported_band *sband, 707 struct ieee80211_supported_band *sband,
708 int n_channels, enum ieee80211_band band) 708 int n_channels, enum ieee80211_band band)
709{ 709{
710 struct ieee80211_channel *chan = &data->channels[0]; 710 struct ieee80211_channel *chan = &data->channels[0];
711 int n = 0, idx = 0; 711 int n = 0, idx = 0;
@@ -728,10 +728,10 @@ static int iwl_init_sband_channels(struct iwl_nvm_data *data,
728#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */ 728#define MAX_BIT_RATE_40_MHZ 150 /* Mbps */
729#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */ 729#define MAX_BIT_RATE_20_MHZ 72 /* Mbps */
730 730
731static void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg, 731void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
732 struct iwl_nvm_data *data, 732 struct iwl_nvm_data *data,
733 struct ieee80211_sta_ht_cap *ht_info, 733 struct ieee80211_sta_ht_cap *ht_info,
734 enum ieee80211_band band) 734 enum ieee80211_band band)
735{ 735{
736 int max_bit_rate = 0; 736 int max_bit_rate = 0;
737 u8 rx_chains; 737 u8 rx_chains;
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
index 074cd0714179..683fe6a8c58f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
@@ -126,4 +126,13 @@ static inline void iwl_free_nvm_data(struct iwl_nvm_data *data)
126int iwl_nvm_check_version(struct iwl_nvm_data *data, 126int iwl_nvm_check_version(struct iwl_nvm_data *data,
127 struct iwl_trans *trans); 127 struct iwl_trans *trans);
128 128
129int iwl_init_sband_channels(struct iwl_nvm_data *data,
130 struct ieee80211_supported_band *sband,
131 int n_channels, enum ieee80211_band band);
132
133void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
134 struct iwl_nvm_data *data,
135 struct ieee80211_sta_ht_cap *ht_info,
136 enum ieee80211_band band);
137
129#endif /* __iwl_eeprom_parse_h__ */ 138#endif /* __iwl_eeprom_parse_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
new file mode 100644
index 000000000000..a70213bdb83c
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
@@ -0,0 +1,346 @@
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 LICENSE.GPL.
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 */
69enum 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) */
87enum 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 */
104static 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) */
121static 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 */
153enum 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),
161};
162
163#define CHECK_AND_PRINT_I(x) \
164 ((ch_flags & NVM_CHANNEL_##x) ? # x " " : "")
165
166static 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)
169{
170 int ch_idx;
171 int n_channels = 0;
172 struct ieee80211_channel *channel;
173 u16 ch_flags;
174 bool is_5ghz;
175
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],
182 ch_flags,
183 (ch_idx >= NUM_2GHZ_CHANNELS) ?
184 "5.2" : "2.4");
185 continue;
186 }
187
188 channel = &data->channels[n_channels];
189 n_channels++;
190
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);
197
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;
210 else
211 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
212 }
213
214 if (!(ch_flags & NVM_CHANNEL_IBSS))
215 channel->flags |= IEEE80211_CHAN_NO_IBSS;
216
217 if (!(ch_flags & NVM_CHANNEL_ACTIVE))
218 channel->flags |= IEEE80211_CHAN_PASSIVE_SCAN;
219
220 if (ch_flags & NVM_CHANNEL_RADAR)
221 channel->flags |= IEEE80211_CHAN_RADAR;
222
223 /* Initialize regulatory-based run-time data */
224
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",
230 channel->hw_value,
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),
238 ch_flags,
239 channel->max_power,
240 ((ch_flags & NVM_CHANNEL_IBSS) &&
241 !(ch_flags & NVM_CHANNEL_RADAR))
242 ? "" : "not ");
243 }
244
245 return n_channels;
246}
247
248static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
249 struct iwl_nvm_data *data, const __le16 *nvm_sw)
250{
251 int n_channels = iwl_init_channel_map(dev, cfg, data,
252 &nvm_sw[NVM_CHANNELS]);
253 int n_used = 0;
254 struct ieee80211_supported_band *sband;
255
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);
263
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);
271
272 if (n_channels != n_used)
273 IWL_ERR_DEV(dev, "NVM: used only %d of %d channels\n",
274 n_used, n_channels);
275}
276
277struct iwl_nvm_data *
278iwl_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)
281{
282 struct iwl_nvm_data *data;
283 u8 hw_addr[ETH_ALEN];
284 u16 radio_cfg, sku;
285
286 data = kzalloc(sizeof(*data) +
287 sizeof(struct ieee80211_channel) * IWL_NUM_CHANNELS,
288 GFP_KERNEL);
289 if (!data)
290 return NULL;
291
292 data->nvm_version = le16_to_cpup(nvm_sw + NVM_VERSION);
293
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);
301
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;
308
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;
314
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);
318 kfree(data);
319 return NULL;
320 }
321
322 data->n_hw_addrs = le16_to_cpup(nvm_sw + N_HW_ADDRS);
323
324 data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB);
325 data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1);
326
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];
335
336 iwl_init_sbands(dev, cfg, data, nvm_sw);
337
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*/
343
344 return data;
345}
346EXPORT_SYMBOL_GPL(iwl_parse_nvm_data);
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
new file mode 100644
index 000000000000..b2692bd287fa
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
@@ -0,0 +1,80 @@
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 LICENSE.GPL.
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#ifndef __iwl_nvm_parse_h__
63#define __iwl_nvm_parse_h__
64
65#include "iwl-eeprom-parse.h"
66
67/**
68 * iwl_parse_nvm_data - parse NVM data and return values
69 *
70 * This function parses all NVM values we need and then
71 * returns a (newly allocated) struct containing all the
72 * relevant values for driver use. The struct must be freed
73 * later with iwl_free_nvm_data().
74 */
75struct iwl_nvm_data *
76iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
77 const __le16 *nvm_hw, const __le16 *nvm_sw,
78 const __le16 *nvm_calib);
79
80#endif /* __iwl_nvm_parse_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/iwlwifi/iwl-phy-db.c
new file mode 100644
index 000000000000..14fc8d39fc28
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.c
@@ -0,0 +1,514 @@
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) 2007 - 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 LICENSE.GPL.
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 *****************************************************************************/
63
64#include <linux/slab.h>
65#include <linux/string.h>
66#include <linux/export.h>
67
68#include "iwl-phy-db.h"
69#include "iwl-debug.h"
70#include "iwl-op-mode.h"
71#include "iwl-trans.h"
72
73#define CHANNEL_NUM_SIZE 4 /* num of channels in calib_ch size */
74#define IWL_NUM_PAPD_CH_GROUPS 4
75#define IWL_NUM_TXP_CH_GROUPS 9
76
77struct iwl_phy_db_entry {
78 u16 size;
79 u8 *data;
80};
81
82/**
83 * struct iwl_phy_db - stores phy configuration and calibration data.
84 *
85 * @cfg: phy configuration.
86 * @calib_nch: non channel specific calibration data.
87 * @calib_ch: channel specific calibration data.
88 * @calib_ch_group_papd: calibration data related to papd channel group.
89 * @calib_ch_group_txp: calibration data related to tx power chanel group.
90 */
91struct iwl_phy_db {
92 struct iwl_phy_db_entry cfg;
93 struct iwl_phy_db_entry calib_nch;
94 struct iwl_phy_db_entry calib_ch;
95 struct iwl_phy_db_entry calib_ch_group_papd[IWL_NUM_PAPD_CH_GROUPS];
96 struct iwl_phy_db_entry calib_ch_group_txp[IWL_NUM_TXP_CH_GROUPS];
97
98 u32 channel_num;
99 u32 channel_size;
100
101 struct iwl_trans *trans;
102};
103
104enum iwl_phy_db_section_type {
105 IWL_PHY_DB_CFG = 1,
106 IWL_PHY_DB_CALIB_NCH,
107 IWL_PHY_DB_CALIB_CH,
108 IWL_PHY_DB_CALIB_CHG_PAPD,
109 IWL_PHY_DB_CALIB_CHG_TXP,
110 IWL_PHY_DB_MAX
111};
112
113#define PHY_DB_CMD 0x6c /* TEMP API - The actual is 0x8c */
114
115/*
116 * phy db - configure operational ucode
117 */
118struct iwl_phy_db_cmd {
119 __le16 type;
120 __le16 length;
121 u8 data[];
122} __packed;
123
124/* for parsing of tx power channel group data that comes from the firmware*/
125struct iwl_phy_db_chg_txp {
126 __le32 space;
127 __le16 max_channel_idx;
128} __packed;
129
130/*
131 * phy db - Receieve phy db chunk after calibrations
132 */
133struct iwl_calib_res_notif_phy_db {
134 __le16 type;
135 __le16 length;
136 u8 data[];
137} __packed;
138
139#define IWL_PHY_DB_STATIC_PIC cpu_to_le32(0x21436587)
140static inline void iwl_phy_db_test_pic(__le32 pic)
141{
142 WARN_ON(IWL_PHY_DB_STATIC_PIC != pic);
143}
144
145struct iwl_phy_db *iwl_phy_db_init(struct iwl_trans *trans)
146{
147 struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db),
148 GFP_KERNEL);
149
150 if (!phy_db)
151 return phy_db;
152
153 phy_db->trans = trans;
154
155 /* TODO: add default values of the phy db. */
156 return phy_db;
157}
158EXPORT_SYMBOL(iwl_phy_db_init);
159
160/*
161 * get phy db section: returns a pointer to a phy db section specified by
162 * type and channel group id.
163 */
164static struct iwl_phy_db_entry *
165iwl_phy_db_get_section(struct iwl_phy_db *phy_db,
166 enum iwl_phy_db_section_type type,
167 u16 chg_id)
168{
169 if (!phy_db || type >= IWL_PHY_DB_MAX)
170 return NULL;
171
172 switch (type) {
173 case IWL_PHY_DB_CFG:
174 return &phy_db->cfg;
175 case IWL_PHY_DB_CALIB_NCH:
176 return &phy_db->calib_nch;
177 case IWL_PHY_DB_CALIB_CH:
178 return &phy_db->calib_ch;
179 case IWL_PHY_DB_CALIB_CHG_PAPD:
180 if (chg_id >= IWL_NUM_PAPD_CH_GROUPS)
181 return NULL;
182 return &phy_db->calib_ch_group_papd[chg_id];
183 case IWL_PHY_DB_CALIB_CHG_TXP:
184 if (chg_id >= IWL_NUM_TXP_CH_GROUPS)
185 return NULL;
186 return &phy_db->calib_ch_group_txp[chg_id];
187 default:
188 return NULL;
189 }
190 return NULL;
191}
192
193static void iwl_phy_db_free_section(struct iwl_phy_db *phy_db,
194 enum iwl_phy_db_section_type type,
195 u16 chg_id)
196{
197 struct iwl_phy_db_entry *entry =
198 iwl_phy_db_get_section(phy_db, type, chg_id);
199 if (!entry)
200 return;
201
202 kfree(entry->data);
203 entry->data = NULL;
204 entry->size = 0;
205}
206
207void iwl_phy_db_free(struct iwl_phy_db *phy_db)
208{
209 int i;
210
211 if (!phy_db)
212 return;
213
214 iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CFG, 0);
215 iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_NCH, 0);
216 iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_CH, 0);
217 for (i = 0; i < IWL_NUM_PAPD_CH_GROUPS; i++)
218 iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_CHG_PAPD, i);
219 for (i = 0; i < IWL_NUM_TXP_CH_GROUPS; i++)
220 iwl_phy_db_free_section(phy_db, IWL_PHY_DB_CALIB_CHG_TXP, i);
221
222 kfree(phy_db);
223}
224EXPORT_SYMBOL(iwl_phy_db_free);
225
226int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt,
227 gfp_t alloc_ctx)
228{
229 struct iwl_calib_res_notif_phy_db *phy_db_notif =
230 (struct iwl_calib_res_notif_phy_db *)pkt->data;
231 enum iwl_phy_db_section_type type = le16_to_cpu(phy_db_notif->type);
232 u16 size = le16_to_cpu(phy_db_notif->length);
233 struct iwl_phy_db_entry *entry;
234 u16 chg_id = 0;
235
236 if (!phy_db)
237 return -EINVAL;
238
239 if (type == IWL_PHY_DB_CALIB_CHG_PAPD ||
240 type == IWL_PHY_DB_CALIB_CHG_TXP)
241 chg_id = le16_to_cpup((__le16 *)phy_db_notif->data);
242
243 entry = iwl_phy_db_get_section(phy_db, type, chg_id);
244 if (!entry)
245 return -EINVAL;
246
247 kfree(entry->data);
248 entry->data = kmemdup(phy_db_notif->data, size, alloc_ctx);
249 if (!entry->data) {
250 entry->size = 0;
251 return -ENOMEM;
252 }
253
254 entry->size = size;
255
256 if (type == IWL_PHY_DB_CALIB_CH) {
257 phy_db->channel_num =
258 le32_to_cpup((__le32 *)phy_db_notif->data);
259 phy_db->channel_size =
260 (size - CHANNEL_NUM_SIZE) / phy_db->channel_num;
261 }
262
263 /* Test PIC */
264 if (type != IWL_PHY_DB_CFG)
265 iwl_phy_db_test_pic(*(((__le32 *)phy_db_notif->data) +
266 (size / sizeof(__le32)) - 1));
267
268 IWL_DEBUG_INFO(phy_db->trans,
269 "%s(%d): [PHYDB]SET: Type %d , Size: %d\n",
270 __func__, __LINE__, type, size);
271
272 return 0;
273}
274EXPORT_SYMBOL(iwl_phy_db_set_section);
275
276static int is_valid_channel(u16 ch_id)
277{
278 if (ch_id <= 14 ||
279 (36 <= ch_id && ch_id <= 64 && ch_id % 4 == 0) ||
280 (100 <= ch_id && ch_id <= 140 && ch_id % 4 == 0) ||
281 (145 <= ch_id && ch_id <= 165 && ch_id % 4 == 1))
282 return 1;
283 return 0;
284}
285
286static u8 ch_id_to_ch_index(u16 ch_id)
287{
288 if (WARN_ON(!is_valid_channel(ch_id)))
289 return 0xff;
290
291 if (ch_id <= 14)
292 return ch_id - 1;
293 if (ch_id <= 64)
294 return (ch_id + 20) / 4;
295 if (ch_id <= 140)
296 return (ch_id - 12) / 4;
297 return (ch_id - 13) / 4;
298}
299
300
301static u16 channel_id_to_papd(u16 ch_id)
302{
303 if (WARN_ON(!is_valid_channel(ch_id)))
304 return 0xff;
305
306 if (1 <= ch_id && ch_id <= 14)
307 return 0;
308 if (36 <= ch_id && ch_id <= 64)
309 return 1;
310 if (100 <= ch_id && ch_id <= 140)
311 return 2;
312 return 3;
313}
314
315static u16 channel_id_to_txp(struct iwl_phy_db *phy_db, u16 ch_id)
316{
317 struct iwl_phy_db_chg_txp *txp_chg;
318 int i;
319 u8 ch_index = ch_id_to_ch_index(ch_id);
320 if (ch_index == 0xff)
321 return 0xff;
322
323 for (i = 0; i < IWL_NUM_TXP_CH_GROUPS; i++) {
324 txp_chg = (void *)phy_db->calib_ch_group_txp[i].data;
325 if (!txp_chg)
326 return 0xff;
327 /*
328 * Looking for the first channel group that its max channel is
329 * higher then wanted channel.
330 */
331 if (le16_to_cpu(txp_chg->max_channel_idx) >= ch_index)
332 return i;
333 }
334 return 0xff;
335}
336static
337int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db,
338 u32 type, u8 **data, u16 *size, u16 ch_id)
339{
340 struct iwl_phy_db_entry *entry;
341 u32 channel_num;
342 u32 channel_size;
343 u16 ch_group_id = 0;
344 u16 index;
345
346 if (!phy_db)
347 return -EINVAL;
348
349 /* find wanted channel group */
350 if (type == IWL_PHY_DB_CALIB_CHG_PAPD)
351 ch_group_id = channel_id_to_papd(ch_id);
352 else if (type == IWL_PHY_DB_CALIB_CHG_TXP)
353 ch_group_id = channel_id_to_txp(phy_db, ch_id);
354
355 entry = iwl_phy_db_get_section(phy_db, type, ch_group_id);
356 if (!entry)
357 return -EINVAL;
358
359 if (type == IWL_PHY_DB_CALIB_CH) {
360 index = ch_id_to_ch_index(ch_id);
361 channel_num = phy_db->channel_num;
362 channel_size = phy_db->channel_size;
363 if (index >= channel_num) {
364 IWL_ERR(phy_db->trans, "Wrong channel number %d\n",
365 ch_id);
366 return -EINVAL;
367 }
368 *data = entry->data + CHANNEL_NUM_SIZE + index * channel_size;
369 *size = channel_size;
370 } else {
371 *data = entry->data;
372 *size = entry->size;
373 }
374
375 /* Test PIC */
376 if (type != IWL_PHY_DB_CFG)
377 iwl_phy_db_test_pic(*(((__le32 *)*data) +
378 (*size / sizeof(__le32)) - 1));
379
380 IWL_DEBUG_INFO(phy_db->trans,
381 "%s(%d): [PHYDB] GET: Type %d , Size: %d\n",
382 __func__, __LINE__, type, *size);
383
384 return 0;
385}
386
387static int iwl_send_phy_db_cmd(struct iwl_phy_db *phy_db, u16 type,
388 u16 length, void *data)
389{
390 struct iwl_phy_db_cmd phy_db_cmd;
391 struct iwl_host_cmd cmd = {
392 .id = PHY_DB_CMD,
393 .flags = CMD_SYNC,
394 };
395
396 IWL_DEBUG_INFO(phy_db->trans,
397 "Sending PHY-DB hcmd of type %d, of length %d\n",
398 type, length);
399
400 /* Set phy db cmd variables */
401 phy_db_cmd.type = cpu_to_le16(type);
402 phy_db_cmd.length = cpu_to_le16(length);
403
404 /* Set hcmd variables */
405 cmd.data[0] = &phy_db_cmd;
406 cmd.len[0] = sizeof(struct iwl_phy_db_cmd);
407 cmd.data[1] = data;
408 cmd.len[1] = length;
409 cmd.dataflags[1] = IWL_HCMD_DFL_NOCOPY;
410
411 return iwl_trans_send_cmd(phy_db->trans, &cmd);
412}
413
414static int iwl_phy_db_send_all_channel_groups(
415 struct iwl_phy_db *phy_db,
416 enum iwl_phy_db_section_type type,
417 u8 max_ch_groups)
418{
419 u16 i;
420 int err;
421 struct iwl_phy_db_entry *entry;
422
423 /* Send all the channel specific groups to operational fw */
424 for (i = 0; i < max_ch_groups; i++) {
425 entry = iwl_phy_db_get_section(phy_db,
426 type,
427 i);
428 if (!entry)
429 return -EINVAL;
430
431 /* Send the requested PHY DB section */
432 err = iwl_send_phy_db_cmd(phy_db,
433 type,
434 entry->size,
435 entry->data);
436 if (err) {
437 IWL_ERR(phy_db->trans,
438 "Can't SEND phy_db section %d (%d), err %d",
439 type, i, err);
440 return err;
441 }
442
443 IWL_DEBUG_INFO(phy_db->trans,
444 "Sent PHY_DB HCMD, type = %d num = %d",
445 type, i);
446 }
447
448 return 0;
449}
450
451int iwl_send_phy_db_data(struct iwl_phy_db *phy_db)
452{
453 u8 *data = NULL;
454 u16 size = 0;
455 int err;
456
457 IWL_DEBUG_INFO(phy_db->trans,
458 "Sending phy db data and configuration to runtime image\n");
459
460 /* Send PHY DB CFG section */
461 err = iwl_phy_db_get_section_data(phy_db, IWL_PHY_DB_CFG,
462 &data, &size, 0);
463 if (err) {
464 IWL_ERR(phy_db->trans, "Cannot get Phy DB cfg section\n");
465 return err;
466 }
467
468 err = iwl_send_phy_db_cmd(phy_db, IWL_PHY_DB_CFG, size, data);
469 if (err) {
470 IWL_ERR(phy_db->trans,
471 "Cannot send HCMD of Phy DB cfg section\n");
472 return err;
473 }
474
475 err = iwl_phy_db_get_section_data(phy_db, IWL_PHY_DB_CALIB_NCH,
476 &data, &size, 0);
477 if (err) {
478 IWL_ERR(phy_db->trans,
479 "Cannot get Phy DB non specific channel section\n");
480 return err;
481 }
482
483 err = iwl_send_phy_db_cmd(phy_db, IWL_PHY_DB_CALIB_NCH, size, data);
484 if (err) {
485 IWL_ERR(phy_db->trans,
486 "Cannot send HCMD of Phy DB non specific channel section\n");
487 return err;
488 }
489
490 /* Send all the TXP channel specific data */
491 err = iwl_phy_db_send_all_channel_groups(phy_db,
492 IWL_PHY_DB_CALIB_CHG_PAPD,
493 IWL_NUM_PAPD_CH_GROUPS);
494 if (err) {
495 IWL_ERR(phy_db->trans,
496 "Cannot send channel specific PAPD groups");
497 return err;
498 }
499
500 /* Send all the TXP channel specific data */
501 err = iwl_phy_db_send_all_channel_groups(phy_db,
502 IWL_PHY_DB_CALIB_CHG_TXP,
503 IWL_NUM_TXP_CH_GROUPS);
504 if (err) {
505 IWL_ERR(phy_db->trans,
506 "Cannot send channel specific TX power groups");
507 return err;
508 }
509
510 IWL_DEBUG_INFO(phy_db->trans,
511 "Finished sending phy db non channel data\n");
512 return 0;
513}
514EXPORT_SYMBOL(iwl_send_phy_db_data);
diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.h b/drivers/net/wireless/iwlwifi/iwl-phy-db.h
new file mode 100644
index 000000000000..d0e43d96ab38
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.h
@@ -0,0 +1,82 @@
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) 2007 - 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 LICENSE.GPL.
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 *****************************************************************************/
63
64#ifndef __IWL_PHYDB_H__
65#define __IWL_PHYDB_H__
66
67#include <linux/types.h>
68
69#include "iwl-op-mode.h"
70#include "iwl-trans.h"
71
72struct iwl_phy_db *iwl_phy_db_init(struct iwl_trans *trans);
73
74void iwl_phy_db_free(struct iwl_phy_db *phy_db);
75
76int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt,
77 gfp_t alloc_ctx);
78
79
80int iwl_send_phy_db_data(struct iwl_phy_db *phy_db);
81
82#endif /* __IWL_PHYDB_H__ */