blob: b6f96b4b1f5c684f6bc2b3453364929033adcd4b [file] [log] [blame]
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001/******************************************************************************
2 *
3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 *
5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of version 2 of the GNU General Public License as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 *
21 * The full GNU General Public License is included in this distribution in the
22 * file called LICENSE.
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 *****************************************************************************/
29
30#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31
32#include <linux/kernel.h>
33#include <linux/module.h>
34#include <linux/init.h>
35#include <linux/pci.h>
36#include <linux/pci-aspm.h>
37#include <linux/slab.h>
38#include <linux/dma-mapping.h>
39#include <linux/delay.h>
40#include <linux/sched.h>
41#include <linux/skbuff.h>
42#include <linux/netdevice.h>
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080043#include <linux/firmware.h>
44#include <linux/etherdevice.h>
45#include <linux/if_arp.h>
46
47#include <net/mac80211.h>
48
49#include <asm/div64.h>
50
51#define DRV_NAME "iwl4965"
52
53#include "iwl-eeprom.h"
54#include "iwl-dev.h"
55#include "iwl-core.h"
56#include "iwl-io.h"
57#include "iwl-helpers.h"
58#include "iwl-sta.h"
59#include "iwl-4965-calib.h"
60#include "iwl-4965.h"
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080061
62
63/******************************************************************************
64 *
65 * module boiler plate
66 *
67 ******************************************************************************/
68
69/*
70 * module name, copyright, version, etc.
71 */
72#define DRV_DESCRIPTION "Intel(R) Wireless WiFi 4965 driver for Linux"
73
Stanislaw Gruszkad3175162011-11-15 11:25:42 +010074#ifdef CONFIG_IWLEGACY_DEBUG
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080075#define VD "d"
76#else
77#define VD
78#endif
79
80#define DRV_VERSION IWLWIFI_VERSION VD
81
82
83MODULE_DESCRIPTION(DRV_DESCRIPTION);
84MODULE_VERSION(DRV_VERSION);
85MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
86MODULE_LICENSE("GPL");
87MODULE_ALIAS("iwl4965");
88
Stanislaw Gruszkaa1751b22011-11-15 12:50:37 +010089void il4965_rx_missed_beacon_notif(struct il_priv *il,
90 struct il_rx_buf *rxb)
91
92{
93 struct il_rx_pkt *pkt = rxb_addr(rxb);
94 struct il_missed_beacon_notif *missed_beacon;
95
96 missed_beacon = &pkt->u.missed_beacon;
97 if (le32_to_cpu(missed_beacon->consecutive_missed_beacons) >
98 il->missed_beacon_threshold) {
99 D_CALIB(
100 "missed bcn cnsq %d totl %d rcd %d expctd %d\n",
101 le32_to_cpu(missed_beacon->consecutive_missed_beacons),
102 le32_to_cpu(missed_beacon->total_missed_becons),
103 le32_to_cpu(missed_beacon->num_recvd_beacons),
104 le32_to_cpu(missed_beacon->num_expected_beacons));
105 if (!test_bit(STATUS_SCANNING, &il->status))
106 il4965_init_sensitivity(il);
107 }
108}
109
110/* Calculate noise level, based on measurements during network silence just
111 * before arriving beacon. This measurement can be done only if we know
112 * exactly when to expect beacons, therefore only when we're associated. */
113static void il4965_rx_calc_noise(struct il_priv *il)
114{
115 struct stats_rx_non_phy *rx_info;
116 int num_active_rx = 0;
117 int total_silence = 0;
118 int bcn_silence_a, bcn_silence_b, bcn_silence_c;
119 int last_rx_noise;
120
121 rx_info = &(il->_4965.stats.rx.general);
122 bcn_silence_a =
123 le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER;
124 bcn_silence_b =
125 le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER;
126 bcn_silence_c =
127 le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER;
128
129 if (bcn_silence_a) {
130 total_silence += bcn_silence_a;
131 num_active_rx++;
132 }
133 if (bcn_silence_b) {
134 total_silence += bcn_silence_b;
135 num_active_rx++;
136 }
137 if (bcn_silence_c) {
138 total_silence += bcn_silence_c;
139 num_active_rx++;
140 }
141
142 /* Average among active antennas */
143 if (num_active_rx)
144 last_rx_noise = (total_silence / num_active_rx) - 107;
145 else
146 last_rx_noise = IL_NOISE_MEAS_NOT_AVAILABLE;
147
148 D_CALIB("inband silence a %u, b %u, c %u, dBm %d\n",
149 bcn_silence_a, bcn_silence_b, bcn_silence_c,
150 last_rx_noise);
151}
152
153#ifdef CONFIG_IWLEGACY_DEBUGFS
154/*
155 * based on the assumption of all stats counter are in DWORD
156 * FIXME: This function is for debugging, do not deal with
157 * the case of counters roll-over.
158 */
159static void il4965_accumulative_stats(struct il_priv *il,
160 __le32 *stats)
161{
162 int i, size;
163 __le32 *prev_stats;
164 u32 *accum_stats;
165 u32 *delta, *max_delta;
166 struct stats_general_common *general, *accum_general;
167 struct stats_tx *tx, *accum_tx;
168
169 prev_stats = (__le32 *)&il->_4965.stats;
170 accum_stats = (u32 *)&il->_4965.accum_stats;
171 size = sizeof(struct il_notif_stats);
172 general = &il->_4965.stats.general.common;
173 accum_general = &il->_4965.accum_stats.general.common;
174 tx = &il->_4965.stats.tx;
175 accum_tx = &il->_4965.accum_stats.tx;
176 delta = (u32 *)&il->_4965.delta_stats;
177 max_delta = (u32 *)&il->_4965.max_delta;
178
179 for (i = sizeof(__le32); i < size;
180 i += sizeof(__le32), stats++, prev_stats++, delta++,
181 max_delta++, accum_stats++) {
182 if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) {
183 *delta = (le32_to_cpu(*stats) -
184 le32_to_cpu(*prev_stats));
185 *accum_stats += *delta;
186 if (*delta > *max_delta)
187 *max_delta = *delta;
188 }
189 }
190
191 /* reset accumulative stats for "no-counter" type stats */
192 accum_general->temperature = general->temperature;
193 accum_general->ttl_timestamp = general->ttl_timestamp;
194}
195#endif
196
197#define REG_RECALIB_PERIOD (60)
198
199void il4965_rx_stats(struct il_priv *il,
200 struct il_rx_buf *rxb)
201{
202 int change;
203 struct il_rx_pkt *pkt = rxb_addr(rxb);
204
205 D_RX(
206 "Statistics notification received (%d vs %d).\n",
207 (int)sizeof(struct il_notif_stats),
208 le32_to_cpu(pkt->len_n_flags) &
209 FH_RSCSR_FRAME_SIZE_MSK);
210
211 change = ((il->_4965.stats.general.common.temperature !=
212 pkt->u.stats.general.common.temperature) ||
213 ((il->_4965.stats.flag &
214 STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
215 (pkt->u.stats.flag &
216 STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
217#ifdef CONFIG_IWLEGACY_DEBUGFS
218 il4965_accumulative_stats(il, (__le32 *)&pkt->u.stats);
219#endif
220
221 /* TODO: reading some of stats is unneeded */
222 memcpy(&il->_4965.stats, &pkt->u.stats,
223 sizeof(il->_4965.stats));
224
225 set_bit(STATUS_STATISTICS, &il->status);
226
227 /* Reschedule the stats timer to occur in
228 * REG_RECALIB_PERIOD seconds to ensure we get a
229 * thermal update even if the uCode doesn't give
230 * us one */
231 mod_timer(&il->stats_periodic, jiffies +
232 msecs_to_jiffies(REG_RECALIB_PERIOD * 1000));
233
234 if (unlikely(!test_bit(STATUS_SCANNING, &il->status)) &&
235 (pkt->hdr.cmd == STATISTICS_NOTIFICATION)) {
236 il4965_rx_calc_noise(il);
237 queue_work(il->workqueue, &il->run_time_calib_work);
238 }
239 if (il->cfg->ops->lib->temp_ops.temperature && change)
240 il->cfg->ops->lib->temp_ops.temperature(il);
241}
242
243void il4965_reply_stats(struct il_priv *il,
244 struct il_rx_buf *rxb)
245{
246 struct il_rx_pkt *pkt = rxb_addr(rxb);
247
248 if (le32_to_cpu(pkt->u.stats.flag) & UCODE_STATISTICS_CLEAR_MSK) {
249#ifdef CONFIG_IWLEGACY_DEBUGFS
250 memset(&il->_4965.accum_stats, 0,
251 sizeof(struct il_notif_stats));
252 memset(&il->_4965.delta_stats, 0,
253 sizeof(struct il_notif_stats));
254 memset(&il->_4965.max_delta, 0,
255 sizeof(struct il_notif_stats));
256#endif
257 D_RX("Statistics have been cleared\n");
258 }
259 il4965_rx_stats(il, rxb);
260}
261
262static const u8 tid_to_ac[] = {
263 IEEE80211_AC_BE,
264 IEEE80211_AC_BK,
265 IEEE80211_AC_BK,
266 IEEE80211_AC_BE,
267 IEEE80211_AC_VI,
268 IEEE80211_AC_VI,
269 IEEE80211_AC_VO,
270 IEEE80211_AC_VO
271};
272
273static inline int il4965_get_ac_from_tid(u16 tid)
274{
275 if (likely(tid < ARRAY_SIZE(tid_to_ac)))
276 return tid_to_ac[tid];
277
278 /* no support for TIDs 8-15 yet */
279 return -EINVAL;
280}
281
282static inline int
283il4965_get_fifo_from_tid(struct il_rxon_context *ctx, u16 tid)
284{
285 if (likely(tid < ARRAY_SIZE(tid_to_ac)))
286 return ctx->ac_to_fifo[tid_to_ac[tid]];
287
288 /* no support for TIDs 8-15 yet */
289 return -EINVAL;
290}
291
292/*
293 * handle build REPLY_TX command notification.
294 */
295static void il4965_tx_cmd_build_basic(struct il_priv *il,
296 struct sk_buff *skb,
297 struct il_tx_cmd *tx_cmd,
298 struct ieee80211_tx_info *info,
299 struct ieee80211_hdr *hdr,
300 u8 std_id)
301{
302 __le16 fc = hdr->frame_control;
303 __le32 tx_flags = tx_cmd->tx_flags;
304
305 tx_cmd->stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
306 if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) {
307 tx_flags |= TX_CMD_FLG_ACK_MSK;
308 if (ieee80211_is_mgmt(fc))
309 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
310 if (ieee80211_is_probe_resp(fc) &&
311 !(le16_to_cpu(hdr->seq_ctrl) & 0xf))
312 tx_flags |= TX_CMD_FLG_TSF_MSK;
313 } else {
314 tx_flags &= (~TX_CMD_FLG_ACK_MSK);
315 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
316 }
317
318 if (ieee80211_is_back_req(fc))
319 tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK;
320
321 tx_cmd->sta_id = std_id;
322 if (ieee80211_has_morefrags(fc))
323 tx_flags |= TX_CMD_FLG_MORE_FRAG_MSK;
324
325 if (ieee80211_is_data_qos(fc)) {
326 u8 *qc = ieee80211_get_qos_ctl(hdr);
327 tx_cmd->tid_tspec = qc[0] & 0xf;
328 tx_flags &= ~TX_CMD_FLG_SEQ_CTL_MSK;
329 } else {
330 tx_flags |= TX_CMD_FLG_SEQ_CTL_MSK;
331 }
332
333 il_tx_cmd_protection(il, info, fc, &tx_flags);
334
335 tx_flags &= ~(TX_CMD_FLG_ANT_SEL_MSK);
336 if (ieee80211_is_mgmt(fc)) {
337 if (ieee80211_is_assoc_req(fc) || ieee80211_is_reassoc_req(fc))
338 tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(3);
339 else
340 tx_cmd->timeout.pm_frame_timeout = cpu_to_le16(2);
341 } else {
342 tx_cmd->timeout.pm_frame_timeout = 0;
343 }
344
345 tx_cmd->driver_txop = 0;
346 tx_cmd->tx_flags = tx_flags;
347 tx_cmd->next_frame_len = 0;
348}
349
350#define RTS_DFAULT_RETRY_LIMIT 60
351
352static void il4965_tx_cmd_build_rate(struct il_priv *il,
353 struct il_tx_cmd *tx_cmd,
354 struct ieee80211_tx_info *info,
355 __le16 fc)
356{
357 u32 rate_flags;
358 int rate_idx;
359 u8 rts_retry_limit;
360 u8 data_retry_limit;
361 u8 rate_plcp;
362
363 /* Set retry limit on DATA packets and Probe Responses*/
364 if (ieee80211_is_probe_resp(fc))
365 data_retry_limit = 3;
366 else
367 data_retry_limit = IL4965_DEFAULT_TX_RETRY;
368 tx_cmd->data_retry_limit = data_retry_limit;
369
370 /* Set retry limit on RTS packets */
371 rts_retry_limit = RTS_DFAULT_RETRY_LIMIT;
372 if (data_retry_limit < rts_retry_limit)
373 rts_retry_limit = data_retry_limit;
374 tx_cmd->rts_retry_limit = rts_retry_limit;
375
376 /* DATA packets will use the uCode station table for rate/antenna
377 * selection */
378 if (ieee80211_is_data(fc)) {
379 tx_cmd->initial_rate_idx = 0;
380 tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
381 return;
382 }
383
384 /**
385 * If the current TX rate stored in mac80211 has the MCS bit set, it's
386 * not really a TX rate. Thus, we use the lowest supported rate for
387 * this band. Also use the lowest supported rate if the stored rate
388 * idx is invalid.
389 */
390 rate_idx = info->control.rates[0].idx;
391 if ((info->control.rates[0].flags & IEEE80211_TX_RC_MCS) ||
392 rate_idx < 0 || rate_idx > RATE_COUNT_LEGACY)
393 rate_idx = rate_lowest_index(&il->bands[info->band],
394 info->control.sta);
395 /* For 5 GHZ band, remap mac80211 rate indices into driver indices */
396 if (info->band == IEEE80211_BAND_5GHZ)
397 rate_idx += IL_FIRST_OFDM_RATE;
398 /* Get PLCP rate for tx_cmd->rate_n_flags */
399 rate_plcp = il_rates[rate_idx].plcp;
400 /* Zero out flags for this packet */
401 rate_flags = 0;
402
403 /* Set CCK flag as needed */
404 if (rate_idx >= IL_FIRST_CCK_RATE && rate_idx <= IL_LAST_CCK_RATE)
405 rate_flags |= RATE_MCS_CCK_MSK;
406
407 /* Set up antennas */
408 il->mgmt_tx_ant = il4965_toggle_tx_ant(il, il->mgmt_tx_ant,
409 il->hw_params.valid_tx_ant);
410
411 rate_flags |= il4965_ant_idx_to_flags(il->mgmt_tx_ant);
412
413 /* Set the rate in the TX cmd */
414 tx_cmd->rate_n_flags = il4965_hw_set_rate_n_flags(rate_plcp, rate_flags);
415}
416
417static void il4965_tx_cmd_build_hwcrypto(struct il_priv *il,
418 struct ieee80211_tx_info *info,
419 struct il_tx_cmd *tx_cmd,
420 struct sk_buff *skb_frag,
421 int sta_id)
422{
423 struct ieee80211_key_conf *keyconf = info->control.hw_key;
424
425 switch (keyconf->cipher) {
426 case WLAN_CIPHER_SUITE_CCMP:
427 tx_cmd->sec_ctl = TX_CMD_SEC_CCM;
428 memcpy(tx_cmd->key, keyconf->key, keyconf->keylen);
429 if (info->flags & IEEE80211_TX_CTL_AMPDU)
430 tx_cmd->tx_flags |= TX_CMD_FLG_AGG_CCMP_MSK;
431 D_TX("tx_cmd with AES hwcrypto\n");
432 break;
433
434 case WLAN_CIPHER_SUITE_TKIP:
435 tx_cmd->sec_ctl = TX_CMD_SEC_TKIP;
436 ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key);
437 D_TX("tx_cmd with tkip hwcrypto\n");
438 break;
439
440 case WLAN_CIPHER_SUITE_WEP104:
441 tx_cmd->sec_ctl |= TX_CMD_SEC_KEY128;
442 /* fall through */
443 case WLAN_CIPHER_SUITE_WEP40:
444 tx_cmd->sec_ctl |= (TX_CMD_SEC_WEP |
445 (keyconf->keyidx & TX_CMD_SEC_MSK) << TX_CMD_SEC_SHIFT);
446
447 memcpy(&tx_cmd->key[3], keyconf->key, keyconf->keylen);
448
449 D_TX("Configuring packet for WEP encryption "
450 "with key %d\n", keyconf->keyidx);
451 break;
452
453 default:
454 IL_ERR("Unknown encode cipher %x\n", keyconf->cipher);
455 break;
456 }
457}
458
459/*
460 * start REPLY_TX command process
461 */
462int il4965_tx_skb(struct il_priv *il, struct sk_buff *skb)
463{
464 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
465 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
466 struct ieee80211_sta *sta = info->control.sta;
467 struct il_station_priv *sta_priv = NULL;
468 struct il_tx_queue *txq;
469 struct il_queue *q;
470 struct il_device_cmd *out_cmd;
471 struct il_cmd_meta *out_meta;
472 struct il_tx_cmd *tx_cmd;
473 struct il_rxon_context *ctx = &il->ctx;
474 int txq_id;
475 dma_addr_t phys_addr;
476 dma_addr_t txcmd_phys;
477 dma_addr_t scratch_phys;
478 u16 len, firstlen, secondlen;
479 u16 seq_number = 0;
480 __le16 fc;
481 u8 hdr_len;
482 u8 sta_id;
483 u8 wait_write_ptr = 0;
484 u8 tid = 0;
485 u8 *qc = NULL;
486 unsigned long flags;
487 bool is_agg = false;
488
489 if (info->control.vif)
490 ctx = il_rxon_ctx_from_vif(info->control.vif);
491
492 spin_lock_irqsave(&il->lock, flags);
493 if (il_is_rfkill(il)) {
494 D_DROP("Dropping - RF KILL\n");
495 goto drop_unlock;
496 }
497
498 fc = hdr->frame_control;
499
500#ifdef CONFIG_IWLEGACY_DEBUG
501 if (ieee80211_is_auth(fc))
502 D_TX("Sending AUTH frame\n");
503 else if (ieee80211_is_assoc_req(fc))
504 D_TX("Sending ASSOC frame\n");
505 else if (ieee80211_is_reassoc_req(fc))
506 D_TX("Sending REASSOC frame\n");
507#endif
508
509 hdr_len = ieee80211_hdrlen(fc);
510
511 /* For management frames use broadcast id to do not break aggregation */
512 if (!ieee80211_is_data(fc))
513 sta_id = ctx->bcast_sta_id;
514 else {
515 /* Find idx into station table for destination station */
516 sta_id = il_sta_id_or_broadcast(il, ctx, info->control.sta);
517
518 if (sta_id == IL_INVALID_STATION) {
519 D_DROP("Dropping - INVALID STATION: %pM\n",
520 hdr->addr1);
521 goto drop_unlock;
522 }
523 }
524
525 D_TX("station Id %d\n", sta_id);
526
527 if (sta)
528 sta_priv = (void *)sta->drv_priv;
529
530 if (sta_priv && sta_priv->asleep &&
531 (info->flags & IEEE80211_TX_CTL_POLL_RESPONSE)) {
532 /*
533 * This sends an asynchronous command to the device,
534 * but we can rely on it being processed before the
535 * next frame is processed -- and the next frame to
536 * this station is the one that will consume this
537 * counter.
538 * For now set the counter to just 1 since we do not
539 * support uAPSD yet.
540 */
541 il4965_sta_modify_sleep_tx_count(il, sta_id, 1);
542 }
543
544 /*
545 * Send this frame after DTIM -- there's a special queue
546 * reserved for this for contexts that support AP mode.
547 */
548 if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
549 txq_id = ctx->mcast_queue;
550 /*
551 * The microcode will clear the more data
552 * bit in the last frame it transmits.
553 */
554 hdr->frame_control |=
555 cpu_to_le16(IEEE80211_FCTL_MOREDATA);
556 } else
557 txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)];
558
559 /* irqs already disabled/saved above when locking il->lock */
560 spin_lock(&il->sta_lock);
561
562 if (ieee80211_is_data_qos(fc)) {
563 qc = ieee80211_get_qos_ctl(hdr);
564 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
565 if (WARN_ON_ONCE(tid >= MAX_TID_COUNT)) {
566 spin_unlock(&il->sta_lock);
567 goto drop_unlock;
568 }
569 seq_number = il->stations[sta_id].tid[tid].seq_number;
570 seq_number &= IEEE80211_SCTL_SEQ;
571 hdr->seq_ctrl = hdr->seq_ctrl &
572 cpu_to_le16(IEEE80211_SCTL_FRAG);
573 hdr->seq_ctrl |= cpu_to_le16(seq_number);
574 seq_number += 0x10;
575 /* aggregation is on for this <sta,tid> */
576 if (info->flags & IEEE80211_TX_CTL_AMPDU &&
577 il->stations[sta_id].tid[tid].agg.state == IL_AGG_ON) {
578 txq_id = il->stations[sta_id].tid[tid].agg.txq_id;
579 is_agg = true;
580 }
581 }
582
583 txq = &il->txq[txq_id];
584 q = &txq->q;
585
586 if (unlikely(il_queue_space(q) < q->high_mark)) {
587 spin_unlock(&il->sta_lock);
588 goto drop_unlock;
589 }
590
591 if (ieee80211_is_data_qos(fc)) {
592 il->stations[sta_id].tid[tid].tfds_in_queue++;
593 if (!ieee80211_has_morefrags(fc))
594 il->stations[sta_id].tid[tid].seq_number = seq_number;
595 }
596
597 spin_unlock(&il->sta_lock);
598
599 /* Set up driver data for this TFD */
600 memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct il_tx_info));
601 txq->txb[q->write_ptr].skb = skb;
602 txq->txb[q->write_ptr].ctx = ctx;
603
604 /* Set up first empty entry in queue's array of Tx/cmd buffers */
605 out_cmd = txq->cmd[q->write_ptr];
606 out_meta = &txq->meta[q->write_ptr];
607 tx_cmd = &out_cmd->cmd.tx;
608 memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
609 memset(tx_cmd, 0, sizeof(struct il_tx_cmd));
610
611 /*
612 * Set up the Tx-command (not MAC!) header.
613 * Store the chosen Tx queue and TFD idx within the sequence field;
614 * after Tx, uCode's Tx response will return this value so driver can
615 * locate the frame within the tx queue and do post-tx processing.
616 */
617 out_cmd->hdr.cmd = REPLY_TX;
618 out_cmd->hdr.sequence = cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) |
619 IDX_TO_SEQ(q->write_ptr)));
620
621 /* Copy MAC header from skb into command buffer */
622 memcpy(tx_cmd->hdr, hdr, hdr_len);
623
624
625 /* Total # bytes to be transmitted */
626 len = (u16)skb->len;
627 tx_cmd->len = cpu_to_le16(len);
628
629 if (info->control.hw_key)
630 il4965_tx_cmd_build_hwcrypto(il, info, tx_cmd, skb, sta_id);
631
632 /* TODO need this for burst mode later on */
633 il4965_tx_cmd_build_basic(il, skb, tx_cmd, info, hdr, sta_id);
634 il_dbg_log_tx_data_frame(il, len, hdr);
635
636 il4965_tx_cmd_build_rate(il, tx_cmd, info, fc);
637
638 il_update_stats(il, true, fc, len);
639 /*
640 * Use the first empty entry in this queue's command buffer array
641 * to contain the Tx command and MAC header concatenated together
642 * (payload data will be in another buffer).
643 * Size of this varies, due to varying MAC header length.
644 * If end is not dword aligned, we'll have 2 extra bytes at the end
645 * of the MAC header (device reads on dword boundaries).
646 * We'll tell device about this padding later.
647 */
648 len = sizeof(struct il_tx_cmd) +
649 sizeof(struct il_cmd_header) + hdr_len;
650 firstlen = (len + 3) & ~3;
651
652 /* Tell NIC about any 2-byte padding after MAC header */
653 if (firstlen != len)
654 tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK;
655
656 /* Physical address of this Tx command's header (not MAC header!),
657 * within command buffer array. */
658 txcmd_phys = pci_map_single(il->pci_dev,
659 &out_cmd->hdr, firstlen,
660 PCI_DMA_BIDIRECTIONAL);
661 dma_unmap_addr_set(out_meta, mapping, txcmd_phys);
662 dma_unmap_len_set(out_meta, len, firstlen);
663 /* Add buffer containing Tx command and MAC(!) header to TFD's
664 * first entry */
665 il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq,
666 txcmd_phys, firstlen, 1, 0);
667
668 if (!ieee80211_has_morefrags(hdr->frame_control)) {
669 txq->need_update = 1;
670 } else {
671 wait_write_ptr = 1;
672 txq->need_update = 0;
673 }
674
675 /* Set up TFD's 2nd entry to point directly to remainder of skb,
676 * if any (802.11 null frames have no payload). */
677 secondlen = skb->len - hdr_len;
678 if (secondlen > 0) {
679 phys_addr = pci_map_single(il->pci_dev, skb->data + hdr_len,
680 secondlen, PCI_DMA_TODEVICE);
681 il->cfg->ops->lib->txq_attach_buf_to_tfd(il, txq,
682 phys_addr, secondlen,
683 0, 0);
684 }
685
686 scratch_phys = txcmd_phys + sizeof(struct il_cmd_header) +
687 offsetof(struct il_tx_cmd, scratch);
688
689 /* take back ownership of DMA buffer to enable update */
690 pci_dma_sync_single_for_cpu(il->pci_dev, txcmd_phys,
691 firstlen, PCI_DMA_BIDIRECTIONAL);
692 tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys);
693 tx_cmd->dram_msb_ptr = il_get_dma_hi_addr(scratch_phys);
694
695 D_TX("sequence nr = 0X%x\n",
696 le16_to_cpu(out_cmd->hdr.sequence));
697 D_TX("tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags));
698 il_print_hex_dump(il, IL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd));
699 il_print_hex_dump(il, IL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len);
700
701 /* Set up entry for this TFD in Tx byte-count array */
702 if (info->flags & IEEE80211_TX_CTL_AMPDU)
703 il->cfg->ops->lib->txq_update_byte_cnt_tbl(il, txq,
704 le16_to_cpu(tx_cmd->len));
705
706 pci_dma_sync_single_for_device(il->pci_dev, txcmd_phys,
707 firstlen, PCI_DMA_BIDIRECTIONAL);
708
709 /* Tell device the write idx *just past* this latest filled TFD */
710 q->write_ptr = il_queue_inc_wrap(q->write_ptr, q->n_bd);
711 il_txq_update_write_ptr(il, txq);
712 spin_unlock_irqrestore(&il->lock, flags);
713
714 /*
715 * At this point the frame is "transmitted" successfully
716 * and we will get a TX status notification eventually,
717 * regardless of the value of ret. "ret" only indicates
718 * whether or not we should update the write pointer.
719 */
720
721 /*
722 * Avoid atomic ops if it isn't an associated client.
723 * Also, if this is a packet for aggregation, don't
724 * increase the counter because the ucode will stop
725 * aggregation queues when their respective station
726 * goes to sleep.
727 */
728 if (sta_priv && sta_priv->client && !is_agg)
729 atomic_inc(&sta_priv->pending_frames);
730
731 if (il_queue_space(q) < q->high_mark && il->mac80211_registered) {
732 if (wait_write_ptr) {
733 spin_lock_irqsave(&il->lock, flags);
734 txq->need_update = 1;
735 il_txq_update_write_ptr(il, txq);
736 spin_unlock_irqrestore(&il->lock, flags);
737 } else {
738 il_stop_queue(il, txq);
739 }
740 }
741
742 return 0;
743
744drop_unlock:
745 spin_unlock_irqrestore(&il->lock, flags);
746 return -1;
747}
748
749static inline int il4965_alloc_dma_ptr(struct il_priv *il,
750 struct il_dma_ptr *ptr, size_t size)
751{
752 ptr->addr = dma_alloc_coherent(&il->pci_dev->dev, size, &ptr->dma,
753 GFP_KERNEL);
754 if (!ptr->addr)
755 return -ENOMEM;
756 ptr->size = size;
757 return 0;
758}
759
760static inline void il4965_free_dma_ptr(struct il_priv *il,
761 struct il_dma_ptr *ptr)
762{
763 if (unlikely(!ptr->addr))
764 return;
765
766 dma_free_coherent(&il->pci_dev->dev, ptr->size, ptr->addr, ptr->dma);
767 memset(ptr, 0, sizeof(*ptr));
768}
769
770/**
771 * il4965_hw_txq_ctx_free - Free TXQ Context
772 *
773 * Destroy all TX DMA queues and structures
774 */
775void il4965_hw_txq_ctx_free(struct il_priv *il)
776{
777 int txq_id;
778
779 /* Tx queues */
780 if (il->txq) {
781 for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++)
782 if (txq_id == il->cmd_queue)
783 il_cmd_queue_free(il);
784 else
785 il_tx_queue_free(il, txq_id);
786 }
787 il4965_free_dma_ptr(il, &il->kw);
788
789 il4965_free_dma_ptr(il, &il->scd_bc_tbls);
790
791 /* free tx queue structure */
792 il_txq_mem(il);
793}
794
795/**
796 * il4965_txq_ctx_alloc - allocate TX queue context
797 * Allocate all Tx DMA structures and initialize them
798 *
799 * @param il
800 * @return error code
801 */
802int il4965_txq_ctx_alloc(struct il_priv *il)
803{
804 int ret;
805 int txq_id, slots_num;
806 unsigned long flags;
807
808 /* Free all tx/cmd queues and keep-warm buffer */
809 il4965_hw_txq_ctx_free(il);
810
811 ret = il4965_alloc_dma_ptr(il, &il->scd_bc_tbls,
812 il->hw_params.scd_bc_tbls_size);
813 if (ret) {
814 IL_ERR("Scheduler BC Table allocation failed\n");
815 goto error_bc_tbls;
816 }
817 /* Alloc keep-warm buffer */
818 ret = il4965_alloc_dma_ptr(il, &il->kw, IL_KW_SIZE);
819 if (ret) {
820 IL_ERR("Keep Warm allocation failed\n");
821 goto error_kw;
822 }
823
824 /* allocate tx queue structure */
825 ret = il_alloc_txq_mem(il);
826 if (ret)
827 goto error;
828
829 spin_lock_irqsave(&il->lock, flags);
830
831 /* Turn off all Tx DMA fifos */
832 il4965_txq_set_sched(il, 0);
833
834 /* Tell NIC where to find the "keep warm" buffer */
835 il_wr(il, FH_KW_MEM_ADDR_REG, il->kw.dma >> 4);
836
837 spin_unlock_irqrestore(&il->lock, flags);
838
839 /* Alloc and init all Tx queues, including the command queue (#4/#9) */
840 for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) {
841 slots_num = (txq_id == il->cmd_queue) ?
842 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
843 ret = il_tx_queue_init(il,
844 &il->txq[txq_id], slots_num,
845 txq_id);
846 if (ret) {
847 IL_ERR("Tx %d queue init failed\n", txq_id);
848 goto error;
849 }
850 }
851
852 return ret;
853
854 error:
855 il4965_hw_txq_ctx_free(il);
856 il4965_free_dma_ptr(il, &il->kw);
857 error_kw:
858 il4965_free_dma_ptr(il, &il->scd_bc_tbls);
859 error_bc_tbls:
860 return ret;
861}
862
863void il4965_txq_ctx_reset(struct il_priv *il)
864{
865 int txq_id, slots_num;
866 unsigned long flags;
867
868 spin_lock_irqsave(&il->lock, flags);
869
870 /* Turn off all Tx DMA fifos */
871 il4965_txq_set_sched(il, 0);
872
873 /* Tell NIC where to find the "keep warm" buffer */
874 il_wr(il, FH_KW_MEM_ADDR_REG, il->kw.dma >> 4);
875
876 spin_unlock_irqrestore(&il->lock, flags);
877
878 /* Alloc and init all Tx queues, including the command queue (#4) */
879 for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++) {
880 slots_num = txq_id == il->cmd_queue ?
881 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
882 il_tx_queue_reset(il, &il->txq[txq_id],
883 slots_num, txq_id);
884 }
885}
886
887/**
888 * il4965_txq_ctx_stop - Stop all Tx DMA channels
889 */
890void il4965_txq_ctx_stop(struct il_priv *il)
891{
892 int ch, txq_id;
893 unsigned long flags;
894
895 /* Turn off all Tx DMA fifos */
896 spin_lock_irqsave(&il->lock, flags);
897
898 il4965_txq_set_sched(il, 0);
899
900 /* Stop each Tx DMA channel, and wait for it to be idle */
901 for (ch = 0; ch < il->hw_params.dma_chnl_num; ch++) {
902 il_wr(il,
903 FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
904 if (il_poll_bit(il, FH_TSSR_TX_STATUS_REG,
905 FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch),
906 1000))
907 IL_ERR("Failing on timeout while stopping"
908 " DMA channel %d [0x%08x]", ch,
909 il_rd(il,
910 FH_TSSR_TX_STATUS_REG));
911 }
912 spin_unlock_irqrestore(&il->lock, flags);
913
914 if (!il->txq)
915 return;
916
917 /* Unmap DMA from host system and free skb's */
918 for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++)
919 if (txq_id == il->cmd_queue)
920 il_cmd_queue_unmap(il);
921 else
922 il_tx_queue_unmap(il, txq_id);
923}
924
925/*
926 * Find first available (lowest unused) Tx Queue, mark it "active".
927 * Called only when finding queue for aggregation.
928 * Should never return anything < 7, because they should already
929 * be in use as EDCA AC (0-3), Command (4), reserved (5, 6)
930 */
931static int il4965_txq_ctx_activate_free(struct il_priv *il)
932{
933 int txq_id;
934
935 for (txq_id = 0; txq_id < il->hw_params.max_txq_num; txq_id++)
936 if (!test_and_set_bit(txq_id, &il->txq_ctx_active_msk))
937 return txq_id;
938 return -1;
939}
940
941/**
942 * il4965_tx_queue_stop_scheduler - Stop queue, but keep configuration
943 */
944static void il4965_tx_queue_stop_scheduler(struct il_priv *il,
945 u16 txq_id)
946{
947 /* Simply stop the queue, but don't change any configuration;
948 * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */
949 il_wr_prph(il,
950 IL49_SCD_QUEUE_STATUS_BITS(txq_id),
951 (0 << IL49_SCD_QUEUE_STTS_REG_POS_ACTIVE)|
952 (1 << IL49_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
953}
954
955/**
956 * il4965_tx_queue_set_q2ratid - Map unique receiver/tid combination to a queue
957 */
958static int il4965_tx_queue_set_q2ratid(struct il_priv *il, u16 ra_tid,
959 u16 txq_id)
960{
961 u32 tbl_dw_addr;
962 u32 tbl_dw;
963 u16 scd_q2ratid;
964
965 scd_q2ratid = ra_tid & IL_SCD_QUEUE_RA_TID_MAP_RATID_MSK;
966
967 tbl_dw_addr = il->scd_base_addr +
968 IL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id);
969
970 tbl_dw = il_read_targ_mem(il, tbl_dw_addr);
971
972 if (txq_id & 0x1)
973 tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF);
974 else
975 tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000);
976
977 il_write_targ_mem(il, tbl_dw_addr, tbl_dw);
978
979 return 0;
980}
981
982/**
983 * il4965_tx_queue_agg_enable - Set up & enable aggregation for selected queue
984 *
985 * NOTE: txq_id must be greater than IL49_FIRST_AMPDU_QUEUE,
986 * i.e. it must be one of the higher queues used for aggregation
987 */
988static int il4965_txq_agg_enable(struct il_priv *il, int txq_id,
989 int tx_fifo, int sta_id, int tid, u16 ssn_idx)
990{
991 unsigned long flags;
992 u16 ra_tid;
993 int ret;
994
995 if ((IL49_FIRST_AMPDU_QUEUE > txq_id) ||
996 (IL49_FIRST_AMPDU_QUEUE +
997 il->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
998 IL_WARN(
999 "queue number out of range: %d, must be %d to %d\n",
1000 txq_id, IL49_FIRST_AMPDU_QUEUE,
1001 IL49_FIRST_AMPDU_QUEUE +
1002 il->cfg->base_params->num_of_ampdu_queues - 1);
1003 return -EINVAL;
1004 }
1005
1006 ra_tid = BUILD_RAxTID(sta_id, tid);
1007
1008 /* Modify device's station table to Tx this TID */
1009 ret = il4965_sta_tx_modify_enable_tid(il, sta_id, tid);
1010 if (ret)
1011 return ret;
1012
1013 spin_lock_irqsave(&il->lock, flags);
1014
1015 /* Stop this Tx queue before configuring it */
1016 il4965_tx_queue_stop_scheduler(il, txq_id);
1017
1018 /* Map receiver-address / traffic-ID to this queue */
1019 il4965_tx_queue_set_q2ratid(il, ra_tid, txq_id);
1020
1021 /* Set this queue as a chain-building queue */
1022 il_set_bits_prph(il, IL49_SCD_QUEUECHAIN_SEL, (1 << txq_id));
1023
1024 /* Place first TFD at idx corresponding to start sequence number.
1025 * Assumes that ssn_idx is valid (!= 0xFFF) */
1026 il->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
1027 il->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
1028 il4965_set_wr_ptrs(il, txq_id, ssn_idx);
1029
1030 /* Set up Tx win size and frame limit for this queue */
1031 il_write_targ_mem(il,
1032 il->scd_base_addr + IL49_SCD_CONTEXT_QUEUE_OFFSET(txq_id),
1033 (SCD_WIN_SIZE << IL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) &
1034 IL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK);
1035
1036 il_write_targ_mem(il, il->scd_base_addr +
1037 IL49_SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32),
1038 (SCD_FRAME_LIMIT << IL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS)
1039 & IL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK);
1040
1041 il_set_bits_prph(il, IL49_SCD_INTERRUPT_MASK, (1 << txq_id));
1042
1043 /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */
1044 il4965_tx_queue_set_status(il, &il->txq[txq_id], tx_fifo, 1);
1045
1046 spin_unlock_irqrestore(&il->lock, flags);
1047
1048 return 0;
1049}
1050
1051
1052int il4965_tx_agg_start(struct il_priv *il, struct ieee80211_vif *vif,
1053 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
1054{
1055 int sta_id;
1056 int tx_fifo;
1057 int txq_id;
1058 int ret;
1059 unsigned long flags;
1060 struct il_tid_data *tid_data;
1061
1062 tx_fifo = il4965_get_fifo_from_tid(il_rxon_ctx_from_vif(vif), tid);
1063 if (unlikely(tx_fifo < 0))
1064 return tx_fifo;
1065
1066 IL_WARN("%s on ra = %pM tid = %d\n",
1067 __func__, sta->addr, tid);
1068
1069 sta_id = il_sta_id(sta);
1070 if (sta_id == IL_INVALID_STATION) {
1071 IL_ERR("Start AGG on invalid station\n");
1072 return -ENXIO;
1073 }
1074 if (unlikely(tid >= MAX_TID_COUNT))
1075 return -EINVAL;
1076
1077 if (il->stations[sta_id].tid[tid].agg.state != IL_AGG_OFF) {
1078 IL_ERR("Start AGG when state is not IL_AGG_OFF !\n");
1079 return -ENXIO;
1080 }
1081
1082 txq_id = il4965_txq_ctx_activate_free(il);
1083 if (txq_id == -1) {
1084 IL_ERR("No free aggregation queue available\n");
1085 return -ENXIO;
1086 }
1087
1088 spin_lock_irqsave(&il->sta_lock, flags);
1089 tid_data = &il->stations[sta_id].tid[tid];
1090 *ssn = SEQ_TO_SN(tid_data->seq_number);
1091 tid_data->agg.txq_id = txq_id;
1092 il_set_swq_id(&il->txq[txq_id],
1093 il4965_get_ac_from_tid(tid), txq_id);
1094 spin_unlock_irqrestore(&il->sta_lock, flags);
1095
1096 ret = il4965_txq_agg_enable(il, txq_id, tx_fifo,
1097 sta_id, tid, *ssn);
1098 if (ret)
1099 return ret;
1100
1101 spin_lock_irqsave(&il->sta_lock, flags);
1102 tid_data = &il->stations[sta_id].tid[tid];
1103 if (tid_data->tfds_in_queue == 0) {
1104 D_HT("HW queue is empty\n");
1105 tid_data->agg.state = IL_AGG_ON;
1106 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1107 } else {
1108 D_HT(
1109 "HW queue is NOT empty: %d packets in HW queue\n",
1110 tid_data->tfds_in_queue);
1111 tid_data->agg.state = IL_EMPTYING_HW_QUEUE_ADDBA;
1112 }
1113 spin_unlock_irqrestore(&il->sta_lock, flags);
1114 return ret;
1115}
1116
1117/**
1118 * txq_id must be greater than IL49_FIRST_AMPDU_QUEUE
1119 * il->lock must be held by the caller
1120 */
1121static int il4965_txq_agg_disable(struct il_priv *il, u16 txq_id,
1122 u16 ssn_idx, u8 tx_fifo)
1123{
1124 if ((IL49_FIRST_AMPDU_QUEUE > txq_id) ||
1125 (IL49_FIRST_AMPDU_QUEUE +
1126 il->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
1127 IL_WARN(
1128 "queue number out of range: %d, must be %d to %d\n",
1129 txq_id, IL49_FIRST_AMPDU_QUEUE,
1130 IL49_FIRST_AMPDU_QUEUE +
1131 il->cfg->base_params->num_of_ampdu_queues - 1);
1132 return -EINVAL;
1133 }
1134
1135 il4965_tx_queue_stop_scheduler(il, txq_id);
1136
1137 il_clear_bits_prph(il,
1138 IL49_SCD_QUEUECHAIN_SEL, (1 << txq_id));
1139
1140 il->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
1141 il->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
1142 /* supposes that ssn_idx is valid (!= 0xFFF) */
1143 il4965_set_wr_ptrs(il, txq_id, ssn_idx);
1144
1145 il_clear_bits_prph(il,
1146 IL49_SCD_INTERRUPT_MASK, (1 << txq_id));
1147 il_txq_ctx_deactivate(il, txq_id);
1148 il4965_tx_queue_set_status(il, &il->txq[txq_id], tx_fifo, 0);
1149
1150 return 0;
1151}
1152
1153int il4965_tx_agg_stop(struct il_priv *il, struct ieee80211_vif *vif,
1154 struct ieee80211_sta *sta, u16 tid)
1155{
1156 int tx_fifo_id, txq_id, sta_id, ssn;
1157 struct il_tid_data *tid_data;
1158 int write_ptr, read_ptr;
1159 unsigned long flags;
1160
1161 tx_fifo_id = il4965_get_fifo_from_tid(il_rxon_ctx_from_vif(vif), tid);
1162 if (unlikely(tx_fifo_id < 0))
1163 return tx_fifo_id;
1164
1165 sta_id = il_sta_id(sta);
1166
1167 if (sta_id == IL_INVALID_STATION) {
1168 IL_ERR("Invalid station for AGG tid %d\n", tid);
1169 return -ENXIO;
1170 }
1171
1172 spin_lock_irqsave(&il->sta_lock, flags);
1173
1174 tid_data = &il->stations[sta_id].tid[tid];
1175 ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
1176 txq_id = tid_data->agg.txq_id;
1177
1178 switch (il->stations[sta_id].tid[tid].agg.state) {
1179 case IL_EMPTYING_HW_QUEUE_ADDBA:
1180 /*
1181 * This can happen if the peer stops aggregation
1182 * again before we've had a chance to drain the
1183 * queue we selected previously, i.e. before the
1184 * session was really started completely.
1185 */
1186 D_HT("AGG stop before setup done\n");
1187 goto turn_off;
1188 case IL_AGG_ON:
1189 break;
1190 default:
1191 IL_WARN("Stopping AGG while state not ON or starting\n");
1192 }
1193
1194 write_ptr = il->txq[txq_id].q.write_ptr;
1195 read_ptr = il->txq[txq_id].q.read_ptr;
1196
1197 /* The queue is not empty */
1198 if (write_ptr != read_ptr) {
1199 D_HT("Stopping a non empty AGG HW QUEUE\n");
1200 il->stations[sta_id].tid[tid].agg.state =
1201 IL_EMPTYING_HW_QUEUE_DELBA;
1202 spin_unlock_irqrestore(&il->sta_lock, flags);
1203 return 0;
1204 }
1205
1206 D_HT("HW queue is empty\n");
1207 turn_off:
1208 il->stations[sta_id].tid[tid].agg.state = IL_AGG_OFF;
1209
1210 /* do not restore/save irqs */
1211 spin_unlock(&il->sta_lock);
1212 spin_lock(&il->lock);
1213
1214 /*
1215 * the only reason this call can fail is queue number out of range,
1216 * which can happen if uCode is reloaded and all the station
1217 * information are lost. if it is outside the range, there is no need
1218 * to deactivate the uCode queue, just return "success" to allow
1219 * mac80211 to clean up it own data.
1220 */
1221 il4965_txq_agg_disable(il, txq_id, ssn, tx_fifo_id);
1222 spin_unlock_irqrestore(&il->lock, flags);
1223
1224 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1225
1226 return 0;
1227}
1228
1229int il4965_txq_check_empty(struct il_priv *il,
1230 int sta_id, u8 tid, int txq_id)
1231{
1232 struct il_queue *q = &il->txq[txq_id].q;
1233 u8 *addr = il->stations[sta_id].sta.sta.addr;
1234 struct il_tid_data *tid_data = &il->stations[sta_id].tid[tid];
1235 struct il_rxon_context *ctx;
1236
1237 ctx = &il->ctx;
1238
1239 lockdep_assert_held(&il->sta_lock);
1240
1241 switch (il->stations[sta_id].tid[tid].agg.state) {
1242 case IL_EMPTYING_HW_QUEUE_DELBA:
1243 /* We are reclaiming the last packet of the */
1244 /* aggregated HW queue */
1245 if (txq_id == tid_data->agg.txq_id &&
1246 q->read_ptr == q->write_ptr) {
1247 u16 ssn = SEQ_TO_SN(tid_data->seq_number);
1248 int tx_fifo = il4965_get_fifo_from_tid(ctx, tid);
1249 D_HT(
1250 "HW queue empty: continue DELBA flow\n");
1251 il4965_txq_agg_disable(il, txq_id, ssn, tx_fifo);
1252 tid_data->agg.state = IL_AGG_OFF;
1253 ieee80211_stop_tx_ba_cb_irqsafe(ctx->vif, addr, tid);
1254 }
1255 break;
1256 case IL_EMPTYING_HW_QUEUE_ADDBA:
1257 /* We are reclaiming the last packet of the queue */
1258 if (tid_data->tfds_in_queue == 0) {
1259 D_HT(
1260 "HW queue empty: continue ADDBA flow\n");
1261 tid_data->agg.state = IL_AGG_ON;
1262 ieee80211_start_tx_ba_cb_irqsafe(ctx->vif, addr, tid);
1263 }
1264 break;
1265 }
1266
1267 return 0;
1268}
1269
1270static void il4965_non_agg_tx_status(struct il_priv *il,
1271 struct il_rxon_context *ctx,
1272 const u8 *addr1)
1273{
1274 struct ieee80211_sta *sta;
1275 struct il_station_priv *sta_priv;
1276
1277 rcu_read_lock();
1278 sta = ieee80211_find_sta(ctx->vif, addr1);
1279 if (sta) {
1280 sta_priv = (void *)sta->drv_priv;
1281 /* avoid atomic ops if this isn't a client */
1282 if (sta_priv->client &&
1283 atomic_dec_return(&sta_priv->pending_frames) == 0)
1284 ieee80211_sta_block_awake(il->hw, sta, false);
1285 }
1286 rcu_read_unlock();
1287}
1288
1289static void
1290il4965_tx_status(struct il_priv *il, struct il_tx_info *tx_info,
1291 bool is_agg)
1292{
1293 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx_info->skb->data;
1294
1295 if (!is_agg)
1296 il4965_non_agg_tx_status(il, tx_info->ctx, hdr->addr1);
1297
1298 ieee80211_tx_status_irqsafe(il->hw, tx_info->skb);
1299}
1300
1301int il4965_tx_queue_reclaim(struct il_priv *il, int txq_id, int idx)
1302{
1303 struct il_tx_queue *txq = &il->txq[txq_id];
1304 struct il_queue *q = &txq->q;
1305 struct il_tx_info *tx_info;
1306 int nfreed = 0;
1307 struct ieee80211_hdr *hdr;
1308
1309 if (idx >= q->n_bd || il_queue_used(q, idx) == 0) {
1310 IL_ERR("Read idx for DMA queue txq id (%d), idx %d, "
1311 "is out of range [0-%d] %d %d.\n", txq_id,
1312 idx, q->n_bd, q->write_ptr, q->read_ptr);
1313 return 0;
1314 }
1315
1316 for (idx = il_queue_inc_wrap(idx, q->n_bd);
1317 q->read_ptr != idx;
1318 q->read_ptr = il_queue_inc_wrap(q->read_ptr, q->n_bd)) {
1319
1320 tx_info = &txq->txb[txq->q.read_ptr];
1321
1322 if (WARN_ON_ONCE(tx_info->skb == NULL))
1323 continue;
1324
1325 hdr = (struct ieee80211_hdr *)tx_info->skb->data;
1326 if (ieee80211_is_data_qos(hdr->frame_control))
1327 nfreed++;
1328
1329 il4965_tx_status(il, tx_info,
1330 txq_id >= IL4965_FIRST_AMPDU_QUEUE);
1331 tx_info->skb = NULL;
1332
1333 il->cfg->ops->lib->txq_free_tfd(il, txq);
1334 }
1335 return nfreed;
1336}
1337
1338/**
1339 * il4965_tx_status_reply_compressed_ba - Update tx status from block-ack
1340 *
1341 * Go through block-ack's bitmap of ACK'd frames, update driver's record of
1342 * ACK vs. not. This gets sent to mac80211, then to rate scaling algo.
1343 */
1344static int il4965_tx_status_reply_compressed_ba(struct il_priv *il,
1345 struct il_ht_agg *agg,
1346 struct il_compressed_ba_resp *ba_resp)
1347
1348{
1349 int i, sh, ack;
1350 u16 seq_ctl = le16_to_cpu(ba_resp->seq_ctl);
1351 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
1352 int successes = 0;
1353 struct ieee80211_tx_info *info;
1354 u64 bitmap, sent_bitmap;
1355
1356 if (unlikely(!agg->wait_for_ba)) {
1357 if (unlikely(ba_resp->bitmap))
1358 IL_ERR("Received BA when not expected\n");
1359 return -EINVAL;
1360 }
1361
1362 /* Mark that the expected block-ack response arrived */
1363 agg->wait_for_ba = 0;
1364 D_TX_REPLY("BA %d %d\n", agg->start_idx,
1365 ba_resp->seq_ctl);
1366
1367 /* Calculate shift to align block-ack bits with our Tx win bits */
1368 sh = agg->start_idx - SEQ_TO_IDX(seq_ctl >> 4);
1369 if (sh < 0) /* tbw something is wrong with indices */
1370 sh += 0x100;
1371
1372 if (agg->frame_count > (64 - sh)) {
1373 D_TX_REPLY("more frames than bitmap size");
1374 return -1;
1375 }
1376
1377 /* don't use 64-bit values for now */
1378 bitmap = le64_to_cpu(ba_resp->bitmap) >> sh;
1379
1380 /* check for success or failure according to the
1381 * transmitted bitmap and block-ack bitmap */
1382 sent_bitmap = bitmap & agg->bitmap;
1383
1384 /* For each frame attempted in aggregation,
1385 * update driver's record of tx frame's status. */
1386 i = 0;
1387 while (sent_bitmap) {
1388 ack = sent_bitmap & 1ULL;
1389 successes += ack;
1390 D_TX_REPLY("%s ON i=%d idx=%d raw=%d\n",
1391 ack ? "ACK" : "NACK", i,
1392 (agg->start_idx + i) & 0xff,
1393 agg->start_idx + i);
1394 sent_bitmap >>= 1;
1395 ++i;
1396 }
1397
1398 D_TX_REPLY("Bitmap %llx\n",
1399 (unsigned long long)bitmap);
1400
1401 info = IEEE80211_SKB_CB(il->txq[scd_flow].txb[agg->start_idx].skb);
1402 memset(&info->status, 0, sizeof(info->status));
1403 info->flags |= IEEE80211_TX_STAT_ACK;
1404 info->flags |= IEEE80211_TX_STAT_AMPDU;
1405 info->status.ampdu_ack_len = successes;
1406 info->status.ampdu_len = agg->frame_count;
1407 il4965_hwrate_to_tx_control(il, agg->rate_n_flags, info);
1408
1409 return 0;
1410}
1411
1412/**
1413 * translate ucode response to mac80211 tx status control values
1414 */
1415void il4965_hwrate_to_tx_control(struct il_priv *il, u32 rate_n_flags,
1416 struct ieee80211_tx_info *info)
1417{
1418 struct ieee80211_tx_rate *r = &info->control.rates[0];
1419
1420 info->antenna_sel_tx =
1421 ((rate_n_flags & RATE_MCS_ANT_ABC_MSK) >> RATE_MCS_ANT_POS);
1422 if (rate_n_flags & RATE_MCS_HT_MSK)
1423 r->flags |= IEEE80211_TX_RC_MCS;
1424 if (rate_n_flags & RATE_MCS_GF_MSK)
1425 r->flags |= IEEE80211_TX_RC_GREEN_FIELD;
1426 if (rate_n_flags & RATE_MCS_HT40_MSK)
1427 r->flags |= IEEE80211_TX_RC_40_MHZ_WIDTH;
1428 if (rate_n_flags & RATE_MCS_DUP_MSK)
1429 r->flags |= IEEE80211_TX_RC_DUP_DATA;
1430 if (rate_n_flags & RATE_MCS_SGI_MSK)
1431 r->flags |= IEEE80211_TX_RC_SHORT_GI;
1432 r->idx = il4965_hwrate_to_mac80211_idx(rate_n_flags, info->band);
1433}
1434
1435/**
1436 * il4965_rx_reply_compressed_ba - Handler for REPLY_COMPRESSED_BA
1437 *
1438 * Handles block-acknowledge notification from device, which reports success
1439 * of frames sent via aggregation.
1440 */
1441void il4965_rx_reply_compressed_ba(struct il_priv *il,
1442 struct il_rx_buf *rxb)
1443{
1444 struct il_rx_pkt *pkt = rxb_addr(rxb);
1445 struct il_compressed_ba_resp *ba_resp = &pkt->u.compressed_ba;
1446 struct il_tx_queue *txq = NULL;
1447 struct il_ht_agg *agg;
1448 int idx;
1449 int sta_id;
1450 int tid;
1451 unsigned long flags;
1452
1453 /* "flow" corresponds to Tx queue */
1454 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
1455
1456 /* "ssn" is start of block-ack Tx win, corresponds to idx
1457 * (in Tx queue's circular buffer) of first TFD/frame in win */
1458 u16 ba_resp_scd_ssn = le16_to_cpu(ba_resp->scd_ssn);
1459
1460 if (scd_flow >= il->hw_params.max_txq_num) {
1461 IL_ERR(
1462 "BUG_ON scd_flow is bigger than number of queues\n");
1463 return;
1464 }
1465
1466 txq = &il->txq[scd_flow];
1467 sta_id = ba_resp->sta_id;
1468 tid = ba_resp->tid;
1469 agg = &il->stations[sta_id].tid[tid].agg;
1470 if (unlikely(agg->txq_id != scd_flow)) {
1471 /*
1472 * FIXME: this is a uCode bug which need to be addressed,
1473 * log the information and return for now!
1474 * since it is possible happen very often and in order
1475 * not to fill the syslog, don't enable the logging by default
1476 */
1477 D_TX_REPLY(
1478 "BA scd_flow %d does not match txq_id %d\n",
1479 scd_flow, agg->txq_id);
1480 return;
1481 }
1482
1483 /* Find idx just before block-ack win */
1484 idx = il_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd);
1485
1486 spin_lock_irqsave(&il->sta_lock, flags);
1487
1488 D_TX_REPLY("REPLY_COMPRESSED_BA [%d] Received from %pM, "
1489 "sta_id = %d\n",
1490 agg->wait_for_ba,
1491 (u8 *) &ba_resp->sta_addr_lo32,
1492 ba_resp->sta_id);
1493 D_TX_REPLY("TID = %d, SeqCtl = %d, bitmap = 0x%llx,"
1494 "scd_flow = "
1495 "%d, scd_ssn = %d\n",
1496 ba_resp->tid,
1497 ba_resp->seq_ctl,
1498 (unsigned long long)le64_to_cpu(ba_resp->bitmap),
1499 ba_resp->scd_flow,
1500 ba_resp->scd_ssn);
1501 D_TX_REPLY("DAT start_idx = %d, bitmap = 0x%llx\n",
1502 agg->start_idx,
1503 (unsigned long long)agg->bitmap);
1504
1505 /* Update driver's record of ACK vs. not for each frame in win */
1506 il4965_tx_status_reply_compressed_ba(il, agg, ba_resp);
1507
1508 /* Release all TFDs before the SSN, i.e. all TFDs in front of
1509 * block-ack win (we assume that they've been successfully
1510 * transmitted ... if not, it's too late anyway). */
1511 if (txq->q.read_ptr != (ba_resp_scd_ssn & 0xff)) {
1512 /* calculate mac80211 ampdu sw queue to wake */
1513 int freed = il4965_tx_queue_reclaim(il, scd_flow, idx);
1514 il4965_free_tfds_in_queue(il, sta_id, tid, freed);
1515
1516 if (il_queue_space(&txq->q) > txq->q.low_mark &&
1517 il->mac80211_registered &&
1518 agg->state != IL_EMPTYING_HW_QUEUE_DELBA)
1519 il_wake_queue(il, txq);
1520
1521 il4965_txq_check_empty(il, sta_id, tid, scd_flow);
1522 }
1523
1524 spin_unlock_irqrestore(&il->sta_lock, flags);
1525}
1526
1527#ifdef CONFIG_IWLEGACY_DEBUG
1528const char *il4965_get_tx_fail_reason(u32 status)
1529{
1530#define TX_STATUS_FAIL(x) case TX_STATUS_FAIL_ ## x: return #x
1531#define TX_STATUS_POSTPONE(x) case TX_STATUS_POSTPONE_ ## x: return #x
1532
1533 switch (status & TX_STATUS_MSK) {
1534 case TX_STATUS_SUCCESS:
1535 return "SUCCESS";
1536 TX_STATUS_POSTPONE(DELAY);
1537 TX_STATUS_POSTPONE(FEW_BYTES);
1538 TX_STATUS_POSTPONE(QUIET_PERIOD);
1539 TX_STATUS_POSTPONE(CALC_TTAK);
1540 TX_STATUS_FAIL(INTERNAL_CROSSED_RETRY);
1541 TX_STATUS_FAIL(SHORT_LIMIT);
1542 TX_STATUS_FAIL(LONG_LIMIT);
1543 TX_STATUS_FAIL(FIFO_UNDERRUN);
1544 TX_STATUS_FAIL(DRAIN_FLOW);
1545 TX_STATUS_FAIL(RFKILL_FLUSH);
1546 TX_STATUS_FAIL(LIFE_EXPIRE);
1547 TX_STATUS_FAIL(DEST_PS);
1548 TX_STATUS_FAIL(HOST_ABORTED);
1549 TX_STATUS_FAIL(BT_RETRY);
1550 TX_STATUS_FAIL(STA_INVALID);
1551 TX_STATUS_FAIL(FRAG_DROPPED);
1552 TX_STATUS_FAIL(TID_DISABLE);
1553 TX_STATUS_FAIL(FIFO_FLUSHED);
1554 TX_STATUS_FAIL(INSUFFICIENT_CF_POLL);
1555 TX_STATUS_FAIL(PASSIVE_NO_RX);
1556 TX_STATUS_FAIL(NO_BEACON_ON_RADAR);
1557 }
1558
1559 return "UNKNOWN";
1560
1561#undef TX_STATUS_FAIL
1562#undef TX_STATUS_POSTPONE
1563}
1564#endif /* CONFIG_IWLEGACY_DEBUG */
1565
Stanislaw Gruszkaeb3cdfb2011-08-30 12:58:35 +02001566static struct il_link_quality_cmd *
1567il4965_sta_alloc_lq(struct il_priv *il, u8 sta_id)
1568{
1569 int i, r;
1570 struct il_link_quality_cmd *link_cmd;
1571 u32 rate_flags = 0;
1572 __le32 rate_n_flags;
1573
1574 link_cmd = kzalloc(sizeof(struct il_link_quality_cmd), GFP_KERNEL);
1575 if (!link_cmd) {
1576 IL_ERR("Unable to allocate memory for LQ cmd.\n");
1577 return NULL;
1578 }
1579 /* Set up the rate scaling to start at selected rate, fall back
1580 * all the way down to 1M in IEEE order, and then spin on 1M */
1581 if (il->band == IEEE80211_BAND_5GHZ)
1582 r = RATE_6M_IDX;
1583 else
1584 r = RATE_1M_IDX;
1585
1586 if (r >= IL_FIRST_CCK_RATE && r <= IL_LAST_CCK_RATE)
1587 rate_flags |= RATE_MCS_CCK_MSK;
1588
1589 rate_flags |= il4965_first_antenna(il->hw_params.valid_tx_ant) <<
1590 RATE_MCS_ANT_POS;
1591 rate_n_flags = il4965_hw_set_rate_n_flags(il_rates[r].plcp,
1592 rate_flags);
1593 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)
1594 link_cmd->rs_table[i].rate_n_flags = rate_n_flags;
1595
1596 link_cmd->general_params.single_stream_ant_msk =
1597 il4965_first_antenna(il->hw_params.valid_tx_ant);
1598
1599 link_cmd->general_params.dual_stream_ant_msk =
1600 il->hw_params.valid_tx_ant &
1601 ~il4965_first_antenna(il->hw_params.valid_tx_ant);
1602 if (!link_cmd->general_params.dual_stream_ant_msk) {
1603 link_cmd->general_params.dual_stream_ant_msk = ANT_AB;
1604 } else if (il4965_num_of_ant(il->hw_params.valid_tx_ant) == 2) {
1605 link_cmd->general_params.dual_stream_ant_msk =
1606 il->hw_params.valid_tx_ant;
1607 }
1608
1609 link_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
1610 link_cmd->agg_params.agg_time_limit =
1611 cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);
1612
1613 link_cmd->sta_id = sta_id;
1614
1615 return link_cmd;
1616}
1617
1618/*
1619 * il4965_add_bssid_station - Add the special IBSS BSSID station
1620 *
1621 * Function sleeps.
1622 */
1623int
1624il4965_add_bssid_station(struct il_priv *il, struct il_rxon_context *ctx,
1625 const u8 *addr, u8 *sta_id_r)
1626{
1627 int ret;
1628 u8 sta_id;
1629 struct il_link_quality_cmd *link_cmd;
1630 unsigned long flags;
1631
1632 if (sta_id_r)
1633 *sta_id_r = IL_INVALID_STATION;
1634
1635 ret = il_add_station_common(il, ctx, addr, 0, NULL, &sta_id);
1636 if (ret) {
1637 IL_ERR("Unable to add station %pM\n", addr);
1638 return ret;
1639 }
1640
1641 if (sta_id_r)
1642 *sta_id_r = sta_id;
1643
1644 spin_lock_irqsave(&il->sta_lock, flags);
1645 il->stations[sta_id].used |= IL_STA_LOCAL;
1646 spin_unlock_irqrestore(&il->sta_lock, flags);
1647
1648 /* Set up default rate scaling table in device's station table */
1649 link_cmd = il4965_sta_alloc_lq(il, sta_id);
1650 if (!link_cmd) {
1651 IL_ERR(
1652 "Unable to initialize rate scaling for station %pM.\n",
1653 addr);
1654 return -ENOMEM;
1655 }
1656
1657 ret = il_send_lq_cmd(il, ctx, link_cmd, CMD_SYNC, true);
1658 if (ret)
1659 IL_ERR("Link quality command failed (%d)\n", ret);
1660
1661 spin_lock_irqsave(&il->sta_lock, flags);
1662 il->stations[sta_id].lq = link_cmd;
1663 spin_unlock_irqrestore(&il->sta_lock, flags);
1664
1665 return 0;
1666}
1667
1668static int il4965_static_wepkey_cmd(struct il_priv *il,
1669 struct il_rxon_context *ctx,
1670 bool send_if_empty)
1671{
1672 int i, not_empty = 0;
1673 u8 buff[sizeof(struct il_wep_cmd) +
1674 sizeof(struct il_wep_key) * WEP_KEYS_MAX];
1675 struct il_wep_cmd *wep_cmd = (struct il_wep_cmd *)buff;
1676 size_t cmd_size = sizeof(struct il_wep_cmd);
1677 struct il_host_cmd cmd = {
1678 .id = ctx->wep_key_cmd,
1679 .data = wep_cmd,
1680 .flags = CMD_SYNC,
1681 };
1682
1683 might_sleep();
1684
1685 memset(wep_cmd, 0, cmd_size +
1686 (sizeof(struct il_wep_key) * WEP_KEYS_MAX));
1687
1688 for (i = 0; i < WEP_KEYS_MAX ; i++) {
1689 wep_cmd->key[i].key_idx = i;
1690 if (ctx->wep_keys[i].key_size) {
1691 wep_cmd->key[i].key_offset = i;
1692 not_empty = 1;
1693 } else {
1694 wep_cmd->key[i].key_offset = WEP_INVALID_OFFSET;
1695 }
1696
1697 wep_cmd->key[i].key_size = ctx->wep_keys[i].key_size;
1698 memcpy(&wep_cmd->key[i].key[3], ctx->wep_keys[i].key,
1699 ctx->wep_keys[i].key_size);
1700 }
1701
1702 wep_cmd->global_key_type = WEP_KEY_WEP_TYPE;
1703 wep_cmd->num_keys = WEP_KEYS_MAX;
1704
1705 cmd_size += sizeof(struct il_wep_key) * WEP_KEYS_MAX;
1706
1707 cmd.len = cmd_size;
1708
1709 if (not_empty || send_if_empty)
1710 return il_send_cmd(il, &cmd);
1711 else
1712 return 0;
1713}
1714
1715int il4965_restore_default_wep_keys(struct il_priv *il,
1716 struct il_rxon_context *ctx)
1717{
1718 lockdep_assert_held(&il->mutex);
1719
1720 return il4965_static_wepkey_cmd(il, ctx, false);
1721}
1722
1723int il4965_remove_default_wep_key(struct il_priv *il,
1724 struct il_rxon_context *ctx,
1725 struct ieee80211_key_conf *keyconf)
1726{
1727 int ret;
1728
1729 lockdep_assert_held(&il->mutex);
1730
1731 D_WEP("Removing default WEP key: idx=%d\n",
1732 keyconf->keyidx);
1733
1734 memset(&ctx->wep_keys[keyconf->keyidx], 0, sizeof(ctx->wep_keys[0]));
1735 if (il_is_rfkill(il)) {
1736 D_WEP(
1737 "Not sending REPLY_WEPKEY command due to RFKILL.\n");
1738 /* but keys in device are clear anyway so return success */
1739 return 0;
1740 }
1741 ret = il4965_static_wepkey_cmd(il, ctx, 1);
1742 D_WEP("Remove default WEP key: idx=%d ret=%d\n",
1743 keyconf->keyidx, ret);
1744
1745 return ret;
1746}
1747
1748int il4965_set_default_wep_key(struct il_priv *il,
1749 struct il_rxon_context *ctx,
1750 struct ieee80211_key_conf *keyconf)
1751{
1752 int ret;
1753
1754 lockdep_assert_held(&il->mutex);
1755
1756 if (keyconf->keylen != WEP_KEY_LEN_128 &&
1757 keyconf->keylen != WEP_KEY_LEN_64) {
1758 D_WEP("Bad WEP key length %d\n", keyconf->keylen);
1759 return -EINVAL;
1760 }
1761
1762 keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
1763 keyconf->hw_key_idx = HW_KEY_DEFAULT;
1764 il->stations[ctx->ap_sta_id].keyinfo.cipher = keyconf->cipher;
1765
1766 ctx->wep_keys[keyconf->keyidx].key_size = keyconf->keylen;
1767 memcpy(&ctx->wep_keys[keyconf->keyidx].key, &keyconf->key,
1768 keyconf->keylen);
1769
1770 ret = il4965_static_wepkey_cmd(il, ctx, false);
1771 D_WEP("Set default WEP key: len=%d idx=%d ret=%d\n",
1772 keyconf->keylen, keyconf->keyidx, ret);
1773
1774 return ret;
1775}
1776
1777static int il4965_set_wep_dynamic_key_info(struct il_priv *il,
1778 struct il_rxon_context *ctx,
1779 struct ieee80211_key_conf *keyconf,
1780 u8 sta_id)
1781{
1782 unsigned long flags;
1783 __le16 key_flags = 0;
1784 struct il_addsta_cmd sta_cmd;
1785
1786 lockdep_assert_held(&il->mutex);
1787
1788 keyconf->flags &= ~IEEE80211_KEY_FLAG_GENERATE_IV;
1789
1790 key_flags |= (STA_KEY_FLG_WEP | STA_KEY_FLG_MAP_KEY_MSK);
1791 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
1792 key_flags &= ~STA_KEY_FLG_INVALID;
1793
1794 if (keyconf->keylen == WEP_KEY_LEN_128)
1795 key_flags |= STA_KEY_FLG_KEY_SIZE_MSK;
1796
1797 if (sta_id == ctx->bcast_sta_id)
1798 key_flags |= STA_KEY_MULTICAST_MSK;
1799
1800 spin_lock_irqsave(&il->sta_lock, flags);
1801
1802 il->stations[sta_id].keyinfo.cipher = keyconf->cipher;
1803 il->stations[sta_id].keyinfo.keylen = keyconf->keylen;
1804 il->stations[sta_id].keyinfo.keyidx = keyconf->keyidx;
1805
1806 memcpy(il->stations[sta_id].keyinfo.key,
1807 keyconf->key, keyconf->keylen);
1808
1809 memcpy(&il->stations[sta_id].sta.key.key[3],
1810 keyconf->key, keyconf->keylen);
1811
1812 if ((il->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
1813 == STA_KEY_FLG_NO_ENC)
1814 il->stations[sta_id].sta.key.key_offset =
1815 il_get_free_ucode_key_idx(il);
1816 /* else, we are overriding an existing key => no need to allocated room
1817 * in uCode. */
1818
1819 WARN(il->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
1820 "no space for a new key");
1821
1822 il->stations[sta_id].sta.key.key_flags = key_flags;
1823 il->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
1824 il->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1825
1826 memcpy(&sta_cmd, &il->stations[sta_id].sta,
1827 sizeof(struct il_addsta_cmd));
1828 spin_unlock_irqrestore(&il->sta_lock, flags);
1829
1830 return il_send_add_sta(il, &sta_cmd, CMD_SYNC);
1831}
1832
1833static int il4965_set_ccmp_dynamic_key_info(struct il_priv *il,
1834 struct il_rxon_context *ctx,
1835 struct ieee80211_key_conf *keyconf,
1836 u8 sta_id)
1837{
1838 unsigned long flags;
1839 __le16 key_flags = 0;
1840 struct il_addsta_cmd sta_cmd;
1841
1842 lockdep_assert_held(&il->mutex);
1843
1844 key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
1845 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
1846 key_flags &= ~STA_KEY_FLG_INVALID;
1847
1848 if (sta_id == ctx->bcast_sta_id)
1849 key_flags |= STA_KEY_MULTICAST_MSK;
1850
1851 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1852
1853 spin_lock_irqsave(&il->sta_lock, flags);
1854 il->stations[sta_id].keyinfo.cipher = keyconf->cipher;
1855 il->stations[sta_id].keyinfo.keylen = keyconf->keylen;
1856
1857 memcpy(il->stations[sta_id].keyinfo.key, keyconf->key,
1858 keyconf->keylen);
1859
1860 memcpy(il->stations[sta_id].sta.key.key, keyconf->key,
1861 keyconf->keylen);
1862
1863 if ((il->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
1864 == STA_KEY_FLG_NO_ENC)
1865 il->stations[sta_id].sta.key.key_offset =
1866 il_get_free_ucode_key_idx(il);
1867 /* else, we are overriding an existing key => no need to allocated room
1868 * in uCode. */
1869
1870 WARN(il->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
1871 "no space for a new key");
1872
1873 il->stations[sta_id].sta.key.key_flags = key_flags;
1874 il->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
1875 il->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1876
1877 memcpy(&sta_cmd, &il->stations[sta_id].sta,
1878 sizeof(struct il_addsta_cmd));
1879 spin_unlock_irqrestore(&il->sta_lock, flags);
1880
1881 return il_send_add_sta(il, &sta_cmd, CMD_SYNC);
1882}
1883
1884static int il4965_set_tkip_dynamic_key_info(struct il_priv *il,
1885 struct il_rxon_context *ctx,
1886 struct ieee80211_key_conf *keyconf,
1887 u8 sta_id)
1888{
1889 unsigned long flags;
1890 int ret = 0;
1891 __le16 key_flags = 0;
1892
1893 key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK);
1894 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
1895 key_flags &= ~STA_KEY_FLG_INVALID;
1896
1897 if (sta_id == ctx->bcast_sta_id)
1898 key_flags |= STA_KEY_MULTICAST_MSK;
1899
1900 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
1901 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
1902
1903 spin_lock_irqsave(&il->sta_lock, flags);
1904
1905 il->stations[sta_id].keyinfo.cipher = keyconf->cipher;
1906 il->stations[sta_id].keyinfo.keylen = 16;
1907
1908 if ((il->stations[sta_id].sta.key.key_flags & STA_KEY_FLG_ENCRYPT_MSK)
1909 == STA_KEY_FLG_NO_ENC)
1910 il->stations[sta_id].sta.key.key_offset =
1911 il_get_free_ucode_key_idx(il);
1912 /* else, we are overriding an existing key => no need to allocated room
1913 * in uCode. */
1914
1915 WARN(il->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET,
1916 "no space for a new key");
1917
1918 il->stations[sta_id].sta.key.key_flags = key_flags;
1919
1920
1921 /* This copy is acutally not needed: we get the key with each TX */
1922 memcpy(il->stations[sta_id].keyinfo.key, keyconf->key, 16);
1923
1924 memcpy(il->stations[sta_id].sta.key.key, keyconf->key, 16);
1925
1926 spin_unlock_irqrestore(&il->sta_lock, flags);
1927
1928 return ret;
1929}
1930
1931void il4965_update_tkip_key(struct il_priv *il,
1932 struct il_rxon_context *ctx,
1933 struct ieee80211_key_conf *keyconf,
1934 struct ieee80211_sta *sta, u32 iv32, u16 *phase1key)
1935{
1936 u8 sta_id;
1937 unsigned long flags;
1938 int i;
1939
1940 if (il_scan_cancel(il)) {
1941 /* cancel scan failed, just live w/ bad key and rely
1942 briefly on SW decryption */
1943 return;
1944 }
1945
1946 sta_id = il_sta_id_or_broadcast(il, ctx, sta);
1947 if (sta_id == IL_INVALID_STATION)
1948 return;
1949
1950 spin_lock_irqsave(&il->sta_lock, flags);
1951
1952 il->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32;
1953
1954 for (i = 0; i < 5; i++)
1955 il->stations[sta_id].sta.key.tkip_rx_ttak[i] =
1956 cpu_to_le16(phase1key[i]);
1957
1958 il->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
1959 il->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1960
1961 il_send_add_sta(il, &il->stations[sta_id].sta, CMD_ASYNC);
1962
1963 spin_unlock_irqrestore(&il->sta_lock, flags);
1964
1965}
1966
1967int il4965_remove_dynamic_key(struct il_priv *il,
1968 struct il_rxon_context *ctx,
1969 struct ieee80211_key_conf *keyconf,
1970 u8 sta_id)
1971{
1972 unsigned long flags;
1973 u16 key_flags;
1974 u8 keyidx;
1975 struct il_addsta_cmd sta_cmd;
1976
1977 lockdep_assert_held(&il->mutex);
1978
1979 ctx->key_mapping_keys--;
1980
1981 spin_lock_irqsave(&il->sta_lock, flags);
1982 key_flags = le16_to_cpu(il->stations[sta_id].sta.key.key_flags);
1983 keyidx = (key_flags >> STA_KEY_FLG_KEYID_POS) & 0x3;
1984
1985 D_WEP("Remove dynamic key: idx=%d sta=%d\n",
1986 keyconf->keyidx, sta_id);
1987
1988 if (keyconf->keyidx != keyidx) {
1989 /* We need to remove a key with idx different that the one
1990 * in the uCode. This means that the key we need to remove has
1991 * been replaced by another one with different idx.
1992 * Don't do anything and return ok
1993 */
1994 spin_unlock_irqrestore(&il->sta_lock, flags);
1995 return 0;
1996 }
1997
1998 if (il->stations[sta_id].sta.key.key_offset == WEP_INVALID_OFFSET) {
1999 IL_WARN("Removing wrong key %d 0x%x\n",
2000 keyconf->keyidx, key_flags);
2001 spin_unlock_irqrestore(&il->sta_lock, flags);
2002 return 0;
2003 }
2004
2005 if (!test_and_clear_bit(il->stations[sta_id].sta.key.key_offset,
2006 &il->ucode_key_table))
2007 IL_ERR("idx %d not used in uCode key table.\n",
2008 il->stations[sta_id].sta.key.key_offset);
2009 memset(&il->stations[sta_id].keyinfo, 0,
2010 sizeof(struct il_hw_key));
2011 memset(&il->stations[sta_id].sta.key, 0,
2012 sizeof(struct il4965_keyinfo));
2013 il->stations[sta_id].sta.key.key_flags =
2014 STA_KEY_FLG_NO_ENC | STA_KEY_FLG_INVALID;
2015 il->stations[sta_id].sta.key.key_offset = WEP_INVALID_OFFSET;
2016 il->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
2017 il->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
2018
2019 if (il_is_rfkill(il)) {
2020 D_WEP(
2021 "Not sending REPLY_ADD_STA command because RFKILL enabled.\n");
2022 spin_unlock_irqrestore(&il->sta_lock, flags);
2023 return 0;
2024 }
2025 memcpy(&sta_cmd, &il->stations[sta_id].sta,
2026 sizeof(struct il_addsta_cmd));
2027 spin_unlock_irqrestore(&il->sta_lock, flags);
2028
2029 return il_send_add_sta(il, &sta_cmd, CMD_SYNC);
2030}
2031
2032int il4965_set_dynamic_key(struct il_priv *il, struct il_rxon_context *ctx,
2033 struct ieee80211_key_conf *keyconf, u8 sta_id)
2034{
2035 int ret;
2036
2037 lockdep_assert_held(&il->mutex);
2038
2039 ctx->key_mapping_keys++;
2040 keyconf->hw_key_idx = HW_KEY_DYNAMIC;
2041
2042 switch (keyconf->cipher) {
2043 case WLAN_CIPHER_SUITE_CCMP:
2044 ret = il4965_set_ccmp_dynamic_key_info(il, ctx,
2045 keyconf, sta_id);
2046 break;
2047 case WLAN_CIPHER_SUITE_TKIP:
2048 ret = il4965_set_tkip_dynamic_key_info(il, ctx,
2049 keyconf, sta_id);
2050 break;
2051 case WLAN_CIPHER_SUITE_WEP40:
2052 case WLAN_CIPHER_SUITE_WEP104:
2053 ret = il4965_set_wep_dynamic_key_info(il, ctx,
2054 keyconf, sta_id);
2055 break;
2056 default:
2057 IL_ERR(
2058 "Unknown alg: %s cipher = %x\n", __func__,
2059 keyconf->cipher);
2060 ret = -EINVAL;
2061 }
2062
2063 D_WEP(
2064 "Set dynamic key: cipher=%x len=%d idx=%d sta=%d ret=%d\n",
2065 keyconf->cipher, keyconf->keylen, keyconf->keyidx,
2066 sta_id, ret);
2067
2068 return ret;
2069}
2070
2071/**
2072 * il4965_alloc_bcast_station - add broadcast station into driver's station table.
2073 *
2074 * This adds the broadcast station into the driver's station table
2075 * and marks it driver active, so that it will be restored to the
2076 * device at the next best time.
2077 */
2078int il4965_alloc_bcast_station(struct il_priv *il,
2079 struct il_rxon_context *ctx)
2080{
2081 struct il_link_quality_cmd *link_cmd;
2082 unsigned long flags;
2083 u8 sta_id;
2084
2085 spin_lock_irqsave(&il->sta_lock, flags);
2086 sta_id = il_prep_station(il, ctx, il_bcast_addr,
2087 false, NULL);
2088 if (sta_id == IL_INVALID_STATION) {
2089 IL_ERR("Unable to prepare broadcast station\n");
2090 spin_unlock_irqrestore(&il->sta_lock, flags);
2091
2092 return -EINVAL;
2093 }
2094
2095 il->stations[sta_id].used |= IL_STA_DRIVER_ACTIVE;
2096 il->stations[sta_id].used |= IL_STA_BCAST;
2097 spin_unlock_irqrestore(&il->sta_lock, flags);
2098
2099 link_cmd = il4965_sta_alloc_lq(il, sta_id);
2100 if (!link_cmd) {
2101 IL_ERR(
2102 "Unable to initialize rate scaling for bcast station.\n");
2103 return -ENOMEM;
2104 }
2105
2106 spin_lock_irqsave(&il->sta_lock, flags);
2107 il->stations[sta_id].lq = link_cmd;
2108 spin_unlock_irqrestore(&il->sta_lock, flags);
2109
2110 return 0;
2111}
2112
2113/**
2114 * il4965_update_bcast_station - update broadcast station's LQ command
2115 *
2116 * Only used by iwl4965. Placed here to have all bcast station management
2117 * code together.
2118 */
2119static int il4965_update_bcast_station(struct il_priv *il,
2120 struct il_rxon_context *ctx)
2121{
2122 unsigned long flags;
2123 struct il_link_quality_cmd *link_cmd;
2124 u8 sta_id = ctx->bcast_sta_id;
2125
2126 link_cmd = il4965_sta_alloc_lq(il, sta_id);
2127 if (!link_cmd) {
2128 IL_ERR(
2129 "Unable to initialize rate scaling for bcast station.\n");
2130 return -ENOMEM;
2131 }
2132
2133 spin_lock_irqsave(&il->sta_lock, flags);
2134 if (il->stations[sta_id].lq)
2135 kfree(il->stations[sta_id].lq);
2136 else
2137 D_INFO(
2138 "Bcast station rate scaling has not been initialized yet.\n");
2139 il->stations[sta_id].lq = link_cmd;
2140 spin_unlock_irqrestore(&il->sta_lock, flags);
2141
2142 return 0;
2143}
2144
2145int il4965_update_bcast_stations(struct il_priv *il)
2146{
2147 return il4965_update_bcast_station(il, &il->ctx);
2148}
2149
2150/**
2151 * il4965_sta_tx_modify_enable_tid - Enable Tx for this TID in station table
2152 */
2153int il4965_sta_tx_modify_enable_tid(struct il_priv *il, int sta_id, int tid)
2154{
2155 unsigned long flags;
2156 struct il_addsta_cmd sta_cmd;
2157
2158 lockdep_assert_held(&il->mutex);
2159
2160 /* Remove "disable" flag, to enable Tx for this TID */
2161 spin_lock_irqsave(&il->sta_lock, flags);
2162 il->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX;
2163 il->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid));
2164 il->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
2165 memcpy(&sta_cmd, &il->stations[sta_id].sta,
2166 sizeof(struct il_addsta_cmd));
2167 spin_unlock_irqrestore(&il->sta_lock, flags);
2168
2169 return il_send_add_sta(il, &sta_cmd, CMD_SYNC);
2170}
2171
2172int il4965_sta_rx_agg_start(struct il_priv *il, struct ieee80211_sta *sta,
2173 int tid, u16 ssn)
2174{
2175 unsigned long flags;
2176 int sta_id;
2177 struct il_addsta_cmd sta_cmd;
2178
2179 lockdep_assert_held(&il->mutex);
2180
2181 sta_id = il_sta_id(sta);
2182 if (sta_id == IL_INVALID_STATION)
2183 return -ENXIO;
2184
2185 spin_lock_irqsave(&il->sta_lock, flags);
2186 il->stations[sta_id].sta.station_flags_msk = 0;
2187 il->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_ADDBA_TID_MSK;
2188 il->stations[sta_id].sta.add_immediate_ba_tid = (u8)tid;
2189 il->stations[sta_id].sta.add_immediate_ba_ssn = cpu_to_le16(ssn);
2190 il->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
2191 memcpy(&sta_cmd, &il->stations[sta_id].sta,
2192 sizeof(struct il_addsta_cmd));
2193 spin_unlock_irqrestore(&il->sta_lock, flags);
2194
2195 return il_send_add_sta(il, &sta_cmd, CMD_SYNC);
2196}
2197
2198int il4965_sta_rx_agg_stop(struct il_priv *il, struct ieee80211_sta *sta,
2199 int tid)
2200{
2201 unsigned long flags;
2202 int sta_id;
2203 struct il_addsta_cmd sta_cmd;
2204
2205 lockdep_assert_held(&il->mutex);
2206
2207 sta_id = il_sta_id(sta);
2208 if (sta_id == IL_INVALID_STATION) {
2209 IL_ERR("Invalid station for AGG tid %d\n", tid);
2210 return -ENXIO;
2211 }
2212
2213 spin_lock_irqsave(&il->sta_lock, flags);
2214 il->stations[sta_id].sta.station_flags_msk = 0;
2215 il->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK;
2216 il->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid;
2217 il->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
2218 memcpy(&sta_cmd, &il->stations[sta_id].sta,
2219 sizeof(struct il_addsta_cmd));
2220 spin_unlock_irqrestore(&il->sta_lock, flags);
2221
2222 return il_send_add_sta(il, &sta_cmd, CMD_SYNC);
2223}
2224
2225void
2226il4965_sta_modify_sleep_tx_count(struct il_priv *il, int sta_id, int cnt)
2227{
2228 unsigned long flags;
2229
2230 spin_lock_irqsave(&il->sta_lock, flags);
2231 il->stations[sta_id].sta.station_flags |= STA_FLG_PWR_SAVE_MSK;
2232 il->stations[sta_id].sta.station_flags_msk = STA_FLG_PWR_SAVE_MSK;
2233 il->stations[sta_id].sta.sta.modify_mask =
2234 STA_MODIFY_SLEEP_TX_COUNT_MSK;
2235 il->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt);
2236 il->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
2237 il_send_add_sta(il,
2238 &il->stations[sta_id].sta, CMD_ASYNC);
2239 spin_unlock_irqrestore(&il->sta_lock, flags);
2240
2241}
2242
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002243void il4965_update_chain_flags(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002244{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002245 if (il->cfg->ops->hcmd->set_rxon_chain) {
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +02002246 il->cfg->ops->hcmd->set_rxon_chain(il, &il->ctx);
2247 if (il->ctx.active.rx_chain != il->ctx.staging.rx_chain)
2248 il_commit_rxon(il, &il->ctx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002249 }
2250}
2251
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002252static void il4965_clear_free_frames(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002253{
2254 struct list_head *element;
2255
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002256 D_INFO("%d frames on pre-allocated heap on clear.\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002257 il->frames_count);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002258
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002259 while (!list_empty(&il->free_frames)) {
2260 element = il->free_frames.next;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002261 list_del(element);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002262 kfree(list_entry(element, struct il_frame, list));
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002263 il->frames_count--;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002264 }
2265
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002266 if (il->frames_count) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002267 IL_WARN("%d frames still in use. Did we lose one?\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002268 il->frames_count);
2269 il->frames_count = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002270 }
2271}
2272
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002273static struct il_frame *il4965_get_free_frame(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002274{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002275 struct il_frame *frame;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002276 struct list_head *element;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002277 if (list_empty(&il->free_frames)) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002278 frame = kzalloc(sizeof(*frame), GFP_KERNEL);
2279 if (!frame) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002280 IL_ERR("Could not allocate frame!\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002281 return NULL;
2282 }
2283
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002284 il->frames_count++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002285 return frame;
2286 }
2287
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002288 element = il->free_frames.next;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002289 list_del(element);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002290 return list_entry(element, struct il_frame, list);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002291}
2292
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002293static void il4965_free_frame(struct il_priv *il, struct il_frame *frame)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002294{
2295 memset(frame, 0, sizeof(*frame));
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002296 list_add(&frame->list, &il->free_frames);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002297}
2298
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002299static u32 il4965_fill_beacon_frame(struct il_priv *il,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002300 struct ieee80211_hdr *hdr,
2301 int left)
2302{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002303 lockdep_assert_held(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002304
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002305 if (!il->beacon_skb)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002306 return 0;
2307
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002308 if (il->beacon_skb->len > left)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002309 return 0;
2310
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002311 memcpy(hdr, il->beacon_skb->data, il->beacon_skb->len);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002312
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002313 return il->beacon_skb->len;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002314}
2315
2316/* Parse the beacon frame to find the TIM element and set tim_idx & tim_size */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002317static void il4965_set_beacon_tim(struct il_priv *il,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002318 struct il_tx_beacon_cmd *tx_beacon_cmd,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002319 u8 *beacon, u32 frame_size)
2320{
2321 u16 tim_idx;
2322 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)beacon;
2323
2324 /*
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +01002325 * The idx is relative to frame start but we start looking at the
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002326 * variable-length part of the beacon.
2327 */
2328 tim_idx = mgmt->u.beacon.variable - beacon;
2329
2330 /* Parse variable-length elements of beacon to find WLAN_EID_TIM */
2331 while ((tim_idx < (frame_size - 2)) &&
2332 (beacon[tim_idx] != WLAN_EID_TIM))
2333 tim_idx += beacon[tim_idx+1] + 2;
2334
2335 /* If TIM field was found, set variables */
2336 if ((tim_idx < (frame_size - 1)) && (beacon[tim_idx] == WLAN_EID_TIM)) {
2337 tx_beacon_cmd->tim_idx = cpu_to_le16(tim_idx);
2338 tx_beacon_cmd->tim_size = beacon[tim_idx+1];
2339 } else
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002340 IL_WARN("Unable to find TIM Element in beacon\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002341}
2342
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002343static unsigned int il4965_hw_get_beacon_cmd(struct il_priv *il,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002344 struct il_frame *frame)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002345{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002346 struct il_tx_beacon_cmd *tx_beacon_cmd;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002347 u32 frame_size;
2348 u32 rate_flags;
2349 u32 rate;
2350 /*
2351 * We have to set up the TX command, the TX Beacon command, and the
2352 * beacon contents.
2353 */
2354
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002355 lockdep_assert_held(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002356
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002357 if (!il->beacon_ctx) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002358 IL_ERR("trying to build beacon w/o beacon context!\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002359 return 0;
2360 }
2361
2362 /* Initialize memory */
2363 tx_beacon_cmd = &frame->u.beacon;
2364 memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
2365
2366 /* Set up TX beacon contents */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002367 frame_size = il4965_fill_beacon_frame(il, tx_beacon_cmd->frame,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002368 sizeof(frame->u) - sizeof(*tx_beacon_cmd));
2369 if (WARN_ON_ONCE(frame_size > MAX_MPDU_SIZE))
2370 return 0;
2371 if (!frame_size)
2372 return 0;
2373
2374 /* Set up TX command fields */
2375 tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002376 tx_beacon_cmd->tx.sta_id = il->beacon_ctx->bcast_sta_id;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002377 tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
2378 tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK |
2379 TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK;
2380
2381 /* Set up TX beacon command fields */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002382 il4965_set_beacon_tim(il, tx_beacon_cmd, (u8 *)tx_beacon_cmd->frame,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002383 frame_size);
2384
2385 /* Set up packet rate and flags */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002386 rate = il_get_lowest_plcp(il, il->beacon_ctx);
2387 il->mgmt_tx_ant = il4965_toggle_tx_ant(il, il->mgmt_tx_ant,
2388 il->hw_params.valid_tx_ant);
2389 rate_flags = il4965_ant_idx_to_flags(il->mgmt_tx_ant);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002390 if ((rate >= IL_FIRST_CCK_RATE) && (rate <= IL_LAST_CCK_RATE))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002391 rate_flags |= RATE_MCS_CCK_MSK;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002392 tx_beacon_cmd->tx.rate_n_flags = il4965_hw_set_rate_n_flags(rate,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002393 rate_flags);
2394
2395 return sizeof(*tx_beacon_cmd) + frame_size;
2396}
2397
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002398int il4965_send_beacon_cmd(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002399{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002400 struct il_frame *frame;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002401 unsigned int frame_size;
2402 int rc;
2403
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002404 frame = il4965_get_free_frame(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002405 if (!frame) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002406 IL_ERR("Could not obtain free frame buffer for beacon "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002407 "command.\n");
2408 return -ENOMEM;
2409 }
2410
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002411 frame_size = il4965_hw_get_beacon_cmd(il, frame);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002412 if (!frame_size) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002413 IL_ERR("Error configuring the beacon command\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002414 il4965_free_frame(il, frame);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002415 return -EINVAL;
2416 }
2417
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002418 rc = il_send_cmd_pdu(il, REPLY_TX_BEACON, frame_size,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002419 &frame->u.cmd[0]);
2420
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002421 il4965_free_frame(il, frame);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002422
2423 return rc;
2424}
2425
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002426static inline dma_addr_t il4965_tfd_tb_get_addr(struct il_tfd *tfd, u8 idx)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002427{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002428 struct il_tfd_tb *tb = &tfd->tbs[idx];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002429
2430 dma_addr_t addr = get_unaligned_le32(&tb->lo);
2431 if (sizeof(dma_addr_t) > sizeof(u32))
2432 addr |=
2433 ((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16;
2434
2435 return addr;
2436}
2437
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002438static inline u16 il4965_tfd_tb_get_len(struct il_tfd *tfd, u8 idx)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002439{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002440 struct il_tfd_tb *tb = &tfd->tbs[idx];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002441
2442 return le16_to_cpu(tb->hi_n_len) >> 4;
2443}
2444
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002445static inline void il4965_tfd_set_tb(struct il_tfd *tfd, u8 idx,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002446 dma_addr_t addr, u16 len)
2447{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002448 struct il_tfd_tb *tb = &tfd->tbs[idx];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002449 u16 hi_n_len = len << 4;
2450
2451 put_unaligned_le32(addr, &tb->lo);
2452 if (sizeof(dma_addr_t) > sizeof(u32))
2453 hi_n_len |= ((addr >> 16) >> 16) & 0xF;
2454
2455 tb->hi_n_len = cpu_to_le16(hi_n_len);
2456
2457 tfd->num_tbs = idx + 1;
2458}
2459
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002460static inline u8 il4965_tfd_get_num_tbs(struct il_tfd *tfd)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002461{
2462 return tfd->num_tbs & 0x1f;
2463}
2464
2465/**
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002466 * il4965_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002467 * @il - driver ilate data
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002468 * @txq - tx queue
2469 *
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +01002470 * Does NOT advance any TFD circular buffer read/write idxes
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002471 * Does NOT free the TFD itself (which is within circular buffer)
2472 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002473void il4965_hw_txq_free_tfd(struct il_priv *il, struct il_tx_queue *txq)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002474{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002475 struct il_tfd *tfd_tmp = (struct il_tfd *)txq->tfds;
2476 struct il_tfd *tfd;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002477 struct pci_dev *dev = il->pci_dev;
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +01002478 int idx = txq->q.read_ptr;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002479 int i;
2480 int num_tbs;
2481
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +01002482 tfd = &tfd_tmp[idx];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002483
2484 /* Sanity check on number of chunks */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002485 num_tbs = il4965_tfd_get_num_tbs(tfd);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002486
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002487 if (num_tbs >= IL_NUM_OF_TBS) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002488 IL_ERR("Too many chunks: %i\n", num_tbs);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002489 /* @todo issue fatal error, it is quite serious situation */
2490 return;
2491 }
2492
2493 /* Unmap tx_cmd */
2494 if (num_tbs)
2495 pci_unmap_single(dev,
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +01002496 dma_unmap_addr(&txq->meta[idx], mapping),
2497 dma_unmap_len(&txq->meta[idx], len),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002498 PCI_DMA_BIDIRECTIONAL);
2499
2500 /* Unmap chunks, if any. */
2501 for (i = 1; i < num_tbs; i++)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002502 pci_unmap_single(dev, il4965_tfd_tb_get_addr(tfd, i),
2503 il4965_tfd_tb_get_len(tfd, i),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002504 PCI_DMA_TODEVICE);
2505
2506 /* free SKB */
2507 if (txq->txb) {
2508 struct sk_buff *skb;
2509
2510 skb = txq->txb[txq->q.read_ptr].skb;
2511
2512 /* can be called from irqs-disabled context */
2513 if (skb) {
2514 dev_kfree_skb_any(skb);
2515 txq->txb[txq->q.read_ptr].skb = NULL;
2516 }
2517 }
2518}
2519
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002520int il4965_hw_txq_attach_buf_to_tfd(struct il_priv *il,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002521 struct il_tx_queue *txq,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002522 dma_addr_t addr, u16 len,
2523 u8 reset, u8 pad)
2524{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002525 struct il_queue *q;
2526 struct il_tfd *tfd, *tfd_tmp;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002527 u32 num_tbs;
2528
2529 q = &txq->q;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002530 tfd_tmp = (struct il_tfd *)txq->tfds;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002531 tfd = &tfd_tmp[q->write_ptr];
2532
2533 if (reset)
2534 memset(tfd, 0, sizeof(*tfd));
2535
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002536 num_tbs = il4965_tfd_get_num_tbs(tfd);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002537
2538 /* Each TFD can point to a maximum 20 Tx buffers */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002539 if (num_tbs >= IL_NUM_OF_TBS) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002540 IL_ERR("Error can not send more than %d chunks\n",
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002541 IL_NUM_OF_TBS);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002542 return -EINVAL;
2543 }
2544
2545 BUG_ON(addr & ~DMA_BIT_MASK(36));
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002546 if (unlikely(addr & ~IL_TX_DMA_MASK))
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002547 IL_ERR("Unaligned address = %llx\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002548 (unsigned long long)addr);
2549
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002550 il4965_tfd_set_tb(tfd, num_tbs, addr, len);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002551
2552 return 0;
2553}
2554
2555/*
2556 * Tell nic where to find circular buffer of Tx Frame Descriptors for
2557 * given Tx queue, and enable the DMA channel used for that queue.
2558 *
2559 * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
2560 * channels supported in hardware.
2561 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002562int il4965_hw_tx_queue_init(struct il_priv *il,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002563 struct il_tx_queue *txq)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002564{
2565 int txq_id = txq->q.id;
2566
2567 /* Circular buffer (TFD queue in DRAM) physical base address */
Stanislaw Gruszka0c1a94e2011-08-24 17:37:16 +02002568 il_wr(il, FH_MEM_CBBC_QUEUE(txq_id),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002569 txq->q.dma_addr >> 8);
2570
2571 return 0;
2572}
2573
2574/******************************************************************************
2575 *
2576 * Generic RX handler implementations
2577 *
2578 ******************************************************************************/
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002579static void il4965_rx_reply_alive(struct il_priv *il,
Stanislaw Gruszkab73bb5f2011-08-26 14:37:54 +02002580 struct il_rx_buf *rxb)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002581{
Stanislaw Gruszkadcae1c62011-08-26 14:36:21 +02002582 struct il_rx_pkt *pkt = rxb_addr(rxb);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002583 struct il_alive_resp *palive;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002584 struct delayed_work *pwork;
2585
2586 palive = &pkt->u.alive_frame;
2587
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002588 D_INFO("Alive ucode status 0x%08X revision "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002589 "0x%01X 0x%01X\n",
2590 palive->is_valid, palive->ver_type,
2591 palive->ver_subtype);
2592
2593 if (palive->ver_subtype == INITIALIZE_SUBTYPE) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002594 D_INFO("Initialization Alive received.\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002595 memcpy(&il->card_alive_init,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002596 &pkt->u.alive_frame,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002597 sizeof(struct il_init_alive_resp));
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002598 pwork = &il->init_alive_start;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002599 } else {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002600 D_INFO("Runtime Alive received.\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002601 memcpy(&il->card_alive, &pkt->u.alive_frame,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002602 sizeof(struct il_alive_resp));
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002603 pwork = &il->alive_start;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002604 }
2605
2606 /* We delay the ALIVE response by 5ms to
2607 * give the HW RF Kill time to activate... */
2608 if (palive->is_valid == UCODE_VALID_OK)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002609 queue_delayed_work(il->workqueue, pwork,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002610 msecs_to_jiffies(5));
2611 else
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002612 IL_WARN("uCode did not respond OK.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002613}
2614
2615/**
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02002616 * il4965_bg_stats_periodic - Timer callback to queue stats
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002617 *
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02002618 * This callback is provided in order to send a stats request.
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002619 *
2620 * This timer function is continually reset to execute within
2621 * REG_RECALIB_PERIOD seconds since the last STATISTICS_NOTIFICATION
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02002622 * was received. We need to ensure we receive the stats in order
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002623 * to update the temperature used for calibrating the TXPOWER.
2624 */
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02002625static void il4965_bg_stats_periodic(unsigned long data)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002626{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002627 struct il_priv *il = (struct il_priv *)data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002628
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002629 if (test_bit(STATUS_EXIT_PENDING, &il->status))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002630 return;
2631
2632 /* dont send host command if rf-kill is on */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002633 if (!il_is_ready_rf(il))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002634 return;
2635
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02002636 il_send_stats_request(il, CMD_ASYNC, false);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002637}
2638
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002639static void il4965_rx_beacon_notif(struct il_priv *il,
Stanislaw Gruszkab73bb5f2011-08-26 14:37:54 +02002640 struct il_rx_buf *rxb)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002641{
Stanislaw Gruszkadcae1c62011-08-26 14:36:21 +02002642 struct il_rx_pkt *pkt = rxb_addr(rxb);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002643 struct il4965_beacon_notif *beacon =
2644 (struct il4965_beacon_notif *)pkt->u.raw;
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01002645#ifdef CONFIG_IWLEGACY_DEBUG
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002646 u8 rate = il4965_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002647
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002648 D_RX("beacon status %x retries %d iss %d "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002649 "tsf %d %d rate %d\n",
2650 le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK,
2651 beacon->beacon_notify_hdr.failure_frame,
2652 le32_to_cpu(beacon->ibss_mgr_status),
2653 le32_to_cpu(beacon->high_tsf),
2654 le32_to_cpu(beacon->low_tsf), rate);
2655#endif
2656
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002657 il->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002658}
2659
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002660static void il4965_perform_ct_kill_task(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002661{
2662 unsigned long flags;
2663
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002664 D_POWER("Stop all queues\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002665
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002666 if (il->mac80211_registered)
2667 ieee80211_stop_queues(il->hw);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002668
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02002669 _il_wr(il, CSR_UCODE_DRV_GP1_SET,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002670 CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02002671 _il_rd(il, CSR_UCODE_DRV_GP1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002672
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002673 spin_lock_irqsave(&il->reg_lock, flags);
Stanislaw Gruszka13882262011-08-24 15:39:23 +02002674 if (!_il_grab_nic_access(il))
2675 _il_release_nic_access(il);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002676 spin_unlock_irqrestore(&il->reg_lock, flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002677}
2678
2679/* Handle notification from uCode that card's power state is changing
2680 * due to software, hardware, or critical temperature RFKILL */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002681static void il4965_rx_card_state_notif(struct il_priv *il,
Stanislaw Gruszkab73bb5f2011-08-26 14:37:54 +02002682 struct il_rx_buf *rxb)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002683{
Stanislaw Gruszkadcae1c62011-08-26 14:36:21 +02002684 struct il_rx_pkt *pkt = rxb_addr(rxb);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002685 u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002686 unsigned long status = il->status;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002687
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002688 D_RF_KILL("Card state received: HW:%s SW:%s CT:%s\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002689 (flags & HW_CARD_DISABLED) ? "Kill" : "On",
2690 (flags & SW_CARD_DISABLED) ? "Kill" : "On",
2691 (flags & CT_CARD_DISABLED) ?
2692 "Reached" : "Not reached");
2693
2694 if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED |
2695 CT_CARD_DISABLED)) {
2696
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02002697 _il_wr(il, CSR_UCODE_DRV_GP1_SET,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002698 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
2699
Stanislaw Gruszka0c1a94e2011-08-24 17:37:16 +02002700 il_wr(il, HBUS_TARG_MBX_C,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002701 HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
2702
2703 if (!(flags & RXON_CARD_DISABLED)) {
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02002704 _il_wr(il, CSR_UCODE_DRV_GP1_CLR,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002705 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
Stanislaw Gruszka0c1a94e2011-08-24 17:37:16 +02002706 il_wr(il, HBUS_TARG_MBX_C,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002707 HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
2708 }
2709 }
2710
2711 if (flags & CT_CARD_DISABLED)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002712 il4965_perform_ct_kill_task(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002713
2714 if (flags & HW_CARD_DISABLED)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002715 set_bit(STATUS_RF_KILL_HW, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002716 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002717 clear_bit(STATUS_RF_KILL_HW, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002718
2719 if (!(flags & RXON_CARD_DISABLED))
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002720 il_scan_cancel(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002721
2722 if ((test_bit(STATUS_RF_KILL_HW, &status) !=
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002723 test_bit(STATUS_RF_KILL_HW, &il->status)))
2724 wiphy_rfkill_set_hw_state(il->hw->wiphy,
2725 test_bit(STATUS_RF_KILL_HW, &il->status));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002726 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002727 wake_up(&il->wait_command_queue);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002728}
2729
2730/**
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002731 * il4965_setup_rx_handlers - Initialize Rx handler callbacks
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002732 *
2733 * Setup the RX handlers for each of the reply types sent from the uCode
2734 * to the host.
2735 *
2736 * This function chains into the hardware specific files for them to setup
2737 * any hardware specific handlers as well.
2738 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002739static void il4965_setup_rx_handlers(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002740{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002741 il->rx_handlers[REPLY_ALIVE] = il4965_rx_reply_alive;
2742 il->rx_handlers[REPLY_ERROR] = il_rx_reply_error;
2743 il->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = il_rx_csa;
2744 il->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002745 il_rx_spectrum_measure_notif;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002746 il->rx_handlers[PM_SLEEP_NOTIFICATION] = il_rx_pm_sleep_notif;
2747 il->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02002748 il_rx_pm_debug_stats_notif;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002749 il->rx_handlers[BEACON_NOTIFICATION] = il4965_rx_beacon_notif;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002750
2751 /*
2752 * The same handler is used for both the REPLY to a discrete
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02002753 * stats request from the host as well as for the periodic
2754 * stats notifications (after received beacons) from the uCode.
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002755 */
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02002756 il->rx_handlers[REPLY_STATISTICS_CMD] = il4965_reply_stats;
2757 il->rx_handlers[STATISTICS_NOTIFICATION] = il4965_rx_stats;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002758
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002759 il_setup_rx_scan_handlers(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002760
2761 /* status change handler */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002762 il->rx_handlers[CARD_STATE_NOTIFICATION] =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002763 il4965_rx_card_state_notif;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002764
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002765 il->rx_handlers[MISSED_BEACONS_NOTIFICATION] =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002766 il4965_rx_missed_beacon_notif;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002767 /* Rx handlers */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002768 il->rx_handlers[REPLY_RX_PHY_CMD] = il4965_rx_reply_rx_phy;
2769 il->rx_handlers[REPLY_RX_MPDU_CMD] = il4965_rx_reply_rx;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002770 /* block ack */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002771 il->rx_handlers[REPLY_COMPRESSED_BA] = il4965_rx_reply_compressed_ba;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002772 /* Set up hardware specific Rx handlers */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002773 il->cfg->ops->lib->rx_handler_setup(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002774}
2775
2776/**
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002777 * il4965_rx_handle - Main entry function for receiving responses from uCode
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002778 *
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002779 * Uses the il->rx_handlers callback function array to invoke
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002780 * the appropriate handlers, including command responses,
2781 * frame-received notifications, and other notifications.
2782 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002783void il4965_rx_handle(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002784{
Stanislaw Gruszkab73bb5f2011-08-26 14:37:54 +02002785 struct il_rx_buf *rxb;
Stanislaw Gruszkadcae1c62011-08-26 14:36:21 +02002786 struct il_rx_pkt *pkt;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002787 struct il_rx_queue *rxq = &il->rxq;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002788 u32 r, i;
2789 int reclaim;
2790 unsigned long flags;
2791 u8 fill_rx = 0;
2792 u32 count = 8;
2793 int total_empty;
2794
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +01002795 /* uCode's read idx (stored in shared DRAM) indicates the last Rx
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002796 * buffer that the driver may process (last buffer filled by ucode). */
2797 r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF;
2798 i = rxq->read;
2799
2800 /* Rx interrupt, but nothing sent from uCode */
2801 if (i == r)
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002802 D_RX("r = %d, i = %d\n", r, i);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002803
2804 /* calculate total frames need to be restock after handling RX */
2805 total_empty = r - rxq->write_actual;
2806 if (total_empty < 0)
2807 total_empty += RX_QUEUE_SIZE;
2808
2809 if (total_empty > (RX_QUEUE_SIZE / 2))
2810 fill_rx = 1;
2811
2812 while (i != r) {
2813 int len;
2814
2815 rxb = rxq->queue[i];
2816
2817 /* If an RXB doesn't have a Rx queue slot associated with it,
2818 * then a bug has been introduced in the queue refilling
2819 * routines -- catch it here */
2820 BUG_ON(rxb == NULL);
2821
2822 rxq->queue[i] = NULL;
2823
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002824 pci_unmap_page(il->pci_dev, rxb->page_dma,
2825 PAGE_SIZE << il->hw_params.rx_page_order,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002826 PCI_DMA_FROMDEVICE);
2827 pkt = rxb_addr(rxb);
2828
2829 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
2830 len += sizeof(u32); /* account for status word */
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002831
2832 /* Reclaim a command buffer only if this packet is a response
2833 * to a (driver-originated) command.
2834 * If the packet (e.g. Rx frame) originated from uCode,
2835 * there is no command buffer to reclaim.
2836 * Ucode should set SEQ_RX_FRAME bit if ucode-originated,
2837 * but apparently a few don't get set; catch them here. */
2838 reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) &&
2839 (pkt->hdr.cmd != REPLY_RX_PHY_CMD) &&
2840 (pkt->hdr.cmd != REPLY_RX) &&
2841 (pkt->hdr.cmd != REPLY_RX_MPDU_CMD) &&
2842 (pkt->hdr.cmd != REPLY_COMPRESSED_BA) &&
2843 (pkt->hdr.cmd != STATISTICS_NOTIFICATION) &&
2844 (pkt->hdr.cmd != REPLY_TX);
2845
2846 /* Based on type of command response or notification,
2847 * handle those that need handling via function in
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002848 * rx_handlers table. See il4965_setup_rx_handlers() */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002849 if (il->rx_handlers[pkt->hdr.cmd]) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002850 D_RX("r = %d, i = %d, %s, 0x%02x\n", r,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002851 i, il_get_cmd_string(pkt->hdr.cmd),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002852 pkt->hdr.cmd);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002853 il->isr_stats.rx_handlers[pkt->hdr.cmd]++;
2854 il->rx_handlers[pkt->hdr.cmd] (il, rxb);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002855 } else {
2856 /* No handling needed */
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002857 D_RX(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002858 "r %d i %d No handler needed for %s, 0x%02x\n",
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002859 r, i, il_get_cmd_string(pkt->hdr.cmd),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002860 pkt->hdr.cmd);
2861 }
2862
2863 /*
2864 * XXX: After here, we should always check rxb->page
2865 * against NULL before touching it or its virtual
2866 * memory (pkt). Because some rx_handler might have
2867 * already taken or freed the pages.
2868 */
2869
2870 if (reclaim) {
2871 /* Invoke any callbacks, transfer the buffer to caller,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002872 * and fire off the (possibly) blocking il_send_cmd()
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002873 * as we reclaim the driver command queue */
2874 if (rxb->page)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002875 il_tx_cmd_complete(il, rxb);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002876 else
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002877 IL_WARN("Claim null rxb?\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002878 }
2879
2880 /* Reuse the page if possible. For notification packets and
2881 * SKBs that fail to Rx correctly, add them back into the
2882 * rx_free list for reuse later. */
2883 spin_lock_irqsave(&rxq->lock, flags);
2884 if (rxb->page != NULL) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002885 rxb->page_dma = pci_map_page(il->pci_dev, rxb->page,
2886 0, PAGE_SIZE << il->hw_params.rx_page_order,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002887 PCI_DMA_FROMDEVICE);
2888 list_add_tail(&rxb->list, &rxq->rx_free);
2889 rxq->free_count++;
2890 } else
2891 list_add_tail(&rxb->list, &rxq->rx_used);
2892
2893 spin_unlock_irqrestore(&rxq->lock, flags);
2894
2895 i = (i + 1) & RX_QUEUE_MASK;
2896 /* If there are a lot of unused frames,
2897 * restock the Rx queue so ucode wont assert. */
2898 if (fill_rx) {
2899 count++;
2900 if (count >= 8) {
2901 rxq->read = i;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002902 il4965_rx_replenish_now(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002903 count = 0;
2904 }
2905 }
2906 }
2907
2908 /* Backtrack one entry */
2909 rxq->read = i;
2910 if (fill_rx)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002911 il4965_rx_replenish_now(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002912 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002913 il4965_rx_queue_restock(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002914}
2915
2916/* call this function to flush any scheduled tasklet */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002917static inline void il4965_synchronize_irq(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002918{
2919 /* wait to make sure we flush pending tasklet*/
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002920 synchronize_irq(il->pci_dev->irq);
2921 tasklet_kill(&il->irq_tasklet);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002922}
2923
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002924static void il4965_irq_tasklet(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002925{
2926 u32 inta, handled = 0;
2927 u32 inta_fh;
2928 unsigned long flags;
2929 u32 i;
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01002930#ifdef CONFIG_IWLEGACY_DEBUG
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002931 u32 inta_mask;
2932#endif
2933
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002934 spin_lock_irqsave(&il->lock, flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002935
2936 /* Ack/clear/reset pending uCode interrupts.
2937 * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
2938 * and will clear only when CSR_FH_INT_STATUS gets cleared. */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02002939 inta = _il_rd(il, CSR_INT);
2940 _il_wr(il, CSR_INT, inta);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002941
2942 /* Ack/clear/reset pending flow-handler (DMA) interrupts.
2943 * Any new interrupts that happen after this, either while we're
2944 * in this tasklet, or later, will show up in next ISR/tasklet. */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02002945 inta_fh = _il_rd(il, CSR_FH_INT_STATUS);
2946 _il_wr(il, CSR_FH_INT_STATUS, inta_fh);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002947
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01002948#ifdef CONFIG_IWLEGACY_DEBUG
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002949 if (il_get_debug_level(il) & IL_DL_ISR) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002950 /* just for debug */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02002951 inta_mask = _il_rd(il, CSR_INT_MASK);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002952 D_ISR("inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002953 inta, inta_mask, inta_fh);
2954 }
2955#endif
2956
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002957 spin_unlock_irqrestore(&il->lock, flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002958
2959 /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not
2960 * atomic, make sure that inta covers all the interrupts that
2961 * we've discovered, even if FH interrupt came in just after
2962 * reading CSR_INT. */
2963 if (inta_fh & CSR49_FH_INT_RX_MASK)
2964 inta |= CSR_INT_BIT_FH_RX;
2965 if (inta_fh & CSR49_FH_INT_TX_MASK)
2966 inta |= CSR_INT_BIT_FH_TX;
2967
2968 /* Now service all interrupt bits discovered above. */
2969 if (inta & CSR_INT_BIT_HW_ERR) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002970 IL_ERR("Hardware error detected. Restarting.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002971
2972 /* Tell the device to stop sending interrupts */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002973 il_disable_interrupts(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002974
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002975 il->isr_stats.hw++;
2976 il_irq_handle_error(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002977
2978 handled |= CSR_INT_BIT_HW_ERR;
2979
2980 return;
2981 }
2982
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01002983#ifdef CONFIG_IWLEGACY_DEBUG
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002984 if (il_get_debug_level(il) & (IL_DL_ISR)) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002985 /* NIC fires this, but we don't use it, redundant with WAKEUP */
2986 if (inta & CSR_INT_BIT_SCD) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002987 D_ISR("Scheduler finished to transmit "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002988 "the frame/frames.\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002989 il->isr_stats.sch++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002990 }
2991
2992 /* Alive notification via Rx interrupt will do the real work */
2993 if (inta & CSR_INT_BIT_ALIVE) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002994 D_ISR("Alive interrupt\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002995 il->isr_stats.alive++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002996 }
2997 }
2998#endif
2999 /* Safely ignore these bits for debug checks below */
3000 inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
3001
3002 /* HW RF KILL switch toggled */
3003 if (inta & CSR_INT_BIT_RF_KILL) {
3004 int hw_rf_kill = 0;
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02003005 if (!(_il_rd(il, CSR_GP_CNTRL) &
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003006 CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
3007 hw_rf_kill = 1;
3008
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003009 IL_WARN("RF_KILL bit toggled to %s.\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003010 hw_rf_kill ? "disable radio" : "enable radio");
3011
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003012 il->isr_stats.rfkill++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003013
3014 /* driver only loads ucode once setting the interface up.
3015 * the driver allows loading the ucode even if the radio
3016 * is killed. Hence update the killswitch state here. The
3017 * rfkill handler will care about restarting if needed.
3018 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003019 if (!test_bit(STATUS_ALIVE, &il->status)) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003020 if (hw_rf_kill)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003021 set_bit(STATUS_RF_KILL_HW, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003022 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003023 clear_bit(STATUS_RF_KILL_HW, &il->status);
3024 wiphy_rfkill_set_hw_state(il->hw->wiphy, hw_rf_kill);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003025 }
3026
3027 handled |= CSR_INT_BIT_RF_KILL;
3028 }
3029
3030 /* Chip got too hot and stopped itself */
3031 if (inta & CSR_INT_BIT_CT_KILL) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003032 IL_ERR("Microcode CT kill error detected.\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003033 il->isr_stats.ctkill++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003034 handled |= CSR_INT_BIT_CT_KILL;
3035 }
3036
3037 /* Error detected by uCode */
3038 if (inta & CSR_INT_BIT_SW_ERR) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003039 IL_ERR("Microcode SW error detected. "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003040 " Restarting 0x%X.\n", inta);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003041 il->isr_stats.sw++;
3042 il_irq_handle_error(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003043 handled |= CSR_INT_BIT_SW_ERR;
3044 }
3045
3046 /*
3047 * uCode wakes up after power-down sleep.
3048 * Tell device about any new tx or host commands enqueued,
3049 * and about any Rx buffers made available while asleep.
3050 */
3051 if (inta & CSR_INT_BIT_WAKEUP) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003052 D_ISR("Wakeup interrupt\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003053 il_rx_queue_update_write_ptr(il, &il->rxq);
3054 for (i = 0; i < il->hw_params.max_txq_num; i++)
3055 il_txq_update_write_ptr(il, &il->txq[i]);
3056 il->isr_stats.wakeup++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003057 handled |= CSR_INT_BIT_WAKEUP;
3058 }
3059
3060 /* All uCode command responses, including Tx command responses,
3061 * Rx "responses" (frame-received notification), and other
3062 * notifications from uCode come through here*/
3063 if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003064 il4965_rx_handle(il);
3065 il->isr_stats.rx++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003066 handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
3067 }
3068
3069 /* This "Tx" DMA channel is used only for loading uCode */
3070 if (inta & CSR_INT_BIT_FH_TX) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003071 D_ISR("uCode load interrupt\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003072 il->isr_stats.tx++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003073 handled |= CSR_INT_BIT_FH_TX;
3074 /* Wake up uCode load routine, now that load is complete */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003075 il->ucode_write_complete = 1;
3076 wake_up(&il->wait_command_queue);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003077 }
3078
3079 if (inta & ~handled) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003080 IL_ERR("Unhandled INTA bits 0x%08x\n", inta & ~handled);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003081 il->isr_stats.unhandled++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003082 }
3083
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003084 if (inta & ~(il->inta_mask)) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003085 IL_WARN("Disabled INTA bits 0x%08x were pending\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003086 inta & ~il->inta_mask);
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003087 IL_WARN(" with FH_INT = 0x%08x\n", inta_fh);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003088 }
3089
3090 /* Re-enable all interrupts */
Stanislaw Gruszka93fd74e2011-04-28 11:51:30 +02003091 /* only Re-enable if disabled by irq */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003092 if (test_bit(STATUS_INT_ENABLED, &il->status))
3093 il_enable_interrupts(il);
Stanislaw Gruszkaa078a1f2011-04-28 11:51:25 +02003094 /* Re-enable RF_KILL if it occurred */
3095 else if (handled & CSR_INT_BIT_RF_KILL)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003096 il_enable_rfkill_int(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003097
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01003098#ifdef CONFIG_IWLEGACY_DEBUG
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003099 if (il_get_debug_level(il) & (IL_DL_ISR)) {
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02003100 inta = _il_rd(il, CSR_INT);
3101 inta_mask = _il_rd(il, CSR_INT_MASK);
3102 inta_fh = _il_rd(il, CSR_FH_INT_STATUS);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003103 D_ISR(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003104 "End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
3105 "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags);
3106 }
3107#endif
3108}
3109
3110/*****************************************************************************
3111 *
3112 * sysfs attributes
3113 *
3114 *****************************************************************************/
3115
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01003116#ifdef CONFIG_IWLEGACY_DEBUG
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003117
3118/*
3119 * The following adds a new attribute to the sysfs representation
3120 * of this device driver (i.e. a new file in /sys/class/net/wlan0/device/)
3121 * used for controlling the debug level.
3122 *
3123 * See the level definitions in iwl for details.
3124 *
3125 * The debug_level being managed using sysfs below is a per device debug
3126 * level that is used instead of the global debug level if it (the per
3127 * device debug level) is set.
3128 */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003129static ssize_t il4965_show_debug_level(struct device *d,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003130 struct device_attribute *attr, char *buf)
3131{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003132 struct il_priv *il = dev_get_drvdata(d);
3133 return sprintf(buf, "0x%08X\n", il_get_debug_level(il));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003134}
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003135static ssize_t il4965_store_debug_level(struct device *d,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003136 struct device_attribute *attr,
3137 const char *buf, size_t count)
3138{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003139 struct il_priv *il = dev_get_drvdata(d);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003140 unsigned long val;
3141 int ret;
3142
3143 ret = strict_strtoul(buf, 0, &val);
3144 if (ret)
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003145 IL_ERR("%s is not in hex or decimal form.\n", buf);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003146 else {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003147 il->debug_level = val;
3148 if (il_alloc_traffic_mem(il))
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003149 IL_ERR(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003150 "Not enough memory to generate traffic log\n");
3151 }
3152 return strnlen(buf, count);
3153}
3154
3155static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003156 il4965_show_debug_level, il4965_store_debug_level);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003157
3158
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01003159#endif /* CONFIG_IWLEGACY_DEBUG */
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003160
3161
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003162static ssize_t il4965_show_temperature(struct device *d,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003163 struct device_attribute *attr, char *buf)
3164{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003165 struct il_priv *il = dev_get_drvdata(d);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003166
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003167 if (!il_is_alive(il))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003168 return -EAGAIN;
3169
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003170 return sprintf(buf, "%d\n", il->temperature);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003171}
3172
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003173static DEVICE_ATTR(temperature, S_IRUGO, il4965_show_temperature, NULL);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003174
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003175static ssize_t il4965_show_tx_power(struct device *d,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003176 struct device_attribute *attr, char *buf)
3177{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003178 struct il_priv *il = dev_get_drvdata(d);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003179
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003180 if (!il_is_ready_rf(il))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003181 return sprintf(buf, "off\n");
3182 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003183 return sprintf(buf, "%d\n", il->tx_power_user_lmt);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003184}
3185
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003186static ssize_t il4965_store_tx_power(struct device *d,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003187 struct device_attribute *attr,
3188 const char *buf, size_t count)
3189{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003190 struct il_priv *il = dev_get_drvdata(d);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003191 unsigned long val;
3192 int ret;
3193
3194 ret = strict_strtoul(buf, 10, &val);
3195 if (ret)
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003196 IL_INFO("%s is not in decimal form.\n", buf);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003197 else {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003198 ret = il_set_tx_power(il, val, false);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003199 if (ret)
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003200 IL_ERR("failed setting tx power (0x%d).\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003201 ret);
3202 else
3203 ret = count;
3204 }
3205 return ret;
3206}
3207
3208static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003209 il4965_show_tx_power, il4965_store_tx_power);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003210
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003211static struct attribute *il_sysfs_entries[] = {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003212 &dev_attr_temperature.attr,
3213 &dev_attr_tx_power.attr,
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01003214#ifdef CONFIG_IWLEGACY_DEBUG
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003215 &dev_attr_debug_level.attr,
3216#endif
3217 NULL
3218};
3219
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003220static struct attribute_group il_attribute_group = {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003221 .name = NULL, /* put in device directory */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003222 .attrs = il_sysfs_entries,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003223};
3224
3225/******************************************************************************
3226 *
3227 * uCode download functions
3228 *
3229 ******************************************************************************/
3230
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003231static void il4965_dealloc_ucode_pci(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003232{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003233 il_free_fw_desc(il->pci_dev, &il->ucode_code);
3234 il_free_fw_desc(il->pci_dev, &il->ucode_data);
3235 il_free_fw_desc(il->pci_dev, &il->ucode_data_backup);
3236 il_free_fw_desc(il->pci_dev, &il->ucode_init);
3237 il_free_fw_desc(il->pci_dev, &il->ucode_init_data);
3238 il_free_fw_desc(il->pci_dev, &il->ucode_boot);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003239}
3240
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003241static void il4965_nic_start(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003242{
3243 /* Remove all resets to allow NIC to operate */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02003244 _il_wr(il, CSR_RESET, 0);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003245}
3246
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003247static void il4965_ucode_callback(const struct firmware *ucode_raw,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003248 void *context);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003249static int il4965_mac_setup_register(struct il_priv *il,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003250 u32 max_probe_length);
3251
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003252static int __must_check il4965_request_firmware(struct il_priv *il, bool first)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003253{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003254 const char *name_pre = il->cfg->fw_name_pre;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003255 char tag[8];
3256
3257 if (first) {
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +01003258 il->fw_idx = il->cfg->ucode_api_max;
3259 sprintf(tag, "%d", il->fw_idx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003260 } else {
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +01003261 il->fw_idx--;
3262 sprintf(tag, "%d", il->fw_idx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003263 }
3264
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +01003265 if (il->fw_idx < il->cfg->ucode_api_min) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003266 IL_ERR("no suitable firmware found!\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003267 return -ENOENT;
3268 }
3269
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003270 sprintf(il->firmware_name, "%s%s%s", name_pre, tag, ".ucode");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003271
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003272 D_INFO("attempting to load firmware '%s'\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003273 il->firmware_name);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003274
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003275 return request_firmware_nowait(THIS_MODULE, 1, il->firmware_name,
3276 &il->pci_dev->dev, GFP_KERNEL, il,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003277 il4965_ucode_callback);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003278}
3279
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003280struct il4965_firmware_pieces {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003281 const void *inst, *data, *init, *init_data, *boot;
3282 size_t inst_size, data_size, init_size, init_data_size, boot_size;
3283};
3284
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003285static int il4965_load_firmware(struct il_priv *il,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003286 const struct firmware *ucode_raw,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003287 struct il4965_firmware_pieces *pieces)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003288{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003289 struct il_ucode_header *ucode = (void *)ucode_raw->data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003290 u32 api_ver, hdr_size;
3291 const u8 *src;
3292
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003293 il->ucode_ver = le32_to_cpu(ucode->ver);
3294 api_ver = IL_UCODE_API(il->ucode_ver);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003295
3296 switch (api_ver) {
3297 default:
3298 case 0:
3299 case 1:
3300 case 2:
3301 hdr_size = 24;
3302 if (ucode_raw->size < hdr_size) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003303 IL_ERR("File size too small!\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003304 return -EINVAL;
3305 }
3306 pieces->inst_size = le32_to_cpu(ucode->v1.inst_size);
3307 pieces->data_size = le32_to_cpu(ucode->v1.data_size);
3308 pieces->init_size = le32_to_cpu(ucode->v1.init_size);
3309 pieces->init_data_size =
3310 le32_to_cpu(ucode->v1.init_data_size);
3311 pieces->boot_size = le32_to_cpu(ucode->v1.boot_size);
3312 src = ucode->v1.data;
3313 break;
3314 }
3315
3316 /* Verify size of file vs. image size info in file's header */
3317 if (ucode_raw->size != hdr_size + pieces->inst_size +
3318 pieces->data_size + pieces->init_size +
3319 pieces->init_data_size + pieces->boot_size) {
3320
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003321 IL_ERR(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003322 "uCode file size %d does not match expected size\n",
3323 (int)ucode_raw->size);
3324 return -EINVAL;
3325 }
3326
3327 pieces->inst = src;
3328 src += pieces->inst_size;
3329 pieces->data = src;
3330 src += pieces->data_size;
3331 pieces->init = src;
3332 src += pieces->init_size;
3333 pieces->init_data = src;
3334 src += pieces->init_data_size;
3335 pieces->boot = src;
3336 src += pieces->boot_size;
3337
3338 return 0;
3339}
3340
3341/**
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003342 * il4965_ucode_callback - callback when firmware was loaded
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003343 *
3344 * If loaded successfully, copies the firmware into buffers
3345 * for the card to fetch (via DMA).
3346 */
3347static void
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003348il4965_ucode_callback(const struct firmware *ucode_raw, void *context)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003349{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003350 struct il_priv *il = context;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003351 struct il_ucode_header *ucode;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003352 int err;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003353 struct il4965_firmware_pieces pieces;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003354 const unsigned int api_max = il->cfg->ucode_api_max;
3355 const unsigned int api_min = il->cfg->ucode_api_min;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003356 u32 api_ver;
3357
3358 u32 max_probe_length = 200;
3359 u32 standard_phy_calibration_size =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003360 IL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003361
3362 memset(&pieces, 0, sizeof(pieces));
3363
3364 if (!ucode_raw) {
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +01003365 if (il->fw_idx <= il->cfg->ucode_api_max)
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003366 IL_ERR(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003367 "request for firmware file '%s' failed.\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003368 il->firmware_name);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003369 goto try_again;
3370 }
3371
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003372 D_INFO("Loaded firmware file '%s' (%zd bytes).\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003373 il->firmware_name, ucode_raw->size);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003374
3375 /* Make sure that we got at least the API version number */
3376 if (ucode_raw->size < 4) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003377 IL_ERR("File size way too small!\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003378 goto try_again;
3379 }
3380
3381 /* Data from ucode file: header followed by uCode images */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003382 ucode = (struct il_ucode_header *)ucode_raw->data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003383
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003384 err = il4965_load_firmware(il, ucode_raw, &pieces);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003385
3386 if (err)
3387 goto try_again;
3388
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003389 api_ver = IL_UCODE_API(il->ucode_ver);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003390
3391 /*
3392 * api_ver should match the api version forming part of the
3393 * firmware filename ... but we don't check for that and only rely
3394 * on the API version read from firmware header from here on forward
3395 */
3396 if (api_ver < api_min || api_ver > api_max) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003397 IL_ERR(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003398 "Driver unable to support your firmware API. "
3399 "Driver supports v%u, firmware is v%u.\n",
3400 api_max, api_ver);
3401 goto try_again;
3402 }
3403
3404 if (api_ver != api_max)
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003405 IL_ERR(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003406 "Firmware has old API version. Expected v%u, "
3407 "got v%u. New firmware can be obtained "
3408 "from http://www.intellinuxwireless.org.\n",
3409 api_max, api_ver);
3410
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003411 IL_INFO("loaded firmware version %u.%u.%u.%u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003412 IL_UCODE_MAJOR(il->ucode_ver),
3413 IL_UCODE_MINOR(il->ucode_ver),
3414 IL_UCODE_API(il->ucode_ver),
3415 IL_UCODE_SERIAL(il->ucode_ver));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003416
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003417 snprintf(il->hw->wiphy->fw_version,
3418 sizeof(il->hw->wiphy->fw_version),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003419 "%u.%u.%u.%u",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003420 IL_UCODE_MAJOR(il->ucode_ver),
3421 IL_UCODE_MINOR(il->ucode_ver),
3422 IL_UCODE_API(il->ucode_ver),
3423 IL_UCODE_SERIAL(il->ucode_ver));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003424
3425 /*
3426 * For any of the failures below (before allocating pci memory)
3427 * we will try to load a version with a smaller API -- maybe the
3428 * user just got a corrupted version of the latest API.
3429 */
3430
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003431 D_INFO("f/w package hdr ucode version raw = 0x%x\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003432 il->ucode_ver);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003433 D_INFO("f/w package hdr runtime inst size = %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003434 pieces.inst_size);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003435 D_INFO("f/w package hdr runtime data size = %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003436 pieces.data_size);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003437 D_INFO("f/w package hdr init inst size = %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003438 pieces.init_size);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003439 D_INFO("f/w package hdr init data size = %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003440 pieces.init_data_size);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003441 D_INFO("f/w package hdr boot inst size = %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003442 pieces.boot_size);
3443
3444 /* Verify that uCode images will fit in card's SRAM */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003445 if (pieces.inst_size > il->hw_params.max_inst_size) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003446 IL_ERR("uCode instr len %Zd too large to fit in\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003447 pieces.inst_size);
3448 goto try_again;
3449 }
3450
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003451 if (pieces.data_size > il->hw_params.max_data_size) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003452 IL_ERR("uCode data len %Zd too large to fit in\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003453 pieces.data_size);
3454 goto try_again;
3455 }
3456
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003457 if (pieces.init_size > il->hw_params.max_inst_size) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003458 IL_ERR("uCode init instr len %Zd too large to fit in\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003459 pieces.init_size);
3460 goto try_again;
3461 }
3462
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003463 if (pieces.init_data_size > il->hw_params.max_data_size) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003464 IL_ERR("uCode init data len %Zd too large to fit in\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003465 pieces.init_data_size);
3466 goto try_again;
3467 }
3468
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003469 if (pieces.boot_size > il->hw_params.max_bsm_size) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003470 IL_ERR("uCode boot instr len %Zd too large to fit in\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003471 pieces.boot_size);
3472 goto try_again;
3473 }
3474
3475 /* Allocate ucode buffers for card's bus-master loading ... */
3476
3477 /* Runtime instructions and 2 copies of data:
3478 * 1) unmodified from disk
3479 * 2) backup cache for save/restore during power-downs */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003480 il->ucode_code.len = pieces.inst_size;
3481 il_alloc_fw_desc(il->pci_dev, &il->ucode_code);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003482
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003483 il->ucode_data.len = pieces.data_size;
3484 il_alloc_fw_desc(il->pci_dev, &il->ucode_data);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003485
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003486 il->ucode_data_backup.len = pieces.data_size;
3487 il_alloc_fw_desc(il->pci_dev, &il->ucode_data_backup);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003488
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003489 if (!il->ucode_code.v_addr || !il->ucode_data.v_addr ||
3490 !il->ucode_data_backup.v_addr)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003491 goto err_pci_alloc;
3492
3493 /* Initialization instructions and data */
3494 if (pieces.init_size && pieces.init_data_size) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003495 il->ucode_init.len = pieces.init_size;
3496 il_alloc_fw_desc(il->pci_dev, &il->ucode_init);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003497
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003498 il->ucode_init_data.len = pieces.init_data_size;
3499 il_alloc_fw_desc(il->pci_dev, &il->ucode_init_data);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003500
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003501 if (!il->ucode_init.v_addr || !il->ucode_init_data.v_addr)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003502 goto err_pci_alloc;
3503 }
3504
3505 /* Bootstrap (instructions only, no data) */
3506 if (pieces.boot_size) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003507 il->ucode_boot.len = pieces.boot_size;
3508 il_alloc_fw_desc(il->pci_dev, &il->ucode_boot);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003509
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003510 if (!il->ucode_boot.v_addr)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003511 goto err_pci_alloc;
3512 }
3513
3514 /* Now that we can no longer fail, copy information */
3515
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003516 il->sta_key_max_num = STA_KEY_MAX_NUM;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003517
3518 /* Copy images into buffers for card's bus-master reads ... */
3519
3520 /* Runtime instructions (first block of data in file) */
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003521 D_INFO("Copying (but not loading) uCode instr len %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003522 pieces.inst_size);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003523 memcpy(il->ucode_code.v_addr, pieces.inst, pieces.inst_size);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003524
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003525 D_INFO("uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003526 il->ucode_code.v_addr, (u32)il->ucode_code.p_addr);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003527
3528 /*
3529 * Runtime data
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003530 * NOTE: Copy into backup buffer will be done in il_up()
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003531 */
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003532 D_INFO("Copying (but not loading) uCode data len %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003533 pieces.data_size);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003534 memcpy(il->ucode_data.v_addr, pieces.data, pieces.data_size);
3535 memcpy(il->ucode_data_backup.v_addr, pieces.data, pieces.data_size);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003536
3537 /* Initialization instructions */
3538 if (pieces.init_size) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003539 D_INFO(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003540 "Copying (but not loading) init instr len %Zd\n",
3541 pieces.init_size);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003542 memcpy(il->ucode_init.v_addr, pieces.init, pieces.init_size);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003543 }
3544
3545 /* Initialization data */
3546 if (pieces.init_data_size) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003547 D_INFO(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003548 "Copying (but not loading) init data len %Zd\n",
3549 pieces.init_data_size);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003550 memcpy(il->ucode_init_data.v_addr, pieces.init_data,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003551 pieces.init_data_size);
3552 }
3553
3554 /* Bootstrap instructions */
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003555 D_INFO("Copying (but not loading) boot instr len %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003556 pieces.boot_size);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003557 memcpy(il->ucode_boot.v_addr, pieces.boot, pieces.boot_size);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003558
3559 /*
3560 * figure out the offset of chain noise reset and gain commands
3561 * base on the size of standard phy calibration commands table size
3562 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003563 il->_4965.phy_calib_chain_noise_reset_cmd =
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003564 standard_phy_calibration_size;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003565 il->_4965.phy_calib_chain_noise_gain_cmd =
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003566 standard_phy_calibration_size + 1;
3567
3568 /**************************************************
3569 * This is still part of probe() in a sense...
3570 *
3571 * 9. Setup and register with mac80211 and debugfs
3572 **************************************************/
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003573 err = il4965_mac_setup_register(il, max_probe_length);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003574 if (err)
3575 goto out_unbind;
3576
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003577 err = il_dbgfs_register(il, DRV_NAME);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003578 if (err)
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003579 IL_ERR(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003580 "failed to create debugfs files. Ignoring error: %d\n", err);
3581
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003582 err = sysfs_create_group(&il->pci_dev->dev.kobj,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003583 &il_attribute_group);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003584 if (err) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003585 IL_ERR("failed to create sysfs device attributes\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003586 goto out_unbind;
3587 }
3588
3589 /* We have our copies now, allow OS release its copies */
3590 release_firmware(ucode_raw);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003591 complete(&il->_4965.firmware_loading_complete);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003592 return;
3593
3594 try_again:
3595 /* try next, if any */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003596 if (il4965_request_firmware(il, false))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003597 goto out_unbind;
3598 release_firmware(ucode_raw);
3599 return;
3600
3601 err_pci_alloc:
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003602 IL_ERR("failed to allocate pci memory\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003603 il4965_dealloc_ucode_pci(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003604 out_unbind:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003605 complete(&il->_4965.firmware_loading_complete);
3606 device_release_driver(&il->pci_dev->dev);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003607 release_firmware(ucode_raw);
3608}
3609
3610static const char * const desc_lookup_text[] = {
3611 "OK",
3612 "FAIL",
3613 "BAD_PARAM",
3614 "BAD_CHECKSUM",
3615 "NMI_INTERRUPT_WDG",
3616 "SYSASSERT",
3617 "FATAL_ERROR",
3618 "BAD_COMMAND",
3619 "HW_ERROR_TUNE_LOCK",
3620 "HW_ERROR_TEMPERATURE",
3621 "ILLEGAL_CHAN_FREQ",
Stanislaw Gruszka3b98c7f2011-08-26 16:29:35 +02003622 "VCC_NOT_STBL",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003623 "FH_ERROR",
3624 "NMI_INTERRUPT_HOST",
3625 "NMI_INTERRUPT_ACTION_PT",
3626 "NMI_INTERRUPT_UNKNOWN",
3627 "UCODE_VERSION_MISMATCH",
3628 "HW_ERROR_ABS_LOCK",
3629 "HW_ERROR_CAL_LOCK_FAIL",
3630 "NMI_INTERRUPT_INST_ACTION_PT",
3631 "NMI_INTERRUPT_DATA_ACTION_PT",
3632 "NMI_TRM_HW_ER",
3633 "NMI_INTERRUPT_TRM",
Joe Perches861d9c32011-07-08 23:20:24 -07003634 "NMI_INTERRUPT_BREAK_POINT",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003635 "DEBUG_0",
3636 "DEBUG_1",
3637 "DEBUG_2",
3638 "DEBUG_3",
3639};
3640
3641static struct { char *name; u8 num; } advanced_lookup[] = {
3642 { "NMI_INTERRUPT_WDG", 0x34 },
3643 { "SYSASSERT", 0x35 },
3644 { "UCODE_VERSION_MISMATCH", 0x37 },
3645 { "BAD_COMMAND", 0x38 },
3646 { "NMI_INTERRUPT_DATA_ACTION_PT", 0x3C },
3647 { "FATAL_ERROR", 0x3D },
3648 { "NMI_TRM_HW_ERR", 0x46 },
3649 { "NMI_INTERRUPT_TRM", 0x4C },
3650 { "NMI_INTERRUPT_BREAK_POINT", 0x54 },
3651 { "NMI_INTERRUPT_WDG_RXF_FULL", 0x5C },
3652 { "NMI_INTERRUPT_WDG_NO_RBD_RXF_FULL", 0x64 },
3653 { "NMI_INTERRUPT_HOST", 0x66 },
3654 { "NMI_INTERRUPT_ACTION_PT", 0x7C },
3655 { "NMI_INTERRUPT_UNKNOWN", 0x84 },
3656 { "NMI_INTERRUPT_INST_ACTION_PT", 0x86 },
3657 { "ADVANCED_SYSASSERT", 0 },
3658};
3659
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003660static const char *il4965_desc_lookup(u32 num)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003661{
3662 int i;
3663 int max = ARRAY_SIZE(desc_lookup_text);
3664
3665 if (num < max)
3666 return desc_lookup_text[num];
3667
3668 max = ARRAY_SIZE(advanced_lookup) - 1;
3669 for (i = 0; i < max; i++) {
3670 if (advanced_lookup[i].num == num)
3671 break;
3672 }
3673 return advanced_lookup[i].name;
3674}
3675
3676#define ERROR_START_OFFSET (1 * sizeof(u32))
3677#define ERROR_ELEM_SIZE (7 * sizeof(u32))
3678
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003679void il4965_dump_nic_error_log(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003680{
3681 u32 data2, line;
3682 u32 desc, time, count, base, data1;
3683 u32 blink1, blink2, ilink1, ilink2;
3684 u32 pc, hcmd;
3685
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003686 if (il->ucode_type == UCODE_INIT) {
3687 base = le32_to_cpu(il->card_alive_init.error_event_table_ptr);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003688 } else {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003689 base = le32_to_cpu(il->card_alive.error_event_table_ptr);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003690 }
3691
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003692 if (!il->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003693 IL_ERR(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003694 "Not valid error log pointer 0x%08X for %s uCode\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003695 base, (il->ucode_type == UCODE_INIT) ? "Init" : "RT");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003696 return;
3697 }
3698
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003699 count = il_read_targ_mem(il, base);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003700
3701 if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003702 IL_ERR("Start IWL Error Log Dump:\n");
3703 IL_ERR("Status: 0x%08lX, count: %d\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003704 il->status, count);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003705 }
3706
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003707 desc = il_read_targ_mem(il, base + 1 * sizeof(u32));
3708 il->isr_stats.err_code = desc;
3709 pc = il_read_targ_mem(il, base + 2 * sizeof(u32));
3710 blink1 = il_read_targ_mem(il, base + 3 * sizeof(u32));
3711 blink2 = il_read_targ_mem(il, base + 4 * sizeof(u32));
3712 ilink1 = il_read_targ_mem(il, base + 5 * sizeof(u32));
3713 ilink2 = il_read_targ_mem(il, base + 6 * sizeof(u32));
3714 data1 = il_read_targ_mem(il, base + 7 * sizeof(u32));
3715 data2 = il_read_targ_mem(il, base + 8 * sizeof(u32));
3716 line = il_read_targ_mem(il, base + 9 * sizeof(u32));
3717 time = il_read_targ_mem(il, base + 11 * sizeof(u32));
3718 hcmd = il_read_targ_mem(il, base + 22 * sizeof(u32));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003719
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003720 IL_ERR("Desc Time "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003721 "data1 data2 line\n");
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003722 IL_ERR("%-28s (0x%04X) %010u 0x%08X 0x%08X %u\n",
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003723 il4965_desc_lookup(desc), desc, time, data1, data2, line);
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003724 IL_ERR("pc blink1 blink2 ilink1 ilink2 hcmd\n");
3725 IL_ERR("0x%05X 0x%05X 0x%05X 0x%05X 0x%05X 0x%05X\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003726 pc, blink1, blink2, ilink1, ilink2, hcmd);
3727}
3728
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003729static void il4965_rf_kill_ct_config(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003730{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003731 struct il_ct_kill_config cmd;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003732 unsigned long flags;
3733 int ret = 0;
3734
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003735 spin_lock_irqsave(&il->lock, flags);
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02003736 _il_wr(il, CSR_UCODE_DRV_GP1_CLR,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003737 CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003738 spin_unlock_irqrestore(&il->lock, flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003739
3740 cmd.critical_temperature_R =
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003741 cpu_to_le32(il->hw_params.ct_kill_threshold);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003742
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003743 ret = il_send_cmd_pdu(il, REPLY_CT_KILL_CONFIG_CMD,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003744 sizeof(cmd), &cmd);
3745 if (ret)
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003746 IL_ERR("REPLY_CT_KILL_CONFIG_CMD failed\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003747 else
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003748 D_INFO("REPLY_CT_KILL_CONFIG_CMD "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003749 "succeeded, "
3750 "critical temperature is %d\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003751 il->hw_params.ct_kill_threshold);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003752}
3753
3754static const s8 default_queue_to_tx_fifo[] = {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003755 IL_TX_FIFO_VO,
3756 IL_TX_FIFO_VI,
3757 IL_TX_FIFO_BE,
3758 IL_TX_FIFO_BK,
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01003759 IL49_CMD_FIFO_NUM,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003760 IL_TX_FIFO_UNUSED,
3761 IL_TX_FIFO_UNUSED,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003762};
3763
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003764static int il4965_alive_notify(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003765{
3766 u32 a;
3767 unsigned long flags;
3768 int i, chan;
3769 u32 reg_val;
3770
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003771 spin_lock_irqsave(&il->lock, flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003772
3773 /* Clear 4965's internal Tx Scheduler data base */
Stanislaw Gruszkadb54eb52011-08-24 21:06:33 +02003774 il->scd_base_addr = il_rd_prph(il,
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01003775 IL49_SCD_SRAM_BASE_ADDR);
3776 a = il->scd_base_addr + IL49_SCD_CONTEXT_DATA_OFFSET;
3777 for (; a < il->scd_base_addr + IL49_SCD_TX_STTS_BITMAP_OFFSET; a += 4)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003778 il_write_targ_mem(il, a, 0);
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01003779 for (; a < il->scd_base_addr + IL49_SCD_TRANSLATE_TBL_OFFSET; a += 4)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003780 il_write_targ_mem(il, a, 0);
3781 for (; a < il->scd_base_addr +
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01003782 IL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(il->hw_params.max_txq_num); a += 4)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003783 il_write_targ_mem(il, a, 0);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003784
3785 /* Tel 4965 where to find Tx byte count tables */
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01003786 il_wr_prph(il, IL49_SCD_DRAM_BASE_ADDR,
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003787 il->scd_bc_tbls.dma >> 10);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003788
3789 /* Enable DMA channel */
3790 for (chan = 0; chan < FH49_TCSR_CHNL_NUM ; chan++)
Stanislaw Gruszka0c1a94e2011-08-24 17:37:16 +02003791 il_wr(il,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003792 FH_TCSR_CHNL_TX_CONFIG_REG(chan),
3793 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
3794 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);
3795
3796 /* Update FH chicken bits */
Stanislaw Gruszka0c1a94e2011-08-24 17:37:16 +02003797 reg_val = il_rd(il, FH_TX_CHICKEN_BITS_REG);
3798 il_wr(il, FH_TX_CHICKEN_BITS_REG,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003799 reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
3800
3801 /* Disable chain mode for all queues */
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01003802 il_wr_prph(il, IL49_SCD_QUEUECHAIN_SEL, 0);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003803
3804 /* Initialize each Tx queue (including the command queue) */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003805 for (i = 0; i < il->hw_params.max_txq_num; i++) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003806
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +01003807 /* TFD circular buffer read/write idxes */
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01003808 il_wr_prph(il, IL49_SCD_QUEUE_RDPTR(i), 0);
Stanislaw Gruszka0c1a94e2011-08-24 17:37:16 +02003809 il_wr(il, HBUS_TARG_WRPTR, 0 | (i << 8));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003810
3811 /* Max Tx Window size for Scheduler-ACK mode */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003812 il_write_targ_mem(il, il->scd_base_addr +
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01003813 IL49_SCD_CONTEXT_QUEUE_OFFSET(i),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003814 (SCD_WIN_SIZE <<
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01003815 IL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) &
3816 IL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003817
3818 /* Frame limit */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003819 il_write_targ_mem(il, il->scd_base_addr +
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01003820 IL49_SCD_CONTEXT_QUEUE_OFFSET(i) +
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003821 sizeof(u32),
3822 (SCD_FRAME_LIMIT <<
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01003823 IL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
3824 IL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003825
3826 }
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01003827 il_wr_prph(il, IL49_SCD_INTERRUPT_MASK,
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003828 (1 << il->hw_params.max_txq_num) - 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003829
3830 /* Activate all Tx DMA/FIFO channels */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003831 il4965_txq_set_sched(il, IL_MASK(0, 6));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003832
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003833 il4965_set_wr_ptrs(il, IL_DEFAULT_CMD_QUEUE_NUM, 0);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003834
3835 /* make sure all queue are not stopped */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003836 memset(&il->queue_stopped[0], 0, sizeof(il->queue_stopped));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003837 for (i = 0; i < 4; i++)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003838 atomic_set(&il->queue_stop_count[i], 0);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003839
3840 /* reset to 0 to enable all the queue first */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003841 il->txq_ctx_active_msk = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003842 /* Map each Tx/cmd queue to its corresponding fifo */
3843 BUILD_BUG_ON(ARRAY_SIZE(default_queue_to_tx_fifo) != 7);
3844
3845 for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) {
3846 int ac = default_queue_to_tx_fifo[i];
3847
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003848 il_txq_ctx_activate(il, i);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003849
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003850 if (ac == IL_TX_FIFO_UNUSED)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003851 continue;
3852
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003853 il4965_tx_queue_set_status(il, &il->txq[i], ac, 0);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003854 }
3855
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003856 spin_unlock_irqrestore(&il->lock, flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003857
3858 return 0;
3859}
3860
3861/**
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003862 * il4965_alive_start - called after REPLY_ALIVE notification received
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003863 * from protocol/runtime uCode (initialization uCode's
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003864 * Alive gets handled by il_init_alive_start()).
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003865 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003866static void il4965_alive_start(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003867{
3868 int ret = 0;
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +01003869 struct il_rxon_context *ctx = &il->ctx;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003870
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003871 D_INFO("Runtime Alive received.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003872
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003873 if (il->card_alive.is_valid != UCODE_VALID_OK) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003874 /* We had an error bringing up the hardware, so take it
3875 * all the way back down so we can try again */
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003876 D_INFO("Alive failed.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003877 goto restart;
3878 }
3879
3880 /* Initialize uCode has loaded Runtime uCode ... verify inst image.
3881 * This is a paranoid check, because we would not have gotten the
3882 * "runtime" alive if code weren't properly loaded. */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003883 if (il4965_verify_ucode(il)) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003884 /* Runtime instruction load was bad;
3885 * take it all the way back down so we can try again */
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003886 D_INFO("Bad runtime uCode load.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003887 goto restart;
3888 }
3889
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003890 ret = il4965_alive_notify(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003891 if (ret) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003892 IL_WARN(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003893 "Could not complete ALIVE transition [ntf]: %d\n", ret);
3894 goto restart;
3895 }
3896
3897
3898 /* After the ALIVE response, we can send host commands to the uCode */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003899 set_bit(STATUS_ALIVE, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003900
3901 /* Enable watchdog to monitor the driver tx queues */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003902 il_setup_watchdog(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003903
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003904 if (il_is_rfkill(il))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003905 return;
3906
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003907 ieee80211_wake_queues(il->hw);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003908
Stanislaw Gruszka2eb05812011-08-26 16:07:43 +02003909 il->active_rate = RATES_MASK;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003910
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003911 if (il_is_associated_ctx(ctx)) {
3912 struct il_rxon_cmd *active_rxon =
3913 (struct il_rxon_cmd *)&ctx->active;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003914 /* apply any changes in staging */
3915 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
3916 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
3917 } else {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003918 /* Initialize our rx_config data */
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +02003919 il_connection_init_rx_config(il, &il->ctx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003920
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003921 if (il->cfg->ops->hcmd->set_rxon_chain)
3922 il->cfg->ops->hcmd->set_rxon_chain(il, ctx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003923 }
3924
3925 /* Configure bluetooth coexistence if enabled */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003926 il_send_bt_config(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003927
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003928 il4965_reset_run_time_calib(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003929
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003930 set_bit(STATUS_READY, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003931
3932 /* Configure the adapter for unassociated operation */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003933 il_commit_rxon(il, ctx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003934
3935 /* At this point, the NIC is initialized and operational */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003936 il4965_rf_kill_ct_config(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003937
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003938 D_INFO("ALIVE processing complete.\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003939 wake_up(&il->wait_command_queue);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003940
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003941 il_power_update_mode(il, true);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003942 D_INFO("Updated power mode\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003943
3944 return;
3945
3946 restart:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003947 queue_work(il->workqueue, &il->restart);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003948}
3949
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003950static void il4965_cancel_deferred_work(struct il_priv *il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003951
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003952static void __il4965_down(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003953{
3954 unsigned long flags;
Stanislaw Gruszkaab42b402011-04-28 11:51:24 +02003955 int exit_pending;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003956
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003957 D_INFO(DRV_NAME " is going down\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003958
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003959 il_scan_cancel_timeout(il, 200);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003960
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003961 exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003962
3963 /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set
3964 * to prevent rearm timer */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003965 del_timer_sync(&il->watchdog);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003966
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003967 il_clear_ucode_stations(il, NULL);
3968 il_dealloc_bcast_stations(il);
3969 il_clear_driver_stations(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003970
3971 /* Unblock any waiting calls */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003972 wake_up_all(&il->wait_command_queue);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003973
3974 /* Wipe out the EXIT_PENDING status bit if we are not actually
3975 * exiting the module */
3976 if (!exit_pending)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003977 clear_bit(STATUS_EXIT_PENDING, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003978
3979 /* stop and reset the on-board processor */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02003980 _il_wr(il, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003981
3982 /* tell the device to stop sending interrupts */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003983 spin_lock_irqsave(&il->lock, flags);
3984 il_disable_interrupts(il);
3985 spin_unlock_irqrestore(&il->lock, flags);
3986 il4965_synchronize_irq(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003987
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003988 if (il->mac80211_registered)
3989 ieee80211_stop_queues(il->hw);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003990
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003991 /* If we have not previously called il_init() then
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003992 * clear all bits but the RF Kill bit and return */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003993 if (!il_is_init(il)) {
3994 il->status = test_bit(STATUS_RF_KILL_HW, &il->status) <<
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003995 STATUS_RF_KILL_HW |
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003996 test_bit(STATUS_GEO_CONFIGURED, &il->status) <<
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003997 STATUS_GEO_CONFIGURED |
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003998 test_bit(STATUS_EXIT_PENDING, &il->status) <<
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003999 STATUS_EXIT_PENDING;
4000 goto exit;
4001 }
4002
4003 /* ...otherwise clear out all the status bits but the RF Kill
4004 * bit and continue taking the NIC down. */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004005 il->status &= test_bit(STATUS_RF_KILL_HW, &il->status) <<
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004006 STATUS_RF_KILL_HW |
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004007 test_bit(STATUS_GEO_CONFIGURED, &il->status) <<
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004008 STATUS_GEO_CONFIGURED |
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004009 test_bit(STATUS_FW_ERROR, &il->status) <<
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004010 STATUS_FW_ERROR |
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004011 test_bit(STATUS_EXIT_PENDING, &il->status) <<
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004012 STATUS_EXIT_PENDING;
4013
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004014 il4965_txq_ctx_stop(il);
4015 il4965_rxq_stop(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004016
4017 /* Power-down device's busmaster DMA clocks */
Stanislaw Gruszkadb54eb52011-08-24 21:06:33 +02004018 il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004019 udelay(5);
4020
4021 /* Make sure (redundant) we've released our request to stay awake */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004022 il_clear_bit(il, CSR_GP_CNTRL,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004023 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
4024
4025 /* Stop the device, and put it in low power state */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004026 il_apm_stop(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004027
4028 exit:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004029 memset(&il->card_alive, 0, sizeof(struct il_alive_resp));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004030
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004031 dev_kfree_skb(il->beacon_skb);
4032 il->beacon_skb = NULL;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004033
4034 /* clear out any free frames */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004035 il4965_clear_free_frames(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004036}
4037
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004038static void il4965_down(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004039{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004040 mutex_lock(&il->mutex);
4041 __il4965_down(il);
4042 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004043
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004044 il4965_cancel_deferred_work(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004045}
4046
4047#define HW_READY_TIMEOUT (50)
4048
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004049static int il4965_set_hw_ready(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004050{
4051 int ret = 0;
4052
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004053 il_set_bit(il, CSR_HW_IF_CONFIG_REG,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004054 CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
4055
4056 /* See if we got it */
Stanislaw Gruszka142b3432011-08-24 15:22:57 +02004057 ret = _il_poll_bit(il, CSR_HW_IF_CONFIG_REG,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004058 CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
4059 CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
4060 HW_READY_TIMEOUT);
4061 if (ret != -ETIMEDOUT)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004062 il->hw_ready = true;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004063 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004064 il->hw_ready = false;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004065
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004066 D_INFO("hardware %s\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004067 (il->hw_ready == 1) ? "ready" : "not ready");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004068 return ret;
4069}
4070
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004071static int il4965_prepare_card_hw(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004072{
4073 int ret = 0;
4074
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004075 D_INFO("il4965_prepare_card_hw enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004076
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004077 ret = il4965_set_hw_ready(il);
4078 if (il->hw_ready)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004079 return ret;
4080
4081 /* If HW is not ready, prepare the conditions to check again */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004082 il_set_bit(il, CSR_HW_IF_CONFIG_REG,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004083 CSR_HW_IF_CONFIG_REG_PREPARE);
4084
Stanislaw Gruszka142b3432011-08-24 15:22:57 +02004085 ret = _il_poll_bit(il, CSR_HW_IF_CONFIG_REG,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004086 ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE,
4087 CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000);
4088
4089 /* HW should be ready by now, check again. */
4090 if (ret != -ETIMEDOUT)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004091 il4965_set_hw_ready(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004092
4093 return ret;
4094}
4095
4096#define MAX_HW_RESTARTS 5
4097
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004098static int __il4965_up(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004099{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004100 int i;
4101 int ret;
4102
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004103 if (test_bit(STATUS_EXIT_PENDING, &il->status)) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02004104 IL_WARN("Exit pending; will not bring the NIC up\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004105 return -EIO;
4106 }
4107
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004108 if (!il->ucode_data_backup.v_addr || !il->ucode_data.v_addr) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02004109 IL_ERR("ucode not available for device bringup\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004110 return -EIO;
4111 }
4112
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +02004113 ret = il4965_alloc_bcast_station(il, &il->ctx);
4114 if (ret) {
4115 il_dealloc_bcast_stations(il);
4116 return ret;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004117 }
4118
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004119 il4965_prepare_card_hw(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004120
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004121 if (!il->hw_ready) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02004122 IL_WARN("Exit HW not ready\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004123 return -EIO;
4124 }
4125
4126 /* If platform's RF_KILL switch is NOT set to KILL */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02004127 if (_il_rd(il,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004128 CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004129 clear_bit(STATUS_RF_KILL_HW, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004130 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004131 set_bit(STATUS_RF_KILL_HW, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004132
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004133 if (il_is_rfkill(il)) {
4134 wiphy_rfkill_set_hw_state(il->hw->wiphy, true);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004135
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004136 il_enable_interrupts(il);
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02004137 IL_WARN("Radio disabled by HW RF Kill switch\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004138 return 0;
4139 }
4140
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02004141 _il_wr(il, CSR_INT, 0xFFFFFFFF);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004142
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004143 /* must be initialised before il_hw_nic_init */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004144 il->cmd_queue = IL_DEFAULT_CMD_QUEUE_NUM;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004145
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004146 ret = il4965_hw_nic_init(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004147 if (ret) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02004148 IL_ERR("Unable to init nic\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004149 return ret;
4150 }
4151
4152 /* make sure rfkill handshake bits are cleared */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02004153 _il_wr(il, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
4154 _il_wr(il, CSR_UCODE_DRV_GP1_CLR,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004155 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
4156
4157 /* clear (again), then enable host interrupts */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02004158 _il_wr(il, CSR_INT, 0xFFFFFFFF);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004159 il_enable_interrupts(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004160
4161 /* really make sure rfkill handshake bits are cleared */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02004162 _il_wr(il, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
4163 _il_wr(il, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004164
4165 /* Copy original ucode data image from disk into backup cache.
4166 * This will be used to initialize the on-board processor's
4167 * data SRAM for a clean start when the runtime program first loads. */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004168 memcpy(il->ucode_data_backup.v_addr, il->ucode_data.v_addr,
4169 il->ucode_data.len);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004170
4171 for (i = 0; i < MAX_HW_RESTARTS; i++) {
4172
4173 /* load bootstrap state machine,
4174 * load bootstrap program into processor's memory,
4175 * prepare to load the "initialize" uCode */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004176 ret = il->cfg->ops->lib->load_ucode(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004177
4178 if (ret) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02004179 IL_ERR("Unable to set up bootstrap uCode: %d\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004180 ret);
4181 continue;
4182 }
4183
4184 /* start card; "initialize" will load runtime ucode */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004185 il4965_nic_start(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004186
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004187 D_INFO(DRV_NAME " is coming up\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004188
4189 return 0;
4190 }
4191
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004192 set_bit(STATUS_EXIT_PENDING, &il->status);
4193 __il4965_down(il);
4194 clear_bit(STATUS_EXIT_PENDING, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004195
4196 /* tried to restart and config the device for as long as our
4197 * patience could withstand */
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02004198 IL_ERR("Unable to initialize device after %d attempts.\n", i);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004199 return -EIO;
4200}
4201
4202
4203/*****************************************************************************
4204 *
4205 * Workqueue callbacks
4206 *
4207 *****************************************************************************/
4208
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004209static void il4965_bg_init_alive_start(struct work_struct *data)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004210{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004211 struct il_priv *il =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004212 container_of(data, struct il_priv, init_alive_start.work);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004213
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004214 mutex_lock(&il->mutex);
4215 if (test_bit(STATUS_EXIT_PENDING, &il->status))
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02004216 goto out;
4217
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004218 il->cfg->ops->lib->init_alive_start(il);
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02004219out:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004220 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004221}
4222
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004223static void il4965_bg_alive_start(struct work_struct *data)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004224{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004225 struct il_priv *il =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004226 container_of(data, struct il_priv, alive_start.work);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004227
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004228 mutex_lock(&il->mutex);
4229 if (test_bit(STATUS_EXIT_PENDING, &il->status))
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02004230 goto out;
4231
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004232 il4965_alive_start(il);
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02004233out:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004234 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004235}
4236
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004237static void il4965_bg_run_time_calib_work(struct work_struct *work)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004238{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004239 struct il_priv *il = container_of(work, struct il_priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004240 run_time_calib_work);
4241
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004242 mutex_lock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004243
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004244 if (test_bit(STATUS_EXIT_PENDING, &il->status) ||
4245 test_bit(STATUS_SCANNING, &il->status)) {
4246 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004247 return;
4248 }
4249
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004250 if (il->start_calib) {
4251 il4965_chain_noise_calibration(il,
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02004252 (void *)&il->_4965.stats);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004253 il4965_sensitivity_calibration(il,
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02004254 (void *)&il->_4965.stats);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004255 }
4256
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004257 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004258}
4259
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004260static void il4965_bg_restart(struct work_struct *data)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004261{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004262 struct il_priv *il = container_of(data, struct il_priv, restart);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004263
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004264 if (test_bit(STATUS_EXIT_PENDING, &il->status))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004265 return;
4266
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004267 if (test_and_clear_bit(STATUS_FW_ERROR, &il->status)) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004268 mutex_lock(&il->mutex);
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +02004269 il->ctx.vif = NULL;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004270 il->is_open = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004271
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004272 __il4965_down(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004273
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004274 mutex_unlock(&il->mutex);
4275 il4965_cancel_deferred_work(il);
4276 ieee80211_restart_hw(il->hw);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004277 } else {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004278 il4965_down(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004279
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004280 mutex_lock(&il->mutex);
4281 if (test_bit(STATUS_EXIT_PENDING, &il->status)) {
4282 mutex_unlock(&il->mutex);
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02004283 return;
4284 }
4285
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004286 __il4965_up(il);
4287 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004288 }
4289}
4290
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004291static void il4965_bg_rx_replenish(struct work_struct *data)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004292{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004293 struct il_priv *il =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004294 container_of(data, struct il_priv, rx_replenish);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004295
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004296 if (test_bit(STATUS_EXIT_PENDING, &il->status))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004297 return;
4298
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004299 mutex_lock(&il->mutex);
4300 il4965_rx_replenish(il);
4301 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004302}
4303
4304/*****************************************************************************
4305 *
4306 * mac80211 entry point functions
4307 *
4308 *****************************************************************************/
4309
4310#define UCODE_READY_TIMEOUT (4 * HZ)
4311
4312/*
4313 * Not a mac80211 entry point function, but it fits in with all the
4314 * other mac80211 functions grouped here.
4315 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004316static int il4965_mac_setup_register(struct il_priv *il,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004317 u32 max_probe_length)
4318{
4319 int ret;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004320 struct ieee80211_hw *hw = il->hw;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004321
4322 hw->rate_control_algorithm = "iwl-4965-rs";
4323
4324 /* Tell mac80211 our characteristics */
4325 hw->flags = IEEE80211_HW_SIGNAL_DBM |
4326 IEEE80211_HW_AMPDU_AGGREGATION |
4327 IEEE80211_HW_NEED_DTIM_PERIOD |
4328 IEEE80211_HW_SPECTRUM_MGMT |
4329 IEEE80211_HW_REPORTS_TX_ACK_STATUS;
4330
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004331 if (il->cfg->sku & IL_SKU_N)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004332 hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
4333 IEEE80211_HW_SUPPORTS_STATIC_SMPS;
4334
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004335 hw->sta_data_size = sizeof(struct il_station_priv);
4336 hw->vif_data_size = sizeof(struct il_vif_priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004337
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +02004338 hw->wiphy->interface_modes |= il->ctx.interface_modes;
4339 hw->wiphy->interface_modes |= il->ctx.exclusive_interface_modes;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004340
4341 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
4342 WIPHY_FLAG_DISABLE_BEACON_HINTS;
4343
4344 /*
4345 * For now, disable PS by default because it affects
4346 * RX performance significantly.
4347 */
4348 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
4349
4350 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
4351 /* we create the 802.11 header and a zero-length SSID element */
4352 hw->wiphy->max_scan_ie_len = max_probe_length - 24 - 2;
4353
4354 /* Default value; 4 EDCA QOS priorities */
4355 hw->queues = 4;
4356
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004357 hw->max_listen_interval = IL_CONN_MAX_LISTEN_INTERVAL;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004358
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004359 if (il->bands[IEEE80211_BAND_2GHZ].n_channels)
4360 il->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
4361 &il->bands[IEEE80211_BAND_2GHZ];
4362 if (il->bands[IEEE80211_BAND_5GHZ].n_channels)
4363 il->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
4364 &il->bands[IEEE80211_BAND_5GHZ];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004365
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004366 il_leds_init(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004367
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004368 ret = ieee80211_register_hw(il->hw);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004369 if (ret) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02004370 IL_ERR("Failed to register hw (error %d)\n", ret);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004371 return ret;
4372 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004373 il->mac80211_registered = 1;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004374
4375 return 0;
4376}
4377
4378
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004379int il4965_mac_start(struct ieee80211_hw *hw)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004380{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004381 struct il_priv *il = hw->priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004382 int ret;
4383
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004384 D_MAC80211("enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004385
4386 /* we should be verifying the device is ready to be opened */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004387 mutex_lock(&il->mutex);
4388 ret = __il4965_up(il);
4389 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004390
4391 if (ret)
4392 return ret;
4393
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004394 if (il_is_rfkill(il))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004395 goto out;
4396
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004397 D_INFO("Start UP work done.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004398
4399 /* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from
4400 * mac80211 will not be run successfully. */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004401 ret = wait_event_timeout(il->wait_command_queue,
4402 test_bit(STATUS_READY, &il->status),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004403 UCODE_READY_TIMEOUT);
4404 if (!ret) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004405 if (!test_bit(STATUS_READY, &il->status)) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02004406 IL_ERR("START_ALIVE timeout after %dms.\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004407 jiffies_to_msecs(UCODE_READY_TIMEOUT));
4408 return -ETIMEDOUT;
4409 }
4410 }
4411
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004412 il4965_led_enable(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004413
4414out:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004415 il->is_open = 1;
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004416 D_MAC80211("leave\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004417 return 0;
4418}
4419
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004420void il4965_mac_stop(struct ieee80211_hw *hw)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004421{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004422 struct il_priv *il = hw->priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004423
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004424 D_MAC80211("enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004425
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004426 if (!il->is_open)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004427 return;
4428
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004429 il->is_open = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004430
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004431 il4965_down(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004432
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004433 flush_workqueue(il->workqueue);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004434
Stanislaw Gruszkaa078a1f2011-04-28 11:51:25 +02004435 /* User space software may expect getting rfkill changes
4436 * even if interface is down */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02004437 _il_wr(il, CSR_INT, 0xFFFFFFFF);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004438 il_enable_rfkill_int(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004439
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004440 D_MAC80211("leave\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004441}
4442
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004443void il4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004444{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004445 struct il_priv *il = hw->priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004446
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004447 D_MACDUMP("enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004448
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004449 D_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004450 ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
4451
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004452 if (il4965_tx_skb(il, skb))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004453 dev_kfree_skb_any(skb);
4454
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004455 D_MACDUMP("leave\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004456}
4457
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004458void il4965_mac_update_tkip_key(struct ieee80211_hw *hw,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004459 struct ieee80211_vif *vif,
4460 struct ieee80211_key_conf *keyconf,
4461 struct ieee80211_sta *sta,
4462 u32 iv32, u16 *phase1key)
4463{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004464 struct il_priv *il = hw->priv;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004465 struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004466
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004467 D_MAC80211("enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004468
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004469 il4965_update_tkip_key(il, vif_priv->ctx, keyconf, sta,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004470 iv32, phase1key);
4471
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004472 D_MAC80211("leave\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004473}
4474
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004475int il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004476 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
4477 struct ieee80211_key_conf *key)
4478{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004479 struct il_priv *il = hw->priv;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004480 struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
4481 struct il_rxon_context *ctx = vif_priv->ctx;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004482 int ret;
4483 u8 sta_id;
4484 bool is_default_wep_key = false;
4485
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004486 D_MAC80211("enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004487
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004488 if (il->cfg->mod_params->sw_crypto) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004489 D_MAC80211("leave - hwcrypto disabled\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004490 return -EOPNOTSUPP;
4491 }
4492
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004493 sta_id = il_sta_id_or_broadcast(il, vif_priv->ctx, sta);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004494 if (sta_id == IL_INVALID_STATION)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004495 return -EINVAL;
4496
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004497 mutex_lock(&il->mutex);
4498 il_scan_cancel_timeout(il, 100);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004499
4500 /*
4501 * If we are getting WEP group key and we didn't receive any key mapping
4502 * so far, we are in legacy wep mode (group key only), otherwise we are
4503 * in 1X mode.
4504 * In legacy wep mode, we use another host command to the uCode.
4505 */
4506 if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
4507 key->cipher == WLAN_CIPHER_SUITE_WEP104) &&
4508 !sta) {
4509 if (cmd == SET_KEY)
4510 is_default_wep_key = !ctx->key_mapping_keys;
4511 else
4512 is_default_wep_key =
4513 (key->hw_key_idx == HW_KEY_DEFAULT);
4514 }
4515
4516 switch (cmd) {
4517 case SET_KEY:
4518 if (is_default_wep_key)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004519 ret = il4965_set_default_wep_key(il,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004520 vif_priv->ctx, key);
4521 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004522 ret = il4965_set_dynamic_key(il, vif_priv->ctx,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004523 key, sta_id);
4524
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004525 D_MAC80211("enable hwcrypto key\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004526 break;
4527 case DISABLE_KEY:
4528 if (is_default_wep_key)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004529 ret = il4965_remove_default_wep_key(il, ctx, key);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004530 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004531 ret = il4965_remove_dynamic_key(il, ctx,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004532 key, sta_id);
4533
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004534 D_MAC80211("disable hwcrypto key\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004535 break;
4536 default:
4537 ret = -EINVAL;
4538 }
4539
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004540 mutex_unlock(&il->mutex);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004541 D_MAC80211("leave\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004542
4543 return ret;
4544}
4545
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004546int il4965_mac_ampdu_action(struct ieee80211_hw *hw,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004547 struct ieee80211_vif *vif,
4548 enum ieee80211_ampdu_mlme_action action,
4549 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
4550 u8 buf_size)
4551{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004552 struct il_priv *il = hw->priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004553 int ret = -EINVAL;
4554
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004555 D_HT("A-MPDU action on addr %pM tid %d\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004556 sta->addr, tid);
4557
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004558 if (!(il->cfg->sku & IL_SKU_N))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004559 return -EACCES;
4560
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004561 mutex_lock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004562
4563 switch (action) {
4564 case IEEE80211_AMPDU_RX_START:
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004565 D_HT("start Rx\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004566 ret = il4965_sta_rx_agg_start(il, sta, tid, *ssn);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004567 break;
4568 case IEEE80211_AMPDU_RX_STOP:
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004569 D_HT("stop Rx\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004570 ret = il4965_sta_rx_agg_stop(il, sta, tid);
4571 if (test_bit(STATUS_EXIT_PENDING, &il->status))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004572 ret = 0;
4573 break;
4574 case IEEE80211_AMPDU_TX_START:
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004575 D_HT("start Tx\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004576 ret = il4965_tx_agg_start(il, vif, sta, tid, ssn);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004577 break;
4578 case IEEE80211_AMPDU_TX_STOP:
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004579 D_HT("stop Tx\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004580 ret = il4965_tx_agg_stop(il, vif, sta, tid);
4581 if (test_bit(STATUS_EXIT_PENDING, &il->status))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004582 ret = 0;
4583 break;
4584 case IEEE80211_AMPDU_TX_OPERATIONAL:
4585 ret = 0;
4586 break;
4587 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004588 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004589
4590 return ret;
4591}
4592
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004593int il4965_mac_sta_add(struct ieee80211_hw *hw,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004594 struct ieee80211_vif *vif,
4595 struct ieee80211_sta *sta)
4596{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004597 struct il_priv *il = hw->priv;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004598 struct il_station_priv *sta_priv = (void *)sta->drv_priv;
4599 struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004600 bool is_ap = vif->type == NL80211_IFTYPE_STATION;
4601 int ret;
4602 u8 sta_id;
4603
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004604 D_INFO("received request to add station %pM\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004605 sta->addr);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004606 mutex_lock(&il->mutex);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004607 D_INFO("proceeding to add station %pM\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004608 sta->addr);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004609 sta_priv->common.sta_id = IL_INVALID_STATION;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004610
4611 atomic_set(&sta_priv->pending_frames, 0);
4612
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004613 ret = il_add_station_common(il, vif_priv->ctx, sta->addr,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004614 is_ap, sta, &sta_id);
4615 if (ret) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02004616 IL_ERR("Unable to add station %pM (%d)\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004617 sta->addr, ret);
4618 /* Should we return success if return code is EEXIST ? */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004619 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004620 return ret;
4621 }
4622
4623 sta_priv->common.sta_id = sta_id;
4624
4625 /* Initialize rate scaling */
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004626 D_INFO("Initializing rate scaling for station %pM\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004627 sta->addr);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004628 il4965_rs_rate_init(il, sta, sta_id);
4629 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004630
4631 return 0;
4632}
4633
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004634void il4965_mac_channel_switch(struct ieee80211_hw *hw,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004635 struct ieee80211_channel_switch *ch_switch)
4636{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004637 struct il_priv *il = hw->priv;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004638 const struct il_channel_info *ch_info;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004639 struct ieee80211_conf *conf = &hw->conf;
4640 struct ieee80211_channel *channel = ch_switch->channel;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004641 struct il_ht_config *ht_conf = &il->current_ht_config;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004642
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +01004643 struct il_rxon_context *ctx = &il->ctx;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004644 u16 ch;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004645
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004646 D_MAC80211("enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004647
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004648 mutex_lock(&il->mutex);
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02004649
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004650 if (il_is_rfkill(il))
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02004651 goto out;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004652
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004653 if (test_bit(STATUS_EXIT_PENDING, &il->status) ||
4654 test_bit(STATUS_SCANNING, &il->status) ||
4655 test_bit(STATUS_CHANNEL_SWITCH_PENDING, &il->status))
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02004656 goto out;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004657
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004658 if (!il_is_associated_ctx(ctx))
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02004659 goto out;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004660
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004661 if (!il->cfg->ops->lib->set_channel_switch)
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02004662 goto out;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004663
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02004664 ch = channel->hw_value;
4665 if (le16_to_cpu(ctx->active.channel) == ch)
4666 goto out;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004667
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004668 ch_info = il_get_channel_info(il, channel->band, ch);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004669 if (!il_is_channel_valid(ch_info)) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004670 D_MAC80211("invalid channel\n");
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02004671 goto out;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004672 }
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02004673
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004674 spin_lock_irq(&il->lock);
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02004675
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004676 il->current_ht_config.smps = conf->smps_mode;
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02004677
4678 /* Configure HT40 channels */
4679 ctx->ht.enabled = conf_is_ht(conf);
4680 if (ctx->ht.enabled) {
4681 if (conf_is_ht40_minus(conf)) {
4682 ctx->ht.extension_chan_offset =
4683 IEEE80211_HT_PARAM_CHA_SEC_BELOW;
4684 ctx->ht.is_40mhz = true;
4685 } else if (conf_is_ht40_plus(conf)) {
4686 ctx->ht.extension_chan_offset =
4687 IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
4688 ctx->ht.is_40mhz = true;
4689 } else {
4690 ctx->ht.extension_chan_offset =
4691 IEEE80211_HT_PARAM_CHA_SEC_NONE;
4692 ctx->ht.is_40mhz = false;
4693 }
4694 } else
4695 ctx->ht.is_40mhz = false;
4696
4697 if ((le16_to_cpu(ctx->staging.channel) != ch))
4698 ctx->staging.flags = 0;
4699
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004700 il_set_rxon_channel(il, channel, ctx);
4701 il_set_rxon_ht(il, ht_conf);
4702 il_set_flags_for_band(il, ctx, channel->band, ctx->vif);
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02004703
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004704 spin_unlock_irq(&il->lock);
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02004705
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004706 il_set_rate(il);
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02004707 /*
4708 * at this point, staging_rxon has the
4709 * configuration for channel switch
4710 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004711 set_bit(STATUS_CHANNEL_SWITCH_PENDING, &il->status);
4712 il->switch_channel = cpu_to_le16(ch);
4713 if (il->cfg->ops->lib->set_channel_switch(il, ch_switch)) {
4714 clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &il->status);
4715 il->switch_channel = 0;
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02004716 ieee80211_chswitch_done(ctx->vif, false);
4717 }
4718
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004719out:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004720 mutex_unlock(&il->mutex);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004721 D_MAC80211("leave\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004722}
4723
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004724void il4965_configure_filter(struct ieee80211_hw *hw,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004725 unsigned int changed_flags,
4726 unsigned int *total_flags,
4727 u64 multicast)
4728{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004729 struct il_priv *il = hw->priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004730 __le32 filter_or = 0, filter_nand = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004731
4732#define CHK(test, flag) do { \
4733 if (*total_flags & (test)) \
4734 filter_or |= (flag); \
4735 else \
4736 filter_nand |= (flag); \
4737 } while (0)
4738
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004739 D_MAC80211("Enter: changed: 0x%x, total: 0x%x\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004740 changed_flags, *total_flags);
4741
4742 CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK);
4743 /* Setting _just_ RXON_FILTER_CTL2HOST_MSK causes FH errors */
4744 CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_PROMISC_MSK);
4745 CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK);
4746
4747#undef CHK
4748
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004749 mutex_lock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004750
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +02004751 il->ctx.staging.filter_flags &= ~filter_nand;
4752 il->ctx.staging.filter_flags |= filter_or;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004753
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +02004754 /*
4755 * Not committing directly because hardware can perform a scan,
4756 * but we'll eventually commit the filter flags change anyway.
4757 */
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004758
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004759 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004760
4761 /*
4762 * Receiving all multicast frames is always enabled by the
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004763 * default flags setup in il_connection_init_rx_config()
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004764 * since we currently do not support programming multicast
4765 * filters into the device.
4766 */
4767 *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
4768 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
4769}
4770
4771/*****************************************************************************
4772 *
4773 * driver setup and teardown
4774 *
4775 *****************************************************************************/
4776
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004777static void il4965_bg_txpower_work(struct work_struct *work)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004778{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004779 struct il_priv *il = container_of(work, struct il_priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004780 txpower_work);
4781
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004782 mutex_lock(&il->mutex);
Stanislaw Gruszkaf3257572011-04-28 11:36:54 +02004783
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004784 /* If a scan happened to start before we got here
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02004785 * then just return; the stats notification will
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004786 * kick off another scheduled work to compensate for
4787 * any temperature delta we missed here. */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004788 if (test_bit(STATUS_EXIT_PENDING, &il->status) ||
4789 test_bit(STATUS_SCANNING, &il->status))
Stanislaw Gruszkaf3257572011-04-28 11:36:54 +02004790 goto out;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004791
4792 /* Regardless of if we are associated, we must reconfigure the
4793 * TX power since frames can be sent on non-radar channels while
4794 * not associated */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004795 il->cfg->ops->lib->send_tx_power(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004796
4797 /* Update last_temperature to keep is_calib_needed from running
4798 * when it isn't needed... */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004799 il->last_temperature = il->temperature;
Stanislaw Gruszkaf3257572011-04-28 11:36:54 +02004800out:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004801 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004802}
4803
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004804static void il4965_setup_deferred_work(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004805{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004806 il->workqueue = create_singlethread_workqueue(DRV_NAME);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004807
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004808 init_waitqueue_head(&il->wait_command_queue);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004809
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004810 INIT_WORK(&il->restart, il4965_bg_restart);
4811 INIT_WORK(&il->rx_replenish, il4965_bg_rx_replenish);
4812 INIT_WORK(&il->run_time_calib_work, il4965_bg_run_time_calib_work);
4813 INIT_DELAYED_WORK(&il->init_alive_start, il4965_bg_init_alive_start);
4814 INIT_DELAYED_WORK(&il->alive_start, il4965_bg_alive_start);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004815
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004816 il_setup_scan_deferred_work(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004817
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004818 INIT_WORK(&il->txpower_work, il4965_bg_txpower_work);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004819
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02004820 init_timer(&il->stats_periodic);
4821 il->stats_periodic.data = (unsigned long)il;
4822 il->stats_periodic.function = il4965_bg_stats_periodic;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004823
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004824 init_timer(&il->watchdog);
4825 il->watchdog.data = (unsigned long)il;
4826 il->watchdog.function = il_bg_watchdog;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004827
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004828 tasklet_init(&il->irq_tasklet, (void (*)(unsigned long))
4829 il4965_irq_tasklet, (unsigned long)il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004830}
4831
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004832static void il4965_cancel_deferred_work(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004833{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004834 cancel_work_sync(&il->txpower_work);
4835 cancel_delayed_work_sync(&il->init_alive_start);
4836 cancel_delayed_work(&il->alive_start);
4837 cancel_work_sync(&il->run_time_calib_work);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004838
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004839 il_cancel_scan_deferred_work(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004840
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02004841 del_timer_sync(&il->stats_periodic);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004842}
4843
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004844static void il4965_init_hw_rates(struct il_priv *il,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004845 struct ieee80211_rate *rates)
4846{
4847 int i;
4848
Stanislaw Gruszka2eb05812011-08-26 16:07:43 +02004849 for (i = 0; i < RATE_COUNT_LEGACY; i++) {
Stanislaw Gruszkad2ddf6212011-08-16 14:17:04 +02004850 rates[i].bitrate = il_rates[i].ieee * 5;
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +01004851 rates[i].hw_value = i; /* Rate scaling will work on idxes */
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004852 rates[i].hw_value_short = i;
4853 rates[i].flags = 0;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004854 if ((i >= IL_FIRST_CCK_RATE) && (i <= IL_LAST_CCK_RATE)) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004855 /*
4856 * If CCK != 1M then set short preamble rate flag.
4857 */
4858 rates[i].flags |=
Stanislaw Gruszka2eb05812011-08-26 16:07:43 +02004859 (il_rates[i].plcp == RATE_1M_PLCP) ?
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004860 0 : IEEE80211_RATE_SHORT_PREAMBLE;
4861 }
4862 }
4863}
4864/*
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004865 * Acquire il->lock before calling this function !
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004866 */
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +01004867void il4965_set_wr_ptrs(struct il_priv *il, int txq_id, u32 idx)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004868{
Stanislaw Gruszka0c1a94e2011-08-24 17:37:16 +02004869 il_wr(il, HBUS_TARG_WRPTR,
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +01004870 (idx & 0xff) | (txq_id << 8));
4871 il_wr_prph(il, IL49_SCD_QUEUE_RDPTR(txq_id), idx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004872}
4873
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004874void il4965_tx_queue_set_status(struct il_priv *il,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004875 struct il_tx_queue *txq,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004876 int tx_fifo_id, int scd_retry)
4877{
4878 int txq_id = txq->q.id;
4879
4880 /* Find out whether to activate Tx queue */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004881 int active = test_bit(txq_id, &il->txq_ctx_active_msk) ? 1 : 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004882
4883 /* Set up and activate */
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01004884 il_wr_prph(il, IL49_SCD_QUEUE_STATUS_BITS(txq_id),
4885 (active << IL49_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
4886 (tx_fifo_id << IL49_SCD_QUEUE_STTS_REG_POS_TXF) |
4887 (scd_retry << IL49_SCD_QUEUE_STTS_REG_POS_WSL) |
4888 (scd_retry << IL49_SCD_QUEUE_STTS_REG_POS_SCD_ACK) |
4889 IL49_SCD_QUEUE_STTS_REG_MSK);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004890
4891 txq->sched_retry = scd_retry;
4892
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004893 D_INFO("%s %s Queue %d on AC %d\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004894 active ? "Activate" : "Deactivate",
4895 scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
4896}
4897
4898
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004899static int il4965_init_drv(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004900{
4901 int ret;
4902
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004903 spin_lock_init(&il->sta_lock);
4904 spin_lock_init(&il->hcmd_lock);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004905
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004906 INIT_LIST_HEAD(&il->free_frames);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004907
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004908 mutex_init(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004909
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004910 il->ieee_channels = NULL;
4911 il->ieee_rates = NULL;
4912 il->band = IEEE80211_BAND_2GHZ;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004913
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004914 il->iw_mode = NL80211_IFTYPE_STATION;
4915 il->current_ht_config.smps = IEEE80211_SMPS_STATIC;
4916 il->missed_beacon_threshold = IL_MISSED_BEACON_THRESHOLD_DEF;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004917
4918 /* initialize force reset */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004919 il->force_reset.reset_duration = IL_DELAY_NEXT_FORCE_FW_RELOAD;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004920
4921 /* Choose which receivers/antennas to use */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004922 if (il->cfg->ops->hcmd->set_rxon_chain)
4923 il->cfg->ops->hcmd->set_rxon_chain(il,
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +01004924 &il->ctx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004925
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004926 il_init_scan_params(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004927
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004928 ret = il_init_channel_map(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004929 if (ret) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02004930 IL_ERR("initializing regulatory failed: %d\n", ret);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004931 goto err;
4932 }
4933
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004934 ret = il_init_geos(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004935 if (ret) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02004936 IL_ERR("initializing geos failed: %d\n", ret);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004937 goto err_free_channel_map;
4938 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004939 il4965_init_hw_rates(il, il->ieee_rates);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004940
4941 return 0;
4942
4943err_free_channel_map:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004944 il_free_channel_map(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004945err:
4946 return ret;
4947}
4948
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004949static void il4965_uninit_drv(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004950{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004951 il4965_calib_free_results(il);
4952 il_free_geos(il);
4953 il_free_channel_map(il);
4954 kfree(il->scan_cmd);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004955}
4956
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004957static void il4965_hw_detect(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004958{
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02004959 il->hw_rev = _il_rd(il, CSR_HW_REV);
4960 il->hw_wa_rev = _il_rd(il, CSR_HW_REV_WA_REG);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004961 il->rev_id = il->pci_dev->revision;
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01004962 D_INFO("HW Revision ID = 0x%X\n", il->rev_id);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004963}
4964
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004965static int il4965_set_hw_params(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004966{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004967 il->hw_params.max_rxq_size = RX_QUEUE_SIZE;
4968 il->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
4969 if (il->cfg->mod_params->amsdu_size_8K)
4970 il->hw_params.rx_page_order = get_order(IL_RX_BUF_SIZE_8K);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004971 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004972 il->hw_params.rx_page_order = get_order(IL_RX_BUF_SIZE_4K);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004973
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004974 il->hw_params.max_beacon_itrvl = IL_MAX_UCODE_BEACON_INTERVAL;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004975
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004976 if (il->cfg->mod_params->disable_11n)
4977 il->cfg->sku &= ~IL_SKU_N;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004978
4979 /* Device-specific setup */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004980 return il->cfg->ops->lib->set_hw_params(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004981}
4982
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004983static const u8 il4965_bss_ac_to_fifo[] = {
4984 IL_TX_FIFO_VO,
4985 IL_TX_FIFO_VI,
4986 IL_TX_FIFO_BE,
4987 IL_TX_FIFO_BK,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004988};
4989
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004990static const u8 il4965_bss_ac_to_queue[] = {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004991 0, 1, 2, 3,
4992};
4993
4994static int
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02004995il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004996{
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +01004997 int err = 0;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02004998 struct il_priv *il;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08004999 struct ieee80211_hw *hw;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02005000 struct il_cfg *cfg = (struct il_cfg *)(ent->driver_data);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005001 unsigned long flags;
5002 u16 pci_cmd;
5003
5004 /************************
5005 * 1. Allocating HW data
5006 ************************/
5007
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02005008 hw = il_alloc_all(cfg);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005009 if (!hw) {
5010 err = -ENOMEM;
5011 goto out;
5012 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005013 il = hw->priv;
5014 /* At this point both hw and il are allocated. */
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005015
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +01005016 il->ctx.ctxid = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005017
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +01005018 il->ctx.always_active = true;
5019 il->ctx.is_active = true;
5020 il->ctx.rxon_cmd = REPLY_RXON;
5021 il->ctx.rxon_timing_cmd = REPLY_RXON_TIMING;
5022 il->ctx.rxon_assoc_cmd = REPLY_RXON_ASSOC;
5023 il->ctx.qos_cmd = REPLY_QOS_PARAM;
5024 il->ctx.ap_sta_id = IL_AP_ID;
5025 il->ctx.wep_key_cmd = REPLY_WEPKEY;
5026 il->ctx.ac_to_fifo = il4965_bss_ac_to_fifo;
5027 il->ctx.ac_to_queue = il4965_bss_ac_to_queue;
5028 il->ctx.exclusive_interface_modes =
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005029 BIT(NL80211_IFTYPE_ADHOC);
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +01005030 il->ctx.interface_modes =
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005031 BIT(NL80211_IFTYPE_STATION);
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +01005032 il->ctx.ap_devtype = RXON_DEV_TYPE_AP;
5033 il->ctx.ibss_devtype = RXON_DEV_TYPE_IBSS;
5034 il->ctx.station_devtype = RXON_DEV_TYPE_ESS;
5035 il->ctx.unused_devtype = RXON_DEV_TYPE_ESS;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005036
5037 SET_IEEE80211_DEV(hw, &pdev->dev);
5038
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01005039 D_INFO("*** LOAD DRIVER ***\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005040 il->cfg = cfg;
5041 il->pci_dev = pdev;
5042 il->inta_mask = CSR_INI_SET_MASK;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005043
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005044 if (il_alloc_traffic_mem(il))
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02005045 IL_ERR("Not enough memory to generate traffic log\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005046
5047 /**************************
5048 * 2. Initializing PCI bus
5049 **************************/
5050 pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 |
5051 PCIE_LINK_STATE_CLKPM);
5052
5053 if (pci_enable_device(pdev)) {
5054 err = -ENODEV;
5055 goto out_ieee80211_free_hw;
5056 }
5057
5058 pci_set_master(pdev);
5059
5060 err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36));
5061 if (!err)
5062 err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36));
5063 if (err) {
5064 err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
5065 if (!err)
5066 err = pci_set_consistent_dma_mask(pdev,
5067 DMA_BIT_MASK(32));
5068 /* both attempts failed: */
5069 if (err) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02005070 IL_WARN("No suitable DMA available.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005071 goto out_pci_disable_device;
5072 }
5073 }
5074
5075 err = pci_request_regions(pdev, DRV_NAME);
5076 if (err)
5077 goto out_pci_disable_device;
5078
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005079 pci_set_drvdata(pdev, il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005080
5081
5082 /***********************
5083 * 3. Read REV register
5084 ***********************/
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005085 il->hw_base = pci_iomap(pdev, 0, 0);
5086 if (!il->hw_base) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005087 err = -ENODEV;
5088 goto out_pci_release_regions;
5089 }
5090
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01005091 D_INFO("pci_resource_len = 0x%08llx\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005092 (unsigned long long) pci_resource_len(pdev, 0));
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01005093 D_INFO("pci_resource_base = %p\n", il->hw_base);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005094
5095 /* these spin locks will be used in apm_ops.init and EEPROM access
5096 * we should init now
5097 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005098 spin_lock_init(&il->reg_lock);
5099 spin_lock_init(&il->lock);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005100
5101 /*
5102 * stop and reset the on-board processor just in case it is in a
5103 * strange state ... like being left stranded by a primary kernel
5104 * and this is now the kdump kernel trying to start up
5105 */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02005106 _il_wr(il, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005107
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005108 il4965_hw_detect(il);
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02005109 IL_INFO("Detected %s, REV=0x%X\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005110 il->cfg->name, il->hw_rev);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005111
5112 /* We disable the RETRY_TIMEOUT register (0x41) to keep
5113 * PCI Tx retries from interfering with C3 CPU state */
5114 pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
5115
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005116 il4965_prepare_card_hw(il);
5117 if (!il->hw_ready) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02005118 IL_WARN("Failed, HW not ready\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005119 goto out_iounmap;
5120 }
5121
5122 /*****************
5123 * 4. Read EEPROM
5124 *****************/
5125 /* Read the EEPROM */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005126 err = il_eeprom_init(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005127 if (err) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02005128 IL_ERR("Unable to init EEPROM\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005129 goto out_iounmap;
5130 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005131 err = il4965_eeprom_check_version(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005132 if (err)
5133 goto out_free_eeprom;
5134
5135 if (err)
5136 goto out_free_eeprom;
5137
5138 /* extract MAC Address */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005139 il4965_eeprom_get_mac(il, il->addresses[0].addr);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01005140 D_INFO("MAC address: %pM\n", il->addresses[0].addr);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005141 il->hw->wiphy->addresses = il->addresses;
5142 il->hw->wiphy->n_addresses = 1;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005143
5144 /************************
5145 * 5. Setup HW constants
5146 ************************/
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005147 if (il4965_set_hw_params(il)) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02005148 IL_ERR("failed to set hw parameters\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005149 goto out_free_eeprom;
5150 }
5151
5152 /*******************
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005153 * 6. Setup il
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005154 *******************/
5155
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005156 err = il4965_init_drv(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005157 if (err)
5158 goto out_free_eeprom;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005159 /* At this point both hw and il are initialized. */
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005160
5161 /********************
5162 * 7. Setup services
5163 ********************/
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005164 spin_lock_irqsave(&il->lock, flags);
5165 il_disable_interrupts(il);
5166 spin_unlock_irqrestore(&il->lock, flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005167
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005168 pci_enable_msi(il->pci_dev);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005169
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005170 err = request_irq(il->pci_dev->irq, il_isr,
5171 IRQF_SHARED, DRV_NAME, il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005172 if (err) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02005173 IL_ERR("Error allocating IRQ %d\n", il->pci_dev->irq);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005174 goto out_disable_msi;
5175 }
5176
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005177 il4965_setup_deferred_work(il);
5178 il4965_setup_rx_handlers(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005179
5180 /*********************************************
5181 * 8. Enable interrupts and read RFKILL state
5182 *********************************************/
5183
Stanislaw Gruszkaa078a1f2011-04-28 11:51:25 +02005184 /* enable rfkill interrupt: hw bug w/a */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005185 pci_read_config_word(il->pci_dev, PCI_COMMAND, &pci_cmd);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005186 if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
5187 pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005188 pci_write_config_word(il->pci_dev, PCI_COMMAND, pci_cmd);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005189 }
5190
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005191 il_enable_rfkill_int(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005192
5193 /* If platform's RF_KILL switch is NOT set to KILL */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02005194 if (_il_rd(il, CSR_GP_CNTRL) &
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005195 CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005196 clear_bit(STATUS_RF_KILL_HW, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005197 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005198 set_bit(STATUS_RF_KILL_HW, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005199
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005200 wiphy_rfkill_set_hw_state(il->hw->wiphy,
5201 test_bit(STATUS_RF_KILL_HW, &il->status));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005202
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005203 il_power_initialize(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005204
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005205 init_completion(&il->_4965.firmware_loading_complete);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005206
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005207 err = il4965_request_firmware(il, true);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005208 if (err)
5209 goto out_destroy_workqueue;
5210
5211 return 0;
5212
5213 out_destroy_workqueue:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005214 destroy_workqueue(il->workqueue);
5215 il->workqueue = NULL;
5216 free_irq(il->pci_dev->irq, il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005217 out_disable_msi:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005218 pci_disable_msi(il->pci_dev);
5219 il4965_uninit_drv(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005220 out_free_eeprom:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005221 il_eeprom_free(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005222 out_iounmap:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005223 pci_iounmap(pdev, il->hw_base);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005224 out_pci_release_regions:
5225 pci_set_drvdata(pdev, NULL);
5226 pci_release_regions(pdev);
5227 out_pci_disable_device:
5228 pci_disable_device(pdev);
5229 out_ieee80211_free_hw:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005230 il_free_traffic_mem(il);
5231 ieee80211_free_hw(il->hw);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005232 out:
5233 return err;
5234}
5235
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02005236static void __devexit il4965_pci_remove(struct pci_dev *pdev)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005237{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005238 struct il_priv *il = pci_get_drvdata(pdev);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005239 unsigned long flags;
5240
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005241 if (!il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005242 return;
5243
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005244 wait_for_completion(&il->_4965.firmware_loading_complete);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005245
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01005246 D_INFO("*** UNLOAD DRIVER ***\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005247
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005248 il_dbgfs_unregister(il);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02005249 sysfs_remove_group(&pdev->dev.kobj, &il_attribute_group);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005250
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02005251 /* ieee80211_unregister_hw call wil cause il_mac_stop to
5252 * to be called and il4965_down since we are removing the device
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005253 * we need to set STATUS_EXIT_PENDING bit.
5254 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005255 set_bit(STATUS_EXIT_PENDING, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005256
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005257 il_leds_exit(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005258
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005259 if (il->mac80211_registered) {
5260 ieee80211_unregister_hw(il->hw);
5261 il->mac80211_registered = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005262 } else {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005263 il4965_down(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005264 }
5265
5266 /*
5267 * Make sure device is reset to low power before unloading driver.
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02005268 * This may be redundant with il4965_down(), but there are paths to
5269 * run il4965_down() without calling apm_ops.stop(), and there are
5270 * paths to avoid running il4965_down() at all before leaving driver.
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005271 * This (inexpensive) call *makes sure* device is reset.
5272 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005273 il_apm_stop(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005274
5275 /* make sure we flush any pending irq or
5276 * tasklet for the driver
5277 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005278 spin_lock_irqsave(&il->lock, flags);
5279 il_disable_interrupts(il);
5280 spin_unlock_irqrestore(&il->lock, flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005281
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005282 il4965_synchronize_irq(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005283
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005284 il4965_dealloc_ucode_pci(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005285
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005286 if (il->rxq.bd)
5287 il4965_rx_queue_free(il, &il->rxq);
5288 il4965_hw_txq_ctx_free(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005289
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005290 il_eeprom_free(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005291
5292
5293 /*netif_stop_queue(dev); */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005294 flush_workqueue(il->workqueue);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005295
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02005296 /* ieee80211_unregister_hw calls il_mac_stop, which flushes
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005297 * il->workqueue... so we can't take down the workqueue
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005298 * until now... */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005299 destroy_workqueue(il->workqueue);
5300 il->workqueue = NULL;
5301 il_free_traffic_mem(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005302
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005303 free_irq(il->pci_dev->irq, il);
5304 pci_disable_msi(il->pci_dev);
5305 pci_iounmap(pdev, il->hw_base);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005306 pci_release_regions(pdev);
5307 pci_disable_device(pdev);
5308 pci_set_drvdata(pdev, NULL);
5309
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005310 il4965_uninit_drv(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005311
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005312 dev_kfree_skb(il->beacon_skb);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005313
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005314 ieee80211_free_hw(il->hw);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005315}
5316
5317/*
5318 * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005319 * must be called under il->lock and mac access
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005320 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02005321void il4965_txq_set_sched(struct il_priv *il, u32 mask)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005322{
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01005323 il_wr_prph(il, IL49_SCD_TXFACT, mask);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005324}
5325
5326/*****************************************************************************
5327 *
5328 * driver and module entry point
5329 *
5330 *****************************************************************************/
5331
5332/* Hardware specific file defines the PCI IDs table for that hardware module */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02005333static DEFINE_PCI_DEVICE_TABLE(il4965_hw_card_ids) = {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02005334 {IL_PCI_DEVICE(0x4229, PCI_ANY_ID, il4965_cfg)},
5335 {IL_PCI_DEVICE(0x4230, PCI_ANY_ID, il4965_cfg)},
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005336 {0}
5337};
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02005338MODULE_DEVICE_TABLE(pci, il4965_hw_card_ids);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005339
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02005340static struct pci_driver il4965_driver = {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005341 .name = DRV_NAME,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02005342 .id_table = il4965_hw_card_ids,
5343 .probe = il4965_pci_probe,
5344 .remove = __devexit_p(il4965_pci_remove),
5345 .driver.pm = IL_LEGACY_PM_OPS,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005346};
5347
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02005348static int __init il4965_init(void)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005349{
5350
5351 int ret;
5352 pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n");
5353 pr_info(DRV_COPYRIGHT "\n");
5354
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02005355 ret = il4965_rate_control_register();
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005356 if (ret) {
5357 pr_err("Unable to register rate control algorithm: %d\n", ret);
5358 return ret;
5359 }
5360
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02005361 ret = pci_register_driver(&il4965_driver);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005362 if (ret) {
5363 pr_err("Unable to initialize PCI module\n");
5364 goto error_register;
5365 }
5366
5367 return ret;
5368
5369error_register:
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02005370 il4965_rate_control_unregister();
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005371 return ret;
5372}
5373
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02005374static void __exit il4965_exit(void)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005375{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02005376 pci_unregister_driver(&il4965_driver);
5377 il4965_rate_control_unregister();
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005378}
5379
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02005380module_exit(il4965_exit);
5381module_init(il4965_init);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005382
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01005383#ifdef CONFIG_IWLEGACY_DEBUG
Stanislaw Gruszkad2ddf6212011-08-16 14:17:04 +02005384module_param_named(debug, il_debug_level, uint, S_IRUGO | S_IWUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005385MODULE_PARM_DESC(debug, "debug output mask");
5386#endif
5387
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02005388module_param_named(swcrypto, il4965_mod_params.sw_crypto, int, S_IRUGO);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005389MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02005390module_param_named(queues_num, il4965_mod_params.num_of_queues, int, S_IRUGO);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005391MODULE_PARM_DESC(queues_num, "number of hw queues.");
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02005392module_param_named(11n_disable, il4965_mod_params.disable_11n, int, S_IRUGO);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005393MODULE_PARM_DESC(11n_disable, "disable 11n functionality");
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02005394module_param_named(amsdu_size_8K, il4965_mod_params.amsdu_size_8K,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005395 int, S_IRUGO);
5396MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02005397module_param_named(fw_restart, il4965_mod_params.restart_fw, int, S_IRUGO);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08005398MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");