blob: 4a8ad8df828d80062e7c74dbe810faaefa352b0b [file] [log] [blame]
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001/******************************************************************************
2 *
3 * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
4 *
5 * Portions of this file are derived from the ipw3945 project, as well
6 * as portions of the ieee80211 subsystem header files.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of version 2 of the GNU General Public License as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 *
21 * The full GNU General Public License is included in this distribution in the
22 * file called LICENSE.
23 *
24 * Contact Information:
25 * Intel Linux Wireless <ilw@linux.intel.com>
26 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
27 *
28 *****************************************************************************/
29
30#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
31
32#include <linux/kernel.h>
33#include <linux/module.h>
34#include <linux/init.h>
35#include <linux/pci.h>
36#include <linux/pci-aspm.h>
37#include <linux/slab.h>
38#include <linux/dma-mapping.h>
39#include <linux/delay.h>
40#include <linux/sched.h>
41#include <linux/skbuff.h>
42#include <linux/netdevice.h>
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080043#include <linux/firmware.h>
44#include <linux/etherdevice.h>
45#include <linux/if_arp.h>
46
47#include <net/mac80211.h>
48
49#include <asm/div64.h>
50
51#define DRV_NAME "iwl4965"
52
53#include "iwl-eeprom.h"
54#include "iwl-dev.h"
55#include "iwl-core.h"
56#include "iwl-io.h"
57#include "iwl-helpers.h"
58#include "iwl-sta.h"
59#include "iwl-4965-calib.h"
60#include "iwl-4965.h"
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080061
62
63/******************************************************************************
64 *
65 * module boiler plate
66 *
67 ******************************************************************************/
68
69/*
70 * module name, copyright, version, etc.
71 */
72#define DRV_DESCRIPTION "Intel(R) Wireless WiFi 4965 driver for Linux"
73
Stanislaw Gruszkad3175162011-11-15 11:25:42 +010074#ifdef CONFIG_IWLEGACY_DEBUG
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080075#define VD "d"
76#else
77#define VD
78#endif
79
80#define DRV_VERSION IWLWIFI_VERSION VD
81
82
83MODULE_DESCRIPTION(DRV_DESCRIPTION);
84MODULE_VERSION(DRV_VERSION);
85MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
86MODULE_LICENSE("GPL");
87MODULE_ALIAS("iwl4965");
88
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +020089void il4965_update_chain_flags(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080090{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +020091 if (il->cfg->ops->hcmd->set_rxon_chain) {
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +020092 il->cfg->ops->hcmd->set_rxon_chain(il, &il->ctx);
93 if (il->ctx.active.rx_chain != il->ctx.staging.rx_chain)
94 il_commit_rxon(il, &il->ctx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080095 }
96}
97
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +020098static void il4965_clear_free_frames(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -080099{
100 struct list_head *element;
101
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100102 D_INFO("%d frames on pre-allocated heap on clear.\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200103 il->frames_count);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800104
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200105 while (!list_empty(&il->free_frames)) {
106 element = il->free_frames.next;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800107 list_del(element);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200108 kfree(list_entry(element, struct il_frame, list));
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200109 il->frames_count--;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800110 }
111
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200112 if (il->frames_count) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200113 IL_WARN("%d frames still in use. Did we lose one?\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200114 il->frames_count);
115 il->frames_count = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800116 }
117}
118
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200119static struct il_frame *il4965_get_free_frame(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800120{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200121 struct il_frame *frame;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800122 struct list_head *element;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200123 if (list_empty(&il->free_frames)) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800124 frame = kzalloc(sizeof(*frame), GFP_KERNEL);
125 if (!frame) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200126 IL_ERR("Could not allocate frame!\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800127 return NULL;
128 }
129
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200130 il->frames_count++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800131 return frame;
132 }
133
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200134 element = il->free_frames.next;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800135 list_del(element);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200136 return list_entry(element, struct il_frame, list);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800137}
138
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200139static void il4965_free_frame(struct il_priv *il, struct il_frame *frame)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800140{
141 memset(frame, 0, sizeof(*frame));
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200142 list_add(&frame->list, &il->free_frames);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800143}
144
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200145static u32 il4965_fill_beacon_frame(struct il_priv *il,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800146 struct ieee80211_hdr *hdr,
147 int left)
148{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200149 lockdep_assert_held(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800150
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200151 if (!il->beacon_skb)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800152 return 0;
153
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200154 if (il->beacon_skb->len > left)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800155 return 0;
156
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200157 memcpy(hdr, il->beacon_skb->data, il->beacon_skb->len);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800158
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200159 return il->beacon_skb->len;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800160}
161
162/* Parse the beacon frame to find the TIM element and set tim_idx & tim_size */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200163static void il4965_set_beacon_tim(struct il_priv *il,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200164 struct il_tx_beacon_cmd *tx_beacon_cmd,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800165 u8 *beacon, u32 frame_size)
166{
167 u16 tim_idx;
168 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)beacon;
169
170 /*
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +0100171 * The idx is relative to frame start but we start looking at the
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800172 * variable-length part of the beacon.
173 */
174 tim_idx = mgmt->u.beacon.variable - beacon;
175
176 /* Parse variable-length elements of beacon to find WLAN_EID_TIM */
177 while ((tim_idx < (frame_size - 2)) &&
178 (beacon[tim_idx] != WLAN_EID_TIM))
179 tim_idx += beacon[tim_idx+1] + 2;
180
181 /* If TIM field was found, set variables */
182 if ((tim_idx < (frame_size - 1)) && (beacon[tim_idx] == WLAN_EID_TIM)) {
183 tx_beacon_cmd->tim_idx = cpu_to_le16(tim_idx);
184 tx_beacon_cmd->tim_size = beacon[tim_idx+1];
185 } else
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200186 IL_WARN("Unable to find TIM Element in beacon\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800187}
188
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200189static unsigned int il4965_hw_get_beacon_cmd(struct il_priv *il,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200190 struct il_frame *frame)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800191{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200192 struct il_tx_beacon_cmd *tx_beacon_cmd;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800193 u32 frame_size;
194 u32 rate_flags;
195 u32 rate;
196 /*
197 * We have to set up the TX command, the TX Beacon command, and the
198 * beacon contents.
199 */
200
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200201 lockdep_assert_held(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800202
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200203 if (!il->beacon_ctx) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200204 IL_ERR("trying to build beacon w/o beacon context!\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800205 return 0;
206 }
207
208 /* Initialize memory */
209 tx_beacon_cmd = &frame->u.beacon;
210 memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
211
212 /* Set up TX beacon contents */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200213 frame_size = il4965_fill_beacon_frame(il, tx_beacon_cmd->frame,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800214 sizeof(frame->u) - sizeof(*tx_beacon_cmd));
215 if (WARN_ON_ONCE(frame_size > MAX_MPDU_SIZE))
216 return 0;
217 if (!frame_size)
218 return 0;
219
220 /* Set up TX command fields */
221 tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200222 tx_beacon_cmd->tx.sta_id = il->beacon_ctx->bcast_sta_id;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800223 tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
224 tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK |
225 TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK;
226
227 /* Set up TX beacon command fields */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200228 il4965_set_beacon_tim(il, tx_beacon_cmd, (u8 *)tx_beacon_cmd->frame,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800229 frame_size);
230
231 /* Set up packet rate and flags */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200232 rate = il_get_lowest_plcp(il, il->beacon_ctx);
233 il->mgmt_tx_ant = il4965_toggle_tx_ant(il, il->mgmt_tx_ant,
234 il->hw_params.valid_tx_ant);
235 rate_flags = il4965_ant_idx_to_flags(il->mgmt_tx_ant);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200236 if ((rate >= IL_FIRST_CCK_RATE) && (rate <= IL_LAST_CCK_RATE))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800237 rate_flags |= RATE_MCS_CCK_MSK;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200238 tx_beacon_cmd->tx.rate_n_flags = il4965_hw_set_rate_n_flags(rate,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800239 rate_flags);
240
241 return sizeof(*tx_beacon_cmd) + frame_size;
242}
243
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200244int il4965_send_beacon_cmd(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800245{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200246 struct il_frame *frame;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800247 unsigned int frame_size;
248 int rc;
249
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200250 frame = il4965_get_free_frame(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800251 if (!frame) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200252 IL_ERR("Could not obtain free frame buffer for beacon "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800253 "command.\n");
254 return -ENOMEM;
255 }
256
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200257 frame_size = il4965_hw_get_beacon_cmd(il, frame);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800258 if (!frame_size) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200259 IL_ERR("Error configuring the beacon command\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200260 il4965_free_frame(il, frame);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800261 return -EINVAL;
262 }
263
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200264 rc = il_send_cmd_pdu(il, REPLY_TX_BEACON, frame_size,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800265 &frame->u.cmd[0]);
266
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200267 il4965_free_frame(il, frame);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800268
269 return rc;
270}
271
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200272static inline dma_addr_t il4965_tfd_tb_get_addr(struct il_tfd *tfd, u8 idx)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800273{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200274 struct il_tfd_tb *tb = &tfd->tbs[idx];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800275
276 dma_addr_t addr = get_unaligned_le32(&tb->lo);
277 if (sizeof(dma_addr_t) > sizeof(u32))
278 addr |=
279 ((dma_addr_t)(le16_to_cpu(tb->hi_n_len) & 0xF) << 16) << 16;
280
281 return addr;
282}
283
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200284static inline u16 il4965_tfd_tb_get_len(struct il_tfd *tfd, u8 idx)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800285{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200286 struct il_tfd_tb *tb = &tfd->tbs[idx];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800287
288 return le16_to_cpu(tb->hi_n_len) >> 4;
289}
290
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200291static inline void il4965_tfd_set_tb(struct il_tfd *tfd, u8 idx,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800292 dma_addr_t addr, u16 len)
293{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200294 struct il_tfd_tb *tb = &tfd->tbs[idx];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800295 u16 hi_n_len = len << 4;
296
297 put_unaligned_le32(addr, &tb->lo);
298 if (sizeof(dma_addr_t) > sizeof(u32))
299 hi_n_len |= ((addr >> 16) >> 16) & 0xF;
300
301 tb->hi_n_len = cpu_to_le16(hi_n_len);
302
303 tfd->num_tbs = idx + 1;
304}
305
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200306static inline u8 il4965_tfd_get_num_tbs(struct il_tfd *tfd)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800307{
308 return tfd->num_tbs & 0x1f;
309}
310
311/**
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200312 * il4965_hw_txq_free_tfd - Free all chunks referenced by TFD [txq->q.read_ptr]
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200313 * @il - driver ilate data
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800314 * @txq - tx queue
315 *
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +0100316 * Does NOT advance any TFD circular buffer read/write idxes
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800317 * Does NOT free the TFD itself (which is within circular buffer)
318 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200319void il4965_hw_txq_free_tfd(struct il_priv *il, struct il_tx_queue *txq)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800320{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200321 struct il_tfd *tfd_tmp = (struct il_tfd *)txq->tfds;
322 struct il_tfd *tfd;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200323 struct pci_dev *dev = il->pci_dev;
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +0100324 int idx = txq->q.read_ptr;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800325 int i;
326 int num_tbs;
327
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +0100328 tfd = &tfd_tmp[idx];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800329
330 /* Sanity check on number of chunks */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200331 num_tbs = il4965_tfd_get_num_tbs(tfd);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800332
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200333 if (num_tbs >= IL_NUM_OF_TBS) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200334 IL_ERR("Too many chunks: %i\n", num_tbs);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800335 /* @todo issue fatal error, it is quite serious situation */
336 return;
337 }
338
339 /* Unmap tx_cmd */
340 if (num_tbs)
341 pci_unmap_single(dev,
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +0100342 dma_unmap_addr(&txq->meta[idx], mapping),
343 dma_unmap_len(&txq->meta[idx], len),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800344 PCI_DMA_BIDIRECTIONAL);
345
346 /* Unmap chunks, if any. */
347 for (i = 1; i < num_tbs; i++)
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200348 pci_unmap_single(dev, il4965_tfd_tb_get_addr(tfd, i),
349 il4965_tfd_tb_get_len(tfd, i),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800350 PCI_DMA_TODEVICE);
351
352 /* free SKB */
353 if (txq->txb) {
354 struct sk_buff *skb;
355
356 skb = txq->txb[txq->q.read_ptr].skb;
357
358 /* can be called from irqs-disabled context */
359 if (skb) {
360 dev_kfree_skb_any(skb);
361 txq->txb[txq->q.read_ptr].skb = NULL;
362 }
363 }
364}
365
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200366int il4965_hw_txq_attach_buf_to_tfd(struct il_priv *il,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200367 struct il_tx_queue *txq,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800368 dma_addr_t addr, u16 len,
369 u8 reset, u8 pad)
370{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200371 struct il_queue *q;
372 struct il_tfd *tfd, *tfd_tmp;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800373 u32 num_tbs;
374
375 q = &txq->q;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200376 tfd_tmp = (struct il_tfd *)txq->tfds;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800377 tfd = &tfd_tmp[q->write_ptr];
378
379 if (reset)
380 memset(tfd, 0, sizeof(*tfd));
381
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200382 num_tbs = il4965_tfd_get_num_tbs(tfd);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800383
384 /* Each TFD can point to a maximum 20 Tx buffers */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200385 if (num_tbs >= IL_NUM_OF_TBS) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200386 IL_ERR("Error can not send more than %d chunks\n",
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200387 IL_NUM_OF_TBS);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800388 return -EINVAL;
389 }
390
391 BUG_ON(addr & ~DMA_BIT_MASK(36));
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200392 if (unlikely(addr & ~IL_TX_DMA_MASK))
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200393 IL_ERR("Unaligned address = %llx\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800394 (unsigned long long)addr);
395
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200396 il4965_tfd_set_tb(tfd, num_tbs, addr, len);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800397
398 return 0;
399}
400
401/*
402 * Tell nic where to find circular buffer of Tx Frame Descriptors for
403 * given Tx queue, and enable the DMA channel used for that queue.
404 *
405 * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
406 * channels supported in hardware.
407 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200408int il4965_hw_tx_queue_init(struct il_priv *il,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200409 struct il_tx_queue *txq)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800410{
411 int txq_id = txq->q.id;
412
413 /* Circular buffer (TFD queue in DRAM) physical base address */
Stanislaw Gruszka0c1a94e2011-08-24 17:37:16 +0200414 il_wr(il, FH_MEM_CBBC_QUEUE(txq_id),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800415 txq->q.dma_addr >> 8);
416
417 return 0;
418}
419
420/******************************************************************************
421 *
422 * Generic RX handler implementations
423 *
424 ******************************************************************************/
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200425static void il4965_rx_reply_alive(struct il_priv *il,
Stanislaw Gruszkab73bb5f2011-08-26 14:37:54 +0200426 struct il_rx_buf *rxb)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800427{
Stanislaw Gruszkadcae1c62011-08-26 14:36:21 +0200428 struct il_rx_pkt *pkt = rxb_addr(rxb);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200429 struct il_alive_resp *palive;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800430 struct delayed_work *pwork;
431
432 palive = &pkt->u.alive_frame;
433
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100434 D_INFO("Alive ucode status 0x%08X revision "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800435 "0x%01X 0x%01X\n",
436 palive->is_valid, palive->ver_type,
437 palive->ver_subtype);
438
439 if (palive->ver_subtype == INITIALIZE_SUBTYPE) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100440 D_INFO("Initialization Alive received.\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200441 memcpy(&il->card_alive_init,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800442 &pkt->u.alive_frame,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200443 sizeof(struct il_init_alive_resp));
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200444 pwork = &il->init_alive_start;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800445 } else {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100446 D_INFO("Runtime Alive received.\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200447 memcpy(&il->card_alive, &pkt->u.alive_frame,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200448 sizeof(struct il_alive_resp));
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200449 pwork = &il->alive_start;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800450 }
451
452 /* We delay the ALIVE response by 5ms to
453 * give the HW RF Kill time to activate... */
454 if (palive->is_valid == UCODE_VALID_OK)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200455 queue_delayed_work(il->workqueue, pwork,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800456 msecs_to_jiffies(5));
457 else
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200458 IL_WARN("uCode did not respond OK.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800459}
460
461/**
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +0200462 * il4965_bg_stats_periodic - Timer callback to queue stats
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800463 *
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +0200464 * This callback is provided in order to send a stats request.
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800465 *
466 * This timer function is continually reset to execute within
467 * REG_RECALIB_PERIOD seconds since the last STATISTICS_NOTIFICATION
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +0200468 * was received. We need to ensure we receive the stats in order
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800469 * to update the temperature used for calibrating the TXPOWER.
470 */
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +0200471static void il4965_bg_stats_periodic(unsigned long data)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800472{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200473 struct il_priv *il = (struct il_priv *)data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800474
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200475 if (test_bit(STATUS_EXIT_PENDING, &il->status))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800476 return;
477
478 /* dont send host command if rf-kill is on */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200479 if (!il_is_ready_rf(il))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800480 return;
481
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +0200482 il_send_stats_request(il, CMD_ASYNC, false);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800483}
484
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200485static void il4965_rx_beacon_notif(struct il_priv *il,
Stanislaw Gruszkab73bb5f2011-08-26 14:37:54 +0200486 struct il_rx_buf *rxb)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800487{
Stanislaw Gruszkadcae1c62011-08-26 14:36:21 +0200488 struct il_rx_pkt *pkt = rxb_addr(rxb);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200489 struct il4965_beacon_notif *beacon =
490 (struct il4965_beacon_notif *)pkt->u.raw;
Stanislaw Gruszkad3175162011-11-15 11:25:42 +0100491#ifdef CONFIG_IWLEGACY_DEBUG
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200492 u8 rate = il4965_hw_get_rate(beacon->beacon_notify_hdr.rate_n_flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800493
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100494 D_RX("beacon status %x retries %d iss %d "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800495 "tsf %d %d rate %d\n",
496 le32_to_cpu(beacon->beacon_notify_hdr.u.status) & TX_STATUS_MSK,
497 beacon->beacon_notify_hdr.failure_frame,
498 le32_to_cpu(beacon->ibss_mgr_status),
499 le32_to_cpu(beacon->high_tsf),
500 le32_to_cpu(beacon->low_tsf), rate);
501#endif
502
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200503 il->ibss_manager = le32_to_cpu(beacon->ibss_mgr_status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800504}
505
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200506static void il4965_perform_ct_kill_task(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800507{
508 unsigned long flags;
509
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100510 D_POWER("Stop all queues\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800511
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200512 if (il->mac80211_registered)
513 ieee80211_stop_queues(il->hw);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800514
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +0200515 _il_wr(il, CSR_UCODE_DRV_GP1_SET,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800516 CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +0200517 _il_rd(il, CSR_UCODE_DRV_GP1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800518
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200519 spin_lock_irqsave(&il->reg_lock, flags);
Stanislaw Gruszka13882262011-08-24 15:39:23 +0200520 if (!_il_grab_nic_access(il))
521 _il_release_nic_access(il);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200522 spin_unlock_irqrestore(&il->reg_lock, flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800523}
524
525/* Handle notification from uCode that card's power state is changing
526 * due to software, hardware, or critical temperature RFKILL */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200527static void il4965_rx_card_state_notif(struct il_priv *il,
Stanislaw Gruszkab73bb5f2011-08-26 14:37:54 +0200528 struct il_rx_buf *rxb)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800529{
Stanislaw Gruszkadcae1c62011-08-26 14:36:21 +0200530 struct il_rx_pkt *pkt = rxb_addr(rxb);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800531 u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200532 unsigned long status = il->status;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800533
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100534 D_RF_KILL("Card state received: HW:%s SW:%s CT:%s\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800535 (flags & HW_CARD_DISABLED) ? "Kill" : "On",
536 (flags & SW_CARD_DISABLED) ? "Kill" : "On",
537 (flags & CT_CARD_DISABLED) ?
538 "Reached" : "Not reached");
539
540 if (flags & (SW_CARD_DISABLED | HW_CARD_DISABLED |
541 CT_CARD_DISABLED)) {
542
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +0200543 _il_wr(il, CSR_UCODE_DRV_GP1_SET,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800544 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
545
Stanislaw Gruszka0c1a94e2011-08-24 17:37:16 +0200546 il_wr(il, HBUS_TARG_MBX_C,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800547 HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
548
549 if (!(flags & RXON_CARD_DISABLED)) {
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +0200550 _il_wr(il, CSR_UCODE_DRV_GP1_CLR,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800551 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
Stanislaw Gruszka0c1a94e2011-08-24 17:37:16 +0200552 il_wr(il, HBUS_TARG_MBX_C,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800553 HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
554 }
555 }
556
557 if (flags & CT_CARD_DISABLED)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200558 il4965_perform_ct_kill_task(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800559
560 if (flags & HW_CARD_DISABLED)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200561 set_bit(STATUS_RF_KILL_HW, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800562 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200563 clear_bit(STATUS_RF_KILL_HW, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800564
565 if (!(flags & RXON_CARD_DISABLED))
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200566 il_scan_cancel(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800567
568 if ((test_bit(STATUS_RF_KILL_HW, &status) !=
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200569 test_bit(STATUS_RF_KILL_HW, &il->status)))
570 wiphy_rfkill_set_hw_state(il->hw->wiphy,
571 test_bit(STATUS_RF_KILL_HW, &il->status));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800572 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200573 wake_up(&il->wait_command_queue);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800574}
575
576/**
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200577 * il4965_setup_rx_handlers - Initialize Rx handler callbacks
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800578 *
579 * Setup the RX handlers for each of the reply types sent from the uCode
580 * to the host.
581 *
582 * This function chains into the hardware specific files for them to setup
583 * any hardware specific handlers as well.
584 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200585static void il4965_setup_rx_handlers(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800586{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200587 il->rx_handlers[REPLY_ALIVE] = il4965_rx_reply_alive;
588 il->rx_handlers[REPLY_ERROR] = il_rx_reply_error;
589 il->rx_handlers[CHANNEL_SWITCH_NOTIFICATION] = il_rx_csa;
590 il->rx_handlers[SPECTRUM_MEASURE_NOTIFICATION] =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200591 il_rx_spectrum_measure_notif;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200592 il->rx_handlers[PM_SLEEP_NOTIFICATION] = il_rx_pm_sleep_notif;
593 il->rx_handlers[PM_DEBUG_STATISTIC_NOTIFIC] =
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +0200594 il_rx_pm_debug_stats_notif;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200595 il->rx_handlers[BEACON_NOTIFICATION] = il4965_rx_beacon_notif;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800596
597 /*
598 * The same handler is used for both the REPLY to a discrete
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +0200599 * stats request from the host as well as for the periodic
600 * stats notifications (after received beacons) from the uCode.
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800601 */
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +0200602 il->rx_handlers[REPLY_STATISTICS_CMD] = il4965_reply_stats;
603 il->rx_handlers[STATISTICS_NOTIFICATION] = il4965_rx_stats;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800604
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200605 il_setup_rx_scan_handlers(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800606
607 /* status change handler */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200608 il->rx_handlers[CARD_STATE_NOTIFICATION] =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200609 il4965_rx_card_state_notif;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800610
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200611 il->rx_handlers[MISSED_BEACONS_NOTIFICATION] =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200612 il4965_rx_missed_beacon_notif;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800613 /* Rx handlers */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200614 il->rx_handlers[REPLY_RX_PHY_CMD] = il4965_rx_reply_rx_phy;
615 il->rx_handlers[REPLY_RX_MPDU_CMD] = il4965_rx_reply_rx;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800616 /* block ack */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200617 il->rx_handlers[REPLY_COMPRESSED_BA] = il4965_rx_reply_compressed_ba;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800618 /* Set up hardware specific Rx handlers */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200619 il->cfg->ops->lib->rx_handler_setup(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800620}
621
622/**
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200623 * il4965_rx_handle - Main entry function for receiving responses from uCode
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800624 *
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200625 * Uses the il->rx_handlers callback function array to invoke
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800626 * the appropriate handlers, including command responses,
627 * frame-received notifications, and other notifications.
628 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200629void il4965_rx_handle(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800630{
Stanislaw Gruszkab73bb5f2011-08-26 14:37:54 +0200631 struct il_rx_buf *rxb;
Stanislaw Gruszkadcae1c62011-08-26 14:36:21 +0200632 struct il_rx_pkt *pkt;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200633 struct il_rx_queue *rxq = &il->rxq;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800634 u32 r, i;
635 int reclaim;
636 unsigned long flags;
637 u8 fill_rx = 0;
638 u32 count = 8;
639 int total_empty;
640
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +0100641 /* uCode's read idx (stored in shared DRAM) indicates the last Rx
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800642 * buffer that the driver may process (last buffer filled by ucode). */
643 r = le16_to_cpu(rxq->rb_stts->closed_rb_num) & 0x0FFF;
644 i = rxq->read;
645
646 /* Rx interrupt, but nothing sent from uCode */
647 if (i == r)
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100648 D_RX("r = %d, i = %d\n", r, i);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800649
650 /* calculate total frames need to be restock after handling RX */
651 total_empty = r - rxq->write_actual;
652 if (total_empty < 0)
653 total_empty += RX_QUEUE_SIZE;
654
655 if (total_empty > (RX_QUEUE_SIZE / 2))
656 fill_rx = 1;
657
658 while (i != r) {
659 int len;
660
661 rxb = rxq->queue[i];
662
663 /* If an RXB doesn't have a Rx queue slot associated with it,
664 * then a bug has been introduced in the queue refilling
665 * routines -- catch it here */
666 BUG_ON(rxb == NULL);
667
668 rxq->queue[i] = NULL;
669
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200670 pci_unmap_page(il->pci_dev, rxb->page_dma,
671 PAGE_SIZE << il->hw_params.rx_page_order,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800672 PCI_DMA_FROMDEVICE);
673 pkt = rxb_addr(rxb);
674
675 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
676 len += sizeof(u32); /* account for status word */
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800677
678 /* Reclaim a command buffer only if this packet is a response
679 * to a (driver-originated) command.
680 * If the packet (e.g. Rx frame) originated from uCode,
681 * there is no command buffer to reclaim.
682 * Ucode should set SEQ_RX_FRAME bit if ucode-originated,
683 * but apparently a few don't get set; catch them here. */
684 reclaim = !(pkt->hdr.sequence & SEQ_RX_FRAME) &&
685 (pkt->hdr.cmd != REPLY_RX_PHY_CMD) &&
686 (pkt->hdr.cmd != REPLY_RX) &&
687 (pkt->hdr.cmd != REPLY_RX_MPDU_CMD) &&
688 (pkt->hdr.cmd != REPLY_COMPRESSED_BA) &&
689 (pkt->hdr.cmd != STATISTICS_NOTIFICATION) &&
690 (pkt->hdr.cmd != REPLY_TX);
691
692 /* Based on type of command response or notification,
693 * handle those that need handling via function in
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200694 * rx_handlers table. See il4965_setup_rx_handlers() */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200695 if (il->rx_handlers[pkt->hdr.cmd]) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100696 D_RX("r = %d, i = %d, %s, 0x%02x\n", r,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200697 i, il_get_cmd_string(pkt->hdr.cmd),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800698 pkt->hdr.cmd);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200699 il->isr_stats.rx_handlers[pkt->hdr.cmd]++;
700 il->rx_handlers[pkt->hdr.cmd] (il, rxb);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800701 } else {
702 /* No handling needed */
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100703 D_RX(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800704 "r %d i %d No handler needed for %s, 0x%02x\n",
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200705 r, i, il_get_cmd_string(pkt->hdr.cmd),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800706 pkt->hdr.cmd);
707 }
708
709 /*
710 * XXX: After here, we should always check rxb->page
711 * against NULL before touching it or its virtual
712 * memory (pkt). Because some rx_handler might have
713 * already taken or freed the pages.
714 */
715
716 if (reclaim) {
717 /* Invoke any callbacks, transfer the buffer to caller,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200718 * and fire off the (possibly) blocking il_send_cmd()
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800719 * as we reclaim the driver command queue */
720 if (rxb->page)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200721 il_tx_cmd_complete(il, rxb);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800722 else
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200723 IL_WARN("Claim null rxb?\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800724 }
725
726 /* Reuse the page if possible. For notification packets and
727 * SKBs that fail to Rx correctly, add them back into the
728 * rx_free list for reuse later. */
729 spin_lock_irqsave(&rxq->lock, flags);
730 if (rxb->page != NULL) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200731 rxb->page_dma = pci_map_page(il->pci_dev, rxb->page,
732 0, PAGE_SIZE << il->hw_params.rx_page_order,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800733 PCI_DMA_FROMDEVICE);
734 list_add_tail(&rxb->list, &rxq->rx_free);
735 rxq->free_count++;
736 } else
737 list_add_tail(&rxb->list, &rxq->rx_used);
738
739 spin_unlock_irqrestore(&rxq->lock, flags);
740
741 i = (i + 1) & RX_QUEUE_MASK;
742 /* If there are a lot of unused frames,
743 * restock the Rx queue so ucode wont assert. */
744 if (fill_rx) {
745 count++;
746 if (count >= 8) {
747 rxq->read = i;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200748 il4965_rx_replenish_now(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800749 count = 0;
750 }
751 }
752 }
753
754 /* Backtrack one entry */
755 rxq->read = i;
756 if (fill_rx)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200757 il4965_rx_replenish_now(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800758 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200759 il4965_rx_queue_restock(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800760}
761
762/* call this function to flush any scheduled tasklet */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200763static inline void il4965_synchronize_irq(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800764{
765 /* wait to make sure we flush pending tasklet*/
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200766 synchronize_irq(il->pci_dev->irq);
767 tasklet_kill(&il->irq_tasklet);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800768}
769
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200770static void il4965_irq_tasklet(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800771{
772 u32 inta, handled = 0;
773 u32 inta_fh;
774 unsigned long flags;
775 u32 i;
Stanislaw Gruszkad3175162011-11-15 11:25:42 +0100776#ifdef CONFIG_IWLEGACY_DEBUG
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800777 u32 inta_mask;
778#endif
779
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200780 spin_lock_irqsave(&il->lock, flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800781
782 /* Ack/clear/reset pending uCode interrupts.
783 * Note: Some bits in CSR_INT are "OR" of bits in CSR_FH_INT_STATUS,
784 * and will clear only when CSR_FH_INT_STATUS gets cleared. */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +0200785 inta = _il_rd(il, CSR_INT);
786 _il_wr(il, CSR_INT, inta);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800787
788 /* Ack/clear/reset pending flow-handler (DMA) interrupts.
789 * Any new interrupts that happen after this, either while we're
790 * in this tasklet, or later, will show up in next ISR/tasklet. */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +0200791 inta_fh = _il_rd(il, CSR_FH_INT_STATUS);
792 _il_wr(il, CSR_FH_INT_STATUS, inta_fh);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800793
Stanislaw Gruszkad3175162011-11-15 11:25:42 +0100794#ifdef CONFIG_IWLEGACY_DEBUG
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200795 if (il_get_debug_level(il) & IL_DL_ISR) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800796 /* just for debug */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +0200797 inta_mask = _il_rd(il, CSR_INT_MASK);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100798 D_ISR("inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800799 inta, inta_mask, inta_fh);
800 }
801#endif
802
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200803 spin_unlock_irqrestore(&il->lock, flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800804
805 /* Since CSR_INT and CSR_FH_INT_STATUS reads and clears are not
806 * atomic, make sure that inta covers all the interrupts that
807 * we've discovered, even if FH interrupt came in just after
808 * reading CSR_INT. */
809 if (inta_fh & CSR49_FH_INT_RX_MASK)
810 inta |= CSR_INT_BIT_FH_RX;
811 if (inta_fh & CSR49_FH_INT_TX_MASK)
812 inta |= CSR_INT_BIT_FH_TX;
813
814 /* Now service all interrupt bits discovered above. */
815 if (inta & CSR_INT_BIT_HW_ERR) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200816 IL_ERR("Hardware error detected. Restarting.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800817
818 /* Tell the device to stop sending interrupts */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200819 il_disable_interrupts(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800820
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200821 il->isr_stats.hw++;
822 il_irq_handle_error(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800823
824 handled |= CSR_INT_BIT_HW_ERR;
825
826 return;
827 }
828
Stanislaw Gruszkad3175162011-11-15 11:25:42 +0100829#ifdef CONFIG_IWLEGACY_DEBUG
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200830 if (il_get_debug_level(il) & (IL_DL_ISR)) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800831 /* NIC fires this, but we don't use it, redundant with WAKEUP */
832 if (inta & CSR_INT_BIT_SCD) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100833 D_ISR("Scheduler finished to transmit "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800834 "the frame/frames.\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200835 il->isr_stats.sch++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800836 }
837
838 /* Alive notification via Rx interrupt will do the real work */
839 if (inta & CSR_INT_BIT_ALIVE) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100840 D_ISR("Alive interrupt\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200841 il->isr_stats.alive++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800842 }
843 }
844#endif
845 /* Safely ignore these bits for debug checks below */
846 inta &= ~(CSR_INT_BIT_SCD | CSR_INT_BIT_ALIVE);
847
848 /* HW RF KILL switch toggled */
849 if (inta & CSR_INT_BIT_RF_KILL) {
850 int hw_rf_kill = 0;
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +0200851 if (!(_il_rd(il, CSR_GP_CNTRL) &
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800852 CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
853 hw_rf_kill = 1;
854
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200855 IL_WARN("RF_KILL bit toggled to %s.\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800856 hw_rf_kill ? "disable radio" : "enable radio");
857
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200858 il->isr_stats.rfkill++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800859
860 /* driver only loads ucode once setting the interface up.
861 * the driver allows loading the ucode even if the radio
862 * is killed. Hence update the killswitch state here. The
863 * rfkill handler will care about restarting if needed.
864 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200865 if (!test_bit(STATUS_ALIVE, &il->status)) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800866 if (hw_rf_kill)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200867 set_bit(STATUS_RF_KILL_HW, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800868 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200869 clear_bit(STATUS_RF_KILL_HW, &il->status);
870 wiphy_rfkill_set_hw_state(il->hw->wiphy, hw_rf_kill);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800871 }
872
873 handled |= CSR_INT_BIT_RF_KILL;
874 }
875
876 /* Chip got too hot and stopped itself */
877 if (inta & CSR_INT_BIT_CT_KILL) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200878 IL_ERR("Microcode CT kill error detected.\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200879 il->isr_stats.ctkill++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800880 handled |= CSR_INT_BIT_CT_KILL;
881 }
882
883 /* Error detected by uCode */
884 if (inta & CSR_INT_BIT_SW_ERR) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200885 IL_ERR("Microcode SW error detected. "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800886 " Restarting 0x%X.\n", inta);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200887 il->isr_stats.sw++;
888 il_irq_handle_error(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800889 handled |= CSR_INT_BIT_SW_ERR;
890 }
891
892 /*
893 * uCode wakes up after power-down sleep.
894 * Tell device about any new tx or host commands enqueued,
895 * and about any Rx buffers made available while asleep.
896 */
897 if (inta & CSR_INT_BIT_WAKEUP) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100898 D_ISR("Wakeup interrupt\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200899 il_rx_queue_update_write_ptr(il, &il->rxq);
900 for (i = 0; i < il->hw_params.max_txq_num; i++)
901 il_txq_update_write_ptr(il, &il->txq[i]);
902 il->isr_stats.wakeup++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800903 handled |= CSR_INT_BIT_WAKEUP;
904 }
905
906 /* All uCode command responses, including Tx command responses,
907 * Rx "responses" (frame-received notification), and other
908 * notifications from uCode come through here*/
909 if (inta & (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX)) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200910 il4965_rx_handle(il);
911 il->isr_stats.rx++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800912 handled |= (CSR_INT_BIT_FH_RX | CSR_INT_BIT_SW_RX);
913 }
914
915 /* This "Tx" DMA channel is used only for loading uCode */
916 if (inta & CSR_INT_BIT_FH_TX) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100917 D_ISR("uCode load interrupt\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200918 il->isr_stats.tx++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800919 handled |= CSR_INT_BIT_FH_TX;
920 /* Wake up uCode load routine, now that load is complete */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200921 il->ucode_write_complete = 1;
922 wake_up(&il->wait_command_queue);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800923 }
924
925 if (inta & ~handled) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200926 IL_ERR("Unhandled INTA bits 0x%08x\n", inta & ~handled);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200927 il->isr_stats.unhandled++;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800928 }
929
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200930 if (inta & ~(il->inta_mask)) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200931 IL_WARN("Disabled INTA bits 0x%08x were pending\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200932 inta & ~il->inta_mask);
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200933 IL_WARN(" with FH_INT = 0x%08x\n", inta_fh);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800934 }
935
936 /* Re-enable all interrupts */
Stanislaw Gruszka93fd74e2011-04-28 11:51:30 +0200937 /* only Re-enable if disabled by irq */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200938 if (test_bit(STATUS_INT_ENABLED, &il->status))
939 il_enable_interrupts(il);
Stanislaw Gruszkaa078a1f2011-04-28 11:51:25 +0200940 /* Re-enable RF_KILL if it occurred */
941 else if (handled & CSR_INT_BIT_RF_KILL)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200942 il_enable_rfkill_int(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800943
Stanislaw Gruszkad3175162011-11-15 11:25:42 +0100944#ifdef CONFIG_IWLEGACY_DEBUG
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200945 if (il_get_debug_level(il) & (IL_DL_ISR)) {
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +0200946 inta = _il_rd(il, CSR_INT);
947 inta_mask = _il_rd(il, CSR_INT_MASK);
948 inta_fh = _il_rd(il, CSR_FH_INT_STATUS);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +0100949 D_ISR(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800950 "End inta 0x%08x, enabled 0x%08x, fh 0x%08x, "
951 "flags 0x%08lx\n", inta, inta_mask, inta_fh, flags);
952 }
953#endif
954}
955
956/*****************************************************************************
957 *
958 * sysfs attributes
959 *
960 *****************************************************************************/
961
Stanislaw Gruszkad3175162011-11-15 11:25:42 +0100962#ifdef CONFIG_IWLEGACY_DEBUG
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800963
964/*
965 * The following adds a new attribute to the sysfs representation
966 * of this device driver (i.e. a new file in /sys/class/net/wlan0/device/)
967 * used for controlling the debug level.
968 *
969 * See the level definitions in iwl for details.
970 *
971 * The debug_level being managed using sysfs below is a per device debug
972 * level that is used instead of the global debug level if it (the per
973 * device debug level) is set.
974 */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200975static ssize_t il4965_show_debug_level(struct device *d,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800976 struct device_attribute *attr, char *buf)
977{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200978 struct il_priv *il = dev_get_drvdata(d);
979 return sprintf(buf, "0x%08X\n", il_get_debug_level(il));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800980}
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +0200981static ssize_t il4965_store_debug_level(struct device *d,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800982 struct device_attribute *attr,
983 const char *buf, size_t count)
984{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200985 struct il_priv *il = dev_get_drvdata(d);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800986 unsigned long val;
987 int ret;
988
989 ret = strict_strtoul(buf, 0, &val);
990 if (ret)
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200991 IL_ERR("%s is not in hex or decimal form.\n", buf);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800992 else {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +0200993 il->debug_level = val;
994 if (il_alloc_traffic_mem(il))
Stanislaw Gruszka9406f792011-08-18 22:07:57 +0200995 IL_ERR(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -0800996 "Not enough memory to generate traffic log\n");
997 }
998 return strnlen(buf, count);
999}
1000
1001static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001002 il4965_show_debug_level, il4965_store_debug_level);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001003
1004
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001005#endif /* CONFIG_IWLEGACY_DEBUG */
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001006
1007
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001008static ssize_t il4965_show_temperature(struct device *d,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001009 struct device_attribute *attr, char *buf)
1010{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001011 struct il_priv *il = dev_get_drvdata(d);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001012
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001013 if (!il_is_alive(il))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001014 return -EAGAIN;
1015
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001016 return sprintf(buf, "%d\n", il->temperature);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001017}
1018
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001019static DEVICE_ATTR(temperature, S_IRUGO, il4965_show_temperature, NULL);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001020
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001021static ssize_t il4965_show_tx_power(struct device *d,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001022 struct device_attribute *attr, char *buf)
1023{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001024 struct il_priv *il = dev_get_drvdata(d);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001025
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001026 if (!il_is_ready_rf(il))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001027 return sprintf(buf, "off\n");
1028 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001029 return sprintf(buf, "%d\n", il->tx_power_user_lmt);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001030}
1031
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001032static ssize_t il4965_store_tx_power(struct device *d,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001033 struct device_attribute *attr,
1034 const char *buf, size_t count)
1035{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001036 struct il_priv *il = dev_get_drvdata(d);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001037 unsigned long val;
1038 int ret;
1039
1040 ret = strict_strtoul(buf, 10, &val);
1041 if (ret)
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001042 IL_INFO("%s is not in decimal form.\n", buf);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001043 else {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001044 ret = il_set_tx_power(il, val, false);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001045 if (ret)
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001046 IL_ERR("failed setting tx power (0x%d).\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001047 ret);
1048 else
1049 ret = count;
1050 }
1051 return ret;
1052}
1053
1054static DEVICE_ATTR(tx_power, S_IWUSR | S_IRUGO,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001055 il4965_show_tx_power, il4965_store_tx_power);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001056
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001057static struct attribute *il_sysfs_entries[] = {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001058 &dev_attr_temperature.attr,
1059 &dev_attr_tx_power.attr,
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001060#ifdef CONFIG_IWLEGACY_DEBUG
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001061 &dev_attr_debug_level.attr,
1062#endif
1063 NULL
1064};
1065
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001066static struct attribute_group il_attribute_group = {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001067 .name = NULL, /* put in device directory */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001068 .attrs = il_sysfs_entries,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001069};
1070
1071/******************************************************************************
1072 *
1073 * uCode download functions
1074 *
1075 ******************************************************************************/
1076
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001077static void il4965_dealloc_ucode_pci(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001078{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001079 il_free_fw_desc(il->pci_dev, &il->ucode_code);
1080 il_free_fw_desc(il->pci_dev, &il->ucode_data);
1081 il_free_fw_desc(il->pci_dev, &il->ucode_data_backup);
1082 il_free_fw_desc(il->pci_dev, &il->ucode_init);
1083 il_free_fw_desc(il->pci_dev, &il->ucode_init_data);
1084 il_free_fw_desc(il->pci_dev, &il->ucode_boot);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001085}
1086
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001087static void il4965_nic_start(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001088{
1089 /* Remove all resets to allow NIC to operate */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02001090 _il_wr(il, CSR_RESET, 0);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001091}
1092
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001093static void il4965_ucode_callback(const struct firmware *ucode_raw,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001094 void *context);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001095static int il4965_mac_setup_register(struct il_priv *il,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001096 u32 max_probe_length);
1097
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001098static int __must_check il4965_request_firmware(struct il_priv *il, bool first)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001099{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001100 const char *name_pre = il->cfg->fw_name_pre;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001101 char tag[8];
1102
1103 if (first) {
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +01001104 il->fw_idx = il->cfg->ucode_api_max;
1105 sprintf(tag, "%d", il->fw_idx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001106 } else {
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +01001107 il->fw_idx--;
1108 sprintf(tag, "%d", il->fw_idx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001109 }
1110
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +01001111 if (il->fw_idx < il->cfg->ucode_api_min) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001112 IL_ERR("no suitable firmware found!\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001113 return -ENOENT;
1114 }
1115
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001116 sprintf(il->firmware_name, "%s%s%s", name_pre, tag, ".ucode");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001117
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001118 D_INFO("attempting to load firmware '%s'\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001119 il->firmware_name);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001120
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001121 return request_firmware_nowait(THIS_MODULE, 1, il->firmware_name,
1122 &il->pci_dev->dev, GFP_KERNEL, il,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001123 il4965_ucode_callback);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001124}
1125
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001126struct il4965_firmware_pieces {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001127 const void *inst, *data, *init, *init_data, *boot;
1128 size_t inst_size, data_size, init_size, init_data_size, boot_size;
1129};
1130
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001131static int il4965_load_firmware(struct il_priv *il,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001132 const struct firmware *ucode_raw,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001133 struct il4965_firmware_pieces *pieces)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001134{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001135 struct il_ucode_header *ucode = (void *)ucode_raw->data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001136 u32 api_ver, hdr_size;
1137 const u8 *src;
1138
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001139 il->ucode_ver = le32_to_cpu(ucode->ver);
1140 api_ver = IL_UCODE_API(il->ucode_ver);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001141
1142 switch (api_ver) {
1143 default:
1144 case 0:
1145 case 1:
1146 case 2:
1147 hdr_size = 24;
1148 if (ucode_raw->size < hdr_size) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001149 IL_ERR("File size too small!\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001150 return -EINVAL;
1151 }
1152 pieces->inst_size = le32_to_cpu(ucode->v1.inst_size);
1153 pieces->data_size = le32_to_cpu(ucode->v1.data_size);
1154 pieces->init_size = le32_to_cpu(ucode->v1.init_size);
1155 pieces->init_data_size =
1156 le32_to_cpu(ucode->v1.init_data_size);
1157 pieces->boot_size = le32_to_cpu(ucode->v1.boot_size);
1158 src = ucode->v1.data;
1159 break;
1160 }
1161
1162 /* Verify size of file vs. image size info in file's header */
1163 if (ucode_raw->size != hdr_size + pieces->inst_size +
1164 pieces->data_size + pieces->init_size +
1165 pieces->init_data_size + pieces->boot_size) {
1166
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001167 IL_ERR(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001168 "uCode file size %d does not match expected size\n",
1169 (int)ucode_raw->size);
1170 return -EINVAL;
1171 }
1172
1173 pieces->inst = src;
1174 src += pieces->inst_size;
1175 pieces->data = src;
1176 src += pieces->data_size;
1177 pieces->init = src;
1178 src += pieces->init_size;
1179 pieces->init_data = src;
1180 src += pieces->init_data_size;
1181 pieces->boot = src;
1182 src += pieces->boot_size;
1183
1184 return 0;
1185}
1186
1187/**
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001188 * il4965_ucode_callback - callback when firmware was loaded
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001189 *
1190 * If loaded successfully, copies the firmware into buffers
1191 * for the card to fetch (via DMA).
1192 */
1193static void
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001194il4965_ucode_callback(const struct firmware *ucode_raw, void *context)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001195{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001196 struct il_priv *il = context;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001197 struct il_ucode_header *ucode;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001198 int err;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001199 struct il4965_firmware_pieces pieces;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001200 const unsigned int api_max = il->cfg->ucode_api_max;
1201 const unsigned int api_min = il->cfg->ucode_api_min;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001202 u32 api_ver;
1203
1204 u32 max_probe_length = 200;
1205 u32 standard_phy_calibration_size =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001206 IL_DEFAULT_STANDARD_PHY_CALIBRATE_TBL_SIZE;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001207
1208 memset(&pieces, 0, sizeof(pieces));
1209
1210 if (!ucode_raw) {
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +01001211 if (il->fw_idx <= il->cfg->ucode_api_max)
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001212 IL_ERR(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001213 "request for firmware file '%s' failed.\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001214 il->firmware_name);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001215 goto try_again;
1216 }
1217
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001218 D_INFO("Loaded firmware file '%s' (%zd bytes).\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001219 il->firmware_name, ucode_raw->size);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001220
1221 /* Make sure that we got at least the API version number */
1222 if (ucode_raw->size < 4) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001223 IL_ERR("File size way too small!\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001224 goto try_again;
1225 }
1226
1227 /* Data from ucode file: header followed by uCode images */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001228 ucode = (struct il_ucode_header *)ucode_raw->data;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001229
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001230 err = il4965_load_firmware(il, ucode_raw, &pieces);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001231
1232 if (err)
1233 goto try_again;
1234
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001235 api_ver = IL_UCODE_API(il->ucode_ver);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001236
1237 /*
1238 * api_ver should match the api version forming part of the
1239 * firmware filename ... but we don't check for that and only rely
1240 * on the API version read from firmware header from here on forward
1241 */
1242 if (api_ver < api_min || api_ver > api_max) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001243 IL_ERR(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001244 "Driver unable to support your firmware API. "
1245 "Driver supports v%u, firmware is v%u.\n",
1246 api_max, api_ver);
1247 goto try_again;
1248 }
1249
1250 if (api_ver != api_max)
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001251 IL_ERR(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001252 "Firmware has old API version. Expected v%u, "
1253 "got v%u. New firmware can be obtained "
1254 "from http://www.intellinuxwireless.org.\n",
1255 api_max, api_ver);
1256
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001257 IL_INFO("loaded firmware version %u.%u.%u.%u\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001258 IL_UCODE_MAJOR(il->ucode_ver),
1259 IL_UCODE_MINOR(il->ucode_ver),
1260 IL_UCODE_API(il->ucode_ver),
1261 IL_UCODE_SERIAL(il->ucode_ver));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001262
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001263 snprintf(il->hw->wiphy->fw_version,
1264 sizeof(il->hw->wiphy->fw_version),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001265 "%u.%u.%u.%u",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001266 IL_UCODE_MAJOR(il->ucode_ver),
1267 IL_UCODE_MINOR(il->ucode_ver),
1268 IL_UCODE_API(il->ucode_ver),
1269 IL_UCODE_SERIAL(il->ucode_ver));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001270
1271 /*
1272 * For any of the failures below (before allocating pci memory)
1273 * we will try to load a version with a smaller API -- maybe the
1274 * user just got a corrupted version of the latest API.
1275 */
1276
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001277 D_INFO("f/w package hdr ucode version raw = 0x%x\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001278 il->ucode_ver);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001279 D_INFO("f/w package hdr runtime inst size = %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001280 pieces.inst_size);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001281 D_INFO("f/w package hdr runtime data size = %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001282 pieces.data_size);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001283 D_INFO("f/w package hdr init inst size = %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001284 pieces.init_size);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001285 D_INFO("f/w package hdr init data size = %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001286 pieces.init_data_size);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001287 D_INFO("f/w package hdr boot inst size = %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001288 pieces.boot_size);
1289
1290 /* Verify that uCode images will fit in card's SRAM */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001291 if (pieces.inst_size > il->hw_params.max_inst_size) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001292 IL_ERR("uCode instr len %Zd too large to fit in\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001293 pieces.inst_size);
1294 goto try_again;
1295 }
1296
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001297 if (pieces.data_size > il->hw_params.max_data_size) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001298 IL_ERR("uCode data len %Zd too large to fit in\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001299 pieces.data_size);
1300 goto try_again;
1301 }
1302
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001303 if (pieces.init_size > il->hw_params.max_inst_size) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001304 IL_ERR("uCode init instr len %Zd too large to fit in\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001305 pieces.init_size);
1306 goto try_again;
1307 }
1308
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001309 if (pieces.init_data_size > il->hw_params.max_data_size) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001310 IL_ERR("uCode init data len %Zd too large to fit in\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001311 pieces.init_data_size);
1312 goto try_again;
1313 }
1314
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001315 if (pieces.boot_size > il->hw_params.max_bsm_size) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001316 IL_ERR("uCode boot instr len %Zd too large to fit in\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001317 pieces.boot_size);
1318 goto try_again;
1319 }
1320
1321 /* Allocate ucode buffers for card's bus-master loading ... */
1322
1323 /* Runtime instructions and 2 copies of data:
1324 * 1) unmodified from disk
1325 * 2) backup cache for save/restore during power-downs */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001326 il->ucode_code.len = pieces.inst_size;
1327 il_alloc_fw_desc(il->pci_dev, &il->ucode_code);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001328
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001329 il->ucode_data.len = pieces.data_size;
1330 il_alloc_fw_desc(il->pci_dev, &il->ucode_data);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001331
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001332 il->ucode_data_backup.len = pieces.data_size;
1333 il_alloc_fw_desc(il->pci_dev, &il->ucode_data_backup);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001334
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001335 if (!il->ucode_code.v_addr || !il->ucode_data.v_addr ||
1336 !il->ucode_data_backup.v_addr)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001337 goto err_pci_alloc;
1338
1339 /* Initialization instructions and data */
1340 if (pieces.init_size && pieces.init_data_size) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001341 il->ucode_init.len = pieces.init_size;
1342 il_alloc_fw_desc(il->pci_dev, &il->ucode_init);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001343
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001344 il->ucode_init_data.len = pieces.init_data_size;
1345 il_alloc_fw_desc(il->pci_dev, &il->ucode_init_data);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001346
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001347 if (!il->ucode_init.v_addr || !il->ucode_init_data.v_addr)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001348 goto err_pci_alloc;
1349 }
1350
1351 /* Bootstrap (instructions only, no data) */
1352 if (pieces.boot_size) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001353 il->ucode_boot.len = pieces.boot_size;
1354 il_alloc_fw_desc(il->pci_dev, &il->ucode_boot);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001355
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001356 if (!il->ucode_boot.v_addr)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001357 goto err_pci_alloc;
1358 }
1359
1360 /* Now that we can no longer fail, copy information */
1361
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001362 il->sta_key_max_num = STA_KEY_MAX_NUM;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001363
1364 /* Copy images into buffers for card's bus-master reads ... */
1365
1366 /* Runtime instructions (first block of data in file) */
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001367 D_INFO("Copying (but not loading) uCode instr len %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001368 pieces.inst_size);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001369 memcpy(il->ucode_code.v_addr, pieces.inst, pieces.inst_size);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001370
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001371 D_INFO("uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001372 il->ucode_code.v_addr, (u32)il->ucode_code.p_addr);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001373
1374 /*
1375 * Runtime data
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001376 * NOTE: Copy into backup buffer will be done in il_up()
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001377 */
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001378 D_INFO("Copying (but not loading) uCode data len %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001379 pieces.data_size);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001380 memcpy(il->ucode_data.v_addr, pieces.data, pieces.data_size);
1381 memcpy(il->ucode_data_backup.v_addr, pieces.data, pieces.data_size);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001382
1383 /* Initialization instructions */
1384 if (pieces.init_size) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001385 D_INFO(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001386 "Copying (but not loading) init instr len %Zd\n",
1387 pieces.init_size);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001388 memcpy(il->ucode_init.v_addr, pieces.init, pieces.init_size);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001389 }
1390
1391 /* Initialization data */
1392 if (pieces.init_data_size) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001393 D_INFO(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001394 "Copying (but not loading) init data len %Zd\n",
1395 pieces.init_data_size);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001396 memcpy(il->ucode_init_data.v_addr, pieces.init_data,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001397 pieces.init_data_size);
1398 }
1399
1400 /* Bootstrap instructions */
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001401 D_INFO("Copying (but not loading) boot instr len %Zd\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001402 pieces.boot_size);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001403 memcpy(il->ucode_boot.v_addr, pieces.boot, pieces.boot_size);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001404
1405 /*
1406 * figure out the offset of chain noise reset and gain commands
1407 * base on the size of standard phy calibration commands table size
1408 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001409 il->_4965.phy_calib_chain_noise_reset_cmd =
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001410 standard_phy_calibration_size;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001411 il->_4965.phy_calib_chain_noise_gain_cmd =
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001412 standard_phy_calibration_size + 1;
1413
1414 /**************************************************
1415 * This is still part of probe() in a sense...
1416 *
1417 * 9. Setup and register with mac80211 and debugfs
1418 **************************************************/
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001419 err = il4965_mac_setup_register(il, max_probe_length);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001420 if (err)
1421 goto out_unbind;
1422
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001423 err = il_dbgfs_register(il, DRV_NAME);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001424 if (err)
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001425 IL_ERR(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001426 "failed to create debugfs files. Ignoring error: %d\n", err);
1427
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001428 err = sysfs_create_group(&il->pci_dev->dev.kobj,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001429 &il_attribute_group);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001430 if (err) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001431 IL_ERR("failed to create sysfs device attributes\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001432 goto out_unbind;
1433 }
1434
1435 /* We have our copies now, allow OS release its copies */
1436 release_firmware(ucode_raw);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001437 complete(&il->_4965.firmware_loading_complete);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001438 return;
1439
1440 try_again:
1441 /* try next, if any */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001442 if (il4965_request_firmware(il, false))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001443 goto out_unbind;
1444 release_firmware(ucode_raw);
1445 return;
1446
1447 err_pci_alloc:
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001448 IL_ERR("failed to allocate pci memory\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001449 il4965_dealloc_ucode_pci(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001450 out_unbind:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001451 complete(&il->_4965.firmware_loading_complete);
1452 device_release_driver(&il->pci_dev->dev);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001453 release_firmware(ucode_raw);
1454}
1455
1456static const char * const desc_lookup_text[] = {
1457 "OK",
1458 "FAIL",
1459 "BAD_PARAM",
1460 "BAD_CHECKSUM",
1461 "NMI_INTERRUPT_WDG",
1462 "SYSASSERT",
1463 "FATAL_ERROR",
1464 "BAD_COMMAND",
1465 "HW_ERROR_TUNE_LOCK",
1466 "HW_ERROR_TEMPERATURE",
1467 "ILLEGAL_CHAN_FREQ",
Stanislaw Gruszka3b98c7f2011-08-26 16:29:35 +02001468 "VCC_NOT_STBL",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001469 "FH_ERROR",
1470 "NMI_INTERRUPT_HOST",
1471 "NMI_INTERRUPT_ACTION_PT",
1472 "NMI_INTERRUPT_UNKNOWN",
1473 "UCODE_VERSION_MISMATCH",
1474 "HW_ERROR_ABS_LOCK",
1475 "HW_ERROR_CAL_LOCK_FAIL",
1476 "NMI_INTERRUPT_INST_ACTION_PT",
1477 "NMI_INTERRUPT_DATA_ACTION_PT",
1478 "NMI_TRM_HW_ER",
1479 "NMI_INTERRUPT_TRM",
Joe Perches861d9c32011-07-08 23:20:24 -07001480 "NMI_INTERRUPT_BREAK_POINT",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001481 "DEBUG_0",
1482 "DEBUG_1",
1483 "DEBUG_2",
1484 "DEBUG_3",
1485};
1486
1487static struct { char *name; u8 num; } advanced_lookup[] = {
1488 { "NMI_INTERRUPT_WDG", 0x34 },
1489 { "SYSASSERT", 0x35 },
1490 { "UCODE_VERSION_MISMATCH", 0x37 },
1491 { "BAD_COMMAND", 0x38 },
1492 { "NMI_INTERRUPT_DATA_ACTION_PT", 0x3C },
1493 { "FATAL_ERROR", 0x3D },
1494 { "NMI_TRM_HW_ERR", 0x46 },
1495 { "NMI_INTERRUPT_TRM", 0x4C },
1496 { "NMI_INTERRUPT_BREAK_POINT", 0x54 },
1497 { "NMI_INTERRUPT_WDG_RXF_FULL", 0x5C },
1498 { "NMI_INTERRUPT_WDG_NO_RBD_RXF_FULL", 0x64 },
1499 { "NMI_INTERRUPT_HOST", 0x66 },
1500 { "NMI_INTERRUPT_ACTION_PT", 0x7C },
1501 { "NMI_INTERRUPT_UNKNOWN", 0x84 },
1502 { "NMI_INTERRUPT_INST_ACTION_PT", 0x86 },
1503 { "ADVANCED_SYSASSERT", 0 },
1504};
1505
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001506static const char *il4965_desc_lookup(u32 num)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001507{
1508 int i;
1509 int max = ARRAY_SIZE(desc_lookup_text);
1510
1511 if (num < max)
1512 return desc_lookup_text[num];
1513
1514 max = ARRAY_SIZE(advanced_lookup) - 1;
1515 for (i = 0; i < max; i++) {
1516 if (advanced_lookup[i].num == num)
1517 break;
1518 }
1519 return advanced_lookup[i].name;
1520}
1521
1522#define ERROR_START_OFFSET (1 * sizeof(u32))
1523#define ERROR_ELEM_SIZE (7 * sizeof(u32))
1524
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001525void il4965_dump_nic_error_log(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001526{
1527 u32 data2, line;
1528 u32 desc, time, count, base, data1;
1529 u32 blink1, blink2, ilink1, ilink2;
1530 u32 pc, hcmd;
1531
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001532 if (il->ucode_type == UCODE_INIT) {
1533 base = le32_to_cpu(il->card_alive_init.error_event_table_ptr);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001534 } else {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001535 base = le32_to_cpu(il->card_alive.error_event_table_ptr);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001536 }
1537
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001538 if (!il->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001539 IL_ERR(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001540 "Not valid error log pointer 0x%08X for %s uCode\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001541 base, (il->ucode_type == UCODE_INIT) ? "Init" : "RT");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001542 return;
1543 }
1544
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001545 count = il_read_targ_mem(il, base);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001546
1547 if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001548 IL_ERR("Start IWL Error Log Dump:\n");
1549 IL_ERR("Status: 0x%08lX, count: %d\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001550 il->status, count);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001551 }
1552
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001553 desc = il_read_targ_mem(il, base + 1 * sizeof(u32));
1554 il->isr_stats.err_code = desc;
1555 pc = il_read_targ_mem(il, base + 2 * sizeof(u32));
1556 blink1 = il_read_targ_mem(il, base + 3 * sizeof(u32));
1557 blink2 = il_read_targ_mem(il, base + 4 * sizeof(u32));
1558 ilink1 = il_read_targ_mem(il, base + 5 * sizeof(u32));
1559 ilink2 = il_read_targ_mem(il, base + 6 * sizeof(u32));
1560 data1 = il_read_targ_mem(il, base + 7 * sizeof(u32));
1561 data2 = il_read_targ_mem(il, base + 8 * sizeof(u32));
1562 line = il_read_targ_mem(il, base + 9 * sizeof(u32));
1563 time = il_read_targ_mem(il, base + 11 * sizeof(u32));
1564 hcmd = il_read_targ_mem(il, base + 22 * sizeof(u32));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001565
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001566 IL_ERR("Desc Time "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001567 "data1 data2 line\n");
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001568 IL_ERR("%-28s (0x%04X) %010u 0x%08X 0x%08X %u\n",
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001569 il4965_desc_lookup(desc), desc, time, data1, data2, line);
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001570 IL_ERR("pc blink1 blink2 ilink1 ilink2 hcmd\n");
1571 IL_ERR("0x%05X 0x%05X 0x%05X 0x%05X 0x%05X 0x%05X\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001572 pc, blink1, blink2, ilink1, ilink2, hcmd);
1573}
1574
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001575static void il4965_rf_kill_ct_config(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001576{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001577 struct il_ct_kill_config cmd;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001578 unsigned long flags;
1579 int ret = 0;
1580
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001581 spin_lock_irqsave(&il->lock, flags);
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02001582 _il_wr(il, CSR_UCODE_DRV_GP1_CLR,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001583 CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001584 spin_unlock_irqrestore(&il->lock, flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001585
1586 cmd.critical_temperature_R =
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001587 cpu_to_le32(il->hw_params.ct_kill_threshold);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001588
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001589 ret = il_send_cmd_pdu(il, REPLY_CT_KILL_CONFIG_CMD,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001590 sizeof(cmd), &cmd);
1591 if (ret)
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001592 IL_ERR("REPLY_CT_KILL_CONFIG_CMD failed\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001593 else
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001594 D_INFO("REPLY_CT_KILL_CONFIG_CMD "
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001595 "succeeded, "
1596 "critical temperature is %d\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001597 il->hw_params.ct_kill_threshold);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001598}
1599
1600static const s8 default_queue_to_tx_fifo[] = {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001601 IL_TX_FIFO_VO,
1602 IL_TX_FIFO_VI,
1603 IL_TX_FIFO_BE,
1604 IL_TX_FIFO_BK,
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001605 IL49_CMD_FIFO_NUM,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001606 IL_TX_FIFO_UNUSED,
1607 IL_TX_FIFO_UNUSED,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001608};
1609
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001610static int il4965_alive_notify(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001611{
1612 u32 a;
1613 unsigned long flags;
1614 int i, chan;
1615 u32 reg_val;
1616
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001617 spin_lock_irqsave(&il->lock, flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001618
1619 /* Clear 4965's internal Tx Scheduler data base */
Stanislaw Gruszkadb54eb52011-08-24 21:06:33 +02001620 il->scd_base_addr = il_rd_prph(il,
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001621 IL49_SCD_SRAM_BASE_ADDR);
1622 a = il->scd_base_addr + IL49_SCD_CONTEXT_DATA_OFFSET;
1623 for (; a < il->scd_base_addr + IL49_SCD_TX_STTS_BITMAP_OFFSET; a += 4)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001624 il_write_targ_mem(il, a, 0);
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001625 for (; a < il->scd_base_addr + IL49_SCD_TRANSLATE_TBL_OFFSET; a += 4)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001626 il_write_targ_mem(il, a, 0);
1627 for (; a < il->scd_base_addr +
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001628 IL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(il->hw_params.max_txq_num); a += 4)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001629 il_write_targ_mem(il, a, 0);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001630
1631 /* Tel 4965 where to find Tx byte count tables */
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001632 il_wr_prph(il, IL49_SCD_DRAM_BASE_ADDR,
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001633 il->scd_bc_tbls.dma >> 10);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001634
1635 /* Enable DMA channel */
1636 for (chan = 0; chan < FH49_TCSR_CHNL_NUM ; chan++)
Stanislaw Gruszka0c1a94e2011-08-24 17:37:16 +02001637 il_wr(il,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001638 FH_TCSR_CHNL_TX_CONFIG_REG(chan),
1639 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
1640 FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);
1641
1642 /* Update FH chicken bits */
Stanislaw Gruszka0c1a94e2011-08-24 17:37:16 +02001643 reg_val = il_rd(il, FH_TX_CHICKEN_BITS_REG);
1644 il_wr(il, FH_TX_CHICKEN_BITS_REG,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001645 reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
1646
1647 /* Disable chain mode for all queues */
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001648 il_wr_prph(il, IL49_SCD_QUEUECHAIN_SEL, 0);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001649
1650 /* Initialize each Tx queue (including the command queue) */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001651 for (i = 0; i < il->hw_params.max_txq_num; i++) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001652
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +01001653 /* TFD circular buffer read/write idxes */
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001654 il_wr_prph(il, IL49_SCD_QUEUE_RDPTR(i), 0);
Stanislaw Gruszka0c1a94e2011-08-24 17:37:16 +02001655 il_wr(il, HBUS_TARG_WRPTR, 0 | (i << 8));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001656
1657 /* Max Tx Window size for Scheduler-ACK mode */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001658 il_write_targ_mem(il, il->scd_base_addr +
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001659 IL49_SCD_CONTEXT_QUEUE_OFFSET(i),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001660 (SCD_WIN_SIZE <<
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001661 IL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) &
1662 IL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001663
1664 /* Frame limit */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001665 il_write_targ_mem(il, il->scd_base_addr +
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001666 IL49_SCD_CONTEXT_QUEUE_OFFSET(i) +
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001667 sizeof(u32),
1668 (SCD_FRAME_LIMIT <<
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001669 IL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
1670 IL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001671
1672 }
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01001673 il_wr_prph(il, IL49_SCD_INTERRUPT_MASK,
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001674 (1 << il->hw_params.max_txq_num) - 1);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001675
1676 /* Activate all Tx DMA/FIFO channels */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001677 il4965_txq_set_sched(il, IL_MASK(0, 6));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001678
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001679 il4965_set_wr_ptrs(il, IL_DEFAULT_CMD_QUEUE_NUM, 0);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001680
1681 /* make sure all queue are not stopped */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001682 memset(&il->queue_stopped[0], 0, sizeof(il->queue_stopped));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001683 for (i = 0; i < 4; i++)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001684 atomic_set(&il->queue_stop_count[i], 0);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001685
1686 /* reset to 0 to enable all the queue first */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001687 il->txq_ctx_active_msk = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001688 /* Map each Tx/cmd queue to its corresponding fifo */
1689 BUILD_BUG_ON(ARRAY_SIZE(default_queue_to_tx_fifo) != 7);
1690
1691 for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) {
1692 int ac = default_queue_to_tx_fifo[i];
1693
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001694 il_txq_ctx_activate(il, i);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001695
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001696 if (ac == IL_TX_FIFO_UNUSED)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001697 continue;
1698
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001699 il4965_tx_queue_set_status(il, &il->txq[i], ac, 0);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001700 }
1701
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001702 spin_unlock_irqrestore(&il->lock, flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001703
1704 return 0;
1705}
1706
1707/**
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001708 * il4965_alive_start - called after REPLY_ALIVE notification received
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001709 * from protocol/runtime uCode (initialization uCode's
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001710 * Alive gets handled by il_init_alive_start()).
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001711 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001712static void il4965_alive_start(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001713{
1714 int ret = 0;
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +01001715 struct il_rxon_context *ctx = &il->ctx;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001716
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001717 D_INFO("Runtime Alive received.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001718
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001719 if (il->card_alive.is_valid != UCODE_VALID_OK) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001720 /* We had an error bringing up the hardware, so take it
1721 * all the way back down so we can try again */
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001722 D_INFO("Alive failed.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001723 goto restart;
1724 }
1725
1726 /* Initialize uCode has loaded Runtime uCode ... verify inst image.
1727 * This is a paranoid check, because we would not have gotten the
1728 * "runtime" alive if code weren't properly loaded. */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001729 if (il4965_verify_ucode(il)) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001730 /* Runtime instruction load was bad;
1731 * take it all the way back down so we can try again */
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001732 D_INFO("Bad runtime uCode load.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001733 goto restart;
1734 }
1735
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001736 ret = il4965_alive_notify(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001737 if (ret) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001738 IL_WARN(
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001739 "Could not complete ALIVE transition [ntf]: %d\n", ret);
1740 goto restart;
1741 }
1742
1743
1744 /* After the ALIVE response, we can send host commands to the uCode */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001745 set_bit(STATUS_ALIVE, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001746
1747 /* Enable watchdog to monitor the driver tx queues */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001748 il_setup_watchdog(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001749
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001750 if (il_is_rfkill(il))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001751 return;
1752
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001753 ieee80211_wake_queues(il->hw);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001754
Stanislaw Gruszka2eb05812011-08-26 16:07:43 +02001755 il->active_rate = RATES_MASK;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001756
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001757 if (il_is_associated_ctx(ctx)) {
1758 struct il_rxon_cmd *active_rxon =
1759 (struct il_rxon_cmd *)&ctx->active;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001760 /* apply any changes in staging */
1761 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
1762 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1763 } else {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001764 /* Initialize our rx_config data */
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +02001765 il_connection_init_rx_config(il, &il->ctx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001766
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001767 if (il->cfg->ops->hcmd->set_rxon_chain)
1768 il->cfg->ops->hcmd->set_rxon_chain(il, ctx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001769 }
1770
1771 /* Configure bluetooth coexistence if enabled */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001772 il_send_bt_config(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001773
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001774 il4965_reset_run_time_calib(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001775
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001776 set_bit(STATUS_READY, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001777
1778 /* Configure the adapter for unassociated operation */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001779 il_commit_rxon(il, ctx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001780
1781 /* At this point, the NIC is initialized and operational */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001782 il4965_rf_kill_ct_config(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001783
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001784 D_INFO("ALIVE processing complete.\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001785 wake_up(&il->wait_command_queue);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001786
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001787 il_power_update_mode(il, true);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001788 D_INFO("Updated power mode\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001789
1790 return;
1791
1792 restart:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001793 queue_work(il->workqueue, &il->restart);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001794}
1795
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001796static void il4965_cancel_deferred_work(struct il_priv *il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001797
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001798static void __il4965_down(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001799{
1800 unsigned long flags;
Stanislaw Gruszkaab42b402011-04-28 11:51:24 +02001801 int exit_pending;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001802
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001803 D_INFO(DRV_NAME " is going down\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001804
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001805 il_scan_cancel_timeout(il, 200);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001806
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001807 exit_pending = test_and_set_bit(STATUS_EXIT_PENDING, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001808
1809 /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set
1810 * to prevent rearm timer */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001811 del_timer_sync(&il->watchdog);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001812
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001813 il_clear_ucode_stations(il, NULL);
1814 il_dealloc_bcast_stations(il);
1815 il_clear_driver_stations(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001816
1817 /* Unblock any waiting calls */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001818 wake_up_all(&il->wait_command_queue);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001819
1820 /* Wipe out the EXIT_PENDING status bit if we are not actually
1821 * exiting the module */
1822 if (!exit_pending)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001823 clear_bit(STATUS_EXIT_PENDING, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001824
1825 /* stop and reset the on-board processor */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02001826 _il_wr(il, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001827
1828 /* tell the device to stop sending interrupts */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001829 spin_lock_irqsave(&il->lock, flags);
1830 il_disable_interrupts(il);
1831 spin_unlock_irqrestore(&il->lock, flags);
1832 il4965_synchronize_irq(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001833
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001834 if (il->mac80211_registered)
1835 ieee80211_stop_queues(il->hw);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001836
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001837 /* If we have not previously called il_init() then
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001838 * clear all bits but the RF Kill bit and return */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001839 if (!il_is_init(il)) {
1840 il->status = test_bit(STATUS_RF_KILL_HW, &il->status) <<
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001841 STATUS_RF_KILL_HW |
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001842 test_bit(STATUS_GEO_CONFIGURED, &il->status) <<
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001843 STATUS_GEO_CONFIGURED |
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001844 test_bit(STATUS_EXIT_PENDING, &il->status) <<
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001845 STATUS_EXIT_PENDING;
1846 goto exit;
1847 }
1848
1849 /* ...otherwise clear out all the status bits but the RF Kill
1850 * bit and continue taking the NIC down. */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001851 il->status &= test_bit(STATUS_RF_KILL_HW, &il->status) <<
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001852 STATUS_RF_KILL_HW |
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001853 test_bit(STATUS_GEO_CONFIGURED, &il->status) <<
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001854 STATUS_GEO_CONFIGURED |
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001855 test_bit(STATUS_FW_ERROR, &il->status) <<
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001856 STATUS_FW_ERROR |
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001857 test_bit(STATUS_EXIT_PENDING, &il->status) <<
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001858 STATUS_EXIT_PENDING;
1859
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001860 il4965_txq_ctx_stop(il);
1861 il4965_rxq_stop(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001862
1863 /* Power-down device's busmaster DMA clocks */
Stanislaw Gruszkadb54eb52011-08-24 21:06:33 +02001864 il_wr_prph(il, APMG_CLK_DIS_REG, APMG_CLK_VAL_DMA_CLK_RQT);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001865 udelay(5);
1866
1867 /* Make sure (redundant) we've released our request to stay awake */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001868 il_clear_bit(il, CSR_GP_CNTRL,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001869 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
1870
1871 /* Stop the device, and put it in low power state */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001872 il_apm_stop(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001873
1874 exit:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001875 memset(&il->card_alive, 0, sizeof(struct il_alive_resp));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001876
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001877 dev_kfree_skb(il->beacon_skb);
1878 il->beacon_skb = NULL;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001879
1880 /* clear out any free frames */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001881 il4965_clear_free_frames(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001882}
1883
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001884static void il4965_down(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001885{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001886 mutex_lock(&il->mutex);
1887 __il4965_down(il);
1888 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001889
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001890 il4965_cancel_deferred_work(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001891}
1892
1893#define HW_READY_TIMEOUT (50)
1894
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001895static int il4965_set_hw_ready(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001896{
1897 int ret = 0;
1898
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001899 il_set_bit(il, CSR_HW_IF_CONFIG_REG,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001900 CSR_HW_IF_CONFIG_REG_BIT_NIC_READY);
1901
1902 /* See if we got it */
Stanislaw Gruszka142b3432011-08-24 15:22:57 +02001903 ret = _il_poll_bit(il, CSR_HW_IF_CONFIG_REG,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001904 CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
1905 CSR_HW_IF_CONFIG_REG_BIT_NIC_READY,
1906 HW_READY_TIMEOUT);
1907 if (ret != -ETIMEDOUT)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001908 il->hw_ready = true;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001909 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001910 il->hw_ready = false;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001911
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001912 D_INFO("hardware %s\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001913 (il->hw_ready == 1) ? "ready" : "not ready");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001914 return ret;
1915}
1916
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001917static int il4965_prepare_card_hw(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001918{
1919 int ret = 0;
1920
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01001921 D_INFO("il4965_prepare_card_hw enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001922
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001923 ret = il4965_set_hw_ready(il);
1924 if (il->hw_ready)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001925 return ret;
1926
1927 /* If HW is not ready, prepare the conditions to check again */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001928 il_set_bit(il, CSR_HW_IF_CONFIG_REG,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001929 CSR_HW_IF_CONFIG_REG_PREPARE);
1930
Stanislaw Gruszka142b3432011-08-24 15:22:57 +02001931 ret = _il_poll_bit(il, CSR_HW_IF_CONFIG_REG,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001932 ~CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE,
1933 CSR_HW_IF_CONFIG_REG_BIT_NIC_PREPARE_DONE, 150000);
1934
1935 /* HW should be ready by now, check again. */
1936 if (ret != -ETIMEDOUT)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001937 il4965_set_hw_ready(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001938
1939 return ret;
1940}
1941
1942#define MAX_HW_RESTARTS 5
1943
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001944static int __il4965_up(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001945{
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001946 int i;
1947 int ret;
1948
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001949 if (test_bit(STATUS_EXIT_PENDING, &il->status)) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001950 IL_WARN("Exit pending; will not bring the NIC up\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001951 return -EIO;
1952 }
1953
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001954 if (!il->ucode_data_backup.v_addr || !il->ucode_data.v_addr) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001955 IL_ERR("ucode not available for device bringup\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001956 return -EIO;
1957 }
1958
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +02001959 ret = il4965_alloc_bcast_station(il, &il->ctx);
1960 if (ret) {
1961 il_dealloc_bcast_stations(il);
1962 return ret;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001963 }
1964
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001965 il4965_prepare_card_hw(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001966
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001967 if (!il->hw_ready) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001968 IL_WARN("Exit HW not ready\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001969 return -EIO;
1970 }
1971
1972 /* If platform's RF_KILL switch is NOT set to KILL */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02001973 if (_il_rd(il,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001974 CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001975 clear_bit(STATUS_RF_KILL_HW, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001976 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001977 set_bit(STATUS_RF_KILL_HW, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001978
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001979 if (il_is_rfkill(il)) {
1980 wiphy_rfkill_set_hw_state(il->hw->wiphy, true);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001981
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001982 il_enable_interrupts(il);
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001983 IL_WARN("Radio disabled by HW RF Kill switch\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001984 return 0;
1985 }
1986
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02001987 _il_wr(il, CSR_INT, 0xFFFFFFFF);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001988
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02001989 /* must be initialised before il_hw_nic_init */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001990 il->cmd_queue = IL_DEFAULT_CMD_QUEUE_NUM;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001991
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02001992 ret = il4965_hw_nic_init(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001993 if (ret) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02001994 IL_ERR("Unable to init nic\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08001995 return ret;
1996 }
1997
1998 /* make sure rfkill handshake bits are cleared */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02001999 _il_wr(il, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
2000 _il_wr(il, CSR_UCODE_DRV_GP1_CLR,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002001 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
2002
2003 /* clear (again), then enable host interrupts */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02002004 _il_wr(il, CSR_INT, 0xFFFFFFFF);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002005 il_enable_interrupts(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002006
2007 /* really make sure rfkill handshake bits are cleared */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02002008 _il_wr(il, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
2009 _il_wr(il, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002010
2011 /* Copy original ucode data image from disk into backup cache.
2012 * This will be used to initialize the on-board processor's
2013 * data SRAM for a clean start when the runtime program first loads. */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002014 memcpy(il->ucode_data_backup.v_addr, il->ucode_data.v_addr,
2015 il->ucode_data.len);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002016
2017 for (i = 0; i < MAX_HW_RESTARTS; i++) {
2018
2019 /* load bootstrap state machine,
2020 * load bootstrap program into processor's memory,
2021 * prepare to load the "initialize" uCode */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002022 ret = il->cfg->ops->lib->load_ucode(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002023
2024 if (ret) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002025 IL_ERR("Unable to set up bootstrap uCode: %d\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002026 ret);
2027 continue;
2028 }
2029
2030 /* start card; "initialize" will load runtime ucode */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002031 il4965_nic_start(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002032
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002033 D_INFO(DRV_NAME " is coming up\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002034
2035 return 0;
2036 }
2037
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002038 set_bit(STATUS_EXIT_PENDING, &il->status);
2039 __il4965_down(il);
2040 clear_bit(STATUS_EXIT_PENDING, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002041
2042 /* tried to restart and config the device for as long as our
2043 * patience could withstand */
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002044 IL_ERR("Unable to initialize device after %d attempts.\n", i);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002045 return -EIO;
2046}
2047
2048
2049/*****************************************************************************
2050 *
2051 * Workqueue callbacks
2052 *
2053 *****************************************************************************/
2054
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002055static void il4965_bg_init_alive_start(struct work_struct *data)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002056{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002057 struct il_priv *il =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002058 container_of(data, struct il_priv, init_alive_start.work);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002059
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002060 mutex_lock(&il->mutex);
2061 if (test_bit(STATUS_EXIT_PENDING, &il->status))
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002062 goto out;
2063
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002064 il->cfg->ops->lib->init_alive_start(il);
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002065out:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002066 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002067}
2068
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002069static void il4965_bg_alive_start(struct work_struct *data)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002070{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002071 struct il_priv *il =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002072 container_of(data, struct il_priv, alive_start.work);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002073
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002074 mutex_lock(&il->mutex);
2075 if (test_bit(STATUS_EXIT_PENDING, &il->status))
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002076 goto out;
2077
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002078 il4965_alive_start(il);
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002079out:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002080 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002081}
2082
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002083static void il4965_bg_run_time_calib_work(struct work_struct *work)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002084{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002085 struct il_priv *il = container_of(work, struct il_priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002086 run_time_calib_work);
2087
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002088 mutex_lock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002089
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002090 if (test_bit(STATUS_EXIT_PENDING, &il->status) ||
2091 test_bit(STATUS_SCANNING, &il->status)) {
2092 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002093 return;
2094 }
2095
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002096 if (il->start_calib) {
2097 il4965_chain_noise_calibration(il,
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02002098 (void *)&il->_4965.stats);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002099 il4965_sensitivity_calibration(il,
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02002100 (void *)&il->_4965.stats);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002101 }
2102
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002103 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002104}
2105
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002106static void il4965_bg_restart(struct work_struct *data)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002107{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002108 struct il_priv *il = container_of(data, struct il_priv, restart);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002109
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002110 if (test_bit(STATUS_EXIT_PENDING, &il->status))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002111 return;
2112
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002113 if (test_and_clear_bit(STATUS_FW_ERROR, &il->status)) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002114 mutex_lock(&il->mutex);
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +02002115 il->ctx.vif = NULL;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002116 il->is_open = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002117
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002118 __il4965_down(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002119
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002120 mutex_unlock(&il->mutex);
2121 il4965_cancel_deferred_work(il);
2122 ieee80211_restart_hw(il->hw);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002123 } else {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002124 il4965_down(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002125
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002126 mutex_lock(&il->mutex);
2127 if (test_bit(STATUS_EXIT_PENDING, &il->status)) {
2128 mutex_unlock(&il->mutex);
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002129 return;
2130 }
2131
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002132 __il4965_up(il);
2133 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002134 }
2135}
2136
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002137static void il4965_bg_rx_replenish(struct work_struct *data)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002138{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002139 struct il_priv *il =
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002140 container_of(data, struct il_priv, rx_replenish);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002141
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002142 if (test_bit(STATUS_EXIT_PENDING, &il->status))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002143 return;
2144
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002145 mutex_lock(&il->mutex);
2146 il4965_rx_replenish(il);
2147 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002148}
2149
2150/*****************************************************************************
2151 *
2152 * mac80211 entry point functions
2153 *
2154 *****************************************************************************/
2155
2156#define UCODE_READY_TIMEOUT (4 * HZ)
2157
2158/*
2159 * Not a mac80211 entry point function, but it fits in with all the
2160 * other mac80211 functions grouped here.
2161 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002162static int il4965_mac_setup_register(struct il_priv *il,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002163 u32 max_probe_length)
2164{
2165 int ret;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002166 struct ieee80211_hw *hw = il->hw;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002167
2168 hw->rate_control_algorithm = "iwl-4965-rs";
2169
2170 /* Tell mac80211 our characteristics */
2171 hw->flags = IEEE80211_HW_SIGNAL_DBM |
2172 IEEE80211_HW_AMPDU_AGGREGATION |
2173 IEEE80211_HW_NEED_DTIM_PERIOD |
2174 IEEE80211_HW_SPECTRUM_MGMT |
2175 IEEE80211_HW_REPORTS_TX_ACK_STATUS;
2176
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002177 if (il->cfg->sku & IL_SKU_N)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002178 hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
2179 IEEE80211_HW_SUPPORTS_STATIC_SMPS;
2180
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002181 hw->sta_data_size = sizeof(struct il_station_priv);
2182 hw->vif_data_size = sizeof(struct il_vif_priv);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002183
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +02002184 hw->wiphy->interface_modes |= il->ctx.interface_modes;
2185 hw->wiphy->interface_modes |= il->ctx.exclusive_interface_modes;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002186
2187 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
2188 WIPHY_FLAG_DISABLE_BEACON_HINTS;
2189
2190 /*
2191 * For now, disable PS by default because it affects
2192 * RX performance significantly.
2193 */
2194 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
2195
2196 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
2197 /* we create the 802.11 header and a zero-length SSID element */
2198 hw->wiphy->max_scan_ie_len = max_probe_length - 24 - 2;
2199
2200 /* Default value; 4 EDCA QOS priorities */
2201 hw->queues = 4;
2202
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002203 hw->max_listen_interval = IL_CONN_MAX_LISTEN_INTERVAL;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002204
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002205 if (il->bands[IEEE80211_BAND_2GHZ].n_channels)
2206 il->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
2207 &il->bands[IEEE80211_BAND_2GHZ];
2208 if (il->bands[IEEE80211_BAND_5GHZ].n_channels)
2209 il->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
2210 &il->bands[IEEE80211_BAND_5GHZ];
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002211
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002212 il_leds_init(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002213
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002214 ret = ieee80211_register_hw(il->hw);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002215 if (ret) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002216 IL_ERR("Failed to register hw (error %d)\n", ret);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002217 return ret;
2218 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002219 il->mac80211_registered = 1;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002220
2221 return 0;
2222}
2223
2224
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002225int il4965_mac_start(struct ieee80211_hw *hw)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002226{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002227 struct il_priv *il = hw->priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002228 int ret;
2229
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002230 D_MAC80211("enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002231
2232 /* we should be verifying the device is ready to be opened */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002233 mutex_lock(&il->mutex);
2234 ret = __il4965_up(il);
2235 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002236
2237 if (ret)
2238 return ret;
2239
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002240 if (il_is_rfkill(il))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002241 goto out;
2242
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002243 D_INFO("Start UP work done.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002244
2245 /* Wait for START_ALIVE from Run Time ucode. Otherwise callbacks from
2246 * mac80211 will not be run successfully. */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002247 ret = wait_event_timeout(il->wait_command_queue,
2248 test_bit(STATUS_READY, &il->status),
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002249 UCODE_READY_TIMEOUT);
2250 if (!ret) {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002251 if (!test_bit(STATUS_READY, &il->status)) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002252 IL_ERR("START_ALIVE timeout after %dms.\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002253 jiffies_to_msecs(UCODE_READY_TIMEOUT));
2254 return -ETIMEDOUT;
2255 }
2256 }
2257
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002258 il4965_led_enable(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002259
2260out:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002261 il->is_open = 1;
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002262 D_MAC80211("leave\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002263 return 0;
2264}
2265
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002266void il4965_mac_stop(struct ieee80211_hw *hw)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002267{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002268 struct il_priv *il = hw->priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002269
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002270 D_MAC80211("enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002271
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002272 if (!il->is_open)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002273 return;
2274
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002275 il->is_open = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002276
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002277 il4965_down(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002278
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002279 flush_workqueue(il->workqueue);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002280
Stanislaw Gruszkaa078a1f2011-04-28 11:51:25 +02002281 /* User space software may expect getting rfkill changes
2282 * even if interface is down */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02002283 _il_wr(il, CSR_INT, 0xFFFFFFFF);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002284 il_enable_rfkill_int(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002285
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002286 D_MAC80211("leave\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002287}
2288
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002289void il4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002290{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002291 struct il_priv *il = hw->priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002292
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002293 D_MACDUMP("enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002294
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002295 D_TX("dev->xmit(%d bytes) at rate 0x%02x\n", skb->len,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002296 ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate);
2297
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002298 if (il4965_tx_skb(il, skb))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002299 dev_kfree_skb_any(skb);
2300
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002301 D_MACDUMP("leave\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002302}
2303
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002304void il4965_mac_update_tkip_key(struct ieee80211_hw *hw,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002305 struct ieee80211_vif *vif,
2306 struct ieee80211_key_conf *keyconf,
2307 struct ieee80211_sta *sta,
2308 u32 iv32, u16 *phase1key)
2309{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002310 struct il_priv *il = hw->priv;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002311 struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002312
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002313 D_MAC80211("enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002314
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002315 il4965_update_tkip_key(il, vif_priv->ctx, keyconf, sta,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002316 iv32, phase1key);
2317
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002318 D_MAC80211("leave\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002319}
2320
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002321int il4965_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002322 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
2323 struct ieee80211_key_conf *key)
2324{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002325 struct il_priv *il = hw->priv;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002326 struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
2327 struct il_rxon_context *ctx = vif_priv->ctx;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002328 int ret;
2329 u8 sta_id;
2330 bool is_default_wep_key = false;
2331
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002332 D_MAC80211("enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002333
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002334 if (il->cfg->mod_params->sw_crypto) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002335 D_MAC80211("leave - hwcrypto disabled\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002336 return -EOPNOTSUPP;
2337 }
2338
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002339 sta_id = il_sta_id_or_broadcast(il, vif_priv->ctx, sta);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002340 if (sta_id == IL_INVALID_STATION)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002341 return -EINVAL;
2342
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002343 mutex_lock(&il->mutex);
2344 il_scan_cancel_timeout(il, 100);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002345
2346 /*
2347 * If we are getting WEP group key and we didn't receive any key mapping
2348 * so far, we are in legacy wep mode (group key only), otherwise we are
2349 * in 1X mode.
2350 * In legacy wep mode, we use another host command to the uCode.
2351 */
2352 if ((key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
2353 key->cipher == WLAN_CIPHER_SUITE_WEP104) &&
2354 !sta) {
2355 if (cmd == SET_KEY)
2356 is_default_wep_key = !ctx->key_mapping_keys;
2357 else
2358 is_default_wep_key =
2359 (key->hw_key_idx == HW_KEY_DEFAULT);
2360 }
2361
2362 switch (cmd) {
2363 case SET_KEY:
2364 if (is_default_wep_key)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002365 ret = il4965_set_default_wep_key(il,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002366 vif_priv->ctx, key);
2367 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002368 ret = il4965_set_dynamic_key(il, vif_priv->ctx,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002369 key, sta_id);
2370
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002371 D_MAC80211("enable hwcrypto key\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002372 break;
2373 case DISABLE_KEY:
2374 if (is_default_wep_key)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002375 ret = il4965_remove_default_wep_key(il, ctx, key);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002376 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002377 ret = il4965_remove_dynamic_key(il, ctx,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002378 key, sta_id);
2379
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002380 D_MAC80211("disable hwcrypto key\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002381 break;
2382 default:
2383 ret = -EINVAL;
2384 }
2385
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002386 mutex_unlock(&il->mutex);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002387 D_MAC80211("leave\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002388
2389 return ret;
2390}
2391
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002392int il4965_mac_ampdu_action(struct ieee80211_hw *hw,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002393 struct ieee80211_vif *vif,
2394 enum ieee80211_ampdu_mlme_action action,
2395 struct ieee80211_sta *sta, u16 tid, u16 *ssn,
2396 u8 buf_size)
2397{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002398 struct il_priv *il = hw->priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002399 int ret = -EINVAL;
2400
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002401 D_HT("A-MPDU action on addr %pM tid %d\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002402 sta->addr, tid);
2403
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002404 if (!(il->cfg->sku & IL_SKU_N))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002405 return -EACCES;
2406
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002407 mutex_lock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002408
2409 switch (action) {
2410 case IEEE80211_AMPDU_RX_START:
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002411 D_HT("start Rx\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002412 ret = il4965_sta_rx_agg_start(il, sta, tid, *ssn);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002413 break;
2414 case IEEE80211_AMPDU_RX_STOP:
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002415 D_HT("stop Rx\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002416 ret = il4965_sta_rx_agg_stop(il, sta, tid);
2417 if (test_bit(STATUS_EXIT_PENDING, &il->status))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002418 ret = 0;
2419 break;
2420 case IEEE80211_AMPDU_TX_START:
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002421 D_HT("start Tx\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002422 ret = il4965_tx_agg_start(il, vif, sta, tid, ssn);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002423 break;
2424 case IEEE80211_AMPDU_TX_STOP:
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002425 D_HT("stop Tx\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002426 ret = il4965_tx_agg_stop(il, vif, sta, tid);
2427 if (test_bit(STATUS_EXIT_PENDING, &il->status))
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002428 ret = 0;
2429 break;
2430 case IEEE80211_AMPDU_TX_OPERATIONAL:
2431 ret = 0;
2432 break;
2433 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002434 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002435
2436 return ret;
2437}
2438
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002439int il4965_mac_sta_add(struct ieee80211_hw *hw,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002440 struct ieee80211_vif *vif,
2441 struct ieee80211_sta *sta)
2442{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002443 struct il_priv *il = hw->priv;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002444 struct il_station_priv *sta_priv = (void *)sta->drv_priv;
2445 struct il_vif_priv *vif_priv = (void *)vif->drv_priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002446 bool is_ap = vif->type == NL80211_IFTYPE_STATION;
2447 int ret;
2448 u8 sta_id;
2449
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002450 D_INFO("received request to add station %pM\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002451 sta->addr);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002452 mutex_lock(&il->mutex);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002453 D_INFO("proceeding to add station %pM\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002454 sta->addr);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002455 sta_priv->common.sta_id = IL_INVALID_STATION;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002456
2457 atomic_set(&sta_priv->pending_frames, 0);
2458
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002459 ret = il_add_station_common(il, vif_priv->ctx, sta->addr,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002460 is_ap, sta, &sta_id);
2461 if (ret) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002462 IL_ERR("Unable to add station %pM (%d)\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002463 sta->addr, ret);
2464 /* Should we return success if return code is EEXIST ? */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002465 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002466 return ret;
2467 }
2468
2469 sta_priv->common.sta_id = sta_id;
2470
2471 /* Initialize rate scaling */
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002472 D_INFO("Initializing rate scaling for station %pM\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002473 sta->addr);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002474 il4965_rs_rate_init(il, sta, sta_id);
2475 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002476
2477 return 0;
2478}
2479
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002480void il4965_mac_channel_switch(struct ieee80211_hw *hw,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002481 struct ieee80211_channel_switch *ch_switch)
2482{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002483 struct il_priv *il = hw->priv;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002484 const struct il_channel_info *ch_info;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002485 struct ieee80211_conf *conf = &hw->conf;
2486 struct ieee80211_channel *channel = ch_switch->channel;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002487 struct il_ht_config *ht_conf = &il->current_ht_config;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002488
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +01002489 struct il_rxon_context *ctx = &il->ctx;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002490 u16 ch;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002491
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002492 D_MAC80211("enter\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002493
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002494 mutex_lock(&il->mutex);
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002495
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002496 if (il_is_rfkill(il))
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002497 goto out;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002498
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002499 if (test_bit(STATUS_EXIT_PENDING, &il->status) ||
2500 test_bit(STATUS_SCANNING, &il->status) ||
2501 test_bit(STATUS_CHANNEL_SWITCH_PENDING, &il->status))
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002502 goto out;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002503
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002504 if (!il_is_associated_ctx(ctx))
Stanislaw Gruszka28a6e572011-04-28 11:51:32 +02002505 goto out;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002506
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002507 if (!il->cfg->ops->lib->set_channel_switch)
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02002508 goto out;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002509
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02002510 ch = channel->hw_value;
2511 if (le16_to_cpu(ctx->active.channel) == ch)
2512 goto out;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002513
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002514 ch_info = il_get_channel_info(il, channel->band, ch);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002515 if (!il_is_channel_valid(ch_info)) {
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002516 D_MAC80211("invalid channel\n");
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02002517 goto out;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002518 }
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02002519
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002520 spin_lock_irq(&il->lock);
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02002521
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002522 il->current_ht_config.smps = conf->smps_mode;
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02002523
2524 /* Configure HT40 channels */
2525 ctx->ht.enabled = conf_is_ht(conf);
2526 if (ctx->ht.enabled) {
2527 if (conf_is_ht40_minus(conf)) {
2528 ctx->ht.extension_chan_offset =
2529 IEEE80211_HT_PARAM_CHA_SEC_BELOW;
2530 ctx->ht.is_40mhz = true;
2531 } else if (conf_is_ht40_plus(conf)) {
2532 ctx->ht.extension_chan_offset =
2533 IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
2534 ctx->ht.is_40mhz = true;
2535 } else {
2536 ctx->ht.extension_chan_offset =
2537 IEEE80211_HT_PARAM_CHA_SEC_NONE;
2538 ctx->ht.is_40mhz = false;
2539 }
2540 } else
2541 ctx->ht.is_40mhz = false;
2542
2543 if ((le16_to_cpu(ctx->staging.channel) != ch))
2544 ctx->staging.flags = 0;
2545
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002546 il_set_rxon_channel(il, channel, ctx);
2547 il_set_rxon_ht(il, ht_conf);
2548 il_set_flags_for_band(il, ctx, channel->band, ctx->vif);
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02002549
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002550 spin_unlock_irq(&il->lock);
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02002551
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002552 il_set_rate(il);
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02002553 /*
2554 * at this point, staging_rxon has the
2555 * configuration for channel switch
2556 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002557 set_bit(STATUS_CHANNEL_SWITCH_PENDING, &il->status);
2558 il->switch_channel = cpu_to_le16(ch);
2559 if (il->cfg->ops->lib->set_channel_switch(il, ch_switch)) {
2560 clear_bit(STATUS_CHANNEL_SWITCH_PENDING, &il->status);
2561 il->switch_channel = 0;
Stanislaw Gruszka7f1f9742011-06-08 15:28:29 +02002562 ieee80211_chswitch_done(ctx->vif, false);
2563 }
2564
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002565out:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002566 mutex_unlock(&il->mutex);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002567 D_MAC80211("leave\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002568}
2569
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002570void il4965_configure_filter(struct ieee80211_hw *hw,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002571 unsigned int changed_flags,
2572 unsigned int *total_flags,
2573 u64 multicast)
2574{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002575 struct il_priv *il = hw->priv;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002576 __le32 filter_or = 0, filter_nand = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002577
2578#define CHK(test, flag) do { \
2579 if (*total_flags & (test)) \
2580 filter_or |= (flag); \
2581 else \
2582 filter_nand |= (flag); \
2583 } while (0)
2584
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002585 D_MAC80211("Enter: changed: 0x%x, total: 0x%x\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002586 changed_flags, *total_flags);
2587
2588 CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK);
2589 /* Setting _just_ RXON_FILTER_CTL2HOST_MSK causes FH errors */
2590 CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK | RXON_FILTER_PROMISC_MSK);
2591 CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK);
2592
2593#undef CHK
2594
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002595 mutex_lock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002596
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +02002597 il->ctx.staging.filter_flags &= ~filter_nand;
2598 il->ctx.staging.filter_flags |= filter_or;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002599
Stanislaw Gruszka17d6e552011-08-29 12:52:20 +02002600 /*
2601 * Not committing directly because hardware can perform a scan,
2602 * but we'll eventually commit the filter flags change anyway.
2603 */
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002604
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002605 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002606
2607 /*
2608 * Receiving all multicast frames is always enabled by the
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002609 * default flags setup in il_connection_init_rx_config()
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002610 * since we currently do not support programming multicast
2611 * filters into the device.
2612 */
2613 *total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
2614 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
2615}
2616
2617/*****************************************************************************
2618 *
2619 * driver setup and teardown
2620 *
2621 *****************************************************************************/
2622
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002623static void il4965_bg_txpower_work(struct work_struct *work)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002624{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002625 struct il_priv *il = container_of(work, struct il_priv,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002626 txpower_work);
2627
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002628 mutex_lock(&il->mutex);
Stanislaw Gruszkaf3257572011-04-28 11:36:54 +02002629
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002630 /* If a scan happened to start before we got here
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02002631 * then just return; the stats notification will
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002632 * kick off another scheduled work to compensate for
2633 * any temperature delta we missed here. */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002634 if (test_bit(STATUS_EXIT_PENDING, &il->status) ||
2635 test_bit(STATUS_SCANNING, &il->status))
Stanislaw Gruszkaf3257572011-04-28 11:36:54 +02002636 goto out;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002637
2638 /* Regardless of if we are associated, we must reconfigure the
2639 * TX power since frames can be sent on non-radar channels while
2640 * not associated */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002641 il->cfg->ops->lib->send_tx_power(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002642
2643 /* Update last_temperature to keep is_calib_needed from running
2644 * when it isn't needed... */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002645 il->last_temperature = il->temperature;
Stanislaw Gruszkaf3257572011-04-28 11:36:54 +02002646out:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002647 mutex_unlock(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002648}
2649
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002650static void il4965_setup_deferred_work(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002651{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002652 il->workqueue = create_singlethread_workqueue(DRV_NAME);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002653
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002654 init_waitqueue_head(&il->wait_command_queue);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002655
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002656 INIT_WORK(&il->restart, il4965_bg_restart);
2657 INIT_WORK(&il->rx_replenish, il4965_bg_rx_replenish);
2658 INIT_WORK(&il->run_time_calib_work, il4965_bg_run_time_calib_work);
2659 INIT_DELAYED_WORK(&il->init_alive_start, il4965_bg_init_alive_start);
2660 INIT_DELAYED_WORK(&il->alive_start, il4965_bg_alive_start);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002661
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002662 il_setup_scan_deferred_work(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002663
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002664 INIT_WORK(&il->txpower_work, il4965_bg_txpower_work);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002665
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02002666 init_timer(&il->stats_periodic);
2667 il->stats_periodic.data = (unsigned long)il;
2668 il->stats_periodic.function = il4965_bg_stats_periodic;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002669
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002670 init_timer(&il->watchdog);
2671 il->watchdog.data = (unsigned long)il;
2672 il->watchdog.function = il_bg_watchdog;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002673
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002674 tasklet_init(&il->irq_tasklet, (void (*)(unsigned long))
2675 il4965_irq_tasklet, (unsigned long)il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002676}
2677
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002678static void il4965_cancel_deferred_work(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002679{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002680 cancel_work_sync(&il->txpower_work);
2681 cancel_delayed_work_sync(&il->init_alive_start);
2682 cancel_delayed_work(&il->alive_start);
2683 cancel_work_sync(&il->run_time_calib_work);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002684
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002685 il_cancel_scan_deferred_work(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002686
Stanislaw Gruszkaebf0d902011-08-26 15:43:47 +02002687 del_timer_sync(&il->stats_periodic);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002688}
2689
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002690static void il4965_init_hw_rates(struct il_priv *il,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002691 struct ieee80211_rate *rates)
2692{
2693 int i;
2694
Stanislaw Gruszka2eb05812011-08-26 16:07:43 +02002695 for (i = 0; i < RATE_COUNT_LEGACY; i++) {
Stanislaw Gruszkad2ddf6212011-08-16 14:17:04 +02002696 rates[i].bitrate = il_rates[i].ieee * 5;
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +01002697 rates[i].hw_value = i; /* Rate scaling will work on idxes */
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002698 rates[i].hw_value_short = i;
2699 rates[i].flags = 0;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002700 if ((i >= IL_FIRST_CCK_RATE) && (i <= IL_LAST_CCK_RATE)) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002701 /*
2702 * If CCK != 1M then set short preamble rate flag.
2703 */
2704 rates[i].flags |=
Stanislaw Gruszka2eb05812011-08-26 16:07:43 +02002705 (il_rates[i].plcp == RATE_1M_PLCP) ?
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002706 0 : IEEE80211_RATE_SHORT_PREAMBLE;
2707 }
2708 }
2709}
2710/*
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002711 * Acquire il->lock before calling this function !
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002712 */
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +01002713void il4965_set_wr_ptrs(struct il_priv *il, int txq_id, u32 idx)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002714{
Stanislaw Gruszka0c1a94e2011-08-24 17:37:16 +02002715 il_wr(il, HBUS_TARG_WRPTR,
Stanislaw Gruszka0c2c8852011-11-15 12:30:17 +01002716 (idx & 0xff) | (txq_id << 8));
2717 il_wr_prph(il, IL49_SCD_QUEUE_RDPTR(txq_id), idx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002718}
2719
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002720void il4965_tx_queue_set_status(struct il_priv *il,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002721 struct il_tx_queue *txq,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002722 int tx_fifo_id, int scd_retry)
2723{
2724 int txq_id = txq->q.id;
2725
2726 /* Find out whether to activate Tx queue */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002727 int active = test_bit(txq_id, &il->txq_ctx_active_msk) ? 1 : 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002728
2729 /* Set up and activate */
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01002730 il_wr_prph(il, IL49_SCD_QUEUE_STATUS_BITS(txq_id),
2731 (active << IL49_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
2732 (tx_fifo_id << IL49_SCD_QUEUE_STTS_REG_POS_TXF) |
2733 (scd_retry << IL49_SCD_QUEUE_STTS_REG_POS_WSL) |
2734 (scd_retry << IL49_SCD_QUEUE_STTS_REG_POS_SCD_ACK) |
2735 IL49_SCD_QUEUE_STTS_REG_MSK);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002736
2737 txq->sched_retry = scd_retry;
2738
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002739 D_INFO("%s %s Queue %d on AC %d\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002740 active ? "Activate" : "Deactivate",
2741 scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
2742}
2743
2744
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002745static int il4965_init_drv(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002746{
2747 int ret;
2748
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002749 spin_lock_init(&il->sta_lock);
2750 spin_lock_init(&il->hcmd_lock);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002751
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002752 INIT_LIST_HEAD(&il->free_frames);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002753
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002754 mutex_init(&il->mutex);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002755
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002756 il->ieee_channels = NULL;
2757 il->ieee_rates = NULL;
2758 il->band = IEEE80211_BAND_2GHZ;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002759
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002760 il->iw_mode = NL80211_IFTYPE_STATION;
2761 il->current_ht_config.smps = IEEE80211_SMPS_STATIC;
2762 il->missed_beacon_threshold = IL_MISSED_BEACON_THRESHOLD_DEF;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002763
2764 /* initialize force reset */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002765 il->force_reset.reset_duration = IL_DELAY_NEXT_FORCE_FW_RELOAD;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002766
2767 /* Choose which receivers/antennas to use */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002768 if (il->cfg->ops->hcmd->set_rxon_chain)
2769 il->cfg->ops->hcmd->set_rxon_chain(il,
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +01002770 &il->ctx);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002771
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002772 il_init_scan_params(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002773
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002774 ret = il_init_channel_map(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002775 if (ret) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002776 IL_ERR("initializing regulatory failed: %d\n", ret);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002777 goto err;
2778 }
2779
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002780 ret = il_init_geos(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002781 if (ret) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002782 IL_ERR("initializing geos failed: %d\n", ret);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002783 goto err_free_channel_map;
2784 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002785 il4965_init_hw_rates(il, il->ieee_rates);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002786
2787 return 0;
2788
2789err_free_channel_map:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002790 il_free_channel_map(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002791err:
2792 return ret;
2793}
2794
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002795static void il4965_uninit_drv(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002796{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002797 il4965_calib_free_results(il);
2798 il_free_geos(il);
2799 il_free_channel_map(il);
2800 kfree(il->scan_cmd);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002801}
2802
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002803static void il4965_hw_detect(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002804{
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02002805 il->hw_rev = _il_rd(il, CSR_HW_REV);
2806 il->hw_wa_rev = _il_rd(il, CSR_HW_REV_WA_REG);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002807 il->rev_id = il->pci_dev->revision;
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002808 D_INFO("HW Revision ID = 0x%X\n", il->rev_id);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002809}
2810
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002811static int il4965_set_hw_params(struct il_priv *il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002812{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002813 il->hw_params.max_rxq_size = RX_QUEUE_SIZE;
2814 il->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
2815 if (il->cfg->mod_params->amsdu_size_8K)
2816 il->hw_params.rx_page_order = get_order(IL_RX_BUF_SIZE_8K);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002817 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002818 il->hw_params.rx_page_order = get_order(IL_RX_BUF_SIZE_4K);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002819
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002820 il->hw_params.max_beacon_itrvl = IL_MAX_UCODE_BEACON_INTERVAL;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002821
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002822 if (il->cfg->mod_params->disable_11n)
2823 il->cfg->sku &= ~IL_SKU_N;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002824
2825 /* Device-specific setup */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002826 return il->cfg->ops->lib->set_hw_params(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002827}
2828
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002829static const u8 il4965_bss_ac_to_fifo[] = {
2830 IL_TX_FIFO_VO,
2831 IL_TX_FIFO_VI,
2832 IL_TX_FIFO_BE,
2833 IL_TX_FIFO_BK,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002834};
2835
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002836static const u8 il4965_bss_ac_to_queue[] = {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002837 0, 1, 2, 3,
2838};
2839
2840static int
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002841il4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002842{
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +01002843 int err = 0;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002844 struct il_priv *il;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002845 struct ieee80211_hw *hw;
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002846 struct il_cfg *cfg = (struct il_cfg *)(ent->driver_data);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002847 unsigned long flags;
2848 u16 pci_cmd;
2849
2850 /************************
2851 * 1. Allocating HW data
2852 ************************/
2853
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02002854 hw = il_alloc_all(cfg);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002855 if (!hw) {
2856 err = -ENOMEM;
2857 goto out;
2858 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002859 il = hw->priv;
2860 /* At this point both hw and il are allocated. */
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002861
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +01002862 il->ctx.ctxid = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002863
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +01002864 il->ctx.always_active = true;
2865 il->ctx.is_active = true;
2866 il->ctx.rxon_cmd = REPLY_RXON;
2867 il->ctx.rxon_timing_cmd = REPLY_RXON_TIMING;
2868 il->ctx.rxon_assoc_cmd = REPLY_RXON_ASSOC;
2869 il->ctx.qos_cmd = REPLY_QOS_PARAM;
2870 il->ctx.ap_sta_id = IL_AP_ID;
2871 il->ctx.wep_key_cmd = REPLY_WEPKEY;
2872 il->ctx.ac_to_fifo = il4965_bss_ac_to_fifo;
2873 il->ctx.ac_to_queue = il4965_bss_ac_to_queue;
2874 il->ctx.exclusive_interface_modes =
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002875 BIT(NL80211_IFTYPE_ADHOC);
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +01002876 il->ctx.interface_modes =
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002877 BIT(NL80211_IFTYPE_STATION);
Stanislaw Gruszka7c2cde22011-11-15 11:29:04 +01002878 il->ctx.ap_devtype = RXON_DEV_TYPE_AP;
2879 il->ctx.ibss_devtype = RXON_DEV_TYPE_IBSS;
2880 il->ctx.station_devtype = RXON_DEV_TYPE_ESS;
2881 il->ctx.unused_devtype = RXON_DEV_TYPE_ESS;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002882
2883 SET_IEEE80211_DEV(hw, &pdev->dev);
2884
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002885 D_INFO("*** LOAD DRIVER ***\n");
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002886 il->cfg = cfg;
2887 il->pci_dev = pdev;
2888 il->inta_mask = CSR_INI_SET_MASK;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002889
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002890 if (il_alloc_traffic_mem(il))
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002891 IL_ERR("Not enough memory to generate traffic log\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002892
2893 /**************************
2894 * 2. Initializing PCI bus
2895 **************************/
2896 pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 |
2897 PCIE_LINK_STATE_CLKPM);
2898
2899 if (pci_enable_device(pdev)) {
2900 err = -ENODEV;
2901 goto out_ieee80211_free_hw;
2902 }
2903
2904 pci_set_master(pdev);
2905
2906 err = pci_set_dma_mask(pdev, DMA_BIT_MASK(36));
2907 if (!err)
2908 err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(36));
2909 if (err) {
2910 err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
2911 if (!err)
2912 err = pci_set_consistent_dma_mask(pdev,
2913 DMA_BIT_MASK(32));
2914 /* both attempts failed: */
2915 if (err) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002916 IL_WARN("No suitable DMA available.\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002917 goto out_pci_disable_device;
2918 }
2919 }
2920
2921 err = pci_request_regions(pdev, DRV_NAME);
2922 if (err)
2923 goto out_pci_disable_device;
2924
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002925 pci_set_drvdata(pdev, il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002926
2927
2928 /***********************
2929 * 3. Read REV register
2930 ***********************/
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002931 il->hw_base = pci_iomap(pdev, 0, 0);
2932 if (!il->hw_base) {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002933 err = -ENODEV;
2934 goto out_pci_release_regions;
2935 }
2936
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002937 D_INFO("pci_resource_len = 0x%08llx\n",
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002938 (unsigned long long) pci_resource_len(pdev, 0));
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002939 D_INFO("pci_resource_base = %p\n", il->hw_base);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002940
2941 /* these spin locks will be used in apm_ops.init and EEPROM access
2942 * we should init now
2943 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002944 spin_lock_init(&il->reg_lock);
2945 spin_lock_init(&il->lock);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002946
2947 /*
2948 * stop and reset the on-board processor just in case it is in a
2949 * strange state ... like being left stranded by a primary kernel
2950 * and this is now the kdump kernel trying to start up
2951 */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02002952 _il_wr(il, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002953
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002954 il4965_hw_detect(il);
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002955 IL_INFO("Detected %s, REV=0x%X\n",
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002956 il->cfg->name, il->hw_rev);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002957
2958 /* We disable the RETRY_TIMEOUT register (0x41) to keep
2959 * PCI Tx retries from interfering with C3 CPU state */
2960 pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
2961
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002962 il4965_prepare_card_hw(il);
2963 if (!il->hw_ready) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002964 IL_WARN("Failed, HW not ready\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002965 goto out_iounmap;
2966 }
2967
2968 /*****************
2969 * 4. Read EEPROM
2970 *****************/
2971 /* Read the EEPROM */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002972 err = il_eeprom_init(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002973 if (err) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002974 IL_ERR("Unable to init EEPROM\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002975 goto out_iounmap;
2976 }
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002977 err = il4965_eeprom_check_version(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002978 if (err)
2979 goto out_free_eeprom;
2980
2981 if (err)
2982 goto out_free_eeprom;
2983
2984 /* extract MAC Address */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002985 il4965_eeprom_get_mac(il, il->addresses[0].addr);
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01002986 D_INFO("MAC address: %pM\n", il->addresses[0].addr);
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002987 il->hw->wiphy->addresses = il->addresses;
2988 il->hw->wiphy->n_addresses = 1;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002989
2990 /************************
2991 * 5. Setup HW constants
2992 ************************/
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002993 if (il4965_set_hw_params(il)) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02002994 IL_ERR("failed to set hw parameters\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08002995 goto out_free_eeprom;
2996 }
2997
2998 /*******************
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02002999 * 6. Setup il
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003000 *******************/
3001
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003002 err = il4965_init_drv(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003003 if (err)
3004 goto out_free_eeprom;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003005 /* At this point both hw and il are initialized. */
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003006
3007 /********************
3008 * 7. Setup services
3009 ********************/
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003010 spin_lock_irqsave(&il->lock, flags);
3011 il_disable_interrupts(il);
3012 spin_unlock_irqrestore(&il->lock, flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003013
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003014 pci_enable_msi(il->pci_dev);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003015
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003016 err = request_irq(il->pci_dev->irq, il_isr,
3017 IRQF_SHARED, DRV_NAME, il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003018 if (err) {
Stanislaw Gruszka9406f792011-08-18 22:07:57 +02003019 IL_ERR("Error allocating IRQ %d\n", il->pci_dev->irq);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003020 goto out_disable_msi;
3021 }
3022
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003023 il4965_setup_deferred_work(il);
3024 il4965_setup_rx_handlers(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003025
3026 /*********************************************
3027 * 8. Enable interrupts and read RFKILL state
3028 *********************************************/
3029
Stanislaw Gruszkaa078a1f2011-04-28 11:51:25 +02003030 /* enable rfkill interrupt: hw bug w/a */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003031 pci_read_config_word(il->pci_dev, PCI_COMMAND, &pci_cmd);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003032 if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
3033 pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003034 pci_write_config_word(il->pci_dev, PCI_COMMAND, pci_cmd);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003035 }
3036
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003037 il_enable_rfkill_int(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003038
3039 /* If platform's RF_KILL switch is NOT set to KILL */
Stanislaw Gruszka841b2cc2011-08-24 15:14:03 +02003040 if (_il_rd(il, CSR_GP_CNTRL) &
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003041 CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003042 clear_bit(STATUS_RF_KILL_HW, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003043 else
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003044 set_bit(STATUS_RF_KILL_HW, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003045
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003046 wiphy_rfkill_set_hw_state(il->hw->wiphy,
3047 test_bit(STATUS_RF_KILL_HW, &il->status));
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003048
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003049 il_power_initialize(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003050
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003051 init_completion(&il->_4965.firmware_loading_complete);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003052
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003053 err = il4965_request_firmware(il, true);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003054 if (err)
3055 goto out_destroy_workqueue;
3056
3057 return 0;
3058
3059 out_destroy_workqueue:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003060 destroy_workqueue(il->workqueue);
3061 il->workqueue = NULL;
3062 free_irq(il->pci_dev->irq, il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003063 out_disable_msi:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003064 pci_disable_msi(il->pci_dev);
3065 il4965_uninit_drv(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003066 out_free_eeprom:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003067 il_eeprom_free(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003068 out_iounmap:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003069 pci_iounmap(pdev, il->hw_base);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003070 out_pci_release_regions:
3071 pci_set_drvdata(pdev, NULL);
3072 pci_release_regions(pdev);
3073 out_pci_disable_device:
3074 pci_disable_device(pdev);
3075 out_ieee80211_free_hw:
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003076 il_free_traffic_mem(il);
3077 ieee80211_free_hw(il->hw);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003078 out:
3079 return err;
3080}
3081
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003082static void __devexit il4965_pci_remove(struct pci_dev *pdev)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003083{
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003084 struct il_priv *il = pci_get_drvdata(pdev);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003085 unsigned long flags;
3086
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003087 if (!il)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003088 return;
3089
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003090 wait_for_completion(&il->_4965.firmware_loading_complete);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003091
Stanislaw Gruszka58de00a2011-11-15 11:21:01 +01003092 D_INFO("*** UNLOAD DRIVER ***\n");
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003093
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003094 il_dbgfs_unregister(il);
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003095 sysfs_remove_group(&pdev->dev.kobj, &il_attribute_group);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003096
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003097 /* ieee80211_unregister_hw call wil cause il_mac_stop to
3098 * to be called and il4965_down since we are removing the device
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003099 * we need to set STATUS_EXIT_PENDING bit.
3100 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003101 set_bit(STATUS_EXIT_PENDING, &il->status);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003102
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003103 il_leds_exit(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003104
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003105 if (il->mac80211_registered) {
3106 ieee80211_unregister_hw(il->hw);
3107 il->mac80211_registered = 0;
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003108 } else {
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003109 il4965_down(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003110 }
3111
3112 /*
3113 * Make sure device is reset to low power before unloading driver.
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003114 * This may be redundant with il4965_down(), but there are paths to
3115 * run il4965_down() without calling apm_ops.stop(), and there are
3116 * paths to avoid running il4965_down() at all before leaving driver.
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003117 * This (inexpensive) call *makes sure* device is reset.
3118 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003119 il_apm_stop(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003120
3121 /* make sure we flush any pending irq or
3122 * tasklet for the driver
3123 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003124 spin_lock_irqsave(&il->lock, flags);
3125 il_disable_interrupts(il);
3126 spin_unlock_irqrestore(&il->lock, flags);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003127
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003128 il4965_synchronize_irq(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003129
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003130 il4965_dealloc_ucode_pci(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003131
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003132 if (il->rxq.bd)
3133 il4965_rx_queue_free(il, &il->rxq);
3134 il4965_hw_txq_ctx_free(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003135
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003136 il_eeprom_free(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003137
3138
3139 /*netif_stop_queue(dev); */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003140 flush_workqueue(il->workqueue);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003141
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003142 /* ieee80211_unregister_hw calls il_mac_stop, which flushes
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003143 * il->workqueue... so we can't take down the workqueue
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003144 * until now... */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003145 destroy_workqueue(il->workqueue);
3146 il->workqueue = NULL;
3147 il_free_traffic_mem(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003148
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003149 free_irq(il->pci_dev->irq, il);
3150 pci_disable_msi(il->pci_dev);
3151 pci_iounmap(pdev, il->hw_base);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003152 pci_release_regions(pdev);
3153 pci_disable_device(pdev);
3154 pci_set_drvdata(pdev, NULL);
3155
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003156 il4965_uninit_drv(il);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003157
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003158 dev_kfree_skb(il->beacon_skb);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003159
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003160 ieee80211_free_hw(il->hw);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003161}
3162
3163/*
3164 * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003165 * must be called under il->lock and mac access
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003166 */
Stanislaw Gruszka46bc8d42011-10-24 16:49:25 +02003167void il4965_txq_set_sched(struct il_priv *il, u32 mask)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003168{
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01003169 il_wr_prph(il, IL49_SCD_TXFACT, mask);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003170}
3171
3172/*****************************************************************************
3173 *
3174 * driver and module entry point
3175 *
3176 *****************************************************************************/
3177
3178/* Hardware specific file defines the PCI IDs table for that hardware module */
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003179static DEFINE_PCI_DEVICE_TABLE(il4965_hw_card_ids) = {
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003180 {IL_PCI_DEVICE(0x4229, PCI_ANY_ID, il4965_cfg)},
3181 {IL_PCI_DEVICE(0x4230, PCI_ANY_ID, il4965_cfg)},
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003182 {0}
3183};
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003184MODULE_DEVICE_TABLE(pci, il4965_hw_card_ids);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003185
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003186static struct pci_driver il4965_driver = {
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003187 .name = DRV_NAME,
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003188 .id_table = il4965_hw_card_ids,
3189 .probe = il4965_pci_probe,
3190 .remove = __devexit_p(il4965_pci_remove),
3191 .driver.pm = IL_LEGACY_PM_OPS,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003192};
3193
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003194static int __init il4965_init(void)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003195{
3196
3197 int ret;
3198 pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n");
3199 pr_info(DRV_COPYRIGHT "\n");
3200
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003201 ret = il4965_rate_control_register();
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003202 if (ret) {
3203 pr_err("Unable to register rate control algorithm: %d\n", ret);
3204 return ret;
3205 }
3206
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003207 ret = pci_register_driver(&il4965_driver);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003208 if (ret) {
3209 pr_err("Unable to initialize PCI module\n");
3210 goto error_register;
3211 }
3212
3213 return ret;
3214
3215error_register:
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003216 il4965_rate_control_unregister();
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003217 return ret;
3218}
3219
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003220static void __exit il4965_exit(void)
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003221{
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003222 pci_unregister_driver(&il4965_driver);
3223 il4965_rate_control_unregister();
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003224}
3225
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003226module_exit(il4965_exit);
3227module_init(il4965_init);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003228
Stanislaw Gruszkad3175162011-11-15 11:25:42 +01003229#ifdef CONFIG_IWLEGACY_DEBUG
Stanislaw Gruszkad2ddf6212011-08-16 14:17:04 +02003230module_param_named(debug, il_debug_level, uint, S_IRUGO | S_IWUSR);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003231MODULE_PARM_DESC(debug, "debug output mask");
3232#endif
3233
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003234module_param_named(swcrypto, il4965_mod_params.sw_crypto, int, S_IRUGO);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003235MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003236module_param_named(queues_num, il4965_mod_params.num_of_queues, int, S_IRUGO);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003237MODULE_PARM_DESC(queues_num, "number of hw queues.");
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003238module_param_named(11n_disable, il4965_mod_params.disable_11n, int, S_IRUGO);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003239MODULE_PARM_DESC(11n_disable, "disable 11n functionality");
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003240module_param_named(amsdu_size_8K, il4965_mod_params.amsdu_size_8K,
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003241 int, S_IRUGO);
3242MODULE_PARM_DESC(amsdu_size_8K, "enable 8K amsdu size");
Stanislaw Gruszkae2ebc832011-10-24 15:41:30 +02003243module_param_named(fw_restart, il4965_mod_params.restart_fw, int, S_IRUGO);
Wey-Yi Guybe663ab2011-02-21 11:27:26 -08003244MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");