blob: d5f91800d32b658171039bed05c14bfb242c0953 [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
Stanislaw Gruszkad3175162011-11-15 11:25:42 +010075#ifdef CONFIG_IWLEGACY_DEBUG
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080076#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 Gruszka46bc8d42011-10-24 16:49:25 +020090void il4965_update_chain_flags(struct il_priv *il)
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
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +020094 if (il->cfg->ops->hcmd->set_rxon_chain) {
95 for_each_context(il, ctx) {
96 il->cfg->ops->hcmd->set_rxon_chain(il, ctx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080097 if (ctx->active.rx_chain != ctx->staging.rx_chain)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +020098 il_commit_rxon(il, ctx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080099 }
100 }
101}
102
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200103static void il4965_clear_free_frames(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800104{
105 struct list_head *element;
106
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100107 D_INFO("%d frames on pre-allocated heap on clear.\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200108 il->frames_count);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800109
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200110 while (!list_empty(&il->free_frames)) {
111 element = il->free_frames.next;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800112 list_del(element);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200113 kfree(list_entry(element, struct il_frame, list));
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200114 il->frames_count--;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800115 }
116
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200117 if (il->frames_count) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200118 IL_WARN("%d frames still in use. Did we lose one?\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200119 il->frames_count);
120 il->frames_count = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800121 }
122}
123
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200124static struct il_frame *il4965_get_free_frame(struct il_priv *il)
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;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200128 if (list_empty(&il->free_frames)) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800129 frame = kzalloc(sizeof(*frame), GFP_KERNEL);
130 if (!frame) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200131 IL_ERR("Could not allocate frame!\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800132 return NULL;
133 }
134
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200135 il->frames_count++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800136 return frame;
137 }
138
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200139 element = il->free_frames.next;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800140 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 Gruszka46bc8d42011-10-24 16:49:25 +0200144static void il4965_free_frame(struct il_priv *il, struct il_frame *frame)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800145{
146 memset(frame, 0, sizeof(*frame));
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200147 list_add(&frame->list, &il->free_frames);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800148}
149
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200150static u32 il4965_fill_beacon_frame(struct il_priv *il,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800151 struct ieee80211_hdr *hdr,
152 int left)
153{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200154 lockdep_assert_held(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800155
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200156 if (!il->beacon_skb)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800157 return 0;
158
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200159 if (il->beacon_skb->len > left)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800160 return 0;
161
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200162 memcpy(hdr, il->beacon_skb->data, il->beacon_skb->len);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800163
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200164 return il->beacon_skb->len;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800165}
166
167/* Parse the beacon frame to find the TIM element and set tim_idx & tim_size */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200168static void il4965_set_beacon_tim(struct il_priv *il,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200169 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 Gruszka9406f792011-08-18 22:07:57 +0200191 IL_WARN("Unable to find TIM Element in beacon\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800192}
193
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200194static unsigned int il4965_hw_get_beacon_cmd(struct il_priv *il,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200195 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
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200206 lockdep_assert_held(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800207
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200208 if (!il->beacon_ctx) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200209 IL_ERR("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 Gruszka46bc8d42011-10-24 16:49:25 +0200218 frame_size = il4965_fill_beacon_frame(il, 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);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200227 tx_beacon_cmd->tx.sta_id = il->beacon_ctx->bcast_sta_id;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800228 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 Gruszka46bc8d42011-10-24 16:49:25 +0200233 il4965_set_beacon_tim(il, 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 Gruszka46bc8d42011-10-24 16:49:25 +0200237 rate = il_get_lowest_plcp(il, il->beacon_ctx);
238 il->mgmt_tx_ant = il4965_toggle_tx_ant(il, il->mgmt_tx_ant,
239 il->hw_params.valid_tx_ant);
240 rate_flags = il4965_ant_idx_to_flags(il->mgmt_tx_ant);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200241 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 Gruszka46bc8d42011-10-24 16:49:25 +0200249int il4965_send_beacon_cmd(struct il_priv *il)
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 Gruszka46bc8d42011-10-24 16:49:25 +0200255 frame = il4965_get_free_frame(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800256 if (!frame) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200257 IL_ERR("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 Gruszka46bc8d42011-10-24 16:49:25 +0200262 frame_size = il4965_hw_get_beacon_cmd(il, frame);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800263 if (!frame_size) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200264 IL_ERR("Error configuring the beacon command\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200265 il4965_free_frame(il, frame);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800266 return -EINVAL;
267 }
268
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200269 rc = il_send_cmd_pdu(il, REPLY_TX_BEACON, frame_size,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800270 &frame->u.cmd[0]);
271
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200272 il4965_free_frame(il, 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]
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200318 * @il - driver ilate data
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800319 * @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 Gruszka46bc8d42011-10-24 16:49:25 +0200324void il4965_hw_txq_free_tfd(struct il_priv *il, 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;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200328 struct pci_dev *dev = il->pci_dev;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800329 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) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200339 IL_ERR("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 Gruszka46bc8d42011-10-24 16:49:25 +0200371int il4965_hw_txq_attach_buf_to_tfd(struct il_priv *il,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200372 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) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200391 IL_ERR("Error can not send more than %d chunks\n",
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200392 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))
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200398 IL_ERR("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 Gruszka46bc8d42011-10-24 16:49:25 +0200413int il4965_hw_tx_queue_init(struct il_priv *il,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200414 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 Gruszka0c1a94e2011-08-24 17:37:16 +0200419 il_wr(il, 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 Gruszka46bc8d42011-10-24 16:49:25 +0200430static void il4965_rx_reply_alive(struct il_priv *il,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200431 struct il_rx_mem_buffer *rxb)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800432{
Stanislaw Gruszkadcae1c62011-08-26 14:36:21 +0200433 struct il_rx_pkt *pkt = rxb_addr(rxb);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200434 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 Gruszka58de00a2011-11-15 11:21:01 +0100439 D_INFO("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 Gruszka58de00a2011-11-15 11:21:01 +0100445 D_INFO("Initialization Alive received.\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200446 memcpy(&il->card_alive_init,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800447 &pkt->u.alive_frame,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200448 sizeof(struct il_init_alive_resp));
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200449 pwork = &il->init_alive_start;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800450 } else {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100451 D_INFO("Runtime Alive received.\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200452 memcpy(&il->card_alive, &pkt->u.alive_frame,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200453 sizeof(struct il_alive_resp));
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200454 pwork = &il->alive_start;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800455 }
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)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200460 queue_delayed_work(il->workqueue, pwork,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800461 msecs_to_jiffies(5));
462 else
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200463 IL_WARN("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 Gruszka46bc8d42011-10-24 16:49:25 +0200478 struct il_priv *il = (struct il_priv *)data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800479
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200480 if (test_bit(STATUS_EXIT_PENDING, &il->status))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800481 return;
482
483 /* dont send host command if rf-kill is on */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200484 if (!il_is_ready_rf(il))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800485 return;
486
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200487 il_send_statistics_request(il, CMD_ASYNC, false);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800488}
489
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200490static void il4965_rx_beacon_notif(struct il_priv *il,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200491 struct il_rx_mem_buffer *rxb)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800492{
Stanislaw Gruszkadcae1c62011-08-26 14:36:21 +0200493 struct il_rx_pkt *pkt = rxb_addr(rxb);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200494 struct il4965_beacon_notif *beacon =
495 (struct il4965_beacon_notif *)pkt->u.raw;
Stanislaw Gruszkad3175162011-11-15 11:25:42 +0100496#ifdef CONFIG_IWLEGACY_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 Gruszka58de00a2011-11-15 11:21:01 +0100499 D_RX("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
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200508 il->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800509}
510
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200511static void il4965_perform_ct_kill_task(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800512{
513 unsigned long flags;
514
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100515 D_POWER("Stop all queues\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800516
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200517 if (il->mac80211_registered)
518 ieee80211_stop_queues(il->hw);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800519
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +0200520 _il_wr(il, CSR_UCODE_DRV_GP1_SET,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800521 CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +0200522 _il_rd(il, CSR_UCODE_DRV_GP1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800523
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200524 spin_lock_irqsave(&il->reg_lock, flags);
Stanislaw Gruszka13882262011-08-24 15:39:23 +0200525 if (!_il_grab_nic_access(il))
526 _il_release_nic_access(il);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200527 spin_unlock_irqrestore(&il->reg_lock, flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800528}
529
530/* Handle notification from uCode that card's power state is changing
531 * due to software, hardware, or critical temperature RFKILL */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200532static void il4965_rx_card_state_notif(struct il_priv *il,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200533 struct il_rx_mem_buffer *rxb)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800534{
Stanislaw Gruszkadcae1c62011-08-26 14:36:21 +0200535 struct il_rx_pkt *pkt = rxb_addr(rxb);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800536 u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200537 unsigned long status = il->status;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800538
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100539 D_RF_KILL("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 Gruszka841b2cc2011-08-24 15:14:03 +0200548 _il_wr(il, CSR_UCODE_DRV_GP1_SET,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800549 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
550
Stanislaw Gruszka0c1a94e2011-08-24 17:37:16 +0200551 il_wr(il, 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 Gruszka841b2cc2011-08-24 15:14:03 +0200555 _il_wr(il, CSR_UCODE_DRV_GP1_CLR,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800556 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
Stanislaw Gruszka0c1a94e2011-08-24 17:37:16 +0200557 il_wr(il, 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 Gruszka46bc8d42011-10-24 16:49:25 +0200563 il4965_perform_ct_kill_task(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800564
565 if (flags & HW_CARD_DISABLED)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200566 set_bit(STATUS_RF_KILL_HW, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800567 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200568 clear_bit(STATUS_RF_KILL_HW, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800569
570 if (!(flags & RXON_CARD_DISABLED))
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200571 il_scan_cancel(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800572
573 if ((test_bit(STATUS_RF_KILL_HW, &status) !=
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200574 test_bit(STATUS_RF_KILL_HW, &il->status)))
575 wiphy_rfkill_set_hw_state(il->hw->wiphy,
576 test_bit(STATUS_RF_KILL_HW, &il->status));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800577 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200578 wake_up(&il->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 Gruszka46bc8d42011-10-24 16:49:25 +0200590static void il4965_setup_rx_handlers(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800591{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200592 il->rx_handlers[REPLY_ALIVE] = il4965_rx_reply_alive;
593 il->rx_handlers[REPLY_ERROR] = il_rx_reply_error;
594 il->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = il_rx_csa;
595 il->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200596 il_rx_spectrum_measure_notif;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200597 il->rx_handlers[PM_SLEEP_NOTIFICATION] = il_rx_pm_sleep_notif;
598 il->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200599 il_rx_pm_debug_statistics_notif;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200600 il->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 Gruszka46bc8d42011-10-24 16:49:25 +0200607 il->rx_handlers[REPLY_STATISTICS_CMD] = il4965_reply_statistics;
608 il->rx_handlers[STATISTICS_NOTIFICATION] = il4965_rx_statistics;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800609
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200610 il_setup_rx_scan_handlers(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800611
612 /* status change handler */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200613 il->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
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200616 il->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 Gruszka46bc8d42011-10-24 16:49:25 +0200619 il->rx_handlers[REPLY_RX_PHY_CMD] = il4965_rx_reply_rx_phy;
620 il->rx_handlers[REPLY_RX_MPDU_CMD] = il4965_rx_reply_rx;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800621 /* block ack */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200622 il->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 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200624 il->cfg->ops->lib->rx_handler_setup(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800625}
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 *
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200630 * Uses the il->rx_handlers callback function array to invoke
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800631 * the appropriate handlers, including command responses,
632 * frame-received notifications, and other notifications.
633 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200634void il4965_rx_handle(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800635{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200636 struct il_rx_mem_buffer *rxb;
Stanislaw Gruszkadcae1c62011-08-26 14:36:21 +0200637 struct il_rx_pkt *pkt;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200638 struct il_rx_queue *rxq = &il->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 Gruszka58de00a2011-11-15 11:21:01 +0100653 D_RX("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
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200675 pci_unmap_page(il->pci_dev, rxb->page_dma,
676 PAGE_SIZE << il->hw_params.rx_page_order,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800677 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() */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200700 if (il->rx_handlers[pkt->hdr.cmd]) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100701 D_RX("r = %d, i = %d, %s, 0x%02x\n", r,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200702 i, il_get_cmd_string(pkt->hdr.cmd),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800703 pkt->hdr.cmd);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200704 il->isr_stats.rx_handlers[pkt->hdr.cmd]++;
705 il->rx_handlers[pkt->hdr.cmd] (il, rxb);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800706 } else {
707 /* No handling needed */
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100708 D_RX(
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 Gruszka46bc8d42011-10-24 16:49:25 +0200726 il_tx_cmd_complete(il, rxb);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800727 else
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200728 IL_WARN("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) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200736 rxb->page_dma = pci_map_page(il->pci_dev, rxb->page,
737 0, PAGE_SIZE << il->hw_params.rx_page_order,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800738 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 Gruszka46bc8d42011-10-24 16:49:25 +0200753 il4965_rx_replenish_now(il);
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 Gruszka46bc8d42011-10-24 16:49:25 +0200762 il4965_rx_replenish_now(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800763 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200764 il4965_rx_queue_restock(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800765}
766
767/* call this function to flush any scheduled tasklet */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200768static inline void il4965_synchronize_irq(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800769{
770 /* wait to make sure we flush pending tasklet*/
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200771 synchronize_irq(il->pci_dev->irq);
772 tasklet_kill(&il->irq_tasklet);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800773}
774
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200775static void il4965_irq_tasklet(struct il_priv *il)
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;
Stanislaw Gruszkad3175162011-11-15 11:25:42 +0100781#ifdef CONFIG_IWLEGACY_DEBUG
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800782 u32 inta_mask;
783#endif
784
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200785 spin_lock_irqsave(&il->lock, flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800786
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 Gruszka841b2cc2011-08-24 15:14:03 +0200790 inta = _il_rd(il, CSR_INT);
791 _il_wr(il, 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 Gruszka841b2cc2011-08-24 15:14:03 +0200796 inta_fh = _il_rd(il, CSR_FH_INT_STATUS);
797 _il_wr(il, CSR_FH_INT_STATUS, inta_fh);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800798
Stanislaw Gruszkad3175162011-11-15 11:25:42 +0100799#ifdef CONFIG_IWLEGACY_DEBUG
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200800 if (il_get_debug_level(il) & IL_DL_ISR) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800801 /* just for debug */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +0200802 inta_mask = _il_rd(il, CSR_INT_MASK);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100803 D_ISR("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
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200808 spin_unlock_irqrestore(&il->lock, flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800809
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 Gruszka9406f792011-08-18 22:07:57 +0200821 IL_ERR("Hardware error detected. Restarting.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800822
823 /* Tell the device to stop sending interrupts */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200824 il_disable_interrupts(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800825
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200826 il->isr_stats.hw++;
827 il_irq_handle_error(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800828
829 handled |= CSR_INT_BIT_HW_ERR;
830
831 return;
832 }
833
Stanislaw Gruszkad3175162011-11-15 11:25:42 +0100834#ifdef CONFIG_IWLEGACY_DEBUG
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200835 if (il_get_debug_level(il) & (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 Gruszka58de00a2011-11-15 11:21:01 +0100838 D_ISR("Scheduler finished to transmit "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800839 "the frame/frames.\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200840 il->isr_stats.sch++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800841 }
842
843 /* Alive notification via Rx interrupt will do the real work */
844 if (inta & CSR_INT_BIT_ALIVE) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100845 D_ISR("Alive interrupt\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200846 il->isr_stats.alive++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800847 }
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 Gruszka841b2cc2011-08-24 15:14:03 +0200856 if (!(_il_rd(il, 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 Gruszka9406f792011-08-18 22:07:57 +0200860 IL_WARN("RF_KILL bit toggled to %s.\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800861 hw_rf_kill ? "disable radio" : "enable radio");
862
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200863 il->isr_stats.rfkill++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800864
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 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200870 if (!test_bit(STATUS_ALIVE, &il->status)) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800871 if (hw_rf_kill)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200872 set_bit(STATUS_RF_KILL_HW, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800873 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200874 clear_bit(STATUS_RF_KILL_HW, &il->status);
875 wiphy_rfkill_set_hw_state(il->hw->wiphy, hw_rf_kill);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800876 }
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 Gruszka9406f792011-08-18 22:07:57 +0200883 IL_ERR("Microcode CT kill error detected.\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200884 il->isr_stats.ctkill++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800885 handled |= CSR_INT_BIT_CT_KILL;
886 }
887
888 /* Error detected by uCode */
889 if (inta & CSR_INT_BIT_SW_ERR) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200890 IL_ERR("Microcode SW error detected. "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800891 " Restarting 0x%X.\n", inta);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200892 il->isr_stats.sw++;
893 il_irq_handle_error(il);
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 Gruszka58de00a2011-11-15 11:21:01 +0100903 D_ISR("Wakeup interrupt\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200904 il_rx_queue_update_write_ptr(il, &il->rxq);
905 for (i = 0; i < il->hw_params.max_txq_num; i++)
906 il_txq_update_write_ptr(il, &il->txq[i]);
907 il->isr_stats.wakeup++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800908 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 Gruszka46bc8d42011-10-24 16:49:25 +0200915 il4965_rx_handle(il);
916 il->isr_stats.rx++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800917 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 Gruszka58de00a2011-11-15 11:21:01 +0100922 D_ISR("uCode load interrupt\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200923 il->isr_stats.tx++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800924 handled |= CSR_INT_BIT_FH_TX;
925 /* Wake up uCode load routine, now that load is complete */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200926 il->ucode_write_complete = 1;
927 wake_up(&il->wait_command_queue);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800928 }
929
930 if (inta & ~handled) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200931 IL_ERR("Unhandled INTA bits 0x%08x\n", inta & ~handled);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200932 il->isr_stats.unhandled++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800933 }
934
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200935 if (inta & ~(il->inta_mask)) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200936 IL_WARN("Disabled INTA bits 0x%08x were pending\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200937 inta & ~il->inta_mask);
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200938 IL_WARN(" 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 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200943 if (test_bit(STATUS_INT_ENABLED, &il->status))
944 il_enable_interrupts(il);
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 Gruszka46bc8d42011-10-24 16:49:25 +0200947 il_enable_rfkill_int(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800948
Stanislaw Gruszkad3175162011-11-15 11:25:42 +0100949#ifdef CONFIG_IWLEGACY_DEBUG
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200950 if (il_get_debug_level(il) & (IL_DL_ISR)) {
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +0200951 inta = _il_rd(il, CSR_INT);
952 inta_mask = _il_rd(il, CSR_INT_MASK);
953 inta_fh = _il_rd(il, CSR_FH_INT_STATUS);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100954 D_ISR(
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
Stanislaw Gruszkad3175162011-11-15 11:25:42 +0100967#ifdef CONFIG_IWLEGACY_DEBUG
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800968
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 Gruszka46bc8d42011-10-24 16:49:25 +0200983 struct il_priv *il = dev_get_drvdata(d);
984 return sprintf(buf, "0x%08X\n", il_get_debug_level(il));
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 Gruszka46bc8d42011-10-24 16:49:25 +0200990 struct il_priv *il = 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 Gruszka9406f792011-08-18 22:07:57 +0200996 IL_ERR("%s is not in hex or decimal form.\n", buf);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800997 else {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200998 il->debug_level = val;
999 if (il_alloc_traffic_mem(il))
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001000 IL_ERR(
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
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001010#endif /* CONFIG_IWLEGACY_DEBUG */
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001011
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 Gruszka46bc8d42011-10-24 16:49:25 +02001016 struct il_priv *il = dev_get_drvdata(d);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001017
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001018 if (!il_is_alive(il))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001019 return -EAGAIN;
1020
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001021 return sprintf(buf, "%d\n", il->temperature);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001022}
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 Gruszka46bc8d42011-10-24 16:49:25 +02001029 struct il_priv *il = dev_get_drvdata(d);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001030
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001031 if (!il_is_ready_rf(il))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001032 return sprintf(buf, "off\n");
1033 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001034 return sprintf(buf, "%d\n", il->tx_power_user_lmt);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001035}
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 Gruszka46bc8d42011-10-24 16:49:25 +02001041 struct il_priv *il = 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 Gruszka9406f792011-08-18 22:07:57 +02001047 IL_INFO("%s is not in decimal form.\n", buf);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001048 else {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001049 ret = il_set_tx_power(il, val, false);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001050 if (ret)
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001051 IL_ERR("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,
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001065#ifdef CONFIG_IWLEGACY_DEBUG
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001066 &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 Gruszka46bc8d42011-10-24 16:49:25 +02001082static void il4965_dealloc_ucode_pci(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001083{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001084 il_free_fw_desc(il->pci_dev, &il->ucode_code);
1085 il_free_fw_desc(il->pci_dev, &il->ucode_data);
1086 il_free_fw_desc(il->pci_dev, &il->ucode_data_backup);
1087 il_free_fw_desc(il->pci_dev, &il->ucode_init);
1088 il_free_fw_desc(il->pci_dev, &il->ucode_init_data);
1089 il_free_fw_desc(il->pci_dev, &il->ucode_boot);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001090}
1091
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001092static void il4965_nic_start(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001093{
1094 /* Remove all resets to allow NIC to operate */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02001095 _il_wr(il, 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 Gruszka46bc8d42011-10-24 16:49:25 +02001100static int il4965_mac_setup_register(struct il_priv *il,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001101 u32 max_probe_length);
1102
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001103static int __must_check il4965_request_firmware(struct il_priv *il, bool first)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001104{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001105 const char *name_pre = il->cfg->fw_name_pre;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001106 char tag[8];
1107
1108 if (first) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001109 il->fw_index = il->cfg->ucode_api_max;
1110 sprintf(tag, "%d", il->fw_index);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001111 } else {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001112 il->fw_index--;
1113 sprintf(tag, "%d", il->fw_index);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001114 }
1115
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001116 if (il->fw_index < il->cfg->ucode_api_min) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001117 IL_ERR("no suitable firmware found!\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001118 return -ENOENT;
1119 }
1120
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001121 sprintf(il->firmware_name, "%s%s%s", name_pre, tag, ".ucode");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001122
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001123 D_INFO("attempting to load firmware '%s'\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001124 il->firmware_name);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001125
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001126 return request_firmware_nowait(THIS_MODULE, 1, il->firmware_name,
1127 &il->pci_dev->dev, GFP_KERNEL, il,
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 Gruszka46bc8d42011-10-24 16:49:25 +02001136static int il4965_load_firmware(struct il_priv *il,
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
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001144 il->ucode_ver = le32_to_cpu(ucode->ver);
1145 api_ver = IL_UCODE_API(il->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 Gruszka9406f792011-08-18 22:07:57 +02001154 IL_ERR("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 Gruszka9406f792011-08-18 22:07:57 +02001172 IL_ERR(
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 Gruszka46bc8d42011-10-24 16:49:25 +02001201 struct il_priv *il = context;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001202 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;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001205 const unsigned int api_max = il->cfg->ucode_api_max;
1206 const unsigned int api_min = il->cfg->ucode_api_min;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001207 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) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001216 if (il->fw_index <= il->cfg->ucode_api_max)
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001217 IL_ERR(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001218 "request for firmware file '%s' failed.\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001219 il->firmware_name);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001220 goto try_again;
1221 }
1222
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001223 D_INFO("Loaded firmware file '%s' (%zd bytes).\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001224 il->firmware_name, ucode_raw->size);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001225
1226 /* Make sure that we got at least the API version number */
1227 if (ucode_raw->size < 4) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001228 IL_ERR("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 Gruszka46bc8d42011-10-24 16:49:25 +02001235 err = il4965_load_firmware(il, ucode_raw, &pieces);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001236
1237 if (err)
1238 goto try_again;
1239
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001240 api_ver = IL_UCODE_API(il->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 Gruszka9406f792011-08-18 22:07:57 +02001248 IL_ERR(
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 Gruszka9406f792011-08-18 22:07:57 +02001256 IL_ERR(
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 Gruszka9406f792011-08-18 22:07:57 +02001262 IL_INFO("loaded firmware version %u.%u.%u.%u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001263 IL_UCODE_MAJOR(il->ucode_ver),
1264 IL_UCODE_MINOR(il->ucode_ver),
1265 IL_UCODE_API(il->ucode_ver),
1266 IL_UCODE_SERIAL(il->ucode_ver));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001267
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001268 snprintf(il->hw->wiphy->fw_version,
1269 sizeof(il->hw->wiphy->fw_version),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001270 "%u.%u.%u.%u",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001271 IL_UCODE_MAJOR(il->ucode_ver),
1272 IL_UCODE_MINOR(il->ucode_ver),
1273 IL_UCODE_API(il->ucode_ver),
1274 IL_UCODE_SERIAL(il->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 Gruszka58de00a2011-11-15 11:21:01 +01001282 D_INFO("f/w package hdr ucode version raw = 0x%x\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001283 il->ucode_ver);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001284 D_INFO("f/w package hdr runtime inst size = %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001285 pieces.inst_size);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001286 D_INFO("f/w package hdr runtime data size = %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001287 pieces.data_size);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001288 D_INFO("f/w package hdr init inst size = %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001289 pieces.init_size);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001290 D_INFO("f/w package hdr init data size = %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001291 pieces.init_data_size);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001292 D_INFO("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 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001296 if (pieces.inst_size > il->hw_params.max_inst_size) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001297 IL_ERR("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
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001302 if (pieces.data_size > il->hw_params.max_data_size) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001303 IL_ERR("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
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001308 if (pieces.init_size > il->hw_params.max_inst_size) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001309 IL_ERR("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
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001314 if (pieces.init_data_size > il->hw_params.max_data_size) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001315 IL_ERR("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
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001320 if (pieces.boot_size > il->hw_params.max_bsm_size) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001321 IL_ERR("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 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001331 il->ucode_code.len = pieces.inst_size;
1332 il_alloc_fw_desc(il->pci_dev, &il->ucode_code);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001333
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001334 il->ucode_data.len = pieces.data_size;
1335 il_alloc_fw_desc(il->pci_dev, &il->ucode_data);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001336
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001337 il->ucode_data_backup.len = pieces.data_size;
1338 il_alloc_fw_desc(il->pci_dev, &il->ucode_data_backup);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001339
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001340 if (!il->ucode_code.v_addr || !il->ucode_data.v_addr ||
1341 !il->ucode_data_backup.v_addr)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001342 goto err_pci_alloc;
1343
1344 /* Initialization instructions and data */
1345 if (pieces.init_size && pieces.init_data_size) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001346 il->ucode_init.len = pieces.init_size;
1347 il_alloc_fw_desc(il->pci_dev, &il->ucode_init);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001348
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001349 il->ucode_init_data.len = pieces.init_data_size;
1350 il_alloc_fw_desc(il->pci_dev, &il->ucode_init_data);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001351
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001352 if (!il->ucode_init.v_addr || !il->ucode_init_data.v_addr)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001353 goto err_pci_alloc;
1354 }
1355
1356 /* Bootstrap (instructions only, no data) */
1357 if (pieces.boot_size) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001358 il->ucode_boot.len = pieces.boot_size;
1359 il_alloc_fw_desc(il->pci_dev, &il->ucode_boot);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001360
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001361 if (!il->ucode_boot.v_addr)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001362 goto err_pci_alloc;
1363 }
1364
1365 /* Now that we can no longer fail, copy information */
1366
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001367 il->sta_key_max_num = STA_KEY_MAX_NUM;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001368
1369 /* Copy images into buffers for card's bus-master reads ... */
1370
1371 /* Runtime instructions (first block of data in file) */
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001372 D_INFO("Copying (but not loading) uCode instr len %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001373 pieces.inst_size);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001374 memcpy(il->ucode_code.v_addr, pieces.inst, pieces.inst_size);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001375
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001376 D_INFO("uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001377 il->ucode_code.v_addr, (u32)il->ucode_code.p_addr);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001378
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 Gruszka58de00a2011-11-15 11:21:01 +01001383 D_INFO("Copying (but not loading) uCode data len %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001384 pieces.data_size);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001385 memcpy(il->ucode_data.v_addr, pieces.data, pieces.data_size);
1386 memcpy(il->ucode_data_backup.v_addr, pieces.data, pieces.data_size);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001387
1388 /* Initialization instructions */
1389 if (pieces.init_size) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001390 D_INFO(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001391 "Copying (but not loading) init instr len %Zd\n",
1392 pieces.init_size);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001393 memcpy(il->ucode_init.v_addr, pieces.init, pieces.init_size);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001394 }
1395
1396 /* Initialization data */
1397 if (pieces.init_data_size) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001398 D_INFO(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001399 "Copying (but not loading) init data len %Zd\n",
1400 pieces.init_data_size);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001401 memcpy(il->ucode_init_data.v_addr, pieces.init_data,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001402 pieces.init_data_size);
1403 }
1404
1405 /* Bootstrap instructions */
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001406 D_INFO("Copying (but not loading) boot instr len %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001407 pieces.boot_size);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001408 memcpy(il->ucode_boot.v_addr, pieces.boot, pieces.boot_size);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001409
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 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001414 il->_4965.phy_calib_chain_noise_reset_cmd =
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001415 standard_phy_calibration_size;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001416 il->_4965.phy_calib_chain_noise_gain_cmd =
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001417 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 Gruszka46bc8d42011-10-24 16:49:25 +02001424 err = il4965_mac_setup_register(il, max_probe_length);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001425 if (err)
1426 goto out_unbind;
1427
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001428 err = il_dbgfs_register(il, DRV_NAME);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001429 if (err)
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001430 IL_ERR(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001431 "failed to create debugfs files. Ignoring error: %d\n", err);
1432
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001433 err = sysfs_create_group(&il->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 Gruszka9406f792011-08-18 22:07:57 +02001436 IL_ERR("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);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001442 complete(&il->_4965.firmware_loading_complete);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001443 return;
1444
1445 try_again:
1446 /* try next, if any */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001447 if (il4965_request_firmware(il, 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 Gruszka9406f792011-08-18 22:07:57 +02001453 IL_ERR("failed to allocate pci memory\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001454 il4965_dealloc_ucode_pci(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001455 out_unbind:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001456 complete(&il->_4965.firmware_loading_complete);
1457 device_release_driver(&il->pci_dev->dev);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001458 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 Gruszka46bc8d42011-10-24 16:49:25 +02001530void il4965_dump_nic_error_log(struct il_priv *il)
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
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001537 if (il->ucode_type == UCODE_INIT) {
1538 base = le32_to_cpu(il->card_alive_init.error_event_table_ptr);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001539 } else {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001540 base = le32_to_cpu(il->card_alive.error_event_table_ptr);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001541 }
1542
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001543 if (!il->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001544 IL_ERR(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001545 "Not valid error log pointer 0x%08X for %s uCode\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001546 base, (il->ucode_type == UCODE_INIT) ? "Init" : "RT");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001547 return;
1548 }
1549
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001550 count = il_read_targ_mem(il, base);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001551
1552 if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001553 IL_ERR("Start IWL Error Log Dump:\n");
1554 IL_ERR("Status: 0x%08lX, count: %d\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001555 il->status, count);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001556 }
1557
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001558 desc = il_read_targ_mem(il, base + 1 * sizeof(u32));
1559 il->isr_stats.err_code = desc;
1560 pc = il_read_targ_mem(il, base + 2 * sizeof(u32));
1561 blink1 = il_read_targ_mem(il, base + 3 * sizeof(u32));
1562 blink2 = il_read_targ_mem(il, base + 4 * sizeof(u32));
1563 ilink1 = il_read_targ_mem(il, base + 5 * sizeof(u32));
1564 ilink2 = il_read_targ_mem(il, base + 6 * sizeof(u32));
1565 data1 = il_read_targ_mem(il, base + 7 * sizeof(u32));
1566 data2 = il_read_targ_mem(il, base + 8 * sizeof(u32));
1567 line = il_read_targ_mem(il, base + 9 * sizeof(u32));
1568 time = il_read_targ_mem(il, base + 11 * sizeof(u32));
1569 hcmd = il_read_targ_mem(il, base + 22 * sizeof(u32));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001570
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001571 IL_ERR("Desc Time "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001572 "data1 data2 line\n");
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001573 IL_ERR("%-28s (0x%04X) %010u 0x%08X 0x%08X %u\n",
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001574 il4965_desc_lookup(desc), desc, time, data1, data2, line);
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001575 IL_ERR("pc blink1 blink2 ilink1 ilink2 hcmd\n");
1576 IL_ERR("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 Gruszka46bc8d42011-10-24 16:49:25 +02001580static void il4965_rf_kill_ct_config(struct il_priv *il)
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
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001586 spin_lock_irqsave(&il->lock, flags);
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02001587 _il_wr(il, CSR_UCODE_DRV_GP1_CLR,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001588 CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001589 spin_unlock_irqrestore(&il->lock, flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001590
1591 cmd.critical_temperature_R =
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001592 cpu_to_le32(il->hw_params.ct_kill_threshold);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001593
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001594 ret = il_send_cmd_pdu(il, REPLY_CT_KILL_CONFIG_CMD,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001595 sizeof(cmd), &cmd);
1596 if (ret)
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001597 IL_ERR("REPLY_CT_KILL_CONFIG_CMD failed\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001598 else
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001599 D_INFO("REPLY_CT_KILL_CONFIG_CMD "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001600 "succeeded, "
1601 "critical temperature is %d\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001602 il->hw_params.ct_kill_threshold);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001603}
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,
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001610 IL49_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 Gruszka46bc8d42011-10-24 16:49:25 +02001615static int il4965_alive_notify(struct il_priv *il)
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
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001622 spin_lock_irqsave(&il->lock, flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001623
1624 /* Clear 4965's internal Tx Scheduler data base */
Stanislaw Gruszkadb54eb52011-08-24 21:06:33 +02001625 il->scd_base_addr = il_rd_prph(il,
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001626 IL49_SCD_SRAM_BASE_ADDR);
1627 a = il->scd_base_addr + IL49_SCD_CONTEXT_DATA_OFFSET;
1628 for (; a < il->scd_base_addr + IL49_SCD_TX_STTS_BITMAP_OFFSET; a += 4)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001629 il_write_targ_mem(il, a, 0);
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001630 for (; a < il->scd_base_addr + IL49_SCD_TRANSLATE_TBL_OFFSET; a += 4)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001631 il_write_targ_mem(il, a, 0);
1632 for (; a < il->scd_base_addr +
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001633 IL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(il->hw_params.max_txq_num); a += 4)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001634 il_write_targ_mem(il, a, 0);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001635
1636 /* Tel 4965 where to find Tx byte count tables */
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001637 il_wr_prph(il, IL49_SCD_DRAM_BASE_ADDR,
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001638 il->scd_bc_tbls.dma >> 10);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001639
1640 /* Enable DMA channel */
1641 for (chan = 0; chan < FH49_TCSR_CHNL_NUM ; chan++)
Stanislaw Gruszka0c1a94e2011-08-24 17:37:16 +02001642 il_wr(il,
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 Gruszka0c1a94e2011-08-24 17:37:16 +02001648 reg_val = il_rd(il, FH_TX_CHICKEN_BITS_REG);
1649 il_wr(il, 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 Gruszkad3175162011-11-15 11:25:42 +01001653 il_wr_prph(il, IL49_SCD_QUEUECHAIN_SEL, 0);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001654
1655 /* Initialize each Tx queue (including the command queue) */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001656 for (i = 0; i < il->hw_params.max_txq_num; i++) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001657
1658 /* TFD circular buffer read/write indexes */
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001659 il_wr_prph(il, IL49_SCD_QUEUE_RDPTR(i), 0);
Stanislaw Gruszka0c1a94e2011-08-24 17:37:16 +02001660 il_wr(il, 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 Gruszka46bc8d42011-10-24 16:49:25 +02001663 il_write_targ_mem(il, il->scd_base_addr +
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001664 IL49_SCD_CONTEXT_QUEUE_OFFSET(i),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001665 (SCD_WIN_SIZE <<
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001666 IL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) &
1667 IL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001668
1669 /* Frame limit */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001670 il_write_targ_mem(il, il->scd_base_addr +
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001671 IL49_SCD_CONTEXT_QUEUE_OFFSET(i) +
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001672 sizeof(u32),
1673 (SCD_FRAME_LIMIT <<
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001674 IL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
1675 IL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001676
1677 }
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001678 il_wr_prph(il, IL49_SCD_INTERRUPT_MASK,
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001679 (1 << il->hw_params.max_txq_num) - 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001680
1681 /* Activate all Tx DMA/FIFO channels */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001682 il4965_txq_set_sched(il, IL_MASK(0, 6));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001683
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001684 il4965_set_wr_ptrs(il, IL_DEFAULT_CMD_QUEUE_NUM, 0);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001685
1686 /* make sure all queue are not stopped */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001687 memset(&il->queue_stopped[0], 0, sizeof(il->queue_stopped));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001688 for (i = 0; i < 4; i++)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001689 atomic_set(&il->queue_stop_count[i], 0);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001690
1691 /* reset to 0 to enable all the queue first */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001692 il->txq_ctx_active_msk = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001693 /* 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 Gruszka46bc8d42011-10-24 16:49:25 +02001699 il_txq_ctx_activate(il, 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 Gruszka46bc8d42011-10-24 16:49:25 +02001704 il4965_tx_queue_set_status(il, &il->txq[i], ac, 0);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001705 }
1706
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001707 spin_unlock_irqrestore(&il->lock, flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001708
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 Gruszka46bc8d42011-10-24 16:49:25 +02001717static void il4965_alive_start(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001718{
1719 int ret = 0;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001720 struct il_rxon_context *ctx = &il->contexts[IL_RXON_CTX_BSS];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001721
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001722 D_INFO("Runtime Alive received.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001723
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001724 if (il->card_alive.is_valid != UCODE_VALID_OK) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001725 /* We had an error bringing up the hardware, so take it
1726 * all the way back down so we can try again */
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001727 D_INFO("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 Gruszka46bc8d42011-10-24 16:49:25 +02001734 if (il4965_verify_ucode(il)) {
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 Gruszka58de00a2011-11-15 11:21:01 +01001737 D_INFO("Bad runtime uCode load.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001738 goto restart;
1739 }
1740
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001741 ret = il4965_alive_notify(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001742 if (ret) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001743 IL_WARN(
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 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001750 set_bit(STATUS_ALIVE, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001751
1752 /* Enable watchdog to monitor the driver tx queues */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001753 il_setup_watchdog(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001754
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001755 if (il_is_rfkill(il))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001756 return;
1757
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001758 ieee80211_wake_queues(il->hw);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001759
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001760 il->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 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001771 for_each_context(il, tmp)
1772 il_connection_init_rx_config(il, tmp);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001773
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001774 if (il->cfg->ops->hcmd->set_rxon_chain)
1775 il->cfg->ops->hcmd->set_rxon_chain(il, ctx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001776 }
1777
1778 /* Configure bluetooth coexistence if enabled */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001779 il_send_bt_config(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001780
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001781 il4965_reset_run_time_calib(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001782
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001783 set_bit(STATUS_READY, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001784
1785 /* Configure the adapter for unassociated operation */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001786 il_commit_rxon(il, ctx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001787
1788 /* At this point, the NIC is initialized and operational */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001789 il4965_rf_kill_ct_config(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001790
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001791 D_INFO("ALIVE processing complete.\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001792 wake_up(&il->wait_command_queue);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001793
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001794 il_power_update_mode(il, true);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001795 D_INFO("Updated power mode\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001796
1797 return;
1798
1799 restart:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001800 queue_work(il->workqueue, &il->restart);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001801}
1802
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001803static void il4965_cancel_deferred_work(struct il_priv *il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001804
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001805static void __il4965_down(struct il_priv *il)
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 Gruszka58de00a2011-11-15 11:21:01 +01001810 D_INFO(DRV_NAME " is going down\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001811
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001812 il_scan_cancel_timeout(il, 200);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001813
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001814 exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001815
1816 /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set
1817 * to prevent rearm timer */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001818 del_timer_sync(&il->watchdog);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001819
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001820 il_clear_ucode_stations(il, NULL);
1821 il_dealloc_bcast_stations(il);
1822 il_clear_driver_stations(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001823
1824 /* Unblock any waiting calls */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001825 wake_up_all(&il->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)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001830 clear_bit(STATUS_EXIT_PENDING, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001831
1832 /* stop and reset the on-board processor */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02001833 _il_wr(il, 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 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001836 spin_lock_irqsave(&il->lock, flags);
1837 il_disable_interrupts(il);
1838 spin_unlock_irqrestore(&il->lock, flags);
1839 il4965_synchronize_irq(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001840
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001841 if (il->mac80211_registered)
1842 ieee80211_stop_queues(il->hw);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001843
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 Gruszka46bc8d42011-10-24 16:49:25 +02001846 if (!il_is_init(il)) {
1847 il->status = test_bit(STATUS_RF_KILL_HW, &il->status) <<
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001848 STATUS_RF_KILL_HW |
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001849 test_bit(STATUS_GEO_CONFIGURED, &il->status) <<
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001850 STATUS_GEO_CONFIGURED |
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001851 test_bit(STATUS_EXIT_PENDING, &il->status) <<
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001852 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. */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001858 il->status &= test_bit(STATUS_RF_KILL_HW, &il->status) <<
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001859 STATUS_RF_KILL_HW |
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001860 test_bit(STATUS_GEO_CONFIGURED, &il->status) <<
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001861 STATUS_GEO_CONFIGURED |
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001862 test_bit(STATUS_FW_ERROR, &il->status) <<
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001863 STATUS_FW_ERROR |
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001864 test_bit(STATUS_EXIT_PENDING, &il->status) <<
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001865 STATUS_EXIT_PENDING;
1866
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001867 il4965_txq_ctx_stop(il);
1868 il4965_rxq_stop(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001869
1870 /* Power-down device's busmaster DMA clocks */
Stanislaw Gruszkadb54eb52011-08-24 21:06:33 +02001871 il_wr_prph(il, 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 Gruszka46bc8d42011-10-24 16:49:25 +02001875 il_clear_bit(il, 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 Gruszka46bc8d42011-10-24 16:49:25 +02001879 il_apm_stop(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001880
1881 exit:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001882 memset(&il->card_alive, 0, sizeof(struct il_alive_resp));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001883
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001884 dev_kfree_skb(il->beacon_skb);
1885 il->beacon_skb = NULL;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001886
1887 /* clear out any free frames */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001888 il4965_clear_free_frames(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001889}
1890
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001891static void il4965_down(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001892{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001893 mutex_lock(&il->mutex);
1894 __il4965_down(il);
1895 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001896
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001897 il4965_cancel_deferred_work(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001898}
1899
1900#define HW_READY_TIMEOUT (50)
1901
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001902static int il4965_set_hw_ready(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001903{
1904 int ret = 0;
1905
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001906 il_set_bit(il, 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 Gruszka142b3432011-08-24 15:22:57 +02001910 ret = _il_poll_bit(il, 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)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001915 il->hw_ready = true;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001916 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001917 il->hw_ready = false;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001918
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001919 D_INFO("hardware %s\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001920 (il->hw_ready == 1) ? "ready" : "not ready");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001921 return ret;
1922}
1923
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001924static int il4965_prepare_card_hw(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001925{
1926 int ret = 0;
1927
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001928 D_INFO("il4965_prepare_card_hw enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001929
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001930 ret = il4965_set_hw_ready(il);
1931 if (il->hw_ready)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001932 return ret;
1933
1934 /* If HW is not ready, prepare the conditions to check again */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001935 il_set_bit(il, CSR_HW_IF_CONFIG_REG,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001936 CSR_HW_IF_CONFIG_REG_PREPARE);
1937
Stanislaw Gruszka142b3432011-08-24 15:22:57 +02001938 ret = _il_poll_bit(il, 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 Gruszka46bc8d42011-10-24 16:49:25 +02001944 il4965_set_hw_ready(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001945
1946 return ret;
1947}
1948
1949#define MAX_HW_RESTARTS 5
1950
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001951static int __il4965_up(struct il_priv *il)
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
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001957 if (test_bit(STATUS_EXIT_PENDING, &il->status)) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001958 IL_WARN("Exit pending; will not bring the NIC up\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001959 return -EIO;
1960 }
1961
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001962 if (!il->ucode_data_backup.v_addr || !il->ucode_data.v_addr) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001963 IL_ERR("ucode not available for device bringup\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001964 return -EIO;
1965 }
1966
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001967 for_each_context(il, ctx) {
1968 ret = il4965_alloc_bcast_station(il, ctx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001969 if (ret) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001970 il_dealloc_bcast_stations(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001971 return ret;
1972 }
1973 }
1974
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001975 il4965_prepare_card_hw(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001976
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001977 if (!il->hw_ready) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001978 IL_WARN("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 Gruszka841b2cc2011-08-24 15:14:03 +02001983 if (_il_rd(il,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001984 CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001985 clear_bit(STATUS_RF_KILL_HW, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001986 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001987 set_bit(STATUS_RF_KILL_HW, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001988
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001989 if (il_is_rfkill(il)) {
1990 wiphy_rfkill_set_hw_state(il->hw->wiphy, true);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001991
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001992 il_enable_interrupts(il);
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001993 IL_WARN("Radio disabled by HW RF Kill switch\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001994 return 0;
1995 }
1996
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02001997 _il_wr(il, 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 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002000 il->cmd_queue = IL_DEFAULT_CMD_QUEUE_NUM;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002001
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002002 ret = il4965_hw_nic_init(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002003 if (ret) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002004 IL_ERR("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 Gruszka841b2cc2011-08-24 15:14:03 +02002009 _il_wr(il, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
2010 _il_wr(il, 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 Gruszka841b2cc2011-08-24 15:14:03 +02002014 _il_wr(il, CSR_INT, 0xFFFFFFFF);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002015 il_enable_interrupts(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002016
2017 /* really make sure rfkill handshake bits are cleared */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02002018 _il_wr(il, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
2019 _il_wr(il, 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. */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002024 memcpy(il->ucode_data_backup.v_addr, il->ucode_data.v_addr,
2025 il->ucode_data.len);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002026
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 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002032 ret = il->cfg->ops->lib->load_ucode(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002033
2034 if (ret) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002035 IL_ERR("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 Gruszka46bc8d42011-10-24 16:49:25 +02002041 il4965_nic_start(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002042
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002043 D_INFO(DRV_NAME " is coming up\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002044
2045 return 0;
2046 }
2047
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002048 set_bit(STATUS_EXIT_PENDING, &il->status);
2049 __il4965_down(il);
2050 clear_bit(STATUS_EXIT_PENDING, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002051
2052 /* tried to restart and config the device for as long as our
2053 * patience could withstand */
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002054 IL_ERR("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 Gruszka46bc8d42011-10-24 16:49:25 +02002067 struct il_priv *il =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002068 container_of(data, struct il_priv, init_alive_start.work);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002069
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002070 mutex_lock(&il->mutex);
2071 if (test_bit(STATUS_EXIT_PENDING, &il->status))
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002072 goto out;
2073
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002074 il->cfg->ops->lib->init_alive_start(il);
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002075out:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002076 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002077}
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 Gruszka46bc8d42011-10-24 16:49:25 +02002081 struct il_priv *il =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002082 container_of(data, struct il_priv, alive_start.work);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002083
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002084 mutex_lock(&il->mutex);
2085 if (test_bit(STATUS_EXIT_PENDING, &il->status))
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002086 goto out;
2087
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002088 il4965_alive_start(il);
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002089out:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002090 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002091}
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 Gruszka46bc8d42011-10-24 16:49:25 +02002095 struct il_priv *il = container_of(work, struct il_priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002096 run_time_calib_work);
2097
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002098 mutex_lock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002099
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002100 if (test_bit(STATUS_EXIT_PENDING, &il->status) ||
2101 test_bit(STATUS_SCANNING, &il->status)) {
2102 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002103 return;
2104 }
2105
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002106 if (il->start_calib) {
2107 il4965_chain_noise_calibration(il,
2108 (void *)&il->_4965.statistics);
2109 il4965_sensitivity_calibration(il,
2110 (void *)&il->_4965.statistics);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002111 }
2112
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002113 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002114}
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 Gruszka46bc8d42011-10-24 16:49:25 +02002118 struct il_priv *il = container_of(data, struct il_priv, restart);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002119
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002120 if (test_bit(STATUS_EXIT_PENDING, &il->status))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002121 return;
2122
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002123 if (test_and_clear_bit(STATUS_FW_ERROR, &il->status)) {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002124 struct il_rxon_context *ctx;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002125
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002126 mutex_lock(&il->mutex);
2127 for_each_context(il, ctx)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002128 ctx->vif = NULL;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002129 il->is_open = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002130
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002131 __il4965_down(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002132
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002133 mutex_unlock(&il->mutex);
2134 il4965_cancel_deferred_work(il);
2135 ieee80211_restart_hw(il->hw);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002136 } else {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002137 il4965_down(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002138
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002139 mutex_lock(&il->mutex);
2140 if (test_bit(STATUS_EXIT_PENDING, &il->status)) {
2141 mutex_unlock(&il->mutex);
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002142 return;
2143 }
2144
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002145 __il4965_up(il);
2146 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002147 }
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 Gruszka46bc8d42011-10-24 16:49:25 +02002152 struct il_priv *il =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002153 container_of(data, struct il_priv, rx_replenish);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002154
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002155 if (test_bit(STATUS_EXIT_PENDING, &il->status))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002156 return;
2157
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002158 mutex_lock(&il->mutex);
2159 il4965_rx_replenish(il);
2160 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002161}
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 Gruszka46bc8d42011-10-24 16:49:25 +02002175static int il4965_mac_setup_register(struct il_priv *il,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002176 u32 max_probe_length)
2177{
2178 int ret;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002179 struct ieee80211_hw *hw = il->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 Gruszka46bc8d42011-10-24 16:49:25 +02002191 if (il->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
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002198 for_each_context(il, ctx) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002199 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
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002221 if (il->bands[IEEE80211_BAND_2GHZ].n_channels)
2222 il->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
2223 &il->bands[IEEE80211_BAND_2GHZ];
2224 if (il->bands[IEEE80211_BAND_5GHZ].n_channels)
2225 il->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
2226 &il->bands[IEEE80211_BAND_5GHZ];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002227
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002228 il_leds_init(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002229
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002230 ret = ieee80211_register_hw(il->hw);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002231 if (ret) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002232 IL_ERR("Failed to register hw (error %d)\n", ret);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002233 return ret;
2234 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002235 il->mac80211_registered = 1;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002236
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 Gruszka46bc8d42011-10-24 16:49:25 +02002243 struct il_priv *il = hw->priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002244 int ret;
2245
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002246 D_MAC80211("enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002247
2248 /* we should be verifying the device is ready to be opened */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002249 mutex_lock(&il->mutex);
2250 ret = __il4965_up(il);
2251 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002252
2253 if (ret)
2254 return ret;
2255
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002256 if (il_is_rfkill(il))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002257 goto out;
2258
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002259 D_INFO("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 Gruszka46bc8d42011-10-24 16:49:25 +02002263 ret = wait_event_timeout(il->wait_command_queue,
2264 test_bit(STATUS_READY, &il->status),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002265 UCODE_READY_TIMEOUT);
2266 if (!ret) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002267 if (!test_bit(STATUS_READY, &il->status)) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002268 IL_ERR("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 Gruszka46bc8d42011-10-24 16:49:25 +02002274 il4965_led_enable(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002275
2276out:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002277 il->is_open = 1;
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002278 D_MAC80211("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 Gruszka46bc8d42011-10-24 16:49:25 +02002284 struct il_priv *il = hw->priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002285
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002286 D_MAC80211("enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002287
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002288 if (!il->is_open)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002289 return;
2290
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002291 il->is_open = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002292
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002293 il4965_down(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002294
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002295 flush_workqueue(il->workqueue);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002296
Stanislaw Gruszkaa078a1f2011-04-28 11:51:25 +02002297 /* User space software may expect getting rfkill changes
2298 * even if interface is down */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02002299 _il_wr(il, CSR_INT, 0xFFFFFFFF);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002300 il_enable_rfkill_int(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002301
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002302 D_MAC80211("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 Gruszka46bc8d42011-10-24 16:49:25 +02002307 struct il_priv *il = hw->priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002308
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002309 D_MACDUMP("enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002310
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002311 D_TX("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 Gruszka46bc8d42011-10-24 16:49:25 +02002314 if (il4965_tx_skb(il, skb))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002315 dev_kfree_skb_any(skb);
2316
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002317 D_MACDUMP("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 Gruszka46bc8d42011-10-24 16:49:25 +02002326 struct il_priv *il = hw->priv;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002327 struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002328
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002329 D_MAC80211("enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002330
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002331 il4965_update_tkip_key(il, vif_priv->ctx, keyconf, sta,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002332 iv32, phase1key);
2333
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002334 D_MAC80211("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 Gruszka46bc8d42011-10-24 16:49:25 +02002341 struct il_priv *il = hw->priv;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002342 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 Gruszka58de00a2011-11-15 11:21:01 +01002348 D_MAC80211("enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002349
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002350 if (il->cfg->mod_params->sw_crypto) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002351 D_MAC80211("leave - hwcrypto disabled\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002352 return -EOPNOTSUPP;
2353 }
2354
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002355 sta_id = il_sta_id_or_broadcast(il, vif_priv->ctx, sta);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002356 if (sta_id == IL_INVALID_STATION)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002357 return -EINVAL;
2358
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002359 mutex_lock(&il->mutex);
2360 il_scan_cancel_timeout(il, 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 Gruszka46bc8d42011-10-24 16:49:25 +02002381 ret = il4965_set_default_wep_key(il,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002382 vif_priv->ctx, key);
2383 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002384 ret = il4965_set_dynamic_key(il, vif_priv->ctx,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002385 key, sta_id);
2386
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002387 D_MAC80211("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 Gruszka46bc8d42011-10-24 16:49:25 +02002391 ret = il4965_remove_default_wep_key(il, ctx, key);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002392 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002393 ret = il4965_remove_dynamic_key(il, ctx,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002394 key, sta_id);
2395
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002396 D_MAC80211("disable hwcrypto key\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002397 break;
2398 default:
2399 ret = -EINVAL;
2400 }
2401
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002402 mutex_unlock(&il->mutex);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002403 D_MAC80211("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 Gruszka46bc8d42011-10-24 16:49:25 +02002414 struct il_priv *il = hw->priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002415 int ret = -EINVAL;
2416
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002417 D_HT("A-MPDU action on addr %pM tid %d\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002418 sta->addr, tid);
2419
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002420 if (!(il->cfg->sku & IL_SKU_N))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002421 return -EACCES;
2422
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002423 mutex_lock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002424
2425 switch (action) {
2426 case IEEE80211_AMPDU_RX_START:
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002427 D_HT("start Rx\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002428 ret = il4965_sta_rx_agg_start(il, sta, tid, *ssn);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002429 break;
2430 case IEEE80211_AMPDU_RX_STOP:
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002431 D_HT("stop Rx\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002432 ret = il4965_sta_rx_agg_stop(il, sta, tid);
2433 if (test_bit(STATUS_EXIT_PENDING, &il->status))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002434 ret = 0;
2435 break;
2436 case IEEE80211_AMPDU_TX_START:
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002437 D_HT("start Tx\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002438 ret = il4965_tx_agg_start(il, vif, sta, tid, ssn);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002439 break;
2440 case IEEE80211_AMPDU_TX_STOP:
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002441 D_HT("stop Tx\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002442 ret = il4965_tx_agg_stop(il, vif, sta, tid);
2443 if (test_bit(STATUS_EXIT_PENDING, &il->status))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002444 ret = 0;
2445 break;
2446 case IEEE80211_AMPDU_TX_OPERATIONAL:
2447 ret = 0;
2448 break;
2449 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002450 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002451
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 Gruszka46bc8d42011-10-24 16:49:25 +02002459 struct il_priv *il = hw->priv;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002460 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 Gruszka58de00a2011-11-15 11:21:01 +01002466 D_INFO("received request to add station %pM\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002467 sta->addr);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002468 mutex_lock(&il->mutex);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002469 D_INFO("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 Gruszka46bc8d42011-10-24 16:49:25 +02002475 ret = il_add_station_common(il, vif_priv->ctx, sta->addr,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002476 is_ap, sta, &sta_id);
2477 if (ret) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002478 IL_ERR("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 ? */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002481 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002482 return ret;
2483 }
2484
2485 sta_priv->common.sta_id = sta_id;
2486
2487 /* Initialize rate scaling */
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002488 D_INFO("Initializing rate scaling for station %pM\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002489 sta->addr);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002490 il4965_rs_rate_init(il, sta, sta_id);
2491 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002492
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 Gruszka46bc8d42011-10-24 16:49:25 +02002499 struct il_priv *il = hw->priv;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002500 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 Gruszka46bc8d42011-10-24 16:49:25 +02002503 struct il_ht_config *ht_conf = &il->current_ht_config;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002504
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002505 struct il_rxon_context *ctx = &il->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 Gruszka58de00a2011-11-15 11:21:01 +01002508 D_MAC80211("enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002509
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002510 mutex_lock(&il->mutex);
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002511
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002512 if (il_is_rfkill(il))
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002513 goto out;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002514
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002515 if (test_bit(STATUS_EXIT_PENDING, &il->status) ||
2516 test_bit(STATUS_SCANNING, &il->status) ||
2517 test_bit(STATUS_CHANNEL_SWITCH_PENDING, &il->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
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002523 if (!il->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 Gruszka46bc8d42011-10-24 16:49:25 +02002530 ch_info = il_get_channel_info(il, channel->band, ch);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002531 if (!il_is_channel_valid(ch_info)) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002532 D_MAC80211("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
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002536 spin_lock_irq(&il->lock);
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02002537
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002538 il->current_ht_config.smps = conf->smps_mode;
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02002539
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 Gruszka46bc8d42011-10-24 16:49:25 +02002562 il_set_rxon_channel(il, channel, ctx);
2563 il_set_rxon_ht(il, ht_conf);
2564 il_set_flags_for_band(il, ctx, channel->band, ctx->vif);
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02002565
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002566 spin_unlock_irq(&il->lock);
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02002567
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002568 il_set_rate(il);
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02002569 /*
2570 * at this point, staging_rxon has the
2571 * configuration for channel switch
2572 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002573 set_bit(STATUS_CHANNEL_SWITCH_PENDING, &il->status);
2574 il->switch_channel = cpu_to_le16(ch);
2575 if (il->cfg->ops->lib->set_channel_switch(il, ch_switch)) {
2576 clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &il->status);
2577 il->switch_channel = 0;
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02002578 ieee80211_chswitch_done(ctx->vif, false);
2579 }
2580
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002581out:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002582 mutex_unlock(&il->mutex);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002583 D_MAC80211("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 Gruszka46bc8d42011-10-24 16:49:25 +02002591 struct il_priv *il = 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 Gruszka58de00a2011-11-15 11:21:01 +01002602 D_MAC80211("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
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002612 mutex_lock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002613
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002614 for_each_context(il, ctx) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002615 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
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002624 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002625
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 Gruszka46bc8d42011-10-24 16:49:25 +02002644 struct il_priv *il = container_of(work, struct il_priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002645 txpower_work);
2646
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002647 mutex_lock(&il->mutex);
Stanislaw Gruszkaf3257572011-04-28 11:36:54 +02002648
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. */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002653 if (test_bit(STATUS_EXIT_PENDING, &il->status) ||
2654 test_bit(STATUS_SCANNING, &il->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 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002660 il->cfg->ops->lib->send_tx_power(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002661
2662 /* Update last_temperature to keep is_calib_needed from running
2663 * when it isn't needed... */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002664 il->last_temperature = il->temperature;
Stanislaw Gruszkaf3257572011-04-28 11:36:54 +02002665out:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002666 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002667}
2668
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002669static void il4965_setup_deferred_work(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002670{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002671 il->workqueue = create_singlethread_workqueue(DRV_NAME);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002672
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002673 init_waitqueue_head(&il->wait_command_queue);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002674
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002675 INIT_WORK(&il->restart, il4965_bg_restart);
2676 INIT_WORK(&il->rx_replenish, il4965_bg_rx_replenish);
2677 INIT_WORK(&il->run_time_calib_work, il4965_bg_run_time_calib_work);
2678 INIT_DELAYED_WORK(&il->init_alive_start, il4965_bg_init_alive_start);
2679 INIT_DELAYED_WORK(&il->alive_start, il4965_bg_alive_start);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002680
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002681 il_setup_scan_deferred_work(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002682
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002683 INIT_WORK(&il->txpower_work, il4965_bg_txpower_work);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002684
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002685 init_timer(&il->statistics_periodic);
2686 il->statistics_periodic.data = (unsigned long)il;
2687 il->statistics_periodic.function = il4965_bg_statistics_periodic;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002688
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002689 init_timer(&il->watchdog);
2690 il->watchdog.data = (unsigned long)il;
2691 il->watchdog.function = il_bg_watchdog;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002692
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002693 tasklet_init(&il->irq_tasklet, (void (*)(unsigned long))
2694 il4965_irq_tasklet, (unsigned long)il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002695}
2696
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002697static void il4965_cancel_deferred_work(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002698{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002699 cancel_work_sync(&il->txpower_work);
2700 cancel_delayed_work_sync(&il->init_alive_start);
2701 cancel_delayed_work(&il->alive_start);
2702 cancel_work_sync(&il->run_time_calib_work);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002703
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002704 il_cancel_scan_deferred_work(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002705
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002706 del_timer_sync(&il->statistics_periodic);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002707}
2708
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002709static void il4965_init_hw_rates(struct il_priv *il,
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++) {
Stanislaw Gruszkad2ddf622011-08-16 14:17:04 +02002715 rates[i].bitrate = il_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 Gruszkad2ddf622011-08-16 14:17:04 +02002724 (il_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/*
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002730 * Acquire il->lock before calling this function !
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002731 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002732void il4965_set_wr_ptrs(struct il_priv *il, int txq_id, u32 index)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002733{
Stanislaw Gruszka0c1a94e2011-08-24 17:37:16 +02002734 il_wr(il, HBUS_TARG_WRPTR,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002735 (index & 0xff) | (txq_id << 8));
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01002736 il_wr_prph(il, IL49_SCD_QUEUE_RDPTR(txq_id), index);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002737}
2738
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002739void il4965_tx_queue_set_status(struct il_priv *il,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002740 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 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002746 int active = test_bit(txq_id, &il->txq_ctx_active_msk) ? 1 : 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002747
2748 /* Set up and activate */
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01002749 il_wr_prph(il, IL49_SCD_QUEUE_STATUS_BITS(txq_id),
2750 (active << IL49_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
2751 (tx_fifo_id << IL49_SCD_QUEUE_STTS_REG_POS_TXF) |
2752 (scd_retry << IL49_SCD_QUEUE_STTS_REG_POS_WSL) |
2753 (scd_retry << IL49_SCD_QUEUE_STTS_REG_POS_SCD_ACK) |
2754 IL49_SCD_QUEUE_STTS_REG_MSK);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002755
2756 txq->sched_retry = scd_retry;
2757
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002758 D_INFO("%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 Gruszka46bc8d42011-10-24 16:49:25 +02002764static int il4965_init_drv(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002765{
2766 int ret;
2767
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002768 spin_lock_init(&il->sta_lock);
2769 spin_lock_init(&il->hcmd_lock);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002770
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002771 INIT_LIST_HEAD(&il->free_frames);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002772
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002773 mutex_init(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002774
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002775 il->ieee_channels = NULL;
2776 il->ieee_rates = NULL;
2777 il->band = IEEE80211_BAND_2GHZ;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002778
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002779 il->iw_mode = NL80211_IFTYPE_STATION;
2780 il->current_ht_config.smps = IEEE80211_SMPS_STATIC;
2781 il->missed_beacon_threshold = IL_MISSED_BEACON_THRESHOLD_DEF;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002782
2783 /* initialize force reset */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002784 il->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 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002787 if (il->cfg->ops->hcmd->set_rxon_chain)
2788 il->cfg->ops->hcmd->set_rxon_chain(il,
2789 &il->contexts[IL_RXON_CTX_BSS]);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002790
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002791 il_init_scan_params(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002792
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002793 ret = il_init_channel_map(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002794 if (ret) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002795 IL_ERR("initializing regulatory failed: %d\n", ret);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002796 goto err;
2797 }
2798
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002799 ret = il_init_geos(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002800 if (ret) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002801 IL_ERR("initializing geos failed: %d\n", ret);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002802 goto err_free_channel_map;
2803 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002804 il4965_init_hw_rates(il, il->ieee_rates);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002805
2806 return 0;
2807
2808err_free_channel_map:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002809 il_free_channel_map(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002810err:
2811 return ret;
2812}
2813
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002814static void il4965_uninit_drv(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002815{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002816 il4965_calib_free_results(il);
2817 il_free_geos(il);
2818 il_free_channel_map(il);
2819 kfree(il->scan_cmd);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002820}
2821
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002822static void il4965_hw_detect(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002823{
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02002824 il->hw_rev = _il_rd(il, CSR_HW_REV);
2825 il->hw_wa_rev = _il_rd(il, CSR_HW_REV_WA_REG);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002826 il->rev_id = il->pci_dev->revision;
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002827 D_INFO("HW Revision ID = 0x%X\n", il->rev_id);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002828}
2829
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002830static int il4965_set_hw_params(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002831{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002832 il->hw_params.max_rxq_size = RX_QUEUE_SIZE;
2833 il->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
2834 if (il->cfg->mod_params->amsdu_size_8K)
2835 il->hw_params.rx_page_order = get_order(IL_RX_BUF_SIZE_8K);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002836 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002837 il->hw_params.rx_page_order = get_order(IL_RX_BUF_SIZE_4K);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002838
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002839 il->hw_params.max_beacon_itrvl = IL_MAX_UCODE_BEACON_INTERVAL;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002840
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002841 if (il->cfg->mod_params->disable_11n)
2842 il->cfg->sku &= ~IL_SKU_N;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002843
2844 /* Device-specific setup */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002845 return il->cfg->ops->lib->set_hw_params(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002846}
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 Gruszka46bc8d42011-10-24 16:49:25 +02002863 struct il_priv *il;
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 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002878 il = hw->priv;
2879 /* At this point both hw and il are allocated. */
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002880
2881 /*
2882 * The default context is always valid,
2883 * more may be discovered when firmware
2884 * is loaded.
2885 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002886 il->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++)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002889 il->contexts[i].ctxid = i;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002890
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002891 il->contexts[IL_RXON_CTX_BSS].always_active = true;
2892 il->contexts[IL_RXON_CTX_BSS].is_active = true;
2893 il->contexts[IL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON;
2894 il->contexts[IL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING;
2895 il->contexts[IL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC;
2896 il->contexts[IL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM;
2897 il->contexts[IL_RXON_CTX_BSS].ap_sta_id = IL_AP_ID;
2898 il->contexts[IL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
2899 il->contexts[IL_RXON_CTX_BSS].ac_to_fifo = il4965_bss_ac_to_fifo;
2900 il->contexts[IL_RXON_CTX_BSS].ac_to_queue = il4965_bss_ac_to_queue;
2901 il->contexts[IL_RXON_CTX_BSS].exclusive_interface_modes =
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002902 BIT(NL80211_IFTYPE_ADHOC);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002903 il->contexts[IL_RXON_CTX_BSS].interface_modes =
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002904 BIT(NL80211_IFTYPE_STATION);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002905 il->contexts[IL_RXON_CTX_BSS].ap_devtype = RXON_DEV_TYPE_AP;
2906 il->contexts[IL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS;
2907 il->contexts[IL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS;
2908 il->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 Gruszka58de00a2011-11-15 11:21:01 +01002914 D_INFO("*** LOAD DRIVER ***\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002915 il->cfg = cfg;
2916 il->pci_dev = pdev;
2917 il->inta_mask = CSR_INI_SET_MASK;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002918
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002919 if (il_alloc_traffic_mem(il))
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002920 IL_ERR("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 Gruszka9406f792011-08-18 22:07:57 +02002945 IL_WARN("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
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002954 pci_set_drvdata(pdev, il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002955
2956
2957 /***********************
2958 * 3. Read REV register
2959 ***********************/
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002960 il->hw_base = pci_iomap(pdev, 0, 0);
2961 if (!il->hw_base) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002962 err = -ENODEV;
2963 goto out_pci_release_regions;
2964 }
2965
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002966 D_INFO("pci_resource_len = 0x%08llx\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002967 (unsigned long long) pci_resource_len(pdev, 0));
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002968 D_INFO("pci_resource_base = %p\n", il->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 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002973 spin_lock_init(&il->reg_lock);
2974 spin_lock_init(&il->lock);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002975
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 Gruszka841b2cc2011-08-24 15:14:03 +02002981 _il_wr(il, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002982
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002983 il4965_hw_detect(il);
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002984 IL_INFO("Detected %s, REV=0x%X\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002985 il->cfg->name, il->hw_rev);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002986
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 Gruszka46bc8d42011-10-24 16:49:25 +02002991 il4965_prepare_card_hw(il);
2992 if (!il->hw_ready) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002993 IL_WARN("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 Gruszka46bc8d42011-10-24 16:49:25 +02003001 err = il_eeprom_init(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003002 if (err) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003003 IL_ERR("Unable to init EEPROM\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003004 goto out_iounmap;
3005 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003006 err = il4965_eeprom_check_version(il);
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 Gruszka46bc8d42011-10-24 16:49:25 +02003014 il4965_eeprom_get_mac(il, il->addresses[0].addr);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003015 D_INFO("MAC address: %pM\n", il->addresses[0].addr);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003016 il->hw->wiphy->addresses = il->addresses;
3017 il->hw->wiphy->n_addresses = 1;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003018
3019 /************************
3020 * 5. Setup HW constants
3021 ************************/
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003022 if (il4965_set_hw_params(il)) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003023 IL_ERR("failed to set hw parameters\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003024 goto out_free_eeprom;
3025 }
3026
3027 /*******************
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003028 * 6. Setup il
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003029 *******************/
3030
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003031 err = il4965_init_drv(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003032 if (err)
3033 goto out_free_eeprom;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003034 /* At this point both hw and il are initialized. */
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003035
3036 /********************
3037 * 7. Setup services
3038 ********************/
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003039 spin_lock_irqsave(&il->lock, flags);
3040 il_disable_interrupts(il);
3041 spin_unlock_irqrestore(&il->lock, flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003042
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003043 pci_enable_msi(il->pci_dev);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003044
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003045 err = request_irq(il->pci_dev->irq, il_isr,
3046 IRQF_SHARED, DRV_NAME, il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003047 if (err) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003048 IL_ERR("Error allocating IRQ %d\n", il->pci_dev->irq);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003049 goto out_disable_msi;
3050 }
3051
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003052 il4965_setup_deferred_work(il);
3053 il4965_setup_rx_handlers(il);
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 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003060 pci_read_config_word(il->pci_dev, PCI_COMMAND, &pci_cmd);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003061 if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
3062 pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003063 pci_write_config_word(il->pci_dev, PCI_COMMAND, pci_cmd);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003064 }
3065
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003066 il_enable_rfkill_int(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003067
3068 /* If platform's RF_KILL switch is NOT set to KILL */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02003069 if (_il_rd(il, CSR_GP_CNTRL) &
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003070 CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003071 clear_bit(STATUS_RF_KILL_HW, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003072 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003073 set_bit(STATUS_RF_KILL_HW, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003074
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003075 wiphy_rfkill_set_hw_state(il->hw->wiphy,
3076 test_bit(STATUS_RF_KILL_HW, &il->status));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003077
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003078 il_power_initialize(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003079
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003080 init_completion(&il->_4965.firmware_loading_complete);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003081
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003082 err = il4965_request_firmware(il, 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:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003089 destroy_workqueue(il->workqueue);
3090 il->workqueue = NULL;
3091 free_irq(il->pci_dev->irq, il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003092 out_disable_msi:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003093 pci_disable_msi(il->pci_dev);
3094 il4965_uninit_drv(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003095 out_free_eeprom:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003096 il_eeprom_free(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003097 out_iounmap:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003098 pci_iounmap(pdev, il->hw_base);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003099 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 Gruszka46bc8d42011-10-24 16:49:25 +02003105 il_free_traffic_mem(il);
3106 ieee80211_free_hw(il->hw);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003107 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 Gruszka46bc8d42011-10-24 16:49:25 +02003113 struct il_priv *il = pci_get_drvdata(pdev);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003114 unsigned long flags;
3115
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003116 if (!il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003117 return;
3118
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003119 wait_for_completion(&il->_4965.firmware_loading_complete);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003120
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003121 D_INFO("*** UNLOAD DRIVER ***\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003122
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003123 il_dbgfs_unregister(il);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003124 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 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003130 set_bit(STATUS_EXIT_PENDING, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003131
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003132 il_leds_exit(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003133
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003134 if (il->mac80211_registered) {
3135 ieee80211_unregister_hw(il->hw);
3136 il->mac80211_registered = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003137 } else {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003138 il4965_down(il);
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 Gruszka46bc8d42011-10-24 16:49:25 +02003148 il_apm_stop(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003149
3150 /* make sure we flush any pending irq or
3151 * tasklet for the driver
3152 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003153 spin_lock_irqsave(&il->lock, flags);
3154 il_disable_interrupts(il);
3155 spin_unlock_irqrestore(&il->lock, flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003156
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003157 il4965_synchronize_irq(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003158
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003159 il4965_dealloc_ucode_pci(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003160
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003161 if (il->rxq.bd)
3162 il4965_rx_queue_free(il, &il->rxq);
3163 il4965_hw_txq_ctx_free(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003164
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003165 il_eeprom_free(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003166
3167
3168 /*netif_stop_queue(dev); */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003169 flush_workqueue(il->workqueue);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003170
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003171 /* ieee80211_unregister_hw calls il_mac_stop, which flushes
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003172 * il->workqueue... so we can't take down the workqueue
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003173 * until now... */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003174 destroy_workqueue(il->workqueue);
3175 il->workqueue = NULL;
3176 il_free_traffic_mem(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003177
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003178 free_irq(il->pci_dev->irq, il);
3179 pci_disable_msi(il->pci_dev);
3180 pci_iounmap(pdev, il->hw_base);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003181 pci_release_regions(pdev);
3182 pci_disable_device(pdev);
3183 pci_set_drvdata(pdev, NULL);
3184
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003185 il4965_uninit_drv(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003186
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003187 dev_kfree_skb(il->beacon_skb);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003188
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003189 ieee80211_free_hw(il->hw);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003190}
3191
3192/*
3193 * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003194 * must be called under il->lock and mac access
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003195 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003196void il4965_txq_set_sched(struct il_priv *il, u32 mask)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003197{
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01003198 il_wr_prph(il, IL49_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) = {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003209 {IL_PCI_DEVICE(0x4229, PCI_ANY_ID, il4965_cfg)},
3210 {IL_PCI_DEVICE(0x4230, PCI_ANY_ID, il4965_cfg)},
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003211 {0}
3212};
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003213MODULE_DEVICE_TABLE(pci, il4965_hw_card_ids);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003214
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003215static struct pci_driver il4965_driver = {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003216 .name = DRV_NAME,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003217 .id_table = il4965_hw_card_ids,
3218 .probe = il4965_pci_probe,
3219 .remove = __devexit_p(il4965_pci_remove),
3220 .driver.pm = IL_LEGACY_PM_OPS,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003221};
3222
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003223static int __init il4965_init(void)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003224{
3225
3226 int ret;
3227 pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n");
3228 pr_info(DRV_COPYRIGHT "\n");
3229
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003230 ret = il4965_rate_control_register();
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003231 if (ret) {
3232 pr_err("Unable to register rate control algorithm: %d\n", ret);
3233 return ret;
3234 }
3235
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003236 ret = pci_register_driver(&il4965_driver);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003237 if (ret) {
3238 pr_err("Unable to initialize PCI module\n");
3239 goto error_register;
3240 }
3241
3242 return ret;
3243
3244error_register:
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003245 il4965_rate_control_unregister();
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003246 return ret;
3247}
3248
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003249static void __exit il4965_exit(void)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003250{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003251 pci_unregister_driver(&il4965_driver);
3252 il4965_rate_control_unregister();
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003253}
3254
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003255module_exit(il4965_exit);
3256module_init(il4965_init);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003257
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01003258#ifdef CONFIG_IWLEGACY_DEBUG
Stanislaw Gruszkad2ddf622011-08-16 14:17:04 +02003259module_param_named(debug, il_debug_level, uint, S_IRUGO | S_IWUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003260MODULE_PARM_DESC(debug, "debug output mask");
3261#endif
3262
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003263module_param_named(swcrypto, il4965_mod_params.sw_crypto, int, S_IRUGO);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003264MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003265module_param_named(queues_num, il4965_mod_params.num_of_queues, int, S_IRUGO);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003266MODULE_PARM_DESC(queues_num, "number of hw queues.");
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003267module_param_named(11n_disable, il4965_mod_params.disable_11n, int, S_IRUGO);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003268MODULE_PARM_DESC(11n_disable, "disable 11n functionality");
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003269module_param_named(amsdu_size_8K, il4965_mod_params.amsdu_size_8K,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003270 int, S_IRUGO);
3271MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003272module_param_named(fw_restart, il4965_mod_params.restart_fw, int, S_IRUGO);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003273MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");