iwlagn: reclaim the packets in transport layer
[deliverable/linux.git] / drivers / net / wireless / iwlwifi / iwl-agn-lib.c
CommitLineData
e04ed0a5
WYG
1/******************************************************************************
2 *
3 * GPL LICENSE SUMMARY
4 *
901069c7 5 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
e04ed0a5
WYG
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
19 * USA
20 *
21 * The full GNU General Public License is included in this distribution
22 * in the file called LICENSE.GPL.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *
28 *****************************************************************************/
8d801080 29#include <linux/etherdevice.h>
e04ed0a5
WYG
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/sched.h>
34
35#include "iwl-dev.h"
36#include "iwl-core.h"
37#include "iwl-io.h"
38#include "iwl-helpers.h"
39#include "iwl-agn-hw.h"
40#include "iwl-agn.h"
1fa61b2e 41#include "iwl-sta.h"
bdfbf092 42#include "iwl-trans.h"
48f20d35 43#include "iwl-shared.h"
e04ed0a5 44
91835ba4
WYG
45static void iwlagn_count_tx_err_status(struct iwl_priv *priv, u16 status)
46{
47 status &= TX_STATUS_MSK;
48
49 switch (status) {
50 case TX_STATUS_POSTPONE_DELAY:
898ed67b 51 priv->reply_tx_stats.pp_delay++;
91835ba4
WYG
52 break;
53 case TX_STATUS_POSTPONE_FEW_BYTES:
898ed67b 54 priv->reply_tx_stats.pp_few_bytes++;
91835ba4
WYG
55 break;
56 case TX_STATUS_POSTPONE_BT_PRIO:
898ed67b 57 priv->reply_tx_stats.pp_bt_prio++;
91835ba4
WYG
58 break;
59 case TX_STATUS_POSTPONE_QUIET_PERIOD:
898ed67b 60 priv->reply_tx_stats.pp_quiet_period++;
91835ba4
WYG
61 break;
62 case TX_STATUS_POSTPONE_CALC_TTAK:
898ed67b 63 priv->reply_tx_stats.pp_calc_ttak++;
91835ba4
WYG
64 break;
65 case TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY:
898ed67b 66 priv->reply_tx_stats.int_crossed_retry++;
91835ba4
WYG
67 break;
68 case TX_STATUS_FAIL_SHORT_LIMIT:
898ed67b 69 priv->reply_tx_stats.short_limit++;
91835ba4
WYG
70 break;
71 case TX_STATUS_FAIL_LONG_LIMIT:
898ed67b 72 priv->reply_tx_stats.long_limit++;
91835ba4
WYG
73 break;
74 case TX_STATUS_FAIL_FIFO_UNDERRUN:
898ed67b 75 priv->reply_tx_stats.fifo_underrun++;
91835ba4
WYG
76 break;
77 case TX_STATUS_FAIL_DRAIN_FLOW:
898ed67b 78 priv->reply_tx_stats.drain_flow++;
91835ba4
WYG
79 break;
80 case TX_STATUS_FAIL_RFKILL_FLUSH:
898ed67b 81 priv->reply_tx_stats.rfkill_flush++;
91835ba4
WYG
82 break;
83 case TX_STATUS_FAIL_LIFE_EXPIRE:
898ed67b 84 priv->reply_tx_stats.life_expire++;
91835ba4
WYG
85 break;
86 case TX_STATUS_FAIL_DEST_PS:
898ed67b 87 priv->reply_tx_stats.dest_ps++;
91835ba4
WYG
88 break;
89 case TX_STATUS_FAIL_HOST_ABORTED:
898ed67b 90 priv->reply_tx_stats.host_abort++;
91835ba4
WYG
91 break;
92 case TX_STATUS_FAIL_BT_RETRY:
898ed67b 93 priv->reply_tx_stats.bt_retry++;
91835ba4
WYG
94 break;
95 case TX_STATUS_FAIL_STA_INVALID:
898ed67b 96 priv->reply_tx_stats.sta_invalid++;
91835ba4
WYG
97 break;
98 case TX_STATUS_FAIL_FRAG_DROPPED:
898ed67b 99 priv->reply_tx_stats.frag_drop++;
91835ba4
WYG
100 break;
101 case TX_STATUS_FAIL_TID_DISABLE:
898ed67b 102 priv->reply_tx_stats.tid_disable++;
91835ba4
WYG
103 break;
104 case TX_STATUS_FAIL_FIFO_FLUSHED:
898ed67b 105 priv->reply_tx_stats.fifo_flush++;
91835ba4
WYG
106 break;
107 case TX_STATUS_FAIL_INSUFFICIENT_CF_POLL:
898ed67b 108 priv->reply_tx_stats.insuff_cf_poll++;
91835ba4 109 break;
1d270075 110 case TX_STATUS_FAIL_PASSIVE_NO_RX:
898ed67b 111 priv->reply_tx_stats.fail_hw_drop++;
91835ba4 112 break;
1d270075 113 case TX_STATUS_FAIL_NO_BEACON_ON_RADAR:
898ed67b 114 priv->reply_tx_stats.sta_color_mismatch++;
91835ba4
WYG
115 break;
116 default:
898ed67b 117 priv->reply_tx_stats.unknown++;
91835ba4
WYG
118 break;
119 }
120}
121
a0eaad71 122void iwlagn_count_agg_tx_err_status(struct iwl_priv *priv, u16 status)
814665fe
WYG
123{
124 status &= AGG_TX_STATUS_MSK;
125
126 switch (status) {
127 case AGG_TX_STATE_UNDERRUN_MSK:
898ed67b 128 priv->reply_agg_tx_stats.underrun++;
814665fe
WYG
129 break;
130 case AGG_TX_STATE_BT_PRIO_MSK:
898ed67b 131 priv->reply_agg_tx_stats.bt_prio++;
814665fe
WYG
132 break;
133 case AGG_TX_STATE_FEW_BYTES_MSK:
898ed67b 134 priv->reply_agg_tx_stats.few_bytes++;
814665fe
WYG
135 break;
136 case AGG_TX_STATE_ABORT_MSK:
898ed67b 137 priv->reply_agg_tx_stats.abort++;
814665fe
WYG
138 break;
139 case AGG_TX_STATE_LAST_SENT_TTL_MSK:
898ed67b 140 priv->reply_agg_tx_stats.last_sent_ttl++;
814665fe
WYG
141 break;
142 case AGG_TX_STATE_LAST_SENT_TRY_CNT_MSK:
898ed67b 143 priv->reply_agg_tx_stats.last_sent_try++;
814665fe
WYG
144 break;
145 case AGG_TX_STATE_LAST_SENT_BT_KILL_MSK:
898ed67b 146 priv->reply_agg_tx_stats.last_sent_bt_kill++;
814665fe
WYG
147 break;
148 case AGG_TX_STATE_SCD_QUERY_MSK:
898ed67b 149 priv->reply_agg_tx_stats.scd_query++;
814665fe
WYG
150 break;
151 case AGG_TX_STATE_TEST_BAD_CRC32_MSK:
898ed67b 152 priv->reply_agg_tx_stats.bad_crc32++;
814665fe
WYG
153 break;
154 case AGG_TX_STATE_RESPONSE_MSK:
898ed67b 155 priv->reply_agg_tx_stats.response++;
814665fe
WYG
156 break;
157 case AGG_TX_STATE_DUMP_TX_MSK:
898ed67b 158 priv->reply_agg_tx_stats.dump_tx++;
814665fe
WYG
159 break;
160 case AGG_TX_STATE_DELAY_TX_MSK:
898ed67b 161 priv->reply_agg_tx_stats.delay_tx++;
814665fe
WYG
162 break;
163 default:
898ed67b 164 priv->reply_agg_tx_stats.unknown++;
814665fe
WYG
165 break;
166 }
167}
168
a0eaad71 169void iwlagn_set_tx_status(struct iwl_priv *priv,
743e015d 170 struct ieee80211_tx_info *info,
898dade1 171 struct iwlagn_tx_resp *tx_resp,
a0eaad71 172 bool is_agg)
743e015d
WYG
173{
174 u16 status = le16_to_cpu(tx_resp->status.status);
175
176 info->status.rates[0].count = tx_resp->failure_frame + 1;
177 if (is_agg)
178 info->flags &= ~IEEE80211_TX_CTL_AMPDU;
179 info->flags |= iwl_tx_status_to_mac80211(status);
180 iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags),
181 info);
91835ba4
WYG
182 if (!iwl_is_tx_success(status))
183 iwlagn_count_tx_err_status(priv, status);
743e015d
WYG
184}
185
e1b3fa0c
WYG
186#ifdef CONFIG_IWLWIFI_DEBUG
187#define AGG_TX_STATE_FAIL(x) case AGG_TX_STATE_ ## x: return #x
188
189const char *iwl_get_agg_tx_fail_reason(u16 status)
190{
191 status &= AGG_TX_STATUS_MSK;
192 switch (status) {
193 case AGG_TX_STATE_TRANSMITTED:
194 return "SUCCESS";
195 AGG_TX_STATE_FAIL(UNDERRUN_MSK);
196 AGG_TX_STATE_FAIL(BT_PRIO_MSK);
197 AGG_TX_STATE_FAIL(FEW_BYTES_MSK);
198 AGG_TX_STATE_FAIL(ABORT_MSK);
199 AGG_TX_STATE_FAIL(LAST_SENT_TTL_MSK);
200 AGG_TX_STATE_FAIL(LAST_SENT_TRY_CNT_MSK);
201 AGG_TX_STATE_FAIL(LAST_SENT_BT_KILL_MSK);
202 AGG_TX_STATE_FAIL(SCD_QUERY_MSK);
203 AGG_TX_STATE_FAIL(TEST_BAD_CRC32_MSK);
204 AGG_TX_STATE_FAIL(RESPONSE_MSK);
205 AGG_TX_STATE_FAIL(DUMP_TX_MSK);
206 AGG_TX_STATE_FAIL(DELAY_TX_MSK);
207 }
208
209 return "UNKNOWN";
210}
211#endif /* CONFIG_IWLWIFI_DEBUG */
212
04569cbe
WYG
213void iwl_check_abort_status(struct iwl_priv *priv,
214 u8 frame_count, u32 status)
215{
216 if (frame_count == 1 && status == TX_STATUS_FAIL_RFKILL_FLUSH) {
65550636 217 IWL_ERR(priv, "Tx flush command to flush out all frames\n");
63013ae3 218 if (!test_bit(STATUS_EXIT_PENDING, &priv->shrd->status))
74e28e44 219 queue_work(priv->shrd->workqueue, &priv->tx_flush);
04569cbe
WYG
220 }
221}
222
e04ed0a5
WYG
223int iwlagn_hw_valid_rtc_data_addr(u32 addr)
224{
225 return (addr >= IWLAGN_RTC_DATA_LOWER_BOUND) &&
226 (addr < IWLAGN_RTC_DATA_UPPER_BOUND);
227}
228
229int iwlagn_send_tx_power(struct iwl_priv *priv)
230{
ab63c68a 231 struct iwlagn_tx_power_dbm_cmd tx_power_cmd;
e04ed0a5
WYG
232 u8 tx_ant_cfg_cmd;
233
63013ae3 234 if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->shrd->status),
4beeba7d
SG
235 "TX Power requested while scanning!\n"))
236 return -EAGAIN;
237
e04ed0a5
WYG
238 /* half dBm need to multiply */
239 tx_power_cmd.global_lmt = (s8)(2 * priv->tx_power_user_lmt);
240
241 if (priv->tx_power_lmt_in_half_dbm &&
242 priv->tx_power_lmt_in_half_dbm < tx_power_cmd.global_lmt) {
243 /*
244 * For the newer devices which using enhanced/extend tx power
245 * table in EEPROM, the format is in half dBm. driver need to
246 * convert to dBm format before report to mac80211.
247 * By doing so, there is a possibility of 1/2 dBm resolution
248 * lost. driver will perform "round-up" operation before
249 * reporting, but it will cause 1/2 dBm tx power over the
250 * regulatory limit. Perform the checking here, if the
251 * "tx_power_user_lmt" is higher than EEPROM value (in
252 * half-dBm format), lower the tx power based on EEPROM
253 */
254 tx_power_cmd.global_lmt = priv->tx_power_lmt_in_half_dbm;
255 }
ab63c68a
WYG
256 tx_power_cmd.flags = IWLAGN_TX_POWER_NO_CLOSED;
257 tx_power_cmd.srv_chan_lmt = IWLAGN_TX_POWER_AUTO;
e04ed0a5
WYG
258
259 if (IWL_UCODE_API(priv->ucode_ver) == 1)
260 tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD_V1;
261 else
262 tx_ant_cfg_cmd = REPLY_TX_POWER_DBM_CMD;
263
e6bb4c9c 264 return iwl_trans_send_cmd_pdu(trans(priv), tx_ant_cfg_cmd, CMD_SYNC,
e419d62d 265 sizeof(tx_power_cmd), &tx_power_cmd);
e04ed0a5
WYG
266}
267
268void iwlagn_temperature(struct iwl_priv *priv)
269{
f8f79a5d 270 /* store temperature from correct statistics (in Celsius) */
0da0e5bf 271 priv->temperature = le32_to_cpu(priv->statistics.common.temperature);
e04ed0a5
WYG
272 iwl_tt_handler(priv);
273}
274
275u16 iwlagn_eeprom_calib_version(struct iwl_priv *priv)
276{
277 struct iwl_eeprom_calib_hdr {
278 u8 version;
279 u8 pa_type;
280 u16 voltage;
281 } *hdr;
282
283 hdr = (struct iwl_eeprom_calib_hdr *)iwl_eeprom_query_addr(priv,
7944f8e4 284 EEPROM_CALIB_ALL);
e04ed0a5
WYG
285 return hdr->version;
286
287}
288
289/*
290 * EEPROM
291 */
292static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address)
293{
294 u16 offset = 0;
295
296 if ((address & INDIRECT_ADDRESS) == 0)
297 return address;
298
299 switch (address & INDIRECT_TYPE_MSK) {
300 case INDIRECT_HOST:
7944f8e4 301 offset = iwl_eeprom_query16(priv, EEPROM_LINK_HOST);
e04ed0a5
WYG
302 break;
303 case INDIRECT_GENERAL:
7944f8e4 304 offset = iwl_eeprom_query16(priv, EEPROM_LINK_GENERAL);
e04ed0a5
WYG
305 break;
306 case INDIRECT_REGULATORY:
7944f8e4 307 offset = iwl_eeprom_query16(priv, EEPROM_LINK_REGULATORY);
e04ed0a5 308 break;
8d6748ca
JB
309 case INDIRECT_TXP_LIMIT:
310 offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT);
311 break;
312 case INDIRECT_TXP_LIMIT_SIZE:
313 offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT_SIZE);
314 break;
e04ed0a5 315 case INDIRECT_CALIBRATION:
7944f8e4 316 offset = iwl_eeprom_query16(priv, EEPROM_LINK_CALIBRATION);
e04ed0a5
WYG
317 break;
318 case INDIRECT_PROCESS_ADJST:
7944f8e4 319 offset = iwl_eeprom_query16(priv, EEPROM_LINK_PROCESS_ADJST);
e04ed0a5
WYG
320 break;
321 case INDIRECT_OTHERS:
7944f8e4 322 offset = iwl_eeprom_query16(priv, EEPROM_LINK_OTHERS);
e04ed0a5
WYG
323 break;
324 default:
325 IWL_ERR(priv, "illegal indirect type: 0x%X\n",
326 address & INDIRECT_TYPE_MSK);
327 break;
328 }
329
330 /* translate the offset from words to byte */
331 return (address & ADDRESS_MSK) + (offset << 1);
332}
333
70e3e8a6 334const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
e04ed0a5
WYG
335{
336 u32 address = eeprom_indirect_address(priv, offset);
7cb1b088 337 BUG_ON(address >= priv->cfg->base_params->eeprom_size);
e04ed0a5
WYG
338 return &priv->eeprom[address];
339}
348ee7cd
WYG
340
341struct iwl_mod_params iwlagn_mod_params = {
342 .amsdu_size_8K = 1,
343 .restart_fw = 1,
b7977ffa 344 .plcp_check = true,
b60eec9b 345 .bt_coex_active = true,
3f1e5f4a 346 .no_sleep_autoadjust = true,
f7538168 347 .power_level = IWL_POWER_INDEX_1,
fee84f0d 348 .bt_ch_announce = true,
48f20d35 349 .wanted_ucode_alternative = 1,
dd5b6d0a 350 .auto_agg = true,
348ee7cd
WYG
351 /* the rest are 0 by default */
352};
74bcdb33 353
8d801080
WYG
354int iwlagn_hwrate_to_mac80211_idx(u32 rate_n_flags, enum ieee80211_band band)
355{
356 int idx = 0;
357 int band_offset = 0;
358
359 /* HT rate format: mac80211 wants an MCS number, which is just LSB */
360 if (rate_n_flags & RATE_MCS_HT_MSK) {
361 idx = (rate_n_flags & 0xff);
362 return idx;
363 /* Legacy rate format, search for match in table */
364 } else {
365 if (band == IEEE80211_BAND_5GHZ)
366 band_offset = IWL_FIRST_OFDM_RATE;
367 for (idx = band_offset; idx < IWL_RATE_COUNT_LEGACY; idx++)
368 if (iwl_rates[idx].plcp == (rate_n_flags & 0xFF))
369 return idx - band_offset;
370 }
371
372 return -1;
373}
374
b6e4c55a 375static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
1dda6d28
JB
376 struct ieee80211_vif *vif,
377 enum ieee80211_band band,
378 struct iwl_scan_channel *scan_ch)
b6e4c55a
JB
379{
380 const struct ieee80211_supported_band *sband;
b6e4c55a
JB
381 u16 passive_dwell = 0;
382 u16 active_dwell = 0;
14023641 383 int added = 0;
b6e4c55a
JB
384 u16 channel = 0;
385
386 sband = iwl_get_hw_mode(priv, band);
387 if (!sband) {
388 IWL_ERR(priv, "invalid band\n");
389 return added;
390 }
391
392 active_dwell = iwl_get_active_dwell_time(priv, band, 0);
1dda6d28 393 passive_dwell = iwl_get_passive_dwell_time(priv, band, vif);
b6e4c55a
JB
394
395 if (passive_dwell <= active_dwell)
396 passive_dwell = active_dwell + 1;
397
14023641 398 channel = iwl_get_single_channel_number(priv, band);
b6e4c55a
JB
399 if (channel) {
400 scan_ch->channel = cpu_to_le16(channel);
401 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
402 scan_ch->active_dwell = cpu_to_le16(active_dwell);
403 scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
404 /* Set txpower levels to defaults */
405 scan_ch->dsp_atten = 110;
406 if (band == IEEE80211_BAND_5GHZ)
407 scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
408 else
409 scan_ch->tx_gain = ((1 << 5) | (5 << 3));
410 added++;
411 } else
412 IWL_ERR(priv, "no valid channel found\n");
413 return added;
414}
415
416static int iwl_get_channels_for_scan(struct iwl_priv *priv,
1dda6d28 417 struct ieee80211_vif *vif,
b6e4c55a
JB
418 enum ieee80211_band band,
419 u8 is_active, u8 n_probes,
420 struct iwl_scan_channel *scan_ch)
421{
422 struct ieee80211_channel *chan;
423 const struct ieee80211_supported_band *sband;
424 const struct iwl_channel_info *ch_info;
425 u16 passive_dwell = 0;
426 u16 active_dwell = 0;
427 int added, i;
428 u16 channel;
429
430 sband = iwl_get_hw_mode(priv, band);
431 if (!sband)
432 return 0;
433
434 active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
1dda6d28 435 passive_dwell = iwl_get_passive_dwell_time(priv, band, vif);
b6e4c55a
JB
436
437 if (passive_dwell <= active_dwell)
438 passive_dwell = active_dwell + 1;
439
440 for (i = 0, added = 0; i < priv->scan_request->n_channels; i++) {
441 chan = priv->scan_request->channels[i];
442
443 if (chan->band != band)
444 continue;
445
81e95430 446 channel = chan->hw_value;
b6e4c55a
JB
447 scan_ch->channel = cpu_to_le16(channel);
448
449 ch_info = iwl_get_channel_info(priv, band, channel);
450 if (!is_channel_valid(ch_info)) {
451 IWL_DEBUG_SCAN(priv, "Channel %d is INVALID for this band.\n",
452 channel);
453 continue;
454 }
455
456 if (!is_active || is_channel_passive(ch_info) ||
457 (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN))
458 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
459 else
460 scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE;
461
462 if (n_probes)
463 scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
464
465 scan_ch->active_dwell = cpu_to_le16(active_dwell);
466 scan_ch->passive_dwell = cpu_to_le16(passive_dwell);
467
468 /* Set txpower levels to defaults */
469 scan_ch->dsp_atten = 110;
470
471 /* NOTE: if we were doing 6Mb OFDM for scans we'd use
472 * power level:
473 * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3;
474 */
475 if (band == IEEE80211_BAND_5GHZ)
476 scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
477 else
478 scan_ch->tx_gain = ((1 << 5) | (5 << 3));
479
480 IWL_DEBUG_SCAN(priv, "Scanning ch=%d prob=0x%X [%s %d]\n",
481 channel, le32_to_cpu(scan_ch->type),
482 (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
483 "ACTIVE" : "PASSIVE",
484 (scan_ch->type & SCAN_CHANNEL_TYPE_ACTIVE) ?
485 active_dwell : passive_dwell);
486
487 scan_ch++;
488 added++;
489 }
490
491 IWL_DEBUG_SCAN(priv, "total channels to scan %d\n", added);
492 return added;
493}
494
3eecce52 495int iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
b6e4c55a
JB
496{
497 struct iwl_host_cmd cmd = {
498 .id = REPLY_SCAN_CMD,
3fa50738 499 .len = { sizeof(struct iwl_scan_cmd), },
e419d62d 500 .flags = CMD_SYNC,
b6e4c55a
JB
501 };
502 struct iwl_scan_cmd *scan;
a194e324 503 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
b6e4c55a
JB
504 u32 rate_flags = 0;
505 u16 cmd_len;
506 u16 rx_chain = 0;
507 enum ieee80211_band band;
508 u8 n_probes = 0;
d6189124 509 u8 rx_ant = hw_params(priv).valid_rx_ant;
b6e4c55a
JB
510 u8 rate;
511 bool is_active = false;
512 int chan_mod;
513 u8 active_chains;
d6189124 514 u8 scan_tx_antennas = hw_params(priv).valid_tx_ant;
3eecce52
JB
515 int ret;
516
6ac2f839 517 lockdep_assert_held(&priv->shrd->mutex);
b6e4c55a 518
a194e324
JB
519 if (vif)
520 ctx = iwl_rxon_ctx_from_vif(vif);
521
b6e4c55a
JB
522 if (!priv->scan_cmd) {
523 priv->scan_cmd = kmalloc(sizeof(struct iwl_scan_cmd) +
524 IWL_MAX_SCAN_SIZE, GFP_KERNEL);
525 if (!priv->scan_cmd) {
526 IWL_DEBUG_SCAN(priv,
527 "fail to allocate memory for scan\n");
3eecce52 528 return -ENOMEM;
b6e4c55a
JB
529 }
530 }
531 scan = priv->scan_cmd;
532 memset(scan, 0, sizeof(struct iwl_scan_cmd) + IWL_MAX_SCAN_SIZE);
533
534 scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
535 scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
536
c6baf7fb 537 if (priv->scan_type != IWL_SCAN_ROC &&
266af4c7 538 iwl_is_any_associated(priv)) {
b6e4c55a
JB
539 u16 interval = 0;
540 u32 extra;
541 u32 suspend_time = 100;
542 u32 scan_suspend_time = 100;
b6e4c55a
JB
543
544 IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
266af4c7 545 switch (priv->scan_type) {
c6baf7fb 546 case IWL_SCAN_ROC:
266af4c7
JB
547 WARN_ON(1);
548 break;
549 case IWL_SCAN_RADIO_RESET:
a6e492b9 550 interval = 0;
266af4c7
JB
551 break;
552 case IWL_SCAN_NORMAL:
a6e492b9 553 interval = vif->bss_conf.beacon_int;
266af4c7
JB
554 break;
555 }
b6e4c55a
JB
556
557 scan->suspend_time = 0;
558 scan->max_out_time = cpu_to_le32(200 * 1024);
559 if (!interval)
560 interval = suspend_time;
561
562 extra = (suspend_time / interval) << 22;
563 scan_suspend_time = (extra |
564 ((suspend_time % interval) * 1024));
565 scan->suspend_time = cpu_to_le32(scan_suspend_time);
566 IWL_DEBUG_SCAN(priv, "suspend_time 0x%X beacon interval %d\n",
567 scan_suspend_time, interval);
c6baf7fb 568 } else if (priv->scan_type == IWL_SCAN_ROC) {
266af4c7 569 scan->suspend_time = 0;
c6baf7fb
JB
570 scan->max_out_time = 0;
571 scan->quiet_time = 0;
572 scan->quiet_plcp_th = 0;
b6e4c55a
JB
573 }
574
266af4c7
JB
575 switch (priv->scan_type) {
576 case IWL_SCAN_RADIO_RESET:
b6e4c55a 577 IWL_DEBUG_SCAN(priv, "Start internal passive scan.\n");
266af4c7
JB
578 break;
579 case IWL_SCAN_NORMAL:
580 if (priv->scan_request->n_ssids) {
581 int i, p = 0;
582 IWL_DEBUG_SCAN(priv, "Kicking off active scan\n");
583 for (i = 0; i < priv->scan_request->n_ssids; i++) {
584 /* always does wildcard anyway */
585 if (!priv->scan_request->ssids[i].ssid_len)
586 continue;
587 scan->direct_scan[p].id = WLAN_EID_SSID;
588 scan->direct_scan[p].len =
589 priv->scan_request->ssids[i].ssid_len;
590 memcpy(scan->direct_scan[p].ssid,
591 priv->scan_request->ssids[i].ssid,
592 priv->scan_request->ssids[i].ssid_len);
593 n_probes++;
594 p++;
595 }
596 is_active = true;
597 } else
598 IWL_DEBUG_SCAN(priv, "Start passive scan.\n");
599 break;
c6baf7fb
JB
600 case IWL_SCAN_ROC:
601 IWL_DEBUG_SCAN(priv, "Start ROC scan.\n");
266af4c7
JB
602 break;
603 }
b6e4c55a
JB
604
605 scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
a194e324 606 scan->tx_cmd.sta_id = ctx->bcast_sta_id;
b6e4c55a
JB
607 scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
608
609 switch (priv->scan_band) {
610 case IEEE80211_BAND_2GHZ:
611 scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
246ed355
JB
612 chan_mod = le32_to_cpu(
613 priv->contexts[IWL_RXON_CTX_BSS].active.flags &
614 RXON_FLG_CHANNEL_MODE_MSK)
b6e4c55a
JB
615 >> RXON_FLG_CHANNEL_MODE_POS;
616 if (chan_mod == CHANNEL_MODE_PURE_40) {
617 rate = IWL_RATE_6M_PLCP;
618 } else {
619 rate = IWL_RATE_1M_PLCP;
620 rate_flags = RATE_MCS_CCK_MSK;
621 }
d44ae69e
JB
622 /*
623 * Internal scans are passive, so we can indiscriminately set
624 * the BT ignore flag on 2.4 GHz since it applies to TX only.
625 */
7cb1b088
WYG
626 if (priv->cfg->bt_params &&
627 priv->cfg->bt_params->advanced_bt_coexist)
d44ae69e 628 scan->tx_cmd.tx_flags |= TX_CMD_FLG_IGNORE_BT;
b6e4c55a
JB
629 break;
630 case IEEE80211_BAND_5GHZ:
631 rate = IWL_RATE_6M_PLCP;
b6e4c55a
JB
632 break;
633 default:
3eecce52
JB
634 IWL_WARN(priv, "Invalid scan band\n");
635 return -EIO;
b6e4c55a
JB
636 }
637
085fbca2
JB
638 /*
639 * If active scanning is requested but a certain channel is
640 * marked passive, we can do active scanning if we detect
641 * transmissions.
642 *
643 * There is an issue with some firmware versions that triggers
644 * a sysassert on a "good CRC threshold" of zero (== disabled),
645 * on a radar channel even though this means that we should NOT
646 * send probes.
647 *
648 * The "good CRC threshold" is the number of frames that we
649 * need to receive during our dwell time on a channel before
650 * sending out probes -- setting this to a huge value will
651 * mean we never reach it, but at the same time work around
652 * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER
653 * here instead of IWL_GOOD_CRC_TH_DISABLED.
d2690c0d
JB
654 *
655 * This was fixed in later versions along with some other
656 * scan changes, and the threshold behaves as a flag in those
657 * versions.
085fbca2 658 */
d2690c0d
JB
659 if (priv->new_scan_threshold_behaviour)
660 scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
661 IWL_GOOD_CRC_TH_DISABLED;
662 else
663 scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT :
664 IWL_GOOD_CRC_TH_NEVER;
085fbca2 665
b6e4c55a
JB
666 band = priv->scan_band;
667
0e1654fa
JB
668 if (priv->cfg->scan_rx_antennas[band])
669 rx_ant = priv->cfg->scan_rx_antennas[band];
e7cb4955 670
cd017f25
SG
671 if (band == IEEE80211_BAND_2GHZ &&
672 priv->cfg->bt_params &&
673 priv->cfg->bt_params->advanced_bt_coexist) {
674 /* transmit 2.4 GHz probes only on first antenna */
675 scan_tx_antennas = first_antenna(scan_tx_antennas);
bee008b7
WYG
676 }
677
0e1654fa
JB
678 priv->scan_tx_ant[band] = iwl_toggle_tx_ant(priv, priv->scan_tx_ant[band],
679 scan_tx_antennas);
b6e4c55a
JB
680 rate_flags |= iwl_ant_idx_to_flags(priv->scan_tx_ant[band]);
681 scan->tx_cmd.rate_n_flags = iwl_hw_set_rate_n_flags(rate, rate_flags);
682
683 /* In power save mode use one chain, otherwise use all chains */
63013ae3 684 if (test_bit(STATUS_POWER_PMI, &priv->shrd->status)) {
b6e4c55a
JB
685 /* rx_ant has been set to all valid chains previously */
686 active_chains = rx_ant &
687 ((u8)(priv->chain_noise_data.active_chains));
688 if (!active_chains)
689 active_chains = rx_ant;
690
691 IWL_DEBUG_SCAN(priv, "chain_noise_data.active_chains: %u\n",
692 priv->chain_noise_data.active_chains);
693
694 rx_ant = first_antenna(active_chains);
695 }
7cb1b088
WYG
696 if (priv->cfg->bt_params &&
697 priv->cfg->bt_params->advanced_bt_coexist &&
698 priv->bt_full_concurrent) {
bee008b7
WYG
699 /* operated as 1x1 in full concurrency mode */
700 rx_ant = first_antenna(rx_ant);
701 }
702
b6e4c55a 703 /* MIMO is not used here, but value is required */
d6189124
EG
704 rx_chain |=
705 hw_params(priv).valid_rx_ant << RXON_RX_CHAIN_VALID_POS;
b6e4c55a
JB
706 rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
707 rx_chain |= rx_ant << RXON_RX_CHAIN_FORCE_SEL_POS;
708 rx_chain |= 0x1 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
709 scan->rx_chain = cpu_to_le16(rx_chain);
266af4c7
JB
710 switch (priv->scan_type) {
711 case IWL_SCAN_NORMAL:
b6e4c55a
JB
712 cmd_len = iwl_fill_probe_req(priv,
713 (struct ieee80211_mgmt *)scan->data,
3a0b9aad 714 vif->addr,
b6e4c55a
JB
715 priv->scan_request->ie,
716 priv->scan_request->ie_len,
717 IWL_MAX_SCAN_SIZE - sizeof(*scan));
266af4c7
JB
718 break;
719 case IWL_SCAN_RADIO_RESET:
c6baf7fb 720 case IWL_SCAN_ROC:
3a0b9aad 721 /* use bcast addr, will not be transmitted but must be valid */
b6e4c55a
JB
722 cmd_len = iwl_fill_probe_req(priv,
723 (struct ieee80211_mgmt *)scan->data,
3a0b9aad 724 iwl_bcast_addr, NULL, 0,
b6e4c55a 725 IWL_MAX_SCAN_SIZE - sizeof(*scan));
266af4c7 726 break;
266af4c7
JB
727 default:
728 BUG();
b6e4c55a
JB
729 }
730 scan->tx_cmd.len = cpu_to_le16(cmd_len);
b6e4c55a
JB
731
732 scan->filter_flags |= (RXON_FILTER_ACCEPT_GRP_MSK |
733 RXON_FILTER_BCON_AWARE_MSK);
734
266af4c7
JB
735 switch (priv->scan_type) {
736 case IWL_SCAN_RADIO_RESET:
b6e4c55a 737 scan->channel_count =
1dda6d28 738 iwl_get_single_channel_for_scan(priv, vif, band,
266af4c7
JB
739 (void *)&scan->data[cmd_len]);
740 break;
741 case IWL_SCAN_NORMAL:
b6e4c55a 742 scan->channel_count =
1dda6d28 743 iwl_get_channels_for_scan(priv, vif, band,
b6e4c55a 744 is_active, n_probes,
266af4c7
JB
745 (void *)&scan->data[cmd_len]);
746 break;
c6baf7fb 747 case IWL_SCAN_ROC: {
266af4c7
JB
748 struct iwl_scan_channel *scan_ch;
749
750 scan->channel_count = 1;
751
752 scan_ch = (void *)&scan->data[cmd_len];
c6baf7fb 753 scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE;
266af4c7 754 scan_ch->channel =
c6baf7fb 755 cpu_to_le16(priv->hw_roc_channel->hw_value);
266af4c7 756 scan_ch->active_dwell =
c6baf7fb
JB
757 scan_ch->passive_dwell =
758 cpu_to_le16(priv->hw_roc_duration);
266af4c7
JB
759
760 /* Set txpower levels to defaults */
761 scan_ch->dsp_atten = 110;
762
763 /* NOTE: if we were doing 6Mb OFDM for scans we'd use
764 * power level:
765 * scan_ch->tx_gain = ((1 << 5) | (2 << 3)) | 3;
766 */
c6baf7fb 767 if (priv->hw_roc_channel->band == IEEE80211_BAND_5GHZ)
266af4c7
JB
768 scan_ch->tx_gain = ((1 << 5) | (3 << 3)) | 3;
769 else
770 scan_ch->tx_gain = ((1 << 5) | (5 << 3));
771 }
772 break;
b6e4c55a 773 }
266af4c7 774
b6e4c55a
JB
775 if (scan->channel_count == 0) {
776 IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
3eecce52 777 return -EIO;
b6e4c55a
JB
778 }
779
3fa50738 780 cmd.len[0] += le16_to_cpu(scan->tx_cmd.len) +
b6e4c55a 781 scan->channel_count * sizeof(struct iwl_scan_channel);
3fa50738 782 cmd.data[0] = scan;
4ce7cc2b 783 cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
3fa50738 784 scan->len = cpu_to_le16(cmd.len[0]);
b6e4c55a 785
1cf26373 786 /* set scan bit here for PAN params */
63013ae3 787 set_bit(STATUS_SCAN_HW, &priv->shrd->status);
1cf26373 788
e3f10cea
WYG
789 ret = iwlagn_set_pan_params(priv);
790 if (ret)
791 return ret;
b6e4c55a 792
e6bb4c9c 793 ret = iwl_trans_send_cmd(trans(priv), &cmd);
3eecce52 794 if (ret) {
63013ae3 795 clear_bit(STATUS_SCAN_HW, &priv->shrd->status);
e3f10cea 796 iwlagn_set_pan_params(priv);
3eecce52 797 }
b6e4c55a 798
3eecce52 799 return ret;
b6e4c55a 800}
1fa61b2e
JB
801
802int iwlagn_manage_ibss_station(struct iwl_priv *priv,
803 struct ieee80211_vif *vif, bool add)
804{
fd1af15d
JB
805 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
806
1fa61b2e 807 if (add)
a30e3112
JB
808 return iwlagn_add_bssid_station(priv, vif_priv->ctx,
809 vif->bss_conf.bssid,
810 &vif_priv->ibss_bssid_sta_id);
fd1af15d
JB
811 return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id,
812 vif->bss_conf.bssid);
1fa61b2e 813}
1ff504e0
JB
814
815void iwl_free_tfds_in_queue(struct iwl_priv *priv,
816 int sta_id, int tid, int freed)
817{
f39c95e8 818 lockdep_assert_held(&priv->shrd->sta_lock);
9c5ac091 819
1ff504e0
JB
820 if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed)
821 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
822 else {
823 IWL_DEBUG_TX(priv, "free more than tfds_in_queue (%u:%d)\n",
824 priv->stations[sta_id].tid[tid].tfds_in_queue,
825 freed);
826 priv->stations[sta_id].tid[tid].tfds_in_queue = 0;
827 }
828}
716c74b0
WYG
829
830#define IWL_FLUSH_WAIT_MS 2000
831
832int iwlagn_wait_tx_queue_empty(struct iwl_priv *priv)
833{
834 struct iwl_tx_queue *txq;
835 struct iwl_queue *q;
836 int cnt;
837 unsigned long now = jiffies;
838 int ret = 0;
839
840 /* waiting for all the tx frames complete might take a while */
d6189124 841 for (cnt = 0; cnt < hw_params(priv).max_txq_num; cnt++) {
cefeaa5f 842 if (cnt == priv->shrd->cmd_queue)
716c74b0
WYG
843 continue;
844 txq = &priv->txq[cnt];
845 q = &txq->q;
846 while (q->read_ptr != q->write_ptr && !time_after(jiffies,
847 now + msecs_to_jiffies(IWL_FLUSH_WAIT_MS)))
848 msleep(1);
849
850 if (q->read_ptr != q->write_ptr) {
851 IWL_ERR(priv, "fail to flush all tx fifo queues\n");
852 ret = -ETIMEDOUT;
853 break;
854 }
855 }
856 return ret;
857}
858
859#define IWL_TX_QUEUE_MSK 0xfffff
860
861/**
862 * iwlagn_txfifo_flush: send REPLY_TXFIFO_FLUSH command to uCode
863 *
864 * pre-requirements:
865 * 1. acquire mutex before calling
866 * 2. make sure rf is on and not in exit state
867 */
868int iwlagn_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
869{
870 struct iwl_txfifo_flush_cmd flush_cmd;
871 struct iwl_host_cmd cmd = {
872 .id = REPLY_TXFIFO_FLUSH,
3fa50738 873 .len = { sizeof(struct iwl_txfifo_flush_cmd), },
716c74b0 874 .flags = CMD_SYNC,
3fa50738 875 .data = { &flush_cmd, },
716c74b0
WYG
876 };
877
878 might_sleep();
879
880 memset(&flush_cmd, 0, sizeof(flush_cmd));
ecdbe86e
WYG
881 if (flush_control & BIT(IWL_RXON_CTX_BSS))
882 flush_cmd.fifo_control = IWL_SCD_VO_MSK | IWL_SCD_VI_MSK |
f88e0ecc
WYG
883 IWL_SCD_BE_MSK | IWL_SCD_BK_MSK |
884 IWL_SCD_MGMT_MSK;
ecdbe86e
WYG
885 if ((flush_control & BIT(IWL_RXON_CTX_PAN)) &&
886 (priv->valid_contexts != BIT(IWL_RXON_CTX_BSS)))
f88e0ecc
WYG
887 flush_cmd.fifo_control |= IWL_PAN_SCD_VO_MSK |
888 IWL_PAN_SCD_VI_MSK | IWL_PAN_SCD_BE_MSK |
889 IWL_PAN_SCD_BK_MSK | IWL_PAN_SCD_MGMT_MSK |
890 IWL_PAN_SCD_MULTICAST_MSK;
891
88950758 892 if (priv->cfg->sku & EEPROM_SKU_CAP_11N_ENABLE)
716c74b0
WYG
893 flush_cmd.fifo_control |= IWL_AGG_TX_QUEUE_MSK;
894
895 IWL_DEBUG_INFO(priv, "fifo queue control: 0X%x\n",
896 flush_cmd.fifo_control);
897 flush_cmd.flush_control = cpu_to_le16(flush_control);
898
e6bb4c9c 899 return iwl_trans_send_cmd(trans(priv), &cmd);
716c74b0 900}
65550636
WYG
901
902void iwlagn_dev_txfifo_flush(struct iwl_priv *priv, u16 flush_control)
903{
6ac2f839 904 mutex_lock(&priv->shrd->mutex);
65550636 905 ieee80211_stop_queues(priv->hw);
c68744fb 906 if (iwlagn_txfifo_flush(priv, IWL_DROP_ALL)) {
65550636
WYG
907 IWL_ERR(priv, "flush request fail\n");
908 goto done;
909 }
910 IWL_DEBUG_INFO(priv, "wait transmit/flush all frames\n");
911 iwlagn_wait_tx_queue_empty(priv);
912done:
913 ieee80211_wake_queues(priv->hw);
6ac2f839 914 mutex_unlock(&priv->shrd->mutex);
65550636 915}
b6e116e8
WYG
916
917/*
918 * BT coex
919 */
920/*
921 * Macros to access the lookup table.
922 *
923 * The lookup table has 7 inputs: bt3_prio, bt3_txrx, bt_rf_act, wifi_req,
924* wifi_prio, wifi_txrx and wifi_sh_ant_req.
925 *
926 * It has three outputs: WLAN_ACTIVE, WLAN_KILL and ANT_SWITCH
927 *
928 * The format is that "registers" 8 through 11 contain the WLAN_ACTIVE bits
929 * one after another in 32-bit registers, and "registers" 0 through 7 contain
930 * the WLAN_KILL and ANT_SWITCH bits interleaved (in that order).
931 *
932 * These macros encode that format.
933 */
934#define LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, wifi_req, wifi_prio, \
935 wifi_txrx, wifi_sh_ant_req) \
936 (bt3_prio | (bt3_txrx << 1) | (bt_rf_act << 2) | (wifi_req << 3) | \
937 (wifi_prio << 4) | (wifi_txrx << 5) | (wifi_sh_ant_req << 6))
938
939#define LUT_PTA_WLAN_ACTIVE_OP(lut, op, val) \
940 lut[8 + ((val) >> 5)] op (cpu_to_le32(BIT((val) & 0x1f)))
941#define LUT_TEST_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
942 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
943 (!!(LUT_PTA_WLAN_ACTIVE_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, \
944 bt_rf_act, wifi_req, wifi_prio, wifi_txrx, \
945 wifi_sh_ant_req))))
946#define LUT_SET_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
947 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
948 LUT_PTA_WLAN_ACTIVE_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, \
949 bt_rf_act, wifi_req, wifi_prio, wifi_txrx, \
950 wifi_sh_ant_req))
951#define LUT_CLEAR_PTA_WLAN_ACTIVE(lut, bt3_prio, bt3_txrx, bt_rf_act, \
952 wifi_req, wifi_prio, wifi_txrx, \
953 wifi_sh_ant_req) \
954 LUT_PTA_WLAN_ACTIVE_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, \
955 bt_rf_act, wifi_req, wifi_prio, wifi_txrx, \
956 wifi_sh_ant_req))
957
958#define LUT_WLAN_KILL_OP(lut, op, val) \
959 lut[(val) >> 4] op (cpu_to_le32(BIT(((val) << 1) & 0x1e)))
960#define LUT_TEST_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
961 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
962 (!!(LUT_WLAN_KILL_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
963 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))))
964#define LUT_SET_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
965 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
966 LUT_WLAN_KILL_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
967 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
968#define LUT_CLEAR_WLAN_KILL(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
969 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
970 LUT_WLAN_KILL_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
971 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
972
973#define LUT_ANT_SWITCH_OP(lut, op, val) \
974 lut[(val) >> 4] op (cpu_to_le32(BIT((((val) << 1) & 0x1e) + 1)))
975#define LUT_TEST_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
976 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
977 (!!(LUT_ANT_SWITCH_OP(lut, &, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
978 wifi_req, wifi_prio, wifi_txrx, \
979 wifi_sh_ant_req))))
980#define LUT_SET_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
981 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
982 LUT_ANT_SWITCH_OP(lut, |=, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
983 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
984#define LUT_CLEAR_ANT_SWITCH(lut, bt3_prio, bt3_txrx, bt_rf_act, wifi_req, \
985 wifi_prio, wifi_txrx, wifi_sh_ant_req) \
986 LUT_ANT_SWITCH_OP(lut, &= ~, LUT_VALUE(bt3_prio, bt3_txrx, bt_rf_act, \
987 wifi_req, wifi_prio, wifi_txrx, wifi_sh_ant_req))
988
989static const __le32 iwlagn_def_3w_lookup[12] = {
990 cpu_to_le32(0xaaaaaaaa),
991 cpu_to_le32(0xaaaaaaaa),
992 cpu_to_le32(0xaeaaaaaa),
993 cpu_to_le32(0xaaaaaaaa),
994 cpu_to_le32(0xcc00ff28),
995 cpu_to_le32(0x0000aaaa),
996 cpu_to_le32(0xcc00aaaa),
997 cpu_to_le32(0x0000aaaa),
998 cpu_to_le32(0xc0004000),
999 cpu_to_le32(0x00004000),
1000 cpu_to_le32(0xf0005000),
9a67d761 1001 cpu_to_le32(0xf0005000),
b6e116e8
WYG
1002};
1003
1004static const __le32 iwlagn_concurrent_lookup[12] = {
1005 cpu_to_le32(0xaaaaaaaa),
1006 cpu_to_le32(0xaaaaaaaa),
1007 cpu_to_le32(0xaaaaaaaa),
1008 cpu_to_le32(0xaaaaaaaa),
1009 cpu_to_le32(0xaaaaaaaa),
1010 cpu_to_le32(0xaaaaaaaa),
1011 cpu_to_le32(0xaaaaaaaa),
1012 cpu_to_le32(0xaaaaaaaa),
1013 cpu_to_le32(0x00000000),
1014 cpu_to_le32(0x00000000),
1015 cpu_to_le32(0x00000000),
1016 cpu_to_le32(0x00000000),
1017};
1018
1019void iwlagn_send_advance_bt_config(struct iwl_priv *priv)
1020{
6013270a 1021 struct iwl_basic_bt_cmd basic = {
b6e116e8
WYG
1022 .max_kill = IWLAGN_BT_MAX_KILL_DEFAULT,
1023 .bt3_timer_t7_value = IWLAGN_BT3_T7_DEFAULT,
1024 .bt3_prio_sample_time = IWLAGN_BT3_PRIO_SAMPLE_DEFAULT,
1025 .bt3_timer_t2_value = IWLAGN_BT3_T2_DEFAULT,
1026 };
6013270a
WYG
1027 struct iwl6000_bt_cmd bt_cmd_6000;
1028 struct iwl2000_bt_cmd bt_cmd_2000;
1029 int ret;
b6e116e8
WYG
1030
1031 BUILD_BUG_ON(sizeof(iwlagn_def_3w_lookup) !=
6013270a
WYG
1032 sizeof(basic.bt3_lookup_table));
1033
1034 if (priv->cfg->bt_params) {
1035 if (priv->cfg->bt_params->bt_session_2) {
1036 bt_cmd_2000.prio_boost = cpu_to_le32(
1037 priv->cfg->bt_params->bt_prio_boost);
1038 bt_cmd_2000.tx_prio_boost = 0;
1039 bt_cmd_2000.rx_prio_boost = 0;
1040 } else {
1041 bt_cmd_6000.prio_boost =
1042 priv->cfg->bt_params->bt_prio_boost;
1043 bt_cmd_6000.tx_prio_boost = 0;
1044 bt_cmd_6000.rx_prio_boost = 0;
1045 }
1046 } else {
1047 IWL_ERR(priv, "failed to construct BT Coex Config\n");
1048 return;
1049 }
506aa156 1050
6013270a
WYG
1051 basic.kill_ack_mask = priv->kill_ack_mask;
1052 basic.kill_cts_mask = priv->kill_cts_mask;
1053 basic.valid = priv->bt_valid;
b6e116e8
WYG
1054
1055 /*
1056 * Configure BT coex mode to "no coexistence" when the
1057 * user disabled BT coexistence, we have no interface
1058 * (might be in monitor mode), or the interface is in
1059 * IBSS mode (no proper uCode support for coex then).
1060 */
b60eec9b
WYG
1061 if (!iwlagn_mod_params.bt_coex_active ||
1062 priv->iw_mode == NL80211_IFTYPE_ADHOC) {
6013270a 1063 basic.flags = IWLAGN_BT_FLAG_COEX_MODE_DISABLED;
b6e116e8 1064 } else {
6013270a 1065 basic.flags = IWLAGN_BT_FLAG_COEX_MODE_3W <<
b6e116e8 1066 IWLAGN_BT_FLAG_COEX_MODE_SHIFT;
207ecc5e
MV
1067
1068 if (!priv->bt_enable_pspoll)
6013270a 1069 basic.flags |= IWLAGN_BT_FLAG_SYNC_2_BT_DISABLE;
207ecc5e
MV
1070 else
1071 basic.flags &= ~IWLAGN_BT_FLAG_SYNC_2_BT_DISABLE;
e366176e 1072
b6e116e8 1073 if (priv->bt_ch_announce)
6013270a 1074 basic.flags |= IWLAGN_BT_FLAG_CHANNEL_INHIBITION;
fa7f1413 1075 IWL_DEBUG_COEX(priv, "BT coex flag: 0X%x\n", basic.flags);
b6e116e8 1076 }
6013270a 1077 priv->bt_enable_flag = basic.flags;
b6e116e8 1078 if (priv->bt_full_concurrent)
6013270a 1079 memcpy(basic.bt3_lookup_table, iwlagn_concurrent_lookup,
b6e116e8
WYG
1080 sizeof(iwlagn_concurrent_lookup));
1081 else
6013270a 1082 memcpy(basic.bt3_lookup_table, iwlagn_def_3w_lookup,
b6e116e8
WYG
1083 sizeof(iwlagn_def_3w_lookup));
1084
fa7f1413 1085 IWL_DEBUG_COEX(priv, "BT coex %s in %s mode\n",
6013270a 1086 basic.flags ? "active" : "disabled",
b6e116e8
WYG
1087 priv->bt_full_concurrent ?
1088 "full concurrency" : "3-wire");
1089
6013270a
WYG
1090 if (priv->cfg->bt_params->bt_session_2) {
1091 memcpy(&bt_cmd_2000.basic, &basic,
1092 sizeof(basic));
e6bb4c9c 1093 ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG,
e419d62d 1094 CMD_SYNC, sizeof(bt_cmd_2000), &bt_cmd_2000);
6013270a
WYG
1095 } else {
1096 memcpy(&bt_cmd_6000.basic, &basic,
1097 sizeof(basic));
e6bb4c9c 1098 ret = iwl_trans_send_cmd_pdu(trans(priv), REPLY_BT_CONFIG,
e419d62d 1099 CMD_SYNC, sizeof(bt_cmd_6000), &bt_cmd_6000);
6013270a
WYG
1100 }
1101 if (ret)
b6e116e8
WYG
1102 IWL_ERR(priv, "failed to send BT Coex Config\n");
1103
b6e116e8
WYG
1104}
1105
207ecc5e
MV
1106void iwlagn_bt_adjust_rssi_monitor(struct iwl_priv *priv, bool rssi_ena)
1107{
1108 struct iwl_rxon_context *ctx, *found_ctx = NULL;
1109 bool found_ap = false;
1110
6ac2f839 1111 lockdep_assert_held(&priv->shrd->mutex);
207ecc5e
MV
1112
1113 /* Check whether AP or GO mode is active. */
1114 if (rssi_ena) {
1115 for_each_context(priv, ctx) {
1116 if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_AP &&
1117 iwl_is_associated_ctx(ctx)) {
1118 found_ap = true;
1119 break;
1120 }
1121 }
1122 }
1123
1124 /*
1125 * If disable was received or If GO/AP mode, disable RSSI
1126 * measurements.
1127 */
1128 if (!rssi_ena || found_ap) {
1129 if (priv->cur_rssi_ctx) {
1130 ctx = priv->cur_rssi_ctx;
1131 ieee80211_disable_rssi_reports(ctx->vif);
1132 priv->cur_rssi_ctx = NULL;
1133 }
1134 return;
1135 }
1136
1137 /*
1138 * If rssi measurements need to be enabled, consider all cases now.
1139 * Figure out how many contexts are active.
1140 */
1141 for_each_context(priv, ctx) {
1142 if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION &&
1143 iwl_is_associated_ctx(ctx)) {
1144 found_ctx = ctx;
1145 break;
1146 }
1147 }
1148
1149 /*
1150 * rssi monitor already enabled for the correct interface...nothing
1151 * to do.
1152 */
1153 if (found_ctx == priv->cur_rssi_ctx)
1154 return;
1155
1156 /*
1157 * Figure out if rssi monitor is currently enabled, and needs
1158 * to be changed. If rssi monitor is already enabled, disable
1159 * it first else just enable rssi measurements on the
1160 * interface found above.
1161 */
1162 if (priv->cur_rssi_ctx) {
1163 ctx = priv->cur_rssi_ctx;
1164 if (ctx->vif)
1165 ieee80211_disable_rssi_reports(ctx->vif);
1166 }
1167
1168 priv->cur_rssi_ctx = found_ctx;
1169
1170 if (!found_ctx)
1171 return;
1172
1173 ieee80211_enable_rssi_reports(found_ctx->vif,
1174 IWLAGN_BT_PSP_MIN_RSSI_THRESHOLD,
1175 IWLAGN_BT_PSP_MAX_RSSI_THRESHOLD);
1176}
1177
1178static bool iwlagn_bt_traffic_is_sco(struct iwl_bt_uart_msg *uart_msg)
1179{
1180 return BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3 >>
1181 BT_UART_MSG_FRAME3SCOESCO_POS;
1182}
1183
b6e116e8
WYG
1184static void iwlagn_bt_traffic_change_work(struct work_struct *work)
1185{
1186 struct iwl_priv *priv =
1187 container_of(work, struct iwl_priv, bt_traffic_change_work);
8bd413e6 1188 struct iwl_rxon_context *ctx;
b6e116e8
WYG
1189 int smps_request = -1;
1190
c4197c62
WYG
1191 if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) {
1192 /* bt coex disabled */
1193 return;
1194 }
1195
5eda74a4
SG
1196 /*
1197 * Note: bt_traffic_load can be overridden by scan complete and
1198 * coex profile notifications. Ignore that since only bad consequence
1199 * can be not matching debug print with actual state.
1200 */
fa7f1413 1201 IWL_DEBUG_COEX(priv, "BT traffic load changes: %d\n",
b6e116e8
WYG
1202 priv->bt_traffic_load);
1203
1204 switch (priv->bt_traffic_load) {
1205 case IWL_BT_COEX_TRAFFIC_LOAD_NONE:
f5682c01
WYG
1206 if (priv->bt_status)
1207 smps_request = IEEE80211_SMPS_DYNAMIC;
1208 else
1209 smps_request = IEEE80211_SMPS_AUTOMATIC;
b6e116e8
WYG
1210 break;
1211 case IWL_BT_COEX_TRAFFIC_LOAD_LOW:
1212 smps_request = IEEE80211_SMPS_DYNAMIC;
1213 break;
1214 case IWL_BT_COEX_TRAFFIC_LOAD_HIGH:
1215 case IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS:
1216 smps_request = IEEE80211_SMPS_STATIC;
1217 break;
1218 default:
1219 IWL_ERR(priv, "Invalid BT traffic load: %d\n",
1220 priv->bt_traffic_load);
1221 break;
1222 }
1223
6ac2f839 1224 mutex_lock(&priv->shrd->mutex);
b6e116e8 1225
5eda74a4
SG
1226 /*
1227 * We can not send command to firmware while scanning. When the scan
1228 * complete we will schedule this work again. We do check with mutex
1229 * locked to prevent new scan request to arrive. We do not check
1230 * STATUS_SCANNING to avoid race when queue_work two times from
1231 * different notifications, but quit and not perform any work at all.
1232 */
63013ae3 1233 if (test_bit(STATUS_SCAN_HW, &priv->shrd->status))
5eda74a4
SG
1234 goto out;
1235
6b6db91c 1236 iwl_update_chain_flags(priv);
b6e116e8 1237
8bd413e6 1238 if (smps_request != -1) {
88e9ba76 1239 priv->current_ht_config.smps = smps_request;
8bd413e6
JB
1240 for_each_context(priv, ctx) {
1241 if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION)
1242 ieee80211_request_smps(ctx->vif, smps_request);
1243 }
1244 }
207ecc5e
MV
1245
1246 /*
1247 * Dynamic PS poll related functionality. Adjust RSSI measurements if
1248 * necessary.
1249 */
1250 iwlagn_bt_coex_rssi_monitor(priv);
5eda74a4 1251out:
6ac2f839 1252 mutex_unlock(&priv->shrd->mutex);
b6e116e8
WYG
1253}
1254
207ecc5e
MV
1255/*
1256 * If BT sco traffic, and RSSI monitor is enabled, move measurements to the
1257 * correct interface or disable it if this is the last interface to be
1258 * removed.
1259 */
1260void iwlagn_bt_coex_rssi_monitor(struct iwl_priv *priv)
1261{
1262 if (priv->bt_is_sco &&
1263 priv->bt_traffic_load == IWL_BT_COEX_TRAFFIC_LOAD_CONTINUOUS)
1264 iwlagn_bt_adjust_rssi_monitor(priv, true);
1265 else
1266 iwlagn_bt_adjust_rssi_monitor(priv, false);
1267}
1268
b6e116e8
WYG
1269static void iwlagn_print_uartmsg(struct iwl_priv *priv,
1270 struct iwl_bt_uart_msg *uart_msg)
1271{
fa7f1413 1272 IWL_DEBUG_COEX(priv, "Message Type = 0x%X, SSN = 0x%X, "
b6e116e8
WYG
1273 "Update Req = 0x%X",
1274 (BT_UART_MSG_FRAME1MSGTYPE_MSK & uart_msg->frame1) >>
1275 BT_UART_MSG_FRAME1MSGTYPE_POS,
1276 (BT_UART_MSG_FRAME1SSN_MSK & uart_msg->frame1) >>
1277 BT_UART_MSG_FRAME1SSN_POS,
1278 (BT_UART_MSG_FRAME1UPDATEREQ_MSK & uart_msg->frame1) >>
1279 BT_UART_MSG_FRAME1UPDATEREQ_POS);
1280
fa7f1413 1281 IWL_DEBUG_COEX(priv, "Open connections = 0x%X, Traffic load = 0x%X, "
b6e116e8
WYG
1282 "Chl_SeqN = 0x%X, In band = 0x%X",
1283 (BT_UART_MSG_FRAME2OPENCONNECTIONS_MSK & uart_msg->frame2) >>
1284 BT_UART_MSG_FRAME2OPENCONNECTIONS_POS,
1285 (BT_UART_MSG_FRAME2TRAFFICLOAD_MSK & uart_msg->frame2) >>
1286 BT_UART_MSG_FRAME2TRAFFICLOAD_POS,
1287 (BT_UART_MSG_FRAME2CHLSEQN_MSK & uart_msg->frame2) >>
1288 BT_UART_MSG_FRAME2CHLSEQN_POS,
1289 (BT_UART_MSG_FRAME2INBAND_MSK & uart_msg->frame2) >>
1290 BT_UART_MSG_FRAME2INBAND_POS);
1291
fa7f1413 1292 IWL_DEBUG_COEX(priv, "SCO/eSCO = 0x%X, Sniff = 0x%X, A2DP = 0x%X, "
b6e116e8
WYG
1293 "ACL = 0x%X, Master = 0x%X, OBEX = 0x%X",
1294 (BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3) >>
1295 BT_UART_MSG_FRAME3SCOESCO_POS,
1296 (BT_UART_MSG_FRAME3SNIFF_MSK & uart_msg->frame3) >>
1297 BT_UART_MSG_FRAME3SNIFF_POS,
1298 (BT_UART_MSG_FRAME3A2DP_MSK & uart_msg->frame3) >>
1299 BT_UART_MSG_FRAME3A2DP_POS,
1300 (BT_UART_MSG_FRAME3ACL_MSK & uart_msg->frame3) >>
1301 BT_UART_MSG_FRAME3ACL_POS,
1302 (BT_UART_MSG_FRAME3MASTER_MSK & uart_msg->frame3) >>
1303 BT_UART_MSG_FRAME3MASTER_POS,
1304 (BT_UART_MSG_FRAME3OBEX_MSK & uart_msg->frame3) >>
1305 BT_UART_MSG_FRAME3OBEX_POS);
1306
fa7f1413 1307 IWL_DEBUG_COEX(priv, "Idle duration = 0x%X",
b6e116e8
WYG
1308 (BT_UART_MSG_FRAME4IDLEDURATION_MSK & uart_msg->frame4) >>
1309 BT_UART_MSG_FRAME4IDLEDURATION_POS);
1310
fa7f1413 1311 IWL_DEBUG_COEX(priv, "Tx Activity = 0x%X, Rx Activity = 0x%X, "
b6e116e8
WYG
1312 "eSCO Retransmissions = 0x%X",
1313 (BT_UART_MSG_FRAME5TXACTIVITY_MSK & uart_msg->frame5) >>
1314 BT_UART_MSG_FRAME5TXACTIVITY_POS,
1315 (BT_UART_MSG_FRAME5RXACTIVITY_MSK & uart_msg->frame5) >>
1316 BT_UART_MSG_FRAME5RXACTIVITY_POS,
1317 (BT_UART_MSG_FRAME5ESCORETRANSMIT_MSK & uart_msg->frame5) >>
1318 BT_UART_MSG_FRAME5ESCORETRANSMIT_POS);
1319
fa7f1413 1320 IWL_DEBUG_COEX(priv, "Sniff Interval = 0x%X, Discoverable = 0x%X",
b6e116e8
WYG
1321 (BT_UART_MSG_FRAME6SNIFFINTERVAL_MSK & uart_msg->frame6) >>
1322 BT_UART_MSG_FRAME6SNIFFINTERVAL_POS,
1323 (BT_UART_MSG_FRAME6DISCOVERABLE_MSK & uart_msg->frame6) >>
1324 BT_UART_MSG_FRAME6DISCOVERABLE_POS);
1325
fa7f1413 1326 IWL_DEBUG_COEX(priv, "Sniff Activity = 0x%X, Page = "
399f66fd 1327 "0x%X, Inquiry = 0x%X, Connectable = 0x%X",
b6e116e8
WYG
1328 (BT_UART_MSG_FRAME7SNIFFACTIVITY_MSK & uart_msg->frame7) >>
1329 BT_UART_MSG_FRAME7SNIFFACTIVITY_POS,
399f66fd
WYG
1330 (BT_UART_MSG_FRAME7PAGE_MSK & uart_msg->frame7) >>
1331 BT_UART_MSG_FRAME7PAGE_POS,
1332 (BT_UART_MSG_FRAME7INQUIRY_MSK & uart_msg->frame7) >>
1333 BT_UART_MSG_FRAME7INQUIRY_POS,
b6e116e8
WYG
1334 (BT_UART_MSG_FRAME7CONNECTABLE_MSK & uart_msg->frame7) >>
1335 BT_UART_MSG_FRAME7CONNECTABLE_POS);
1336}
1337
506aa156
WYG
1338static void iwlagn_set_kill_msk(struct iwl_priv *priv,
1339 struct iwl_bt_uart_msg *uart_msg)
b6e116e8 1340{
506aa156 1341 u8 kill_msk;
20407ed8 1342 static const __le32 bt_kill_ack_msg[2] = {
506aa156
WYG
1343 IWLAGN_BT_KILL_ACK_MASK_DEFAULT,
1344 IWLAGN_BT_KILL_ACK_CTS_MASK_SCO };
1345 static const __le32 bt_kill_cts_msg[2] = {
1346 IWLAGN_BT_KILL_CTS_MASK_DEFAULT,
1347 IWLAGN_BT_KILL_ACK_CTS_MASK_SCO };
1348
1349 kill_msk = (BT_UART_MSG_FRAME3SCOESCO_MSK & uart_msg->frame3)
1350 ? 1 : 0;
1351 if (priv->kill_ack_mask != bt_kill_ack_msg[kill_msk] ||
1352 priv->kill_cts_mask != bt_kill_cts_msg[kill_msk]) {
b6e116e8 1353 priv->bt_valid |= IWLAGN_BT_VALID_KILL_ACK_MASK;
506aa156
WYG
1354 priv->kill_ack_mask = bt_kill_ack_msg[kill_msk];
1355 priv->bt_valid |= IWLAGN_BT_VALID_KILL_CTS_MASK;
1356 priv->kill_cts_mask = bt_kill_cts_msg[kill_msk];
1357
b6e116e8 1358 /* schedule to send runtime bt_config */
74e28e44 1359 queue_work(priv->shrd->workqueue, &priv->bt_runtime_config);
b6e116e8 1360 }
b6e116e8
WYG
1361}
1362
1363void iwlagn_bt_coex_profile_notif(struct iwl_priv *priv,
1364 struct iwl_rx_mem_buffer *rxb)
1365{
1366 unsigned long flags;
1367 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1368 struct iwl_bt_coex_profile_notif *coex = &pkt->u.bt_coex_profile_notif;
b6e116e8 1369 struct iwl_bt_uart_msg *uart_msg = &coex->last_bt_uart_msg;
b6e116e8 1370
c4197c62
WYG
1371 if (priv->bt_enable_flag == IWLAGN_BT_FLAG_COEX_MODE_DISABLED) {
1372 /* bt coex disabled */
1373 return;
1374 }
1375
fa7f1413
WYG
1376 IWL_DEBUG_COEX(priv, "BT Coex notification:\n");
1377 IWL_DEBUG_COEX(priv, " status: %d\n", coex->bt_status);
1378 IWL_DEBUG_COEX(priv, " traffic load: %d\n", coex->bt_traffic_load);
1379 IWL_DEBUG_COEX(priv, " CI compliance: %d\n",
b6e116e8
WYG
1380 coex->bt_ci_compliance);
1381 iwlagn_print_uartmsg(priv, uart_msg);
1382
66e863a5 1383 priv->last_bt_traffic_load = priv->bt_traffic_load;
207ecc5e
MV
1384 priv->bt_is_sco = iwlagn_bt_traffic_is_sco(uart_msg);
1385
b6e116e8
WYG
1386 if (priv->iw_mode != NL80211_IFTYPE_ADHOC) {
1387 if (priv->bt_status != coex->bt_status ||
66e863a5 1388 priv->last_bt_traffic_load != coex->bt_traffic_load) {
b6e116e8
WYG
1389 if (coex->bt_status) {
1390 /* BT on */
1391 if (!priv->bt_ch_announce)
1392 priv->bt_traffic_load =
1393 IWL_BT_COEX_TRAFFIC_LOAD_HIGH;
1394 else
1395 priv->bt_traffic_load =
1396 coex->bt_traffic_load;
1397 } else {
1398 /* BT off */
1399 priv->bt_traffic_load =
1400 IWL_BT_COEX_TRAFFIC_LOAD_NONE;
1401 }
1402 priv->bt_status = coex->bt_status;
74e28e44 1403 queue_work(priv->shrd->workqueue,
b6e116e8
WYG
1404 &priv->bt_traffic_change_work);
1405 }
b6e116e8
WYG
1406 }
1407
506aa156 1408 iwlagn_set_kill_msk(priv, uart_msg);
b6e116e8
WYG
1409
1410 /* FIXME: based on notification, adjust the prio_boost */
1411
10b15e6f 1412 spin_lock_irqsave(&priv->shrd->lock, flags);
b6e116e8 1413 priv->bt_ci_compliance = coex->bt_ci_compliance;
10b15e6f 1414 spin_unlock_irqrestore(&priv->shrd->lock, flags);
b6e116e8
WYG
1415}
1416
1417void iwlagn_bt_rx_handler_setup(struct iwl_priv *priv)
1418{
b6e116e8
WYG
1419 priv->rx_handlers[REPLY_BT_COEX_PROFILE_NOTIF] =
1420 iwlagn_bt_coex_profile_notif;
1421}
1422
1423void iwlagn_bt_setup_deferred_work(struct iwl_priv *priv)
1424{
b6e116e8
WYG
1425 INIT_WORK(&priv->bt_traffic_change_work,
1426 iwlagn_bt_traffic_change_work);
1427}
1428
1429void iwlagn_bt_cancel_deferred_work(struct iwl_priv *priv)
1430{
1431 cancel_work_sync(&priv->bt_traffic_change_work);
1432}
5de33068
JB
1433
1434static bool is_single_rx_stream(struct iwl_priv *priv)
1435{
1436 return priv->current_ht_config.smps == IEEE80211_SMPS_STATIC ||
1437 priv->current_ht_config.single_chain_sufficient;
1438}
1439
1440#define IWL_NUM_RX_CHAINS_MULTIPLE 3
1441#define IWL_NUM_RX_CHAINS_SINGLE 2
1442#define IWL_NUM_IDLE_CHAINS_DUAL 2
1443#define IWL_NUM_IDLE_CHAINS_SINGLE 1
1444
1445/*
1446 * Determine how many receiver/antenna chains to use.
1447 *
1448 * More provides better reception via diversity. Fewer saves power
1449 * at the expense of throughput, but only when not in powersave to
1450 * start with.
1451 *
1452 * MIMO (dual stream) requires at least 2, but works better with 3.
1453 * This does not determine *which* chains to use, just how many.
1454 */
1455static int iwl_get_active_rx_chain_count(struct iwl_priv *priv)
1456{
1457 if (priv->cfg->bt_params &&
1458 priv->cfg->bt_params->advanced_bt_coexist &&
1459 (priv->bt_full_concurrent ||
1460 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
1461 /*
1462 * only use chain 'A' in bt high traffic load or
1463 * full concurrency mode
1464 */
1465 return IWL_NUM_RX_CHAINS_SINGLE;
1466 }
1467 /* # of Rx chains to use when expecting MIMO. */
1468 if (is_single_rx_stream(priv))
1469 return IWL_NUM_RX_CHAINS_SINGLE;
1470 else
1471 return IWL_NUM_RX_CHAINS_MULTIPLE;
1472}
1473
1474/*
1475 * When we are in power saving mode, unless device support spatial
1476 * multiplexing power save, use the active count for rx chain count.
1477 */
1478static int iwl_get_idle_rx_chain_count(struct iwl_priv *priv, int active_cnt)
1479{
1480 /* # Rx chains when idling, depending on SMPS mode */
1481 switch (priv->current_ht_config.smps) {
1482 case IEEE80211_SMPS_STATIC:
1483 case IEEE80211_SMPS_DYNAMIC:
1484 return IWL_NUM_IDLE_CHAINS_SINGLE;
1485 case IEEE80211_SMPS_OFF:
1486 return active_cnt;
1487 default:
1488 WARN(1, "invalid SMPS mode %d",
1489 priv->current_ht_config.smps);
1490 return active_cnt;
1491 }
1492}
1493
1494/* up to 4 chains */
1495static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
1496{
1497 u8 res;
1498 res = (chain_bitmap & BIT(0)) >> 0;
1499 res += (chain_bitmap & BIT(1)) >> 1;
1500 res += (chain_bitmap & BIT(2)) >> 2;
1501 res += (chain_bitmap & BIT(3)) >> 3;
1502 return res;
1503}
1504
1505/**
1506 * iwlagn_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
1507 *
1508 * Selects how many and which Rx receivers/antennas/chains to use.
1509 * This should not be used for scan command ... it puts data in wrong place.
1510 */
1511void iwlagn_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
1512{
1513 bool is_single = is_single_rx_stream(priv);
63013ae3 1514 bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->shrd->status);
5de33068
JB
1515 u8 idle_rx_cnt, active_rx_cnt, valid_rx_cnt;
1516 u32 active_chains;
1517 u16 rx_chain;
1518
1519 /* Tell uCode which antennas are actually connected.
1520 * Before first association, we assume all antennas are connected.
1521 * Just after first association, iwl_chain_noise_calibration()
1522 * checks which antennas actually *are* connected. */
1523 if (priv->chain_noise_data.active_chains)
1524 active_chains = priv->chain_noise_data.active_chains;
1525 else
d6189124 1526 active_chains = hw_params(priv).valid_rx_ant;
5de33068
JB
1527
1528 if (priv->cfg->bt_params &&
1529 priv->cfg->bt_params->advanced_bt_coexist &&
1530 (priv->bt_full_concurrent ||
1531 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)) {
1532 /*
1533 * only use chain 'A' in bt high traffic load or
1534 * full concurrency mode
1535 */
1536 active_chains = first_antenna(active_chains);
1537 }
1538
1539 rx_chain = active_chains << RXON_RX_CHAIN_VALID_POS;
1540
1541 /* How many receivers should we use? */
1542 active_rx_cnt = iwl_get_active_rx_chain_count(priv);
1543 idle_rx_cnt = iwl_get_idle_rx_chain_count(priv, active_rx_cnt);
1544
1545
1546 /* correct rx chain count according hw settings
1547 * and chain noise calibration
1548 */
1549 valid_rx_cnt = iwl_count_chain_bitmap(active_chains);
1550 if (valid_rx_cnt < active_rx_cnt)
1551 active_rx_cnt = valid_rx_cnt;
1552
1553 if (valid_rx_cnt < idle_rx_cnt)
1554 idle_rx_cnt = valid_rx_cnt;
1555
1556 rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
1557 rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS;
1558
1559 ctx->staging.rx_chain = cpu_to_le16(rx_chain);
1560
1561 if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam)
1562 ctx->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK;
1563 else
1564 ctx->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
1565
1566 IWL_DEBUG_ASSOC(priv, "rx_chain=0x%X active=%d idle=%d\n",
1567 ctx->staging.rx_chain,
1568 active_rx_cnt, idle_rx_cnt);
1569
1570 WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 ||
1571 active_rx_cnt < idle_rx_cnt);
1572}
facd982e
JB
1573
1574u8 iwl_toggle_tx_ant(struct iwl_priv *priv, u8 ant, u8 valid)
1575{
1576 int i;
1577 u8 ind = ant;
1578
1579 if (priv->band == IEEE80211_BAND_2GHZ &&
1580 priv->bt_traffic_load >= IWL_BT_COEX_TRAFFIC_LOAD_HIGH)
1581 return 0;
1582
1583 for (i = 0; i < RATE_ANT_NUM - 1; i++) {
1584 ind = (ind + 1) < RATE_ANT_NUM ? ind + 1 : 0;
1585 if (valid & BIT(ind))
1586 return ind;
1587 }
1588 return ant;
1589}
fed73292
JB
1590
1591static const char *get_csr_string(int cmd)
1592{
1593 switch (cmd) {
1594 IWL_CMD(CSR_HW_IF_CONFIG_REG);
1595 IWL_CMD(CSR_INT_COALESCING);
1596 IWL_CMD(CSR_INT);
1597 IWL_CMD(CSR_INT_MASK);
1598 IWL_CMD(CSR_FH_INT_STATUS);
1599 IWL_CMD(CSR_GPIO_IN);
1600 IWL_CMD(CSR_RESET);
1601 IWL_CMD(CSR_GP_CNTRL);
1602 IWL_CMD(CSR_HW_REV);
1603 IWL_CMD(CSR_EEPROM_REG);
1604 IWL_CMD(CSR_EEPROM_GP);
1605 IWL_CMD(CSR_OTP_GP_REG);
1606 IWL_CMD(CSR_GIO_REG);
1607 IWL_CMD(CSR_GP_UCODE_REG);
1608 IWL_CMD(CSR_GP_DRIVER_REG);
1609 IWL_CMD(CSR_UCODE_DRV_GP1);
1610 IWL_CMD(CSR_UCODE_DRV_GP2);
1611 IWL_CMD(CSR_LED_REG);
1612 IWL_CMD(CSR_DRAM_INT_TBL_REG);
1613 IWL_CMD(CSR_GIO_CHICKEN_BITS);
1614 IWL_CMD(CSR_ANA_PLL_CFG);
1615 IWL_CMD(CSR_HW_REV_WA_REG);
1616 IWL_CMD(CSR_DBG_HPET_MEM_REG);
1617 default:
1618 return "UNKNOWN";
1619 }
1620}
1621
1622void iwl_dump_csr(struct iwl_priv *priv)
1623{
1624 int i;
20407ed8 1625 static const u32 csr_tbl[] = {
fed73292
JB
1626 CSR_HW_IF_CONFIG_REG,
1627 CSR_INT_COALESCING,
1628 CSR_INT,
1629 CSR_INT_MASK,
1630 CSR_FH_INT_STATUS,
1631 CSR_GPIO_IN,
1632 CSR_RESET,
1633 CSR_GP_CNTRL,
1634 CSR_HW_REV,
1635 CSR_EEPROM_REG,
1636 CSR_EEPROM_GP,
1637 CSR_OTP_GP_REG,
1638 CSR_GIO_REG,
1639 CSR_GP_UCODE_REG,
1640 CSR_GP_DRIVER_REG,
1641 CSR_UCODE_DRV_GP1,
1642 CSR_UCODE_DRV_GP2,
1643 CSR_LED_REG,
1644 CSR_DRAM_INT_TBL_REG,
1645 CSR_GIO_CHICKEN_BITS,
1646 CSR_ANA_PLL_CFG,
1647 CSR_HW_REV_WA_REG,
1648 CSR_DBG_HPET_MEM_REG
1649 };
1650 IWL_ERR(priv, "CSR values:\n");
1651 IWL_ERR(priv, "(2nd byte of CSR_INT_COALESCING is "
1652 "CSR_INT_PERIODIC_REG)\n");
1653 for (i = 0; i < ARRAY_SIZE(csr_tbl); i++) {
1654 IWL_ERR(priv, " %25s: 0X%08x\n",
1655 get_csr_string(csr_tbl[i]),
1656 iwl_read32(priv, csr_tbl[i]));
1657 }
1658}
84fac3d9
JB
1659
1660static const char *get_fh_string(int cmd)
1661{
1662 switch (cmd) {
1663 IWL_CMD(FH_RSCSR_CHNL0_STTS_WPTR_REG);
1664 IWL_CMD(FH_RSCSR_CHNL0_RBDCB_BASE_REG);
1665 IWL_CMD(FH_RSCSR_CHNL0_WPTR);
1666 IWL_CMD(FH_MEM_RCSR_CHNL0_CONFIG_REG);
1667 IWL_CMD(FH_MEM_RSSR_SHARED_CTRL_REG);
1668 IWL_CMD(FH_MEM_RSSR_RX_STATUS_REG);
1669 IWL_CMD(FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV);
1670 IWL_CMD(FH_TSSR_TX_STATUS_REG);
1671 IWL_CMD(FH_TSSR_TX_ERROR_REG);
1672 default:
1673 return "UNKNOWN";
1674 }
1675}
1676
1677int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display)
1678{
1679 int i;
1680#ifdef CONFIG_IWLWIFI_DEBUG
1681 int pos = 0;
1682 size_t bufsz = 0;
1683#endif
20407ed8 1684 static const u32 fh_tbl[] = {
84fac3d9
JB
1685 FH_RSCSR_CHNL0_STTS_WPTR_REG,
1686 FH_RSCSR_CHNL0_RBDCB_BASE_REG,
1687 FH_RSCSR_CHNL0_WPTR,
1688 FH_MEM_RCSR_CHNL0_CONFIG_REG,
1689 FH_MEM_RSSR_SHARED_CTRL_REG,
1690 FH_MEM_RSSR_RX_STATUS_REG,
1691 FH_MEM_RSSR_RX_ENABLE_ERR_IRQ2DRV,
1692 FH_TSSR_TX_STATUS_REG,
1693 FH_TSSR_TX_ERROR_REG
1694 };
1695#ifdef CONFIG_IWLWIFI_DEBUG
1696 if (display) {
1697 bufsz = ARRAY_SIZE(fh_tbl) * 48 + 40;
1698 *buf = kmalloc(bufsz, GFP_KERNEL);
1699 if (!*buf)
1700 return -ENOMEM;
1701 pos += scnprintf(*buf + pos, bufsz - pos,
1702 "FH register values:\n");
1703 for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
1704 pos += scnprintf(*buf + pos, bufsz - pos,
1705 " %34s: 0X%08x\n",
1706 get_fh_string(fh_tbl[i]),
1707 iwl_read_direct32(priv, fh_tbl[i]));
1708 }
1709 return pos;
1710 }
1711#endif
1712 IWL_ERR(priv, "FH register values:\n");
1713 for (i = 0; i < ARRAY_SIZE(fh_tbl); i++) {
1714 IWL_ERR(priv, " %34s: 0X%08x\n",
1715 get_fh_string(fh_tbl[i]),
1716 iwl_read_direct32(priv, fh_tbl[i]));
1717 }
1718 return 0;
1719}
7194207c
JB
1720
1721/* notification wait support */
1722void iwlagn_init_notification_wait(struct iwl_priv *priv,
1723 struct iwl_notification_wait *wait_entry,
09f18afe 1724 u8 cmd,
7194207c 1725 void (*fn)(struct iwl_priv *priv,
09f18afe
JB
1726 struct iwl_rx_packet *pkt,
1727 void *data),
1728 void *fn_data)
7194207c
JB
1729{
1730 wait_entry->fn = fn;
09f18afe 1731 wait_entry->fn_data = fn_data;
7194207c
JB
1732 wait_entry->cmd = cmd;
1733 wait_entry->triggered = false;
e74fe233 1734 wait_entry->aborted = false;
7194207c 1735
898ed67b
WYG
1736 spin_lock_bh(&priv->notif_wait_lock);
1737 list_add(&wait_entry->list, &priv->notif_waits);
1738 spin_unlock_bh(&priv->notif_wait_lock);
7194207c
JB
1739}
1740
a8674a1e
JB
1741int iwlagn_wait_notification(struct iwl_priv *priv,
1742 struct iwl_notification_wait *wait_entry,
1743 unsigned long timeout)
7194207c
JB
1744{
1745 int ret;
1746
898ed67b 1747 ret = wait_event_timeout(priv->notif_waitq,
e74fe233 1748 wait_entry->triggered || wait_entry->aborted,
7194207c
JB
1749 timeout);
1750
898ed67b 1751 spin_lock_bh(&priv->notif_wait_lock);
7194207c 1752 list_del(&wait_entry->list);
898ed67b 1753 spin_unlock_bh(&priv->notif_wait_lock);
7194207c 1754
e74fe233
JB
1755 if (wait_entry->aborted)
1756 return -EIO;
1757
a8674a1e
JB
1758 /* return value is always >= 0 */
1759 if (ret <= 0)
1760 return -ETIMEDOUT;
1761 return 0;
7194207c
JB
1762}
1763
1764void iwlagn_remove_notification(struct iwl_priv *priv,
1765 struct iwl_notification_wait *wait_entry)
1766{
898ed67b 1767 spin_lock_bh(&priv->notif_wait_lock);
7194207c 1768 list_del(&wait_entry->list);
898ed67b 1769 spin_unlock_bh(&priv->notif_wait_lock);
7194207c 1770}
This page took 0.40326 seconds and 5 git commands to generate.