blob: bd37c9226e65b6e040076be6da1ef6e10f57f746 [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"
61#include "iwl-4965-led.h"
62
63
64/******************************************************************************
65 *
66 * module boiler plate
67 *
68 ******************************************************************************/
69
70/*
71 * module name, copyright, version, etc.
72 */
73#define DRV_DESCRIPTION "Intel(R) Wireless WiFi 4965 driver for Linux"
74
75#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
76#define VD "d"
77#else
78#define VD
79#endif
80
81#define DRV_VERSION IWLWIFI_VERSION VD
82
83
84MODULE_DESCRIPTION(DRV_DESCRIPTION);
85MODULE_VERSION(DRV_VERSION);
86MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
87MODULE_LICENSE("GPL");
88MODULE_ALIAS("iwl4965");
89
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020090void il4965_update_chain_flags(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080091{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020092 struct il_rxon_context *ctx;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080093
94 if (priv->cfg->ops->hcmd->set_rxon_chain) {
95 for_each_context(priv, ctx) {
96 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
97 if (ctx->active.rx_chain != ctx->staging.rx_chain)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +020098 il_commit_rxon(priv, ctx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080099 }
100 }
101}
102
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200103static void il4965_clear_free_frames(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800104{
105 struct list_head *element;
106
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200107 IL_DEBUG_INFO(priv, "%d frames on pre-allocated heap on clear.\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800108 priv->frames_count);
109
110 while (!list_empty(&priv->free_frames)) {
111 element = priv->free_frames.next;
112 list_del(element);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200113 kfree(list_entry(element, struct il_frame, list));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800114 priv->frames_count--;
115 }
116
117 if (priv->frames_count) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200118 IL_WARN(priv, "%d frames still in use. Did we lose one?\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800119 priv->frames_count);
120 priv->frames_count = 0;
121 }
122}
123
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200124static struct il_frame *il4965_get_free_frame(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800125{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200126 struct il_frame *frame;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800127 struct list_head *element;
128 if (list_empty(&priv->free_frames)) {
129 frame = kzalloc(sizeof(*frame), GFP_KERNEL);
130 if (!frame) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200131 IL_ERR(priv, "Could not allocate frame!\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800132 return NULL;
133 }
134
135 priv->frames_count++;
136 return frame;
137 }
138
139 element = priv->free_frames.next;
140 list_del(element);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200141 return list_entry(element, struct il_frame, list);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800142}
143
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200144static void il4965_free_frame(struct il_priv *priv, struct il_frame *frame)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800145{
146 memset(frame, 0, sizeof(*frame));
147 list_add(&frame->list, &priv->free_frames);
148}
149
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200150static u32 il4965_fill_beacon_frame(struct il_priv *priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800151 struct ieee80211_hdr *hdr,
152 int left)
153{
154 lockdep_assert_held(&priv->mutex);
155
156 if (!priv->beacon_skb)
157 return 0;
158
159 if (priv->beacon_skb->len > left)
160 return 0;
161
162 memcpy(hdr, priv->beacon_skb->data, priv->beacon_skb->len);
163
164 return priv->beacon_skb->len;
165}
166
167/* Parse the beacon frame to find the TIM element and set tim_idx & tim_size */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200168static void il4965_set_beacon_tim(struct il_priv *priv,
169 struct il_tx_beacon_cmd *tx_beacon_cmd,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800170 u8 *beacon, u32 frame_size)
171{
172 u16 tim_idx;
173 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)beacon;
174
175 /*
176 * The index is relative to frame start but we start looking at the
177 * variable-length part of the beacon.
178 */
179 tim_idx = mgmt->u.beacon.variable - beacon;
180
181 /* Parse variable-length elements of beacon to find WLAN_EID_TIM */
182 while ((tim_idx < (frame_size - 2)) &&
183 (beacon[tim_idx] != WLAN_EID_TIM))
184 tim_idx += beacon[tim_idx+1] + 2;
185
186 /* If TIM field was found, set variables */
187 if ((tim_idx < (frame_size - 1)) && (beacon[tim_idx] == WLAN_EID_TIM)) {
188 tx_beacon_cmd->tim_idx = cpu_to_le16(tim_idx);
189 tx_beacon_cmd->tim_size = beacon[tim_idx+1];
190 } else
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200191 IL_WARN(priv, "Unable to find TIM Element in beacon\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800192}
193
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200194static unsigned int il4965_hw_get_beacon_cmd(struct il_priv *priv,
195 struct il_frame *frame)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800196{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200197 struct il_tx_beacon_cmd *tx_beacon_cmd;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800198 u32 frame_size;
199 u32 rate_flags;
200 u32 rate;
201 /*
202 * We have to set up the TX command, the TX Beacon command, and the
203 * beacon contents.
204 */
205
206 lockdep_assert_held(&priv->mutex);
207
208 if (!priv->beacon_ctx) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200209 IL_ERR(priv, "trying to build beacon w/o beacon context!\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800210 return 0;
211 }
212
213 /* Initialize memory */
214 tx_beacon_cmd = &frame->u.beacon;
215 memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
216
217 /* Set up TX beacon contents */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200218 frame_size = il4965_fill_beacon_frame(priv, tx_beacon_cmd->frame,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800219 sizeof(frame->u) - sizeof(*tx_beacon_cmd));
220 if (WARN_ON_ONCE(frame_size > MAX_MPDU_SIZE))
221 return 0;
222 if (!frame_size)
223 return 0;
224
225 /* Set up TX command fields */
226 tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
227 tx_beacon_cmd->tx.sta_id = priv->beacon_ctx->bcast_sta_id;
228 tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
229 tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK |
230 TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK;
231
232 /* Set up TX beacon command fields */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200233 il4965_set_beacon_tim(priv, tx_beacon_cmd, (u8 *)tx_beacon_cmd->frame,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800234 frame_size);
235
236 /* Set up packet rate and flags */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200237 rate = il_get_lowest_plcp(priv, priv->beacon_ctx);
238 priv->mgmt_tx_ant = il4965_toggle_tx_ant(priv, priv->mgmt_tx_ant,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800239 priv->hw_params.valid_tx_ant);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200240 rate_flags = il4965_ant_idx_to_flags(priv->mgmt_tx_ant);
241 if ((rate >= IL_FIRST_CCK_RATE) && (rate <= IL_LAST_CCK_RATE))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800242 rate_flags |= RATE_MCS_CCK_MSK;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200243 tx_beacon_cmd->tx.rate_n_flags = il4965_hw_set_rate_n_flags(rate,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800244 rate_flags);
245
246 return sizeof(*tx_beacon_cmd) + frame_size;
247}
248
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200249int il4965_send_beacon_cmd(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800250{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200251 struct il_frame *frame;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800252 unsigned int frame_size;
253 int rc;
254
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200255 frame = il4965_get_free_frame(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800256 if (!frame) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200257 IL_ERR(priv, "Could not obtain free frame buffer for beacon "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800258 "command.\n");
259 return -ENOMEM;
260 }
261
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200262 frame_size = il4965_hw_get_beacon_cmd(priv, frame);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800263 if (!frame_size) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200264 IL_ERR(priv, "Error configuring the beacon command\n");
265 il4965_free_frame(priv, frame);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800266 return -EINVAL;
267 }
268
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200269 rc = il_send_cmd_pdu(priv, REPLY_TX_BEACON, frame_size,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800270 &frame->u.cmd[0]);
271
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200272 il4965_free_frame(priv, frame);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800273
274 return rc;
275}
276
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200277static inline dma_addr_t il4965_tfd_tb_get_addr(struct il_tfd *tfd, u8 idx)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800278{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200279 struct il_tfd_tb *tb = &tfd->tbs[idx];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800280
281 dma_addr_t addr = get_unaligned_le32(&tb->lo);
282 if (sizeof(dma_addr_t) > sizeof(u32))
283 addr |=
284 ((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16;
285
286 return addr;
287}
288
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200289static inline u16 il4965_tfd_tb_get_len(struct il_tfd *tfd, u8 idx)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800290{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200291 struct il_tfd_tb *tb = &tfd->tbs[idx];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800292
293 return le16_to_cpu(tb->hi_n_len) >> 4;
294}
295
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200296static inline void il4965_tfd_set_tb(struct il_tfd *tfd, u8 idx,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800297 dma_addr_t addr, u16 len)
298{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200299 struct il_tfd_tb *tb = &tfd->tbs[idx];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800300 u16 hi_n_len = len << 4;
301
302 put_unaligned_le32(addr, &tb->lo);
303 if (sizeof(dma_addr_t) > sizeof(u32))
304 hi_n_len |= ((addr >> 16) >> 16) & 0xF;
305
306 tb->hi_n_len = cpu_to_le16(hi_n_len);
307
308 tfd->num_tbs = idx + 1;
309}
310
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200311static inline u8 il4965_tfd_get_num_tbs(struct il_tfd *tfd)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800312{
313 return tfd->num_tbs & 0x1f;
314}
315
316/**
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200317 * il4965_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800318 * @priv - driver private data
319 * @txq - tx queue
320 *
321 * Does NOT advance any TFD circular buffer read/write indexes
322 * Does NOT free the TFD itself (which is within circular buffer)
323 */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200324void il4965_hw_txq_free_tfd(struct il_priv *priv, struct il_tx_queue *txq)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800325{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200326 struct il_tfd *tfd_tmp = (struct il_tfd *)txq->tfds;
327 struct il_tfd *tfd;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800328 struct pci_dev *dev = priv->pci_dev;
329 int index = txq->q.read_ptr;
330 int i;
331 int num_tbs;
332
333 tfd = &tfd_tmp[index];
334
335 /* Sanity check on number of chunks */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200336 num_tbs = il4965_tfd_get_num_tbs(tfd);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800337
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200338 if (num_tbs >= IL_NUM_OF_TBS) {
339 IL_ERR(priv, "Too many chunks: %i\n", num_tbs);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800340 /* @todo issue fatal error, it is quite serious situation */
341 return;
342 }
343
344 /* Unmap tx_cmd */
345 if (num_tbs)
346 pci_unmap_single(dev,
347 dma_unmap_addr(&txq->meta[index], mapping),
348 dma_unmap_len(&txq->meta[index], len),
349 PCI_DMA_BIDIRECTIONAL);
350
351 /* Unmap chunks, if any. */
352 for (i = 1; i < num_tbs; i++)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200353 pci_unmap_single(dev, il4965_tfd_tb_get_addr(tfd, i),
354 il4965_tfd_tb_get_len(tfd, i),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800355 PCI_DMA_TODEVICE);
356
357 /* free SKB */
358 if (txq->txb) {
359 struct sk_buff *skb;
360
361 skb = txq->txb[txq->q.read_ptr].skb;
362
363 /* can be called from irqs-disabled context */
364 if (skb) {
365 dev_kfree_skb_any(skb);
366 txq->txb[txq->q.read_ptr].skb = NULL;
367 }
368 }
369}
370
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200371int il4965_hw_txq_attach_buf_to_tfd(struct il_priv *priv,
372 struct il_tx_queue *txq,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800373 dma_addr_t addr, u16 len,
374 u8 reset, u8 pad)
375{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200376 struct il_queue *q;
377 struct il_tfd *tfd, *tfd_tmp;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800378 u32 num_tbs;
379
380 q = &txq->q;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200381 tfd_tmp = (struct il_tfd *)txq->tfds;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800382 tfd = &tfd_tmp[q->write_ptr];
383
384 if (reset)
385 memset(tfd, 0, sizeof(*tfd));
386
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200387 num_tbs = il4965_tfd_get_num_tbs(tfd);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800388
389 /* Each TFD can point to a maximum 20 Tx buffers */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200390 if (num_tbs >= IL_NUM_OF_TBS) {
391 IL_ERR(priv, "Error can not send more than %d chunks\n",
392 IL_NUM_OF_TBS);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800393 return -EINVAL;
394 }
395
396 BUG_ON(addr & ~DMA_BIT_MASK(36));
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200397 if (unlikely(addr & ~IL_TX_DMA_MASK))
398 IL_ERR(priv, "Unaligned address = %llx\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800399 (unsigned long long)addr);
400
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200401 il4965_tfd_set_tb(tfd, num_tbs, addr, len);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800402
403 return 0;
404}
405
406/*
407 * Tell nic where to find circular buffer of Tx Frame Descriptors for
408 * given Tx queue, and enable the DMA channel used for that queue.
409 *
410 * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
411 * channels supported in hardware.
412 */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200413int il4965_hw_tx_queue_init(struct il_priv *priv,
414 struct il_tx_queue *txq)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800415{
416 int txq_id = txq->q.id;
417
418 /* Circular buffer (TFD queue in DRAM) physical base address */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200419 il_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800420 txq->q.dma_addr >> 8);
421
422 return 0;
423}
424
425/******************************************************************************
426 *
427 * Generic RX handler implementations
428 *
429 ******************************************************************************/
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200430static void il4965_rx_reply_alive(struct il_priv *priv,
431 struct il_rx_mem_buffer *rxb)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800432{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200433 struct il_rx_packet *pkt = rxb_addr(rxb);
434 struct il_alive_resp *palive;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800435 struct delayed_work *pwork;
436
437 palive = &pkt->u.alive_frame;
438
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200439 IL_DEBUG_INFO(priv, "Alive ucode status 0x%08X revision "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800440 "0x%01X 0x%01X\n",
441 palive->is_valid, palive->ver_type,
442 palive->ver_subtype);
443
444 if (palive->ver_subtype == INITIALIZE_SUBTYPE) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200445 IL_DEBUG_INFO(priv, "Initialization Alive received.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800446 memcpy(&priv->card_alive_init,
447 &pkt->u.alive_frame,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200448 sizeof(struct il_init_alive_resp));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800449 pwork = &priv->init_alive_start;
450 } else {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200451 IL_DEBUG_INFO(priv, "Runtime Alive received.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800452 memcpy(&priv->card_alive, &pkt->u.alive_frame,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200453 sizeof(struct il_alive_resp));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800454 pwork = &priv->alive_start;
455 }
456
457 /* We delay the ALIVE response by 5ms to
458 * give the HW RF Kill time to activate... */
459 if (palive->is_valid == UCODE_VALID_OK)
460 queue_delayed_work(priv->workqueue, pwork,
461 msecs_to_jiffies(5));
462 else
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200463 IL_WARN(priv, "uCode did not respond OK.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800464}
465
466/**
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200467 * il4965_bg_statistics_periodic - Timer callback to queue statistics
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800468 *
469 * This callback is provided in order to send a statistics request.
470 *
471 * This timer function is continually reset to execute within
472 * REG_RECALIB_PERIOD seconds since the last STATISTICS_NOTIFICATION
473 * was received. We need to ensure we receive the statistics in order
474 * to update the temperature used for calibrating the TXPOWER.
475 */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200476static void il4965_bg_statistics_periodic(unsigned long data)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800477{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200478 struct il_priv *priv = (struct il_priv *)data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800479
480 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
481 return;
482
483 /* dont send host command if rf-kill is on */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200484 if (!il_is_ready_rf(priv))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800485 return;
486
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200487 il_send_statistics_request(priv, CMD_ASYNC, false);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800488}
489
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200490static void il4965_rx_beacon_notif(struct il_priv *priv,
491 struct il_rx_mem_buffer *rxb)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800492{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200493 struct il_rx_packet *pkt = rxb_addr(rxb);
494 struct il4965_beacon_notif *beacon =
495 (struct il4965_beacon_notif *)pkt->u.raw;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800496#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200497 u8 rate = il4965_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800498
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200499 IL_DEBUG_RX(priv, "beacon status %x retries %d iss %d "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800500 "tsf %d %d rate %d\n",
501 le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK,
502 beacon->beacon_notify_hdr.failure_frame,
503 le32_to_cpu(beacon->ibss_mgr_status),
504 le32_to_cpu(beacon->high_tsf),
505 le32_to_cpu(beacon->low_tsf), rate);
506#endif
507
508 priv->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status);
509}
510
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200511static void il4965_perform_ct_kill_task(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800512{
513 unsigned long flags;
514
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200515 IL_DEBUG_POWER(priv, "Stop all queues\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800516
517 if (priv->mac80211_registered)
518 ieee80211_stop_queues(priv->hw);
519
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200520 il_write32(priv, CSR_UCODE_DRV_GP1_SET,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800521 CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200522 il_read32(priv, CSR_UCODE_DRV_GP1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800523
524 spin_lock_irqsave(&priv->reg_lock, flags);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200525 if (!il_grab_nic_access(priv))
526 il_release_nic_access(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800527 spin_unlock_irqrestore(&priv->reg_lock, flags);
528}
529
530/* Handle notification from uCode that card's power state is changing
531 * due to software, hardware, or critical temperature RFKILL */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200532static void il4965_rx_card_state_notif(struct il_priv *priv,
533 struct il_rx_mem_buffer *rxb)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800534{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200535 struct il_rx_packet *pkt = rxb_addr(rxb);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800536 u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
537 unsigned long status = priv->status;
538
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200539 IL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s CT:%s\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800540 (flags & HW_CARD_DISABLED) ? "Kill" : "On",
541 (flags & SW_CARD_DISABLED) ? "Kill" : "On",
542 (flags & CT_CARD_DISABLED) ?
543 "Reached" : "Not reached");
544
545 if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED |
546 CT_CARD_DISABLED)) {
547
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200548 il_write32(priv, CSR_UCODE_DRV_GP1_SET,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800549 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
550
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200551 il_write_direct32(priv, HBUS_TARG_MBX_C,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800552 HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
553
554 if (!(flags & RXON_CARD_DISABLED)) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200555 il_write32(priv, CSR_UCODE_DRV_GP1_CLR,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800556 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200557 il_write_direct32(priv, HBUS_TARG_MBX_C,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800558 HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
559 }
560 }
561
562 if (flags & CT_CARD_DISABLED)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200563 il4965_perform_ct_kill_task(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800564
565 if (flags & HW_CARD_DISABLED)
566 set_bit(STATUS_RF_KILL_HW, &priv->status);
567 else
568 clear_bit(STATUS_RF_KILL_HW, &priv->status);
569
570 if (!(flags & RXON_CARD_DISABLED))
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200571 il_scan_cancel(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800572
573 if ((test_bit(STATUS_RF_KILL_HW, &status) !=
574 test_bit(STATUS_RF_KILL_HW, &priv->status)))
575 wiphy_rfkill_set_hw_state(priv->hw->wiphy,
576 test_bit(STATUS_RF_KILL_HW, &priv->status));
577 else
Stanislaw Gruszka65d0f192011-09-20 16:49:03 +0200578 wake_up(&priv->wait_command_queue);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800579}
580
581/**
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200582 * il4965_setup_rx_handlers - Initialize Rx handler callbacks
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800583 *
584 * Setup the RX handlers for each of the reply types sent from the uCode
585 * to the host.
586 *
587 * This function chains into the hardware specific files for them to setup
588 * any hardware specific handlers as well.
589 */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200590static void il4965_setup_rx_handlers(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800591{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200592 priv->rx_handlers[REPLY_ALIVE] = il4965_rx_reply_alive;
593 priv->rx_handlers[REPLY_ERROR] = il_rx_reply_error;
594 priv->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = il_rx_csa;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800595 priv->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200596 il_rx_spectrum_measure_notif;
597 priv->rx_handlers[PM_SLEEP_NOTIFICATION] = il_rx_pm_sleep_notif;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800598 priv->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200599 il_rx_pm_debug_statistics_notif;
600 priv->rx_handlers[BEACON_NOTIFICATION] = il4965_rx_beacon_notif;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800601
602 /*
603 * The same handler is used for both the REPLY to a discrete
604 * statistics request from the host as well as for the periodic
605 * statistics notifications (after received beacons) from the uCode.
606 */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200607 priv->rx_handlers[REPLY_STATISTICS_CMD] = il4965_reply_statistics;
608 priv->rx_handlers[STATISTICS_NOTIFICATION] = il4965_rx_statistics;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800609
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200610 il_setup_rx_scan_handlers(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800611
612 /* status change handler */
613 priv->rx_handlers[CARD_STATE_NOTIFICATION] =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200614 il4965_rx_card_state_notif;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800615
616 priv->rx_handlers[MISSED_BEACONS_NOTIFICATION] =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200617 il4965_rx_missed_beacon_notif;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800618 /* Rx handlers */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200619 priv->rx_handlers[REPLY_RX_PHY_CMD] = il4965_rx_reply_rx_phy;
620 priv->rx_handlers[REPLY_RX_MPDU_CMD] = il4965_rx_reply_rx;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800621 /* block ack */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200622 priv->rx_handlers[REPLY_COMPRESSED_BA] = il4965_rx_reply_compressed_ba;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800623 /* Set up hardware specific Rx handlers */
624 priv->cfg->ops->lib->rx_handler_setup(priv);
625}
626
627/**
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200628 * il4965_rx_handle - Main entry function for receiving responses from uCode
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800629 *
630 * Uses the priv->rx_handlers callback function array to invoke
631 * the appropriate handlers, including command responses,
632 * frame-received notifications, and other notifications.
633 */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200634void il4965_rx_handle(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800635{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200636 struct il_rx_mem_buffer *rxb;
637 struct il_rx_packet *pkt;
638 struct il_rx_queue *rxq = &priv->rxq;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800639 u32 r, i;
640 int reclaim;
641 unsigned long flags;
642 u8 fill_rx = 0;
643 u32 count = 8;
644 int total_empty;
645
646 /* uCode's read index (stored in shared DRAM) indicates the last Rx
647 * buffer that the driver may process (last buffer filled by ucode). */
648 r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF;
649 i = rxq->read;
650
651 /* Rx interrupt, but nothing sent from uCode */
652 if (i == r)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200653 IL_DEBUG_RX(priv, "r = %d, i = %d\n", r, i);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800654
655 /* calculate total frames need to be restock after handling RX */
656 total_empty = r - rxq->write_actual;
657 if (total_empty < 0)
658 total_empty += RX_QUEUE_SIZE;
659
660 if (total_empty > (RX_QUEUE_SIZE / 2))
661 fill_rx = 1;
662
663 while (i != r) {
664 int len;
665
666 rxb = rxq->queue[i];
667
668 /* If an RXB doesn't have a Rx queue slot associated with it,
669 * then a bug has been introduced in the queue refilling
670 * routines -- catch it here */
671 BUG_ON(rxb == NULL);
672
673 rxq->queue[i] = NULL;
674
675 pci_unmap_page(priv->pci_dev, rxb->page_dma,
676 PAGE_SIZE << priv->hw_params.rx_page_order,
677 PCI_DMA_FROMDEVICE);
678 pkt = rxb_addr(rxb);
679
680 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
681 len += sizeof(u32); /* account for status word */
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800682
683 /* Reclaim a command buffer only if this packet is a response
684 * to a (driver-originated) command.
685 * If the packet (e.g. Rx frame) originated from uCode,
686 * there is no command buffer to reclaim.
687 * Ucode should set SEQ_RX_FRAME bit if ucode-originated,
688 * but apparently a few don't get set; catch them here. */
689 reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) &&
690 (pkt->hdr.cmd != REPLY_RX_PHY_CMD) &&
691 (pkt->hdr.cmd != REPLY_RX) &&
692 (pkt->hdr.cmd != REPLY_RX_MPDU_CMD) &&
693 (pkt->hdr.cmd != REPLY_COMPRESSED_BA) &&
694 (pkt->hdr.cmd != STATISTICS_NOTIFICATION) &&
695 (pkt->hdr.cmd != REPLY_TX);
696
697 /* Based on type of command response or notification,
698 * handle those that need handling via function in
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200699 * rx_handlers table. See il4965_setup_rx_handlers() */
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800700 if (priv->rx_handlers[pkt->hdr.cmd]) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200701 IL_DEBUG_RX(priv, "r = %d, i = %d, %s, 0x%02x\n", r,
702 i, il_get_cmd_string(pkt->hdr.cmd),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800703 pkt->hdr.cmd);
704 priv->isr_stats.rx_handlers[pkt->hdr.cmd]++;
705 priv->rx_handlers[pkt->hdr.cmd] (priv, rxb);
706 } else {
707 /* No handling needed */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200708 IL_DEBUG_RX(priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800709 "r %d i %d No handler needed for %s, 0x%02x\n",
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200710 r, i, il_get_cmd_string(pkt->hdr.cmd),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800711 pkt->hdr.cmd);
712 }
713
714 /*
715 * XXX: After here, we should always check rxb->page
716 * against NULL before touching it or its virtual
717 * memory (pkt). Because some rx_handler might have
718 * already taken or freed the pages.
719 */
720
721 if (reclaim) {
722 /* Invoke any callbacks, transfer the buffer to caller,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200723 * and fire off the (possibly) blocking il_send_cmd()
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800724 * as we reclaim the driver command queue */
725 if (rxb->page)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200726 il_tx_cmd_complete(priv, rxb);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800727 else
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200728 IL_WARN(priv, "Claim null rxb?\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800729 }
730
731 /* Reuse the page if possible. For notification packets and
732 * SKBs that fail to Rx correctly, add them back into the
733 * rx_free list for reuse later. */
734 spin_lock_irqsave(&rxq->lock, flags);
735 if (rxb->page != NULL) {
736 rxb->page_dma = pci_map_page(priv->pci_dev, rxb->page,
737 0, PAGE_SIZE << priv->hw_params.rx_page_order,
738 PCI_DMA_FROMDEVICE);
739 list_add_tail(&rxb->list, &rxq->rx_free);
740 rxq->free_count++;
741 } else
742 list_add_tail(&rxb->list, &rxq->rx_used);
743
744 spin_unlock_irqrestore(&rxq->lock, flags);
745
746 i = (i + 1) & RX_QUEUE_MASK;
747 /* If there are a lot of unused frames,
748 * restock the Rx queue so ucode wont assert. */
749 if (fill_rx) {
750 count++;
751 if (count >= 8) {
752 rxq->read = i;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200753 il4965_rx_replenish_now(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800754 count = 0;
755 }
756 }
757 }
758
759 /* Backtrack one entry */
760 rxq->read = i;
761 if (fill_rx)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200762 il4965_rx_replenish_now(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800763 else
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200764 il4965_rx_queue_restock(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800765}
766
767/* call this function to flush any scheduled tasklet */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200768static inline void il4965_synchronize_irq(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800769{
770 /* wait to make sure we flush pending tasklet*/
771 synchronize_irq(priv->pci_dev->irq);
772 tasklet_kill(&priv->irq_tasklet);
773}
774
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200775static void il4965_irq_tasklet(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800776{
777 u32 inta, handled = 0;
778 u32 inta_fh;
779 unsigned long flags;
780 u32 i;
781#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
782 u32 inta_mask;
783#endif
784
785 spin_lock_irqsave(&priv->lock, flags);
786
787 /* Ack/clear/reset pending uCode interrupts.
788 * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
789 * and will clear only when CSR_FH_INT_STATUS gets cleared. */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200790 inta = il_read32(priv, CSR_INT);
791 il_write32(priv, CSR_INT, inta);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800792
793 /* Ack/clear/reset pending flow-handler (DMA) interrupts.
794 * Any new interrupts that happen after this, either while we're
795 * in this tasklet, or later, will show up in next ISR/tasklet. */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200796 inta_fh = il_read32(priv, CSR_FH_INT_STATUS);
797 il_write32(priv, CSR_FH_INT_STATUS, inta_fh);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800798
799#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200800 if (il_get_debug_level(priv) & IL_DL_ISR) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800801 /* just for debug */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200802 inta_mask = il_read32(priv, CSR_INT_MASK);
803 IL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800804 inta, inta_mask, inta_fh);
805 }
806#endif
807
808 spin_unlock_irqrestore(&priv->lock, flags);
809
810 /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not
811 * atomic, make sure that inta covers all the interrupts that
812 * we've discovered, even if FH interrupt came in just after
813 * reading CSR_INT. */
814 if (inta_fh & CSR49_FH_INT_RX_MASK)
815 inta |= CSR_INT_BIT_FH_RX;
816 if (inta_fh & CSR49_FH_INT_TX_MASK)
817 inta |= CSR_INT_BIT_FH_TX;
818
819 /* Now service all interrupt bits discovered above. */
820 if (inta & CSR_INT_BIT_HW_ERR) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200821 IL_ERR(priv, "Hardware error detected. Restarting.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800822
823 /* Tell the device to stop sending interrupts */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200824 il_disable_interrupts(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800825
826 priv->isr_stats.hw++;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200827 il_irq_handle_error(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800828
829 handled |= CSR_INT_BIT_HW_ERR;
830
831 return;
832 }
833
834#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200835 if (il_get_debug_level(priv) & (IL_DL_ISR)) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800836 /* NIC fires this, but we don't use it, redundant with WAKEUP */
837 if (inta & CSR_INT_BIT_SCD) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200838 IL_DEBUG_ISR(priv, "Scheduler finished to transmit "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800839 "the frame/frames.\n");
840 priv->isr_stats.sch++;
841 }
842
843 /* Alive notification via Rx interrupt will do the real work */
844 if (inta & CSR_INT_BIT_ALIVE) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200845 IL_DEBUG_ISR(priv, "Alive interrupt\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800846 priv->isr_stats.alive++;
847 }
848 }
849#endif
850 /* Safely ignore these bits for debug checks below */
851 inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
852
853 /* HW RF KILL switch toggled */
854 if (inta & CSR_INT_BIT_RF_KILL) {
855 int hw_rf_kill = 0;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200856 if (!(il_read32(priv, CSR_GP_CNTRL) &
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800857 CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
858 hw_rf_kill = 1;
859
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200860 IL_WARN(priv, "RF_KILL bit toggled to %s.\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800861 hw_rf_kill ? "disable radio" : "enable radio");
862
863 priv->isr_stats.rfkill++;
864
865 /* driver only loads ucode once setting the interface up.
866 * the driver allows loading the ucode even if the radio
867 * is killed. Hence update the killswitch state here. The
868 * rfkill handler will care about restarting if needed.
869 */
870 if (!test_bit(STATUS_ALIVE, &priv->status)) {
871 if (hw_rf_kill)
872 set_bit(STATUS_RF_KILL_HW, &priv->status);
873 else
874 clear_bit(STATUS_RF_KILL_HW, &priv->status);
875 wiphy_rfkill_set_hw_state(priv->hw->wiphy, hw_rf_kill);
876 }
877
878 handled |= CSR_INT_BIT_RF_KILL;
879 }
880
881 /* Chip got too hot and stopped itself */
882 if (inta & CSR_INT_BIT_CT_KILL) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200883 IL_ERR(priv, "Microcode CT kill error detected.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800884 priv->isr_stats.ctkill++;
885 handled |= CSR_INT_BIT_CT_KILL;
886 }
887
888 /* Error detected by uCode */
889 if (inta & CSR_INT_BIT_SW_ERR) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200890 IL_ERR(priv, "Microcode SW error detected. "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800891 " Restarting 0x%X.\n", inta);
892 priv->isr_stats.sw++;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200893 il_irq_handle_error(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800894 handled |= CSR_INT_BIT_SW_ERR;
895 }
896
897 /*
898 * uCode wakes up after power-down sleep.
899 * Tell device about any new tx or host commands enqueued,
900 * and about any Rx buffers made available while asleep.
901 */
902 if (inta & CSR_INT_BIT_WAKEUP) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200903 IL_DEBUG_ISR(priv, "Wakeup interrupt\n");
904 il_rx_queue_update_write_ptr(priv, &priv->rxq);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800905 for (i = 0; i < priv->hw_params.max_txq_num; i++)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200906 il_txq_update_write_ptr(priv, &priv->txq[i]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800907 priv->isr_stats.wakeup++;
908 handled |= CSR_INT_BIT_WAKEUP;
909 }
910
911 /* All uCode command responses, including Tx command responses,
912 * Rx "responses" (frame-received notification), and other
913 * notifications from uCode come through here*/
914 if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200915 il4965_rx_handle(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800916 priv->isr_stats.rx++;
917 handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
918 }
919
920 /* This "Tx" DMA channel is used only for loading uCode */
921 if (inta & CSR_INT_BIT_FH_TX) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200922 IL_DEBUG_ISR(priv, "uCode load interrupt\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800923 priv->isr_stats.tx++;
924 handled |= CSR_INT_BIT_FH_TX;
925 /* Wake up uCode load routine, now that load is complete */
926 priv->ucode_write_complete = 1;
Stanislaw Gruszka65d0f192011-09-20 16:49:03 +0200927 wake_up(&priv->wait_command_queue);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800928 }
929
930 if (inta & ~handled) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200931 IL_ERR(priv, "Unhandled INTA bits 0x%08x\n", inta & ~handled);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800932 priv->isr_stats.unhandled++;
933 }
934
935 if (inta & ~(priv->inta_mask)) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200936 IL_WARN(priv, "Disabled INTA bits 0x%08x were pending\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800937 inta & ~priv->inta_mask);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200938 IL_WARN(priv, " with FH_INT = 0x%08x\n", inta_fh);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800939 }
940
941 /* Re-enable all interrupts */
Stanislaw Gruszka93fd74e2011-04-28 11:51:30 +0200942 /* only Re-enable if disabled by irq */
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800943 if (test_bit(STATUS_INT_ENABLED, &priv->status))
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200944 il_enable_interrupts(priv);
Stanislaw Gruszkaa078a1f2011-04-28 11:51:25 +0200945 /* Re-enable RF_KILL if it occurred */
946 else if (handled & CSR_INT_BIT_RF_KILL)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200947 il_enable_rfkill_int(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800948
949#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200950 if (il_get_debug_level(priv) & (IL_DL_ISR)) {
951 inta = il_read32(priv, CSR_INT);
952 inta_mask = il_read32(priv, CSR_INT_MASK);
953 inta_fh = il_read32(priv, CSR_FH_INT_STATUS);
954 IL_DEBUG_ISR(priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800955 "End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
956 "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags);
957 }
958#endif
959}
960
961/*****************************************************************************
962 *
963 * sysfs attributes
964 *
965 *****************************************************************************/
966
967#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
968
969/*
970 * The following adds a new attribute to the sysfs representation
971 * of this device driver (i.e. a new file in /sys/class/net/wlan0/device/)
972 * used for controlling the debug level.
973 *
974 * See the level definitions in iwl for details.
975 *
976 * The debug_level being managed using sysfs below is a per device debug
977 * level that is used instead of the global debug level if it (the per
978 * device debug level) is set.
979 */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200980static ssize_t il4965_show_debug_level(struct device *d,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800981 struct device_attribute *attr, char *buf)
982{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200983 struct il_priv *priv = dev_get_drvdata(d);
984 return sprintf(buf, "0x%08X\n", il_get_debug_level(priv));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800985}
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200986static ssize_t il4965_store_debug_level(struct device *d,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800987 struct device_attribute *attr,
988 const char *buf, size_t count)
989{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200990 struct il_priv *priv = dev_get_drvdata(d);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800991 unsigned long val;
992 int ret;
993
994 ret = strict_strtoul(buf, 0, &val);
995 if (ret)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200996 IL_ERR(priv, "%s is not in hex or decimal form.\n", buf);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800997 else {
998 priv->debug_level = val;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200999 if (il_alloc_traffic_mem(priv))
1000 IL_ERR(priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001001 "Not enough memory to generate traffic log\n");
1002 }
1003 return strnlen(buf, count);
1004}
1005
1006static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001007 il4965_show_debug_level, il4965_store_debug_level);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001008
1009
1010#endif /* CONFIG_IWLWIFI_LEGACY_DEBUG */
1011
1012
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001013static ssize_t il4965_show_temperature(struct device *d,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001014 struct device_attribute *attr, char *buf)
1015{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001016 struct il_priv *priv = dev_get_drvdata(d);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001017
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001018 if (!il_is_alive(priv))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001019 return -EAGAIN;
1020
1021 return sprintf(buf, "%d\n", priv->temperature);
1022}
1023
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001024static DEVICE_ATTR(temperature, S_IRUGO, il4965_show_temperature, NULL);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001025
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001026static ssize_t il4965_show_tx_power(struct device *d,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001027 struct device_attribute *attr, char *buf)
1028{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001029 struct il_priv *priv = dev_get_drvdata(d);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001030
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001031 if (!il_is_ready_rf(priv))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001032 return sprintf(buf, "off\n");
1033 else
1034 return sprintf(buf, "%d\n", priv->tx_power_user_lmt);
1035}
1036
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001037static ssize_t il4965_store_tx_power(struct device *d,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001038 struct device_attribute *attr,
1039 const char *buf, size_t count)
1040{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001041 struct il_priv *priv = dev_get_drvdata(d);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001042 unsigned long val;
1043 int ret;
1044
1045 ret = strict_strtoul(buf, 10, &val);
1046 if (ret)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001047 IL_INFO(priv, "%s is not in decimal form.\n", buf);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001048 else {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001049 ret = il_set_tx_power(priv, val, false);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001050 if (ret)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001051 IL_ERR(priv, "failed setting tx power (0x%d).\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001052 ret);
1053 else
1054 ret = count;
1055 }
1056 return ret;
1057}
1058
1059static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001060 il4965_show_tx_power, il4965_store_tx_power);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001061
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001062static struct attribute *il_sysfs_entries[] = {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001063 &dev_attr_temperature.attr,
1064 &dev_attr_tx_power.attr,
1065#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
1066 &dev_attr_debug_level.attr,
1067#endif
1068 NULL
1069};
1070
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001071static struct attribute_group il_attribute_group = {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001072 .name = NULL, /* put in device directory */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001073 .attrs = il_sysfs_entries,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001074};
1075
1076/******************************************************************************
1077 *
1078 * uCode download functions
1079 *
1080 ******************************************************************************/
1081
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001082static void il4965_dealloc_ucode_pci(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001083{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001084 il_free_fw_desc(priv->pci_dev, &priv->ucode_code);
1085 il_free_fw_desc(priv->pci_dev, &priv->ucode_data);
1086 il_free_fw_desc(priv->pci_dev, &priv->ucode_data_backup);
1087 il_free_fw_desc(priv->pci_dev, &priv->ucode_init);
1088 il_free_fw_desc(priv->pci_dev, &priv->ucode_init_data);
1089 il_free_fw_desc(priv->pci_dev, &priv->ucode_boot);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001090}
1091
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001092static void il4965_nic_start(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001093{
1094 /* Remove all resets to allow NIC to operate */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001095 il_write32(priv, CSR_RESET, 0);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001096}
1097
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001098static void il4965_ucode_callback(const struct firmware *ucode_raw,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001099 void *context);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001100static int il4965_mac_setup_register(struct il_priv *priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001101 u32 max_probe_length);
1102
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001103static int __must_check il4965_request_firmware(struct il_priv *priv, bool first)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001104{
1105 const char *name_pre = priv->cfg->fw_name_pre;
1106 char tag[8];
1107
1108 if (first) {
1109 priv->fw_index = priv->cfg->ucode_api_max;
1110 sprintf(tag, "%d", priv->fw_index);
1111 } else {
1112 priv->fw_index--;
1113 sprintf(tag, "%d", priv->fw_index);
1114 }
1115
1116 if (priv->fw_index < priv->cfg->ucode_api_min) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001117 IL_ERR(priv, "no suitable firmware found!\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001118 return -ENOENT;
1119 }
1120
1121 sprintf(priv->firmware_name, "%s%s%s", name_pre, tag, ".ucode");
1122
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001123 IL_DEBUG_INFO(priv, "attempting to load firmware '%s'\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001124 priv->firmware_name);
1125
1126 return request_firmware_nowait(THIS_MODULE, 1, priv->firmware_name,
1127 &priv->pci_dev->dev, GFP_KERNEL, priv,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001128 il4965_ucode_callback);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001129}
1130
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001131struct il4965_firmware_pieces {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001132 const void *inst, *data, *init, *init_data, *boot;
1133 size_t inst_size, data_size, init_size, init_data_size, boot_size;
1134};
1135
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001136static int il4965_load_firmware(struct il_priv *priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001137 const struct firmware *ucode_raw,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001138 struct il4965_firmware_pieces *pieces)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001139{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001140 struct il_ucode_header *ucode = (void *)ucode_raw->data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001141 u32 api_ver, hdr_size;
1142 const u8 *src;
1143
1144 priv->ucode_ver = le32_to_cpu(ucode->ver);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001145 api_ver = IL_UCODE_API(priv->ucode_ver);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001146
1147 switch (api_ver) {
1148 default:
1149 case 0:
1150 case 1:
1151 case 2:
1152 hdr_size = 24;
1153 if (ucode_raw->size < hdr_size) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001154 IL_ERR(priv, "File size too small!\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001155 return -EINVAL;
1156 }
1157 pieces->inst_size = le32_to_cpu(ucode->v1.inst_size);
1158 pieces->data_size = le32_to_cpu(ucode->v1.data_size);
1159 pieces->init_size = le32_to_cpu(ucode->v1.init_size);
1160 pieces->init_data_size =
1161 le32_to_cpu(ucode->v1.init_data_size);
1162 pieces->boot_size = le32_to_cpu(ucode->v1.boot_size);
1163 src = ucode->v1.data;
1164 break;
1165 }
1166
1167 /* Verify size of file vs. image size info in file's header */
1168 if (ucode_raw->size != hdr_size + pieces->inst_size +
1169 pieces->data_size + pieces->init_size +
1170 pieces->init_data_size + pieces->boot_size) {
1171
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001172 IL_ERR(priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001173 "uCode file size %d does not match expected size\n",
1174 (int)ucode_raw->size);
1175 return -EINVAL;
1176 }
1177
1178 pieces->inst = src;
1179 src += pieces->inst_size;
1180 pieces->data = src;
1181 src += pieces->data_size;
1182 pieces->init = src;
1183 src += pieces->init_size;
1184 pieces->init_data = src;
1185 src += pieces->init_data_size;
1186 pieces->boot = src;
1187 src += pieces->boot_size;
1188
1189 return 0;
1190}
1191
1192/**
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001193 * il4965_ucode_callback - callback when firmware was loaded
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001194 *
1195 * If loaded successfully, copies the firmware into buffers
1196 * for the card to fetch (via DMA).
1197 */
1198static void
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001199il4965_ucode_callback(const struct firmware *ucode_raw, void *context)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001200{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001201 struct il_priv *priv = context;
1202 struct il_ucode_header *ucode;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001203 int err;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001204 struct il4965_firmware_pieces pieces;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001205 const unsigned int api_max = priv->cfg->ucode_api_max;
1206 const unsigned int api_min = priv->cfg->ucode_api_min;
1207 u32 api_ver;
1208
1209 u32 max_probe_length = 200;
1210 u32 standard_phy_calibration_size =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001211 IL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001212
1213 memset(&pieces, 0, sizeof(pieces));
1214
1215 if (!ucode_raw) {
1216 if (priv->fw_index <= priv->cfg->ucode_api_max)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001217 IL_ERR(priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001218 "request for firmware file '%s' failed.\n",
1219 priv->firmware_name);
1220 goto try_again;
1221 }
1222
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001223 IL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001224 priv->firmware_name, ucode_raw->size);
1225
1226 /* Make sure that we got at least the API version number */
1227 if (ucode_raw->size < 4) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001228 IL_ERR(priv, "File size way too small!\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001229 goto try_again;
1230 }
1231
1232 /* Data from ucode file: header followed by uCode images */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001233 ucode = (struct il_ucode_header *)ucode_raw->data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001234
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001235 err = il4965_load_firmware(priv, ucode_raw, &pieces);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001236
1237 if (err)
1238 goto try_again;
1239
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001240 api_ver = IL_UCODE_API(priv->ucode_ver);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001241
1242 /*
1243 * api_ver should match the api version forming part of the
1244 * firmware filename ... but we don't check for that and only rely
1245 * on the API version read from firmware header from here on forward
1246 */
1247 if (api_ver < api_min || api_ver > api_max) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001248 IL_ERR(priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001249 "Driver unable to support your firmware API. "
1250 "Driver supports v%u, firmware is v%u.\n",
1251 api_max, api_ver);
1252 goto try_again;
1253 }
1254
1255 if (api_ver != api_max)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001256 IL_ERR(priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001257 "Firmware has old API version. Expected v%u, "
1258 "got v%u. New firmware can be obtained "
1259 "from http://www.intellinuxwireless.org.\n",
1260 api_max, api_ver);
1261
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001262 IL_INFO(priv, "loaded firmware version %u.%u.%u.%u\n",
1263 IL_UCODE_MAJOR(priv->ucode_ver),
1264 IL_UCODE_MINOR(priv->ucode_ver),
1265 IL_UCODE_API(priv->ucode_ver),
1266 IL_UCODE_SERIAL(priv->ucode_ver));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001267
1268 snprintf(priv->hw->wiphy->fw_version,
1269 sizeof(priv->hw->wiphy->fw_version),
1270 "%u.%u.%u.%u",
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001271 IL_UCODE_MAJOR(priv->ucode_ver),
1272 IL_UCODE_MINOR(priv->ucode_ver),
1273 IL_UCODE_API(priv->ucode_ver),
1274 IL_UCODE_SERIAL(priv->ucode_ver));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001275
1276 /*
1277 * For any of the failures below (before allocating pci memory)
1278 * we will try to load a version with a smaller API -- maybe the
1279 * user just got a corrupted version of the latest API.
1280 */
1281
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001282 IL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001283 priv->ucode_ver);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001284 IL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001285 pieces.inst_size);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001286 IL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001287 pieces.data_size);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001288 IL_DEBUG_INFO(priv, "f/w package hdr init inst size = %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001289 pieces.init_size);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001290 IL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001291 pieces.init_data_size);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001292 IL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001293 pieces.boot_size);
1294
1295 /* Verify that uCode images will fit in card's SRAM */
1296 if (pieces.inst_size > priv->hw_params.max_inst_size) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001297 IL_ERR(priv, "uCode instr len %Zd too large to fit in\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001298 pieces.inst_size);
1299 goto try_again;
1300 }
1301
1302 if (pieces.data_size > priv->hw_params.max_data_size) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001303 IL_ERR(priv, "uCode data len %Zd too large to fit in\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001304 pieces.data_size);
1305 goto try_again;
1306 }
1307
1308 if (pieces.init_size > priv->hw_params.max_inst_size) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001309 IL_ERR(priv, "uCode init instr len %Zd too large to fit in\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001310 pieces.init_size);
1311 goto try_again;
1312 }
1313
1314 if (pieces.init_data_size > priv->hw_params.max_data_size) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001315 IL_ERR(priv, "uCode init data len %Zd too large to fit in\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001316 pieces.init_data_size);
1317 goto try_again;
1318 }
1319
1320 if (pieces.boot_size > priv->hw_params.max_bsm_size) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001321 IL_ERR(priv, "uCode boot instr len %Zd too large to fit in\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001322 pieces.boot_size);
1323 goto try_again;
1324 }
1325
1326 /* Allocate ucode buffers for card's bus-master loading ... */
1327
1328 /* Runtime instructions and 2 copies of data:
1329 * 1) unmodified from disk
1330 * 2) backup cache for save/restore during power-downs */
1331 priv->ucode_code.len = pieces.inst_size;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001332 il_alloc_fw_desc(priv->pci_dev, &priv->ucode_code);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001333
1334 priv->ucode_data.len = pieces.data_size;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001335 il_alloc_fw_desc(priv->pci_dev, &priv->ucode_data);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001336
1337 priv->ucode_data_backup.len = pieces.data_size;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001338 il_alloc_fw_desc(priv->pci_dev, &priv->ucode_data_backup);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001339
1340 if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr ||
1341 !priv->ucode_data_backup.v_addr)
1342 goto err_pci_alloc;
1343
1344 /* Initialization instructions and data */
1345 if (pieces.init_size && pieces.init_data_size) {
1346 priv->ucode_init.len = pieces.init_size;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001347 il_alloc_fw_desc(priv->pci_dev, &priv->ucode_init);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001348
1349 priv->ucode_init_data.len = pieces.init_data_size;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001350 il_alloc_fw_desc(priv->pci_dev, &priv->ucode_init_data);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001351
1352 if (!priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr)
1353 goto err_pci_alloc;
1354 }
1355
1356 /* Bootstrap (instructions only, no data) */
1357 if (pieces.boot_size) {
1358 priv->ucode_boot.len = pieces.boot_size;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001359 il_alloc_fw_desc(priv->pci_dev, &priv->ucode_boot);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001360
1361 if (!priv->ucode_boot.v_addr)
1362 goto err_pci_alloc;
1363 }
1364
1365 /* Now that we can no longer fail, copy information */
1366
1367 priv->sta_key_max_num = STA_KEY_MAX_NUM;
1368
1369 /* Copy images into buffers for card's bus-master reads ... */
1370
1371 /* Runtime instructions (first block of data in file) */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001372 IL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001373 pieces.inst_size);
1374 memcpy(priv->ucode_code.v_addr, pieces.inst, pieces.inst_size);
1375
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001376 IL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001377 priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);
1378
1379 /*
1380 * Runtime data
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001381 * NOTE: Copy into backup buffer will be done in il_up()
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001382 */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001383 IL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001384 pieces.data_size);
1385 memcpy(priv->ucode_data.v_addr, pieces.data, pieces.data_size);
1386 memcpy(priv->ucode_data_backup.v_addr, pieces.data, pieces.data_size);
1387
1388 /* Initialization instructions */
1389 if (pieces.init_size) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001390 IL_DEBUG_INFO(priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001391 "Copying (but not loading) init instr len %Zd\n",
1392 pieces.init_size);
1393 memcpy(priv->ucode_init.v_addr, pieces.init, pieces.init_size);
1394 }
1395
1396 /* Initialization data */
1397 if (pieces.init_data_size) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001398 IL_DEBUG_INFO(priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001399 "Copying (but not loading) init data len %Zd\n",
1400 pieces.init_data_size);
1401 memcpy(priv->ucode_init_data.v_addr, pieces.init_data,
1402 pieces.init_data_size);
1403 }
1404
1405 /* Bootstrap instructions */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001406 IL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001407 pieces.boot_size);
1408 memcpy(priv->ucode_boot.v_addr, pieces.boot, pieces.boot_size);
1409
1410 /*
1411 * figure out the offset of chain noise reset and gain commands
1412 * base on the size of standard phy calibration commands table size
1413 */
1414 priv->_4965.phy_calib_chain_noise_reset_cmd =
1415 standard_phy_calibration_size;
1416 priv->_4965.phy_calib_chain_noise_gain_cmd =
1417 standard_phy_calibration_size + 1;
1418
1419 /**************************************************
1420 * This is still part of probe() in a sense...
1421 *
1422 * 9. Setup and register with mac80211 and debugfs
1423 **************************************************/
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001424 err = il4965_mac_setup_register(priv, max_probe_length);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001425 if (err)
1426 goto out_unbind;
1427
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001428 err = il_dbgfs_register(priv, DRV_NAME);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001429 if (err)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001430 IL_ERR(priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001431 "failed to create debugfs files. Ignoring error: %d\n", err);
1432
1433 err = sysfs_create_group(&priv->pci_dev->dev.kobj,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001434 &il_attribute_group);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001435 if (err) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001436 IL_ERR(priv, "failed to create sysfs device attributes\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001437 goto out_unbind;
1438 }
1439
1440 /* We have our copies now, allow OS release its copies */
1441 release_firmware(ucode_raw);
1442 complete(&priv->_4965.firmware_loading_complete);
1443 return;
1444
1445 try_again:
1446 /* try next, if any */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001447 if (il4965_request_firmware(priv, false))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001448 goto out_unbind;
1449 release_firmware(ucode_raw);
1450 return;
1451
1452 err_pci_alloc:
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001453 IL_ERR(priv, "failed to allocate pci memory\n");
1454 il4965_dealloc_ucode_pci(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001455 out_unbind:
1456 complete(&priv->_4965.firmware_loading_complete);
1457 device_release_driver(&priv->pci_dev->dev);
1458 release_firmware(ucode_raw);
1459}
1460
1461static const char * const desc_lookup_text[] = {
1462 "OK",
1463 "FAIL",
1464 "BAD_PARAM",
1465 "BAD_CHECKSUM",
1466 "NMI_INTERRUPT_WDG",
1467 "SYSASSERT",
1468 "FATAL_ERROR",
1469 "BAD_COMMAND",
1470 "HW_ERROR_TUNE_LOCK",
1471 "HW_ERROR_TEMPERATURE",
1472 "ILLEGAL_CHAN_FREQ",
1473 "VCC_NOT_STABLE",
1474 "FH_ERROR",
1475 "NMI_INTERRUPT_HOST",
1476 "NMI_INTERRUPT_ACTION_PT",
1477 "NMI_INTERRUPT_UNKNOWN",
1478 "UCODE_VERSION_MISMATCH",
1479 "HW_ERROR_ABS_LOCK",
1480 "HW_ERROR_CAL_LOCK_FAIL",
1481 "NMI_INTERRUPT_INST_ACTION_PT",
1482 "NMI_INTERRUPT_DATA_ACTION_PT",
1483 "NMI_TRM_HW_ER",
1484 "NMI_INTERRUPT_TRM",
Joe Perches861d9c32011-07-08 23:20:24 -07001485 "NMI_INTERRUPT_BREAK_POINT",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001486 "DEBUG_0",
1487 "DEBUG_1",
1488 "DEBUG_2",
1489 "DEBUG_3",
1490};
1491
1492static struct { char *name; u8 num; } advanced_lookup[] = {
1493 { "NMI_INTERRUPT_WDG", 0x34 },
1494 { "SYSASSERT", 0x35 },
1495 { "UCODE_VERSION_MISMATCH", 0x37 },
1496 { "BAD_COMMAND", 0x38 },
1497 { "NMI_INTERRUPT_DATA_ACTION_PT", 0x3C },
1498 { "FATAL_ERROR", 0x3D },
1499 { "NMI_TRM_HW_ERR", 0x46 },
1500 { "NMI_INTERRUPT_TRM", 0x4C },
1501 { "NMI_INTERRUPT_BREAK_POINT", 0x54 },
1502 { "NMI_INTERRUPT_WDG_RXF_FULL", 0x5C },
1503 { "NMI_INTERRUPT_WDG_NO_RBD_RXF_FULL", 0x64 },
1504 { "NMI_INTERRUPT_HOST", 0x66 },
1505 { "NMI_INTERRUPT_ACTION_PT", 0x7C },
1506 { "NMI_INTERRUPT_UNKNOWN", 0x84 },
1507 { "NMI_INTERRUPT_INST_ACTION_PT", 0x86 },
1508 { "ADVANCED_SYSASSERT", 0 },
1509};
1510
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001511static const char *il4965_desc_lookup(u32 num)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001512{
1513 int i;
1514 int max = ARRAY_SIZE(desc_lookup_text);
1515
1516 if (num < max)
1517 return desc_lookup_text[num];
1518
1519 max = ARRAY_SIZE(advanced_lookup) - 1;
1520 for (i = 0; i < max; i++) {
1521 if (advanced_lookup[i].num == num)
1522 break;
1523 }
1524 return advanced_lookup[i].name;
1525}
1526
1527#define ERROR_START_OFFSET (1 * sizeof(u32))
1528#define ERROR_ELEM_SIZE (7 * sizeof(u32))
1529
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001530void il4965_dump_nic_error_log(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001531{
1532 u32 data2, line;
1533 u32 desc, time, count, base, data1;
1534 u32 blink1, blink2, ilink1, ilink2;
1535 u32 pc, hcmd;
1536
1537 if (priv->ucode_type == UCODE_INIT) {
1538 base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
1539 } else {
1540 base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
1541 }
1542
1543 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001544 IL_ERR(priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001545 "Not valid error log pointer 0x%08X for %s uCode\n",
1546 base, (priv->ucode_type == UCODE_INIT) ? "Init" : "RT");
1547 return;
1548 }
1549
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001550 count = il_read_targ_mem(priv, base);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001551
1552 if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001553 IL_ERR(priv, "Start IWL Error Log Dump:\n");
1554 IL_ERR(priv, "Status: 0x%08lX, count: %d\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001555 priv->status, count);
1556 }
1557
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001558 desc = il_read_targ_mem(priv, base + 1 * sizeof(u32));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001559 priv->isr_stats.err_code = desc;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001560 pc = il_read_targ_mem(priv, base + 2 * sizeof(u32));
1561 blink1 = il_read_targ_mem(priv, base + 3 * sizeof(u32));
1562 blink2 = il_read_targ_mem(priv, base + 4 * sizeof(u32));
1563 ilink1 = il_read_targ_mem(priv, base + 5 * sizeof(u32));
1564 ilink2 = il_read_targ_mem(priv, base + 6 * sizeof(u32));
1565 data1 = il_read_targ_mem(priv, base + 7 * sizeof(u32));
1566 data2 = il_read_targ_mem(priv, base + 8 * sizeof(u32));
1567 line = il_read_targ_mem(priv, base + 9 * sizeof(u32));
1568 time = il_read_targ_mem(priv, base + 11 * sizeof(u32));
1569 hcmd = il_read_targ_mem(priv, base + 22 * sizeof(u32));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001570
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001571 IL_ERR(priv, "Desc Time "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001572 "data1 data2 line\n");
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001573 IL_ERR(priv, "%-28s (0x%04X) %010u 0x%08X 0x%08X %u\n",
1574 il4965_desc_lookup(desc), desc, time, data1, data2, line);
1575 IL_ERR(priv, "pc blink1 blink2 ilink1 ilink2 hcmd\n");
1576 IL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X 0x%05X 0x%05X\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001577 pc, blink1, blink2, ilink1, ilink2, hcmd);
1578}
1579
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001580static void il4965_rf_kill_ct_config(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001581{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001582 struct il_ct_kill_config cmd;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001583 unsigned long flags;
1584 int ret = 0;
1585
1586 spin_lock_irqsave(&priv->lock, flags);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001587 il_write32(priv, CSR_UCODE_DRV_GP1_CLR,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001588 CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
1589 spin_unlock_irqrestore(&priv->lock, flags);
1590
1591 cmd.critical_temperature_R =
1592 cpu_to_le32(priv->hw_params.ct_kill_threshold);
1593
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001594 ret = il_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001595 sizeof(cmd), &cmd);
1596 if (ret)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001597 IL_ERR(priv, "REPLY_CT_KILL_CONFIG_CMD failed\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001598 else
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001599 IL_DEBUG_INFO(priv, "REPLY_CT_KILL_CONFIG_CMD "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001600 "succeeded, "
1601 "critical temperature is %d\n",
1602 priv->hw_params.ct_kill_threshold);
1603}
1604
1605static const s8 default_queue_to_tx_fifo[] = {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001606 IL_TX_FIFO_VO,
1607 IL_TX_FIFO_VI,
1608 IL_TX_FIFO_BE,
1609 IL_TX_FIFO_BK,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001610 IWL49_CMD_FIFO_NUM,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001611 IL_TX_FIFO_UNUSED,
1612 IL_TX_FIFO_UNUSED,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001613};
1614
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001615static int il4965_alive_notify(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001616{
1617 u32 a;
1618 unsigned long flags;
1619 int i, chan;
1620 u32 reg_val;
1621
1622 spin_lock_irqsave(&priv->lock, flags);
1623
1624 /* Clear 4965's internal Tx Scheduler data base */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001625 priv->scd_base_addr = il_read_prph(priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001626 IWL49_SCD_SRAM_BASE_ADDR);
1627 a = priv->scd_base_addr + IWL49_SCD_CONTEXT_DATA_OFFSET;
1628 for (; a < priv->scd_base_addr + IWL49_SCD_TX_STTS_BITMAP_OFFSET; a += 4)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001629 il_write_targ_mem(priv, a, 0);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001630 for (; a < priv->scd_base_addr + IWL49_SCD_TRANSLATE_TBL_OFFSET; a += 4)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001631 il_write_targ_mem(priv, a, 0);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001632 for (; a < priv->scd_base_addr +
1633 IWL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001634 il_write_targ_mem(priv, a, 0);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001635
1636 /* Tel 4965 where to find Tx byte count tables */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001637 il_write_prph(priv, IWL49_SCD_DRAM_BASE_ADDR,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001638 priv->scd_bc_tbls.dma >> 10);
1639
1640 /* Enable DMA channel */
1641 for (chan = 0; chan < FH49_TCSR_CHNL_NUM ; chan++)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001642 il_write_direct32(priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001643 FH_TCSR_CHNL_TX_CONFIG_REG(chan),
1644 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
1645 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);
1646
1647 /* Update FH chicken bits */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001648 reg_val = il_read_direct32(priv, FH_TX_CHICKEN_BITS_REG);
1649 il_write_direct32(priv, FH_TX_CHICKEN_BITS_REG,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001650 reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
1651
1652 /* Disable chain mode for all queues */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001653 il_write_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, 0);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001654
1655 /* Initialize each Tx queue (including the command queue) */
1656 for (i = 0; i < priv->hw_params.max_txq_num; i++) {
1657
1658 /* TFD circular buffer read/write indexes */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001659 il_write_prph(priv, IWL49_SCD_QUEUE_RDPTR(i), 0);
1660 il_write_direct32(priv, HBUS_TARG_WRPTR, 0 | (i << 8));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001661
1662 /* Max Tx Window size for Scheduler-ACK mode */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001663 il_write_targ_mem(priv, priv->scd_base_addr +
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001664 IWL49_SCD_CONTEXT_QUEUE_OFFSET(i),
1665 (SCD_WIN_SIZE <<
1666 IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) &
1667 IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK);
1668
1669 /* Frame limit */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001670 il_write_targ_mem(priv, priv->scd_base_addr +
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001671 IWL49_SCD_CONTEXT_QUEUE_OFFSET(i) +
1672 sizeof(u32),
1673 (SCD_FRAME_LIMIT <<
1674 IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
1675 IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK);
1676
1677 }
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001678 il_write_prph(priv, IWL49_SCD_INTERRUPT_MASK,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001679 (1 << priv->hw_params.max_txq_num) - 1);
1680
1681 /* Activate all Tx DMA/FIFO channels */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001682 il4965_txq_set_sched(priv, IL_MASK(0, 6));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001683
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001684 il4965_set_wr_ptrs(priv, IL_DEFAULT_CMD_QUEUE_NUM, 0);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001685
1686 /* make sure all queue are not stopped */
1687 memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped));
1688 for (i = 0; i < 4; i++)
1689 atomic_set(&priv->queue_stop_count[i], 0);
1690
1691 /* reset to 0 to enable all the queue first */
1692 priv->txq_ctx_active_msk = 0;
1693 /* Map each Tx/cmd queue to its corresponding fifo */
1694 BUILD_BUG_ON(ARRAY_SIZE(default_queue_to_tx_fifo) != 7);
1695
1696 for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) {
1697 int ac = default_queue_to_tx_fifo[i];
1698
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001699 il_txq_ctx_activate(priv, i);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001700
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001701 if (ac == IL_TX_FIFO_UNUSED)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001702 continue;
1703
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001704 il4965_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001705 }
1706
1707 spin_unlock_irqrestore(&priv->lock, flags);
1708
1709 return 0;
1710}
1711
1712/**
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001713 * il4965_alive_start - called after REPLY_ALIVE notification received
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001714 * from protocol/runtime uCode (initialization uCode's
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001715 * Alive gets handled by il_init_alive_start()).
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001716 */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001717static void il4965_alive_start(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001718{
1719 int ret = 0;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001720 struct il_rxon_context *ctx = &priv->contexts[IL_RXON_CTX_BSS];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001721
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001722 IL_DEBUG_INFO(priv, "Runtime Alive received.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001723
1724 if (priv->card_alive.is_valid != UCODE_VALID_OK) {
1725 /* We had an error bringing up the hardware, so take it
1726 * all the way back down so we can try again */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001727 IL_DEBUG_INFO(priv, "Alive failed.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001728 goto restart;
1729 }
1730
1731 /* Initialize uCode has loaded Runtime uCode ... verify inst image.
1732 * This is a paranoid check, because we would not have gotten the
1733 * "runtime" alive if code weren't properly loaded. */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001734 if (il4965_verify_ucode(priv)) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001735 /* Runtime instruction load was bad;
1736 * take it all the way back down so we can try again */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001737 IL_DEBUG_INFO(priv, "Bad runtime uCode load.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001738 goto restart;
1739 }
1740
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001741 ret = il4965_alive_notify(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001742 if (ret) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001743 IL_WARN(priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001744 "Could not complete ALIVE transition [ntf]: %d\n", ret);
1745 goto restart;
1746 }
1747
1748
1749 /* After the ALIVE response, we can send host commands to the uCode */
1750 set_bit(STATUS_ALIVE, &priv->status);
1751
1752 /* Enable watchdog to monitor the driver tx queues */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001753 il_setup_watchdog(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001754
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001755 if (il_is_rfkill(priv))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001756 return;
1757
1758 ieee80211_wake_queues(priv->hw);
1759
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001760 priv->active_rate = IL_RATES_MASK;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001761
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001762 if (il_is_associated_ctx(ctx)) {
1763 struct il_rxon_cmd *active_rxon =
1764 (struct il_rxon_cmd *)&ctx->active;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001765 /* apply any changes in staging */
1766 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
1767 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1768 } else {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001769 struct il_rxon_context *tmp;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001770 /* Initialize our rx_config data */
1771 for_each_context(priv, tmp)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001772 il_connection_init_rx_config(priv, tmp);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001773
1774 if (priv->cfg->ops->hcmd->set_rxon_chain)
1775 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
1776 }
1777
1778 /* Configure bluetooth coexistence if enabled */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001779 il_send_bt_config(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001780
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001781 il4965_reset_run_time_calib(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001782
1783 set_bit(STATUS_READY, &priv->status);
1784
1785 /* Configure the adapter for unassociated operation */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001786 il_commit_rxon(priv, ctx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001787
1788 /* At this point, the NIC is initialized and operational */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001789 il4965_rf_kill_ct_config(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001790
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001791 IL_DEBUG_INFO(priv, "ALIVE processing complete.\n");
Stanislaw Gruszka65d0f192011-09-20 16:49:03 +02001792 wake_up(&priv->wait_command_queue);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001793
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001794 il_power_update_mode(priv, true);
1795 IL_DEBUG_INFO(priv, "Updated power mode\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001796
1797 return;
1798
1799 restart:
1800 queue_work(priv->workqueue, &priv->restart);
1801}
1802
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001803static void il4965_cancel_deferred_work(struct il_priv *priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001804
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001805static void __il4965_down(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001806{
1807 unsigned long flags;
Stanislaw Gruszkaab42b402011-04-28 11:51:24 +02001808 int exit_pending;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001809
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001810 IL_DEBUG_INFO(priv, DRV_NAME " is going down\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001811
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001812 il_scan_cancel_timeout(priv, 200);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001813
1814 exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &priv->status);
1815
1816 /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set
1817 * to prevent rearm timer */
1818 del_timer_sync(&priv->watchdog);
1819
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001820 il_clear_ucode_stations(priv, NULL);
1821 il_dealloc_bcast_stations(priv);
1822 il_clear_driver_stations(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001823
1824 /* Unblock any waiting calls */
Stanislaw Gruszka65d0f192011-09-20 16:49:03 +02001825 wake_up_all(&priv->wait_command_queue);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001826
1827 /* Wipe out the EXIT_PENDING status bit if we are not actually
1828 * exiting the module */
1829 if (!exit_pending)
1830 clear_bit(STATUS_EXIT_PENDING, &priv->status);
1831
1832 /* stop and reset the on-board processor */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001833 il_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001834
1835 /* tell the device to stop sending interrupts */
1836 spin_lock_irqsave(&priv->lock, flags);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001837 il_disable_interrupts(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001838 spin_unlock_irqrestore(&priv->lock, flags);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001839 il4965_synchronize_irq(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001840
1841 if (priv->mac80211_registered)
1842 ieee80211_stop_queues(priv->hw);
1843
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001844 /* If we have not previously called il_init() then
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001845 * clear all bits but the RF Kill bit and return */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001846 if (!il_is_init(priv)) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001847 priv->status = test_bit(STATUS_RF_KILL_HW, &priv->status) <<
1848 STATUS_RF_KILL_HW |
1849 test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
1850 STATUS_GEO_CONFIGURED |
1851 test_bit(STATUS_EXIT_PENDING, &priv->status) <<
1852 STATUS_EXIT_PENDING;
1853 goto exit;
1854 }
1855
1856 /* ...otherwise clear out all the status bits but the RF Kill
1857 * bit and continue taking the NIC down. */
1858 priv->status &= test_bit(STATUS_RF_KILL_HW, &priv->status) <<
1859 STATUS_RF_KILL_HW |
1860 test_bit(STATUS_GEO_CONFIGURED, &priv->status) <<
1861 STATUS_GEO_CONFIGURED |
1862 test_bit(STATUS_FW_ERROR, &priv->status) <<
1863 STATUS_FW_ERROR |
1864 test_bit(STATUS_EXIT_PENDING, &priv->status) <<
1865 STATUS_EXIT_PENDING;
1866
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001867 il4965_txq_ctx_stop(priv);
1868 il4965_rxq_stop(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001869
1870 /* Power-down device's busmaster DMA clocks */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001871 il_write_prph(priv, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001872 udelay(5);
1873
1874 /* Make sure (redundant) we've released our request to stay awake */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001875 il_clear_bit(priv, CSR_GP_CNTRL,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001876 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1877
1878 /* Stop the device, and put it in low power state */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001879 il_apm_stop(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001880
1881 exit:
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001882 memset(&priv->card_alive, 0, sizeof(struct il_alive_resp));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001883
1884 dev_kfree_skb(priv->beacon_skb);
1885 priv->beacon_skb = NULL;
1886
1887 /* clear out any free frames */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001888 il4965_clear_free_frames(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001889}
1890
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001891static void il4965_down(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001892{
1893 mutex_lock(&priv->mutex);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001894 __il4965_down(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001895 mutex_unlock(&priv->mutex);
1896
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001897 il4965_cancel_deferred_work(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001898}
1899
1900#define HW_READY_TIMEOUT (50)
1901
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001902static int il4965_set_hw_ready(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001903{
1904 int ret = 0;
1905
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001906 il_set_bit(priv, CSR_HW_IF_CONFIG_REG,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001907 CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
1908
1909 /* See if we got it */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001910 ret = il_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001911 CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
1912 CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
1913 HW_READY_TIMEOUT);
1914 if (ret != -ETIMEDOUT)
1915 priv->hw_ready = true;
1916 else
1917 priv->hw_ready = false;
1918
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001919 IL_DEBUG_INFO(priv, "hardware %s\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001920 (priv->hw_ready == 1) ? "ready" : "not ready");
1921 return ret;
1922}
1923
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001924static int il4965_prepare_card_hw(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001925{
1926 int ret = 0;
1927
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001928 IL_DEBUG_INFO(priv, "il4965_prepare_card_hw enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001929
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001930 ret = il4965_set_hw_ready(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001931 if (priv->hw_ready)
1932 return ret;
1933
1934 /* If HW is not ready, prepare the conditions to check again */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001935 il_set_bit(priv, CSR_HW_IF_CONFIG_REG,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001936 CSR_HW_IF_CONFIG_REG_PREPARE);
1937
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001938 ret = il_poll_bit(priv, CSR_HW_IF_CONFIG_REG,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001939 ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE,
1940 CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000);
1941
1942 /* HW should be ready by now, check again. */
1943 if (ret != -ETIMEDOUT)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001944 il4965_set_hw_ready(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001945
1946 return ret;
1947}
1948
1949#define MAX_HW_RESTARTS 5
1950
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001951static int __il4965_up(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001952{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001953 struct il_rxon_context *ctx;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001954 int i;
1955 int ret;
1956
1957 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001958 IL_WARN(priv, "Exit pending; will not bring the NIC up\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001959 return -EIO;
1960 }
1961
1962 if (!priv->ucode_data_backup.v_addr || !priv->ucode_data.v_addr) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001963 IL_ERR(priv, "ucode not available for device bringup\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001964 return -EIO;
1965 }
1966
1967 for_each_context(priv, ctx) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001968 ret = il4965_alloc_bcast_station(priv, ctx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001969 if (ret) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001970 il_dealloc_bcast_stations(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001971 return ret;
1972 }
1973 }
1974
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001975 il4965_prepare_card_hw(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001976
1977 if (!priv->hw_ready) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001978 IL_WARN(priv, "Exit HW not ready\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001979 return -EIO;
1980 }
1981
1982 /* If platform's RF_KILL switch is NOT set to KILL */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001983 if (il_read32(priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001984 CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
1985 clear_bit(STATUS_RF_KILL_HW, &priv->status);
1986 else
1987 set_bit(STATUS_RF_KILL_HW, &priv->status);
1988
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001989 if (il_is_rfkill(priv)) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001990 wiphy_rfkill_set_hw_state(priv->hw->wiphy, true);
1991
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001992 il_enable_interrupts(priv);
1993 IL_WARN(priv, "Radio disabled by HW RF Kill switch\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001994 return 0;
1995 }
1996
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001997 il_write32(priv, CSR_INT, 0xFFFFFFFF);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001998
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001999 /* must be initialised before il_hw_nic_init */
2000 priv->cmd_queue = IL_DEFAULT_CMD_QUEUE_NUM;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002001
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002002 ret = il4965_hw_nic_init(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002003 if (ret) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002004 IL_ERR(priv, "Unable to init nic\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002005 return ret;
2006 }
2007
2008 /* make sure rfkill handshake bits are cleared */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002009 il_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
2010 il_write32(priv, CSR_UCODE_DRV_GP1_CLR,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002011 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
2012
2013 /* clear (again), then enable host interrupts */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002014 il_write32(priv, CSR_INT, 0xFFFFFFFF);
2015 il_enable_interrupts(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002016
2017 /* really make sure rfkill handshake bits are cleared */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002018 il_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
2019 il_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002020
2021 /* Copy original ucode data image from disk into backup cache.
2022 * This will be used to initialize the on-board processor's
2023 * data SRAM for a clean start when the runtime program first loads. */
2024 memcpy(priv->ucode_data_backup.v_addr, priv->ucode_data.v_addr,
2025 priv->ucode_data.len);
2026
2027 for (i = 0; i < MAX_HW_RESTARTS; i++) {
2028
2029 /* load bootstrap state machine,
2030 * load bootstrap program into processor's memory,
2031 * prepare to load the "initialize" uCode */
2032 ret = priv->cfg->ops->lib->load_ucode(priv);
2033
2034 if (ret) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002035 IL_ERR(priv, "Unable to set up bootstrap uCode: %d\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002036 ret);
2037 continue;
2038 }
2039
2040 /* start card; "initialize" will load runtime ucode */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002041 il4965_nic_start(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002042
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002043 IL_DEBUG_INFO(priv, DRV_NAME " is coming up\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002044
2045 return 0;
2046 }
2047
2048 set_bit(STATUS_EXIT_PENDING, &priv->status);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002049 __il4965_down(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002050 clear_bit(STATUS_EXIT_PENDING, &priv->status);
2051
2052 /* tried to restart and config the device for as long as our
2053 * patience could withstand */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002054 IL_ERR(priv, "Unable to initialize device after %d attempts.\n", i);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002055 return -EIO;
2056}
2057
2058
2059/*****************************************************************************
2060 *
2061 * Workqueue callbacks
2062 *
2063 *****************************************************************************/
2064
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002065static void il4965_bg_init_alive_start(struct work_struct *data)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002066{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002067 struct il_priv *priv =
2068 container_of(data, struct il_priv, init_alive_start.work);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002069
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002070 mutex_lock(&priv->mutex);
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002071 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2072 goto out;
2073
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002074 priv->cfg->ops->lib->init_alive_start(priv);
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002075out:
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002076 mutex_unlock(&priv->mutex);
2077}
2078
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002079static void il4965_bg_alive_start(struct work_struct *data)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002080{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002081 struct il_priv *priv =
2082 container_of(data, struct il_priv, alive_start.work);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002083
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002084 mutex_lock(&priv->mutex);
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002085 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2086 goto out;
2087
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002088 il4965_alive_start(priv);
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002089out:
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002090 mutex_unlock(&priv->mutex);
2091}
2092
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002093static void il4965_bg_run_time_calib_work(struct work_struct *work)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002094{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002095 struct il_priv *priv = container_of(work, struct il_priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002096 run_time_calib_work);
2097
2098 mutex_lock(&priv->mutex);
2099
2100 if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
2101 test_bit(STATUS_SCANNING, &priv->status)) {
2102 mutex_unlock(&priv->mutex);
2103 return;
2104 }
2105
2106 if (priv->start_calib) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002107 il4965_chain_noise_calibration(priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002108 (void *)&priv->_4965.statistics);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002109 il4965_sensitivity_calibration(priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002110 (void *)&priv->_4965.statistics);
2111 }
2112
2113 mutex_unlock(&priv->mutex);
2114}
2115
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002116static void il4965_bg_restart(struct work_struct *data)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002117{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002118 struct il_priv *priv = container_of(data, struct il_priv, restart);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002119
2120 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2121 return;
2122
2123 if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002124 struct il_rxon_context *ctx;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002125
2126 mutex_lock(&priv->mutex);
2127 for_each_context(priv, ctx)
2128 ctx->vif = NULL;
2129 priv->is_open = 0;
2130
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002131 __il4965_down(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002132
2133 mutex_unlock(&priv->mutex);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002134 il4965_cancel_deferred_work(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002135 ieee80211_restart_hw(priv->hw);
2136 } else {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002137 il4965_down(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002138
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002139 mutex_lock(&priv->mutex);
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002140 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
2141 mutex_unlock(&priv->mutex);
2142 return;
2143 }
2144
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002145 __il4965_up(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002146 mutex_unlock(&priv->mutex);
2147 }
2148}
2149
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002150static void il4965_bg_rx_replenish(struct work_struct *data)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002151{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002152 struct il_priv *priv =
2153 container_of(data, struct il_priv, rx_replenish);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002154
2155 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2156 return;
2157
2158 mutex_lock(&priv->mutex);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002159 il4965_rx_replenish(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002160 mutex_unlock(&priv->mutex);
2161}
2162
2163/*****************************************************************************
2164 *
2165 * mac80211 entry point functions
2166 *
2167 *****************************************************************************/
2168
2169#define UCODE_READY_TIMEOUT (4 * HZ)
2170
2171/*
2172 * Not a mac80211 entry point function, but it fits in with all the
2173 * other mac80211 functions grouped here.
2174 */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002175static int il4965_mac_setup_register(struct il_priv *priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002176 u32 max_probe_length)
2177{
2178 int ret;
2179 struct ieee80211_hw *hw = priv->hw;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002180 struct il_rxon_context *ctx;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002181
2182 hw->rate_control_algorithm = "iwl-4965-rs";
2183
2184 /* Tell mac80211 our characteristics */
2185 hw->flags = IEEE80211_HW_SIGNAL_DBM |
2186 IEEE80211_HW_AMPDU_AGGREGATION |
2187 IEEE80211_HW_NEED_DTIM_PERIOD |
2188 IEEE80211_HW_SPECTRUM_MGMT |
2189 IEEE80211_HW_REPORTS_TX_ACK_STATUS;
2190
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002191 if (priv->cfg->sku & IL_SKU_N)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002192 hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
2193 IEEE80211_HW_SUPPORTS_STATIC_SMPS;
2194
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002195 hw->sta_data_size = sizeof(struct il_station_priv);
2196 hw->vif_data_size = sizeof(struct il_vif_priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002197
2198 for_each_context(priv, ctx) {
2199 hw->wiphy->interface_modes |= ctx->interface_modes;
2200 hw->wiphy->interface_modes |= ctx->exclusive_interface_modes;
2201 }
2202
2203 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
2204 WIPHY_FLAG_DISABLE_BEACON_HINTS;
2205
2206 /*
2207 * For now, disable PS by default because it affects
2208 * RX performance significantly.
2209 */
2210 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
2211
2212 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
2213 /* we create the 802.11 header and a zero-length SSID element */
2214 hw->wiphy->max_scan_ie_len = max_probe_length - 24 - 2;
2215
2216 /* Default value; 4 EDCA QOS priorities */
2217 hw->queues = 4;
2218
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002219 hw->max_listen_interval = IL_CONN_MAX_LISTEN_INTERVAL;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002220
2221 if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
2222 priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
2223 &priv->bands[IEEE80211_BAND_2GHZ];
2224 if (priv->bands[IEEE80211_BAND_5GHZ].n_channels)
2225 priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
2226 &priv->bands[IEEE80211_BAND_5GHZ];
2227
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002228 il_leds_init(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002229
2230 ret = ieee80211_register_hw(priv->hw);
2231 if (ret) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002232 IL_ERR(priv, "Failed to register hw (error %d)\n", ret);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002233 return ret;
2234 }
2235 priv->mac80211_registered = 1;
2236
2237 return 0;
2238}
2239
2240
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002241int il4965_mac_start(struct ieee80211_hw *hw)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002242{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002243 struct il_priv *priv = hw->priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002244 int ret;
2245
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002246 IL_DEBUG_MAC80211(priv, "enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002247
2248 /* we should be verifying the device is ready to be opened */
2249 mutex_lock(&priv->mutex);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002250 ret = __il4965_up(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002251 mutex_unlock(&priv->mutex);
2252
2253 if (ret)
2254 return ret;
2255
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002256 if (il_is_rfkill(priv))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002257 goto out;
2258
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002259 IL_DEBUG_INFO(priv, "Start UP work done.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002260
2261 /* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from
2262 * mac80211 will not be run successfully. */
Stanislaw Gruszka65d0f192011-09-20 16:49:03 +02002263 ret = wait_event_timeout(priv->wait_command_queue,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002264 test_bit(STATUS_READY, &priv->status),
2265 UCODE_READY_TIMEOUT);
2266 if (!ret) {
2267 if (!test_bit(STATUS_READY, &priv->status)) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002268 IL_ERR(priv, "START_ALIVE timeout after %dms.\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002269 jiffies_to_msecs(UCODE_READY_TIMEOUT));
2270 return -ETIMEDOUT;
2271 }
2272 }
2273
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002274 il4965_led_enable(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002275
2276out:
2277 priv->is_open = 1;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002278 IL_DEBUG_MAC80211(priv, "leave\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002279 return 0;
2280}
2281
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002282void il4965_mac_stop(struct ieee80211_hw *hw)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002283{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002284 struct il_priv *priv = hw->priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002285
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002286 IL_DEBUG_MAC80211(priv, "enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002287
2288 if (!priv->is_open)
2289 return;
2290
2291 priv->is_open = 0;
2292
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002293 il4965_down(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002294
2295 flush_workqueue(priv->workqueue);
2296
Stanislaw Gruszkaa078a1f2011-04-28 11:51:25 +02002297 /* User space software may expect getting rfkill changes
2298 * even if interface is down */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002299 il_write32(priv, CSR_INT, 0xFFFFFFFF);
2300 il_enable_rfkill_int(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002301
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002302 IL_DEBUG_MAC80211(priv, "leave\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002303}
2304
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002305void il4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002306{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002307 struct il_priv *priv = hw->priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002308
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002309 IL_DEBUG_MACDUMP(priv, "enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002310
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002311 IL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002312 ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
2313
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002314 if (il4965_tx_skb(priv, skb))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002315 dev_kfree_skb_any(skb);
2316
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002317 IL_DEBUG_MACDUMP(priv, "leave\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002318}
2319
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002320void il4965_mac_update_tkip_key(struct ieee80211_hw *hw,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002321 struct ieee80211_vif *vif,
2322 struct ieee80211_key_conf *keyconf,
2323 struct ieee80211_sta *sta,
2324 u32 iv32, u16 *phase1key)
2325{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002326 struct il_priv *priv = hw->priv;
2327 struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002328
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002329 IL_DEBUG_MAC80211(priv, "enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002330
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002331 il4965_update_tkip_key(priv, vif_priv->ctx, keyconf, sta,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002332 iv32, phase1key);
2333
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002334 IL_DEBUG_MAC80211(priv, "leave\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002335}
2336
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002337int il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002338 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
2339 struct ieee80211_key_conf *key)
2340{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002341 struct il_priv *priv = hw->priv;
2342 struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
2343 struct il_rxon_context *ctx = vif_priv->ctx;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002344 int ret;
2345 u8 sta_id;
2346 bool is_default_wep_key = false;
2347
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002348 IL_DEBUG_MAC80211(priv, "enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002349
2350 if (priv->cfg->mod_params->sw_crypto) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002351 IL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002352 return -EOPNOTSUPP;
2353 }
2354
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002355 sta_id = il_sta_id_or_broadcast(priv, vif_priv->ctx, sta);
2356 if (sta_id == IL_INVALID_STATION)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002357 return -EINVAL;
2358
2359 mutex_lock(&priv->mutex);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002360 il_scan_cancel_timeout(priv, 100);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002361
2362 /*
2363 * If we are getting WEP group key and we didn't receive any key mapping
2364 * so far, we are in legacy wep mode (group key only), otherwise we are
2365 * in 1X mode.
2366 * In legacy wep mode, we use another host command to the uCode.
2367 */
2368 if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
2369 key->cipher == WLAN_CIPHER_SUITE_WEP104) &&
2370 !sta) {
2371 if (cmd == SET_KEY)
2372 is_default_wep_key = !ctx->key_mapping_keys;
2373 else
2374 is_default_wep_key =
2375 (key->hw_key_idx == HW_KEY_DEFAULT);
2376 }
2377
2378 switch (cmd) {
2379 case SET_KEY:
2380 if (is_default_wep_key)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002381 ret = il4965_set_default_wep_key(priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002382 vif_priv->ctx, key);
2383 else
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002384 ret = il4965_set_dynamic_key(priv, vif_priv->ctx,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002385 key, sta_id);
2386
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002387 IL_DEBUG_MAC80211(priv, "enable hwcrypto key\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002388 break;
2389 case DISABLE_KEY:
2390 if (is_default_wep_key)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002391 ret = il4965_remove_default_wep_key(priv, ctx, key);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002392 else
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002393 ret = il4965_remove_dynamic_key(priv, ctx,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002394 key, sta_id);
2395
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002396 IL_DEBUG_MAC80211(priv, "disable hwcrypto key\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002397 break;
2398 default:
2399 ret = -EINVAL;
2400 }
2401
2402 mutex_unlock(&priv->mutex);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002403 IL_DEBUG_MAC80211(priv, "leave\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002404
2405 return ret;
2406}
2407
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002408int il4965_mac_ampdu_action(struct ieee80211_hw *hw,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002409 struct ieee80211_vif *vif,
2410 enum ieee80211_ampdu_mlme_action action,
2411 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
2412 u8 buf_size)
2413{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002414 struct il_priv *priv = hw->priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002415 int ret = -EINVAL;
2416
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002417 IL_DEBUG_HT(priv, "A-MPDU action on addr %pM tid %d\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002418 sta->addr, tid);
2419
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002420 if (!(priv->cfg->sku & IL_SKU_N))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002421 return -EACCES;
2422
2423 mutex_lock(&priv->mutex);
2424
2425 switch (action) {
2426 case IEEE80211_AMPDU_RX_START:
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002427 IL_DEBUG_HT(priv, "start Rx\n");
2428 ret = il4965_sta_rx_agg_start(priv, sta, tid, *ssn);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002429 break;
2430 case IEEE80211_AMPDU_RX_STOP:
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002431 IL_DEBUG_HT(priv, "stop Rx\n");
2432 ret = il4965_sta_rx_agg_stop(priv, sta, tid);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002433 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2434 ret = 0;
2435 break;
2436 case IEEE80211_AMPDU_TX_START:
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002437 IL_DEBUG_HT(priv, "start Tx\n");
2438 ret = il4965_tx_agg_start(priv, vif, sta, tid, ssn);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002439 break;
2440 case IEEE80211_AMPDU_TX_STOP:
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002441 IL_DEBUG_HT(priv, "stop Tx\n");
2442 ret = il4965_tx_agg_stop(priv, vif, sta, tid);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002443 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2444 ret = 0;
2445 break;
2446 case IEEE80211_AMPDU_TX_OPERATIONAL:
2447 ret = 0;
2448 break;
2449 }
2450 mutex_unlock(&priv->mutex);
2451
2452 return ret;
2453}
2454
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002455int il4965_mac_sta_add(struct ieee80211_hw *hw,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002456 struct ieee80211_vif *vif,
2457 struct ieee80211_sta *sta)
2458{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002459 struct il_priv *priv = hw->priv;
2460 struct il_station_priv *sta_priv = (void *)sta->drv_priv;
2461 struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002462 bool is_ap = vif->type == NL80211_IFTYPE_STATION;
2463 int ret;
2464 u8 sta_id;
2465
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002466 IL_DEBUG_INFO(priv, "received request to add station %pM\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002467 sta->addr);
2468 mutex_lock(&priv->mutex);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002469 IL_DEBUG_INFO(priv, "proceeding to add station %pM\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002470 sta->addr);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002471 sta_priv->common.sta_id = IL_INVALID_STATION;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002472
2473 atomic_set(&sta_priv->pending_frames, 0);
2474
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002475 ret = il_add_station_common(priv, vif_priv->ctx, sta->addr,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002476 is_ap, sta, &sta_id);
2477 if (ret) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002478 IL_ERR(priv, "Unable to add station %pM (%d)\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002479 sta->addr, ret);
2480 /* Should we return success if return code is EEXIST ? */
2481 mutex_unlock(&priv->mutex);
2482 return ret;
2483 }
2484
2485 sta_priv->common.sta_id = sta_id;
2486
2487 /* Initialize rate scaling */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002488 IL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002489 sta->addr);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002490 il4965_rs_rate_init(priv, sta, sta_id);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002491 mutex_unlock(&priv->mutex);
2492
2493 return 0;
2494}
2495
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002496void il4965_mac_channel_switch(struct ieee80211_hw *hw,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002497 struct ieee80211_channel_switch *ch_switch)
2498{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002499 struct il_priv *priv = hw->priv;
2500 const struct il_channel_info *ch_info;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002501 struct ieee80211_conf *conf = &hw->conf;
2502 struct ieee80211_channel *channel = ch_switch->channel;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002503 struct il_ht_config *ht_conf = &priv->current_ht_config;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002504
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002505 struct il_rxon_context *ctx = &priv->contexts[IL_RXON_CTX_BSS];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002506 u16 ch;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002507
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002508 IL_DEBUG_MAC80211(priv, "enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002509
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002510 mutex_lock(&priv->mutex);
2511
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002512 if (il_is_rfkill(priv))
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002513 goto out;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002514
2515 if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
Stanislaw Gruszka51e65252011-06-08 15:26:31 +02002516 test_bit(STATUS_SCANNING, &priv->status) ||
2517 test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status))
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002518 goto out;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002519
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002520 if (!il_is_associated_ctx(ctx))
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002521 goto out;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002522
Dan Carpentera6f0f042011-06-15 16:10:10 +03002523 if (!priv->cfg->ops->lib->set_channel_switch)
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02002524 goto out;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002525
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02002526 ch = channel->hw_value;
2527 if (le16_to_cpu(ctx->active.channel) == ch)
2528 goto out;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002529
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002530 ch_info = il_get_channel_info(priv, channel->band, ch);
2531 if (!il_is_channel_valid(ch_info)) {
2532 IL_DEBUG_MAC80211(priv, "invalid channel\n");
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02002533 goto out;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002534 }
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02002535
Dan Carpentera6f0f042011-06-15 16:10:10 +03002536 spin_lock_irq(&priv->lock);
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02002537
2538 priv->current_ht_config.smps = conf->smps_mode;
2539
2540 /* Configure HT40 channels */
2541 ctx->ht.enabled = conf_is_ht(conf);
2542 if (ctx->ht.enabled) {
2543 if (conf_is_ht40_minus(conf)) {
2544 ctx->ht.extension_chan_offset =
2545 IEEE80211_HT_PARAM_CHA_SEC_BELOW;
2546 ctx->ht.is_40mhz = true;
2547 } else if (conf_is_ht40_plus(conf)) {
2548 ctx->ht.extension_chan_offset =
2549 IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
2550 ctx->ht.is_40mhz = true;
2551 } else {
2552 ctx->ht.extension_chan_offset =
2553 IEEE80211_HT_PARAM_CHA_SEC_NONE;
2554 ctx->ht.is_40mhz = false;
2555 }
2556 } else
2557 ctx->ht.is_40mhz = false;
2558
2559 if ((le16_to_cpu(ctx->staging.channel) != ch))
2560 ctx->staging.flags = 0;
2561
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002562 il_set_rxon_channel(priv, channel, ctx);
2563 il_set_rxon_ht(priv, ht_conf);
2564 il_set_flags_for_band(priv, ctx, channel->band, ctx->vif);
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02002565
2566 spin_unlock_irq(&priv->lock);
2567
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002568 il_set_rate(priv);
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02002569 /*
2570 * at this point, staging_rxon has the
2571 * configuration for channel switch
2572 */
2573 set_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status);
2574 priv->switch_channel = cpu_to_le16(ch);
2575 if (priv->cfg->ops->lib->set_channel_switch(priv, ch_switch)) {
2576 clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status);
2577 priv->switch_channel = 0;
2578 ieee80211_chswitch_done(ctx->vif, false);
2579 }
2580
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002581out:
2582 mutex_unlock(&priv->mutex);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002583 IL_DEBUG_MAC80211(priv, "leave\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002584}
2585
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002586void il4965_configure_filter(struct ieee80211_hw *hw,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002587 unsigned int changed_flags,
2588 unsigned int *total_flags,
2589 u64 multicast)
2590{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002591 struct il_priv *priv = hw->priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002592 __le32 filter_or = 0, filter_nand = 0;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002593 struct il_rxon_context *ctx;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002594
2595#define CHK(test, flag) do { \
2596 if (*total_flags & (test)) \
2597 filter_or |= (flag); \
2598 else \
2599 filter_nand |= (flag); \
2600 } while (0)
2601
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002602 IL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002603 changed_flags, *total_flags);
2604
2605 CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK);
2606 /* Setting _just_ RXON_FILTER_CTL2HOST_MSK causes FH errors */
2607 CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_PROMISC_MSK);
2608 CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK);
2609
2610#undef CHK
2611
2612 mutex_lock(&priv->mutex);
2613
2614 for_each_context(priv, ctx) {
2615 ctx->staging.filter_flags &= ~filter_nand;
2616 ctx->staging.filter_flags |= filter_or;
2617
2618 /*
2619 * Not committing directly because hardware can perform a scan,
2620 * but we'll eventually commit the filter flags change anyway.
2621 */
2622 }
2623
2624 mutex_unlock(&priv->mutex);
2625
2626 /*
2627 * Receiving all multicast frames is always enabled by the
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002628 * default flags setup in il_connection_init_rx_config()
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002629 * since we currently do not support programming multicast
2630 * filters into the device.
2631 */
2632 *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
2633 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
2634}
2635
2636/*****************************************************************************
2637 *
2638 * driver setup and teardown
2639 *
2640 *****************************************************************************/
2641
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002642static void il4965_bg_txpower_work(struct work_struct *work)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002643{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002644 struct il_priv *priv = container_of(work, struct il_priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002645 txpower_work);
2646
Stanislaw Gruszkaf3257572011-04-28 11:36:54 +02002647 mutex_lock(&priv->mutex);
2648
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002649 /* If a scan happened to start before we got here
2650 * then just return; the statistics notification will
2651 * kick off another scheduled work to compensate for
2652 * any temperature delta we missed here. */
2653 if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
2654 test_bit(STATUS_SCANNING, &priv->status))
Stanislaw Gruszkaf3257572011-04-28 11:36:54 +02002655 goto out;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002656
2657 /* Regardless of if we are associated, we must reconfigure the
2658 * TX power since frames can be sent on non-radar channels while
2659 * not associated */
2660 priv->cfg->ops->lib->send_tx_power(priv);
2661
2662 /* Update last_temperature to keep is_calib_needed from running
2663 * when it isn't needed... */
2664 priv->last_temperature = priv->temperature;
Stanislaw Gruszkaf3257572011-04-28 11:36:54 +02002665out:
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002666 mutex_unlock(&priv->mutex);
2667}
2668
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002669static void il4965_setup_deferred_work(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002670{
2671 priv->workqueue = create_singlethread_workqueue(DRV_NAME);
2672
2673 init_waitqueue_head(&priv->wait_command_queue);
2674
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002675 INIT_WORK(&priv->restart, il4965_bg_restart);
2676 INIT_WORK(&priv->rx_replenish, il4965_bg_rx_replenish);
2677 INIT_WORK(&priv->run_time_calib_work, il4965_bg_run_time_calib_work);
2678 INIT_DELAYED_WORK(&priv->init_alive_start, il4965_bg_init_alive_start);
2679 INIT_DELAYED_WORK(&priv->alive_start, il4965_bg_alive_start);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002680
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002681 il_setup_scan_deferred_work(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002682
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002683 INIT_WORK(&priv->txpower_work, il4965_bg_txpower_work);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002684
2685 init_timer(&priv->statistics_periodic);
2686 priv->statistics_periodic.data = (unsigned long)priv;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002687 priv->statistics_periodic.function = il4965_bg_statistics_periodic;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002688
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002689 init_timer(&priv->watchdog);
2690 priv->watchdog.data = (unsigned long)priv;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002691 priv->watchdog.function = il_bg_watchdog;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002692
2693 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002694 il4965_irq_tasklet, (unsigned long)priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002695}
2696
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002697static void il4965_cancel_deferred_work(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002698{
2699 cancel_work_sync(&priv->txpower_work);
2700 cancel_delayed_work_sync(&priv->init_alive_start);
2701 cancel_delayed_work(&priv->alive_start);
2702 cancel_work_sync(&priv->run_time_calib_work);
2703
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002704 il_cancel_scan_deferred_work(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002705
2706 del_timer_sync(&priv->statistics_periodic);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002707}
2708
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002709static void il4965_init_hw_rates(struct il_priv *priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002710 struct ieee80211_rate *rates)
2711{
2712 int i;
2713
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002714 for (i = 0; i < IL_RATE_COUNT_LEGACY; i++) {
John W. Linvilleef334172011-02-25 15:51:01 -05002715 rates[i].bitrate = iwlegacy_rates[i].ieee * 5;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002716 rates[i].hw_value = i; /* Rate scaling will work on indexes */
2717 rates[i].hw_value_short = i;
2718 rates[i].flags = 0;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002719 if ((i >= IL_FIRST_CCK_RATE) && (i <= IL_LAST_CCK_RATE)) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002720 /*
2721 * If CCK != 1M then set short preamble rate flag.
2722 */
2723 rates[i].flags |=
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002724 (iwlegacy_rates[i].plcp == IL_RATE_1M_PLCP) ?
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002725 0 : IEEE80211_RATE_SHORT_PREAMBLE;
2726 }
2727 }
2728}
2729/*
2730 * Acquire priv->lock before calling this function !
2731 */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002732void il4965_set_wr_ptrs(struct il_priv *priv, int txq_id, u32 index)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002733{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002734 il_write_direct32(priv, HBUS_TARG_WRPTR,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002735 (index & 0xff) | (txq_id << 8));
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002736 il_write_prph(priv, IWL49_SCD_QUEUE_RDPTR(txq_id), index);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002737}
2738
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002739void il4965_tx_queue_set_status(struct il_priv *priv,
2740 struct il_tx_queue *txq,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002741 int tx_fifo_id, int scd_retry)
2742{
2743 int txq_id = txq->q.id;
2744
2745 /* Find out whether to activate Tx queue */
2746 int active = test_bit(txq_id, &priv->txq_ctx_active_msk) ? 1 : 0;
2747
2748 /* Set up and activate */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002749 il_write_prph(priv, IWL49_SCD_QUEUE_STATUS_BITS(txq_id),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002750 (active << IWL49_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
2751 (tx_fifo_id << IWL49_SCD_QUEUE_STTS_REG_POS_TXF) |
2752 (scd_retry << IWL49_SCD_QUEUE_STTS_REG_POS_WSL) |
2753 (scd_retry << IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACK) |
2754 IWL49_SCD_QUEUE_STTS_REG_MSK);
2755
2756 txq->sched_retry = scd_retry;
2757
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002758 IL_DEBUG_INFO(priv, "%s %s Queue %d on AC %d\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002759 active ? "Activate" : "Deactivate",
2760 scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
2761}
2762
2763
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002764static int il4965_init_drv(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002765{
2766 int ret;
2767
2768 spin_lock_init(&priv->sta_lock);
2769 spin_lock_init(&priv->hcmd_lock);
2770
2771 INIT_LIST_HEAD(&priv->free_frames);
2772
2773 mutex_init(&priv->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002774
2775 priv->ieee_channels = NULL;
2776 priv->ieee_rates = NULL;
2777 priv->band = IEEE80211_BAND_2GHZ;
2778
2779 priv->iw_mode = NL80211_IFTYPE_STATION;
2780 priv->current_ht_config.smps = IEEE80211_SMPS_STATIC;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002781 priv->missed_beacon_threshold = IL_MISSED_BEACON_THRESHOLD_DEF;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002782
2783 /* initialize force reset */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002784 priv->force_reset.reset_duration = IL_DELAY_NEXT_FORCE_FW_RELOAD;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002785
2786 /* Choose which receivers/antennas to use */
2787 if (priv->cfg->ops->hcmd->set_rxon_chain)
2788 priv->cfg->ops->hcmd->set_rxon_chain(priv,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002789 &priv->contexts[IL_RXON_CTX_BSS]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002790
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002791 il_init_scan_params(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002792
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002793 ret = il_init_channel_map(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002794 if (ret) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002795 IL_ERR(priv, "initializing regulatory failed: %d\n", ret);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002796 goto err;
2797 }
2798
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002799 ret = il_init_geos(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002800 if (ret) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002801 IL_ERR(priv, "initializing geos failed: %d\n", ret);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002802 goto err_free_channel_map;
2803 }
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002804 il4965_init_hw_rates(priv, priv->ieee_rates);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002805
2806 return 0;
2807
2808err_free_channel_map:
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002809 il_free_channel_map(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002810err:
2811 return ret;
2812}
2813
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002814static void il4965_uninit_drv(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002815{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002816 il4965_calib_free_results(priv);
2817 il_free_geos(priv);
2818 il_free_channel_map(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002819 kfree(priv->scan_cmd);
2820}
2821
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002822static void il4965_hw_detect(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002823{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002824 priv->hw_rev = _il_read32(priv, CSR_HW_REV);
2825 priv->hw_wa_rev = _il_read32(priv, CSR_HW_REV_WA_REG);
Sergei Shtylyov0477ad72011-04-15 19:23:11 +04002826 priv->rev_id = priv->pci_dev->revision;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002827 IL_DEBUG_INFO(priv, "HW Revision ID = 0x%X\n", priv->rev_id);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002828}
2829
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002830static int il4965_set_hw_params(struct il_priv *priv)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002831{
2832 priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
2833 priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
2834 if (priv->cfg->mod_params->amsdu_size_8K)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002835 priv->hw_params.rx_page_order = get_order(IL_RX_BUF_SIZE_8K);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002836 else
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002837 priv->hw_params.rx_page_order = get_order(IL_RX_BUF_SIZE_4K);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002838
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002839 priv->hw_params.max_beacon_itrvl = IL_MAX_UCODE_BEACON_INTERVAL;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002840
2841 if (priv->cfg->mod_params->disable_11n)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002842 priv->cfg->sku &= ~IL_SKU_N;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002843
2844 /* Device-specific setup */
2845 return priv->cfg->ops->lib->set_hw_params(priv);
2846}
2847
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002848static const u8 il4965_bss_ac_to_fifo[] = {
2849 IL_TX_FIFO_VO,
2850 IL_TX_FIFO_VI,
2851 IL_TX_FIFO_BE,
2852 IL_TX_FIFO_BK,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002853};
2854
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002855static const u8 il4965_bss_ac_to_queue[] = {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002856 0, 1, 2, 3,
2857};
2858
2859static int
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002860il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002861{
2862 int err = 0, i;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002863 struct il_priv *priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002864 struct ieee80211_hw *hw;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002865 struct il_cfg *cfg = (struct il_cfg *)(ent->driver_data);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002866 unsigned long flags;
2867 u16 pci_cmd;
2868
2869 /************************
2870 * 1. Allocating HW data
2871 ************************/
2872
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002873 hw = il_alloc_all(cfg);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002874 if (!hw) {
2875 err = -ENOMEM;
2876 goto out;
2877 }
2878 priv = hw->priv;
2879 /* At this point both hw and priv are allocated. */
2880
2881 /*
2882 * The default context is always valid,
2883 * more may be discovered when firmware
2884 * is loaded.
2885 */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002886 priv->valid_contexts = BIT(IL_RXON_CTX_BSS);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002887
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002888 for (i = 0; i < NUM_IL_RXON_CTX; i++)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002889 priv->contexts[i].ctxid = i;
2890
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002891 priv->contexts[IL_RXON_CTX_BSS].always_active = true;
2892 priv->contexts[IL_RXON_CTX_BSS].is_active = true;
2893 priv->contexts[IL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON;
2894 priv->contexts[IL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING;
2895 priv->contexts[IL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC;
2896 priv->contexts[IL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM;
2897 priv->contexts[IL_RXON_CTX_BSS].ap_sta_id = IL_AP_ID;
2898 priv->contexts[IL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
2899 priv->contexts[IL_RXON_CTX_BSS].ac_to_fifo = il4965_bss_ac_to_fifo;
2900 priv->contexts[IL_RXON_CTX_BSS].ac_to_queue = il4965_bss_ac_to_queue;
2901 priv->contexts[IL_RXON_CTX_BSS].exclusive_interface_modes =
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002902 BIT(NL80211_IFTYPE_ADHOC);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002903 priv->contexts[IL_RXON_CTX_BSS].interface_modes =
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002904 BIT(NL80211_IFTYPE_STATION);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002905 priv->contexts[IL_RXON_CTX_BSS].ap_devtype = RXON_DEV_TYPE_AP;
2906 priv->contexts[IL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS;
2907 priv->contexts[IL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS;
2908 priv->contexts[IL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002909
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002910 BUILD_BUG_ON(NUM_IL_RXON_CTX != 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002911
2912 SET_IEEE80211_DEV(hw, &pdev->dev);
2913
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002914 IL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002915 priv->cfg = cfg;
2916 priv->pci_dev = pdev;
2917 priv->inta_mask = CSR_INI_SET_MASK;
2918
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002919 if (il_alloc_traffic_mem(priv))
2920 IL_ERR(priv, "Not enough memory to generate traffic log\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002921
2922 /**************************
2923 * 2. Initializing PCI bus
2924 **************************/
2925 pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 |
2926 PCIE_LINK_STATE_CLKPM);
2927
2928 if (pci_enable_device(pdev)) {
2929 err = -ENODEV;
2930 goto out_ieee80211_free_hw;
2931 }
2932
2933 pci_set_master(pdev);
2934
2935 err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36));
2936 if (!err)
2937 err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36));
2938 if (err) {
2939 err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
2940 if (!err)
2941 err = pci_set_consistent_dma_mask(pdev,
2942 DMA_BIT_MASK(32));
2943 /* both attempts failed: */
2944 if (err) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002945 IL_WARN(priv, "No suitable DMA available.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002946 goto out_pci_disable_device;
2947 }
2948 }
2949
2950 err = pci_request_regions(pdev, DRV_NAME);
2951 if (err)
2952 goto out_pci_disable_device;
2953
2954 pci_set_drvdata(pdev, priv);
2955
2956
2957 /***********************
2958 * 3. Read REV register
2959 ***********************/
2960 priv->hw_base = pci_iomap(pdev, 0, 0);
2961 if (!priv->hw_base) {
2962 err = -ENODEV;
2963 goto out_pci_release_regions;
2964 }
2965
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002966 IL_DEBUG_INFO(priv, "pci_resource_len = 0x%08llx\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002967 (unsigned long long) pci_resource_len(pdev, 0));
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002968 IL_DEBUG_INFO(priv, "pci_resource_base = %p\n", priv->hw_base);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002969
2970 /* these spin locks will be used in apm_ops.init and EEPROM access
2971 * we should init now
2972 */
2973 spin_lock_init(&priv->reg_lock);
2974 spin_lock_init(&priv->lock);
2975
2976 /*
2977 * stop and reset the on-board processor just in case it is in a
2978 * strange state ... like being left stranded by a primary kernel
2979 * and this is now the kdump kernel trying to start up
2980 */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002981 il_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002982
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002983 il4965_hw_detect(priv);
2984 IL_INFO(priv, "Detected %s, REV=0x%X\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002985 priv->cfg->name, priv->hw_rev);
2986
2987 /* We disable the RETRY_TIMEOUT register (0x41) to keep
2988 * PCI Tx retries from interfering with C3 CPU state */
2989 pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
2990
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002991 il4965_prepare_card_hw(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002992 if (!priv->hw_ready) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002993 IL_WARN(priv, "Failed, HW not ready\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002994 goto out_iounmap;
2995 }
2996
2997 /*****************
2998 * 4. Read EEPROM
2999 *****************/
3000 /* Read the EEPROM */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003001 err = il_eeprom_init(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003002 if (err) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003003 IL_ERR(priv, "Unable to init EEPROM\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003004 goto out_iounmap;
3005 }
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003006 err = il4965_eeprom_check_version(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003007 if (err)
3008 goto out_free_eeprom;
3009
3010 if (err)
3011 goto out_free_eeprom;
3012
3013 /* extract MAC Address */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003014 il4965_eeprom_get_mac(priv, priv->addresses[0].addr);
3015 IL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003016 priv->hw->wiphy->addresses = priv->addresses;
3017 priv->hw->wiphy->n_addresses = 1;
3018
3019 /************************
3020 * 5. Setup HW constants
3021 ************************/
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003022 if (il4965_set_hw_params(priv)) {
3023 IL_ERR(priv, "failed to set hw parameters\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003024 goto out_free_eeprom;
3025 }
3026
3027 /*******************
3028 * 6. Setup priv
3029 *******************/
3030
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003031 err = il4965_init_drv(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003032 if (err)
3033 goto out_free_eeprom;
3034 /* At this point both hw and priv are initialized. */
3035
3036 /********************
3037 * 7. Setup services
3038 ********************/
3039 spin_lock_irqsave(&priv->lock, flags);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003040 il_disable_interrupts(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003041 spin_unlock_irqrestore(&priv->lock, flags);
3042
3043 pci_enable_msi(priv->pci_dev);
3044
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003045 err = request_irq(priv->pci_dev->irq, il_isr,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003046 IRQF_SHARED, DRV_NAME, priv);
3047 if (err) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003048 IL_ERR(priv, "Error allocating IRQ %d\n", priv->pci_dev->irq);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003049 goto out_disable_msi;
3050 }
3051
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003052 il4965_setup_deferred_work(priv);
3053 il4965_setup_rx_handlers(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003054
3055 /*********************************************
3056 * 8. Enable interrupts and read RFKILL state
3057 *********************************************/
3058
Stanislaw Gruszkaa078a1f2011-04-28 11:51:25 +02003059 /* enable rfkill interrupt: hw bug w/a */
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003060 pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd);
3061 if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
3062 pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
3063 pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd);
3064 }
3065
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003066 il_enable_rfkill_int(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003067
3068 /* If platform's RF_KILL switch is NOT set to KILL */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003069 if (il_read32(priv, CSR_GP_CNTRL) &
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003070 CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
3071 clear_bit(STATUS_RF_KILL_HW, &priv->status);
3072 else
3073 set_bit(STATUS_RF_KILL_HW, &priv->status);
3074
3075 wiphy_rfkill_set_hw_state(priv->hw->wiphy,
3076 test_bit(STATUS_RF_KILL_HW, &priv->status));
3077
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003078 il_power_initialize(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003079
3080 init_completion(&priv->_4965.firmware_loading_complete);
3081
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003082 err = il4965_request_firmware(priv, true);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003083 if (err)
3084 goto out_destroy_workqueue;
3085
3086 return 0;
3087
3088 out_destroy_workqueue:
3089 destroy_workqueue(priv->workqueue);
3090 priv->workqueue = NULL;
3091 free_irq(priv->pci_dev->irq, priv);
3092 out_disable_msi:
3093 pci_disable_msi(priv->pci_dev);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003094 il4965_uninit_drv(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003095 out_free_eeprom:
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003096 il_eeprom_free(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003097 out_iounmap:
3098 pci_iounmap(pdev, priv->hw_base);
3099 out_pci_release_regions:
3100 pci_set_drvdata(pdev, NULL);
3101 pci_release_regions(pdev);
3102 out_pci_disable_device:
3103 pci_disable_device(pdev);
3104 out_ieee80211_free_hw:
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003105 il_free_traffic_mem(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003106 ieee80211_free_hw(priv->hw);
3107 out:
3108 return err;
3109}
3110
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003111static void __devexit il4965_pci_remove(struct pci_dev *pdev)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003112{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003113 struct il_priv *priv = pci_get_drvdata(pdev);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003114 unsigned long flags;
3115
3116 if (!priv)
3117 return;
3118
3119 wait_for_completion(&priv->_4965.firmware_loading_complete);
3120
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003121 IL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003122
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003123 il_dbgfs_unregister(priv);
3124 sysfs_remove_group(&pdev->dev.kobj, &il_attribute_group);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003125
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003126 /* ieee80211_unregister_hw call wil cause il_mac_stop to
3127 * to be called and il4965_down since we are removing the device
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003128 * we need to set STATUS_EXIT_PENDING bit.
3129 */
3130 set_bit(STATUS_EXIT_PENDING, &priv->status);
3131
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003132 il_leds_exit(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003133
3134 if (priv->mac80211_registered) {
3135 ieee80211_unregister_hw(priv->hw);
3136 priv->mac80211_registered = 0;
3137 } else {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003138 il4965_down(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003139 }
3140
3141 /*
3142 * Make sure device is reset to low power before unloading driver.
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003143 * This may be redundant with il4965_down(), but there are paths to
3144 * run il4965_down() without calling apm_ops.stop(), and there are
3145 * paths to avoid running il4965_down() at all before leaving driver.
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003146 * This (inexpensive) call *makes sure* device is reset.
3147 */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003148 il_apm_stop(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003149
3150 /* make sure we flush any pending irq or
3151 * tasklet for the driver
3152 */
3153 spin_lock_irqsave(&priv->lock, flags);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003154 il_disable_interrupts(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003155 spin_unlock_irqrestore(&priv->lock, flags);
3156
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003157 il4965_synchronize_irq(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003158
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003159 il4965_dealloc_ucode_pci(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003160
3161 if (priv->rxq.bd)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003162 il4965_rx_queue_free(priv, &priv->rxq);
3163 il4965_hw_txq_ctx_free(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003164
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003165 il_eeprom_free(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003166
3167
3168 /*netif_stop_queue(dev); */
3169 flush_workqueue(priv->workqueue);
3170
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003171 /* ieee80211_unregister_hw calls il_mac_stop, which flushes
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003172 * priv->workqueue... so we can't take down the workqueue
3173 * until now... */
3174 destroy_workqueue(priv->workqueue);
3175 priv->workqueue = NULL;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003176 il_free_traffic_mem(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003177
3178 free_irq(priv->pci_dev->irq, priv);
3179 pci_disable_msi(priv->pci_dev);
3180 pci_iounmap(pdev, priv->hw_base);
3181 pci_release_regions(pdev);
3182 pci_disable_device(pdev);
3183 pci_set_drvdata(pdev, NULL);
3184
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003185 il4965_uninit_drv(priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003186
3187 dev_kfree_skb(priv->beacon_skb);
3188
3189 ieee80211_free_hw(priv->hw);
3190}
3191
3192/*
3193 * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
3194 * must be called under priv->lock and mac access
3195 */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003196void il4965_txq_set_sched(struct il_priv *priv, u32 mask)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003197{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003198 il_write_prph(priv, IWL49_SCD_TXFACT, mask);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003199}
3200
3201/*****************************************************************************
3202 *
3203 * driver and module entry point
3204 *
3205 *****************************************************************************/
3206
3207/* Hardware specific file defines the PCI IDs table for that hardware module */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003208static DEFINE_PCI_DEVICE_TABLE(il4965_hw_card_ids) = {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003209#if defined(CONFIG_IWL4965_MODULE) || defined(CONFIG_IWL4965)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003210 {IL_PCI_DEVICE(0x4229, PCI_ANY_ID, il4965_cfg)},
3211 {IL_PCI_DEVICE(0x4230, PCI_ANY_ID, il4965_cfg)},
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003212#endif /* CONFIG_IWL4965 */
3213
3214 {0}
3215};
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003216MODULE_DEVICE_TABLE(pci, il4965_hw_card_ids);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003217
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003218static struct pci_driver il4965_driver = {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003219 .name = DRV_NAME,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003220 .id_table = il4965_hw_card_ids,
3221 .probe = il4965_pci_probe,
3222 .remove = __devexit_p(il4965_pci_remove),
3223 .driver.pm = IL_LEGACY_PM_OPS,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003224};
3225
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003226static int __init il4965_init(void)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003227{
3228
3229 int ret;
3230 pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n");
3231 pr_info(DRV_COPYRIGHT "\n");
3232
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003233 ret = il4965_rate_control_register();
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003234 if (ret) {
3235 pr_err("Unable to register rate control algorithm: %d\n", ret);
3236 return ret;
3237 }
3238
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003239 ret = pci_register_driver(&il4965_driver);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003240 if (ret) {
3241 pr_err("Unable to initialize PCI module\n");
3242 goto error_register;
3243 }
3244
3245 return ret;
3246
3247error_register:
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003248 il4965_rate_control_unregister();
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003249 return ret;
3250}
3251
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003252static void __exit il4965_exit(void)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003253{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003254 pci_unregister_driver(&il4965_driver);
3255 il4965_rate_control_unregister();
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003256}
3257
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003258module_exit(il4965_exit);
3259module_init(il4965_init);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003260
3261#ifdef CONFIG_IWLWIFI_LEGACY_DEBUG
John W. Linvilleef334172011-02-25 15:51:01 -05003262module_param_named(debug, iwlegacy_debug_level, uint, S_IRUGO | S_IWUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003263MODULE_PARM_DESC(debug, "debug output mask");
3264#endif
3265
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003266module_param_named(swcrypto, il4965_mod_params.sw_crypto, int, S_IRUGO);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003267MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003268module_param_named(queues_num, il4965_mod_params.num_of_queues, int, S_IRUGO);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003269MODULE_PARM_DESC(queues_num, "number of hw queues.");
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003270module_param_named(11n_disable, il4965_mod_params.disable_11n, int, S_IRUGO);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003271MODULE_PARM_DESC(11n_disable, "disable 11n functionality");
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003272module_param_named(amsdu_size_8K, il4965_mod_params.amsdu_size_8K,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003273 int, S_IRUGO);
3274MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003275module_param_named(fw_restart, il4965_mod_params.restart_fw, int, S_IRUGO);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003276MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");