~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/net/wireless/iwlwifi/iwl-4965.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/******************************************************************************
2
 
 *
3
 
 * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or modify it
6
 
 * under the terms of version 2 of the GNU General Public License as
7
 
 * published by the Free Software Foundation.
8
 
 *
9
 
 * This program is distributed in the hope that it will be useful, but WITHOUT
10
 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
 
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12
 
 * more details.
13
 
 *
14
 
 * You should have received a copy of the GNU General Public License along with
15
 
 * this program; if not, write to the Free Software Foundation, Inc.,
16
 
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17
 
 *
18
 
 * The full GNU General Public License is included in this distribution in the
19
 
 * file called LICENSE.
20
 
 *
21
 
 * Contact Information:
22
 
 *  Intel Linux Wireless <ilw@linux.intel.com>
23
 
 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
24
 
 *
25
 
 *****************************************************************************/
26
 
 
27
 
#include <linux/kernel.h>
28
 
#include <linux/module.h>
29
 
#include <linux/init.h>
30
 
#include <linux/pci.h>
31
 
#include <linux/dma-mapping.h>
32
 
#include <linux/delay.h>
33
 
#include <linux/sched.h>
34
 
#include <linux/skbuff.h>
35
 
#include <linux/netdevice.h>
36
 
#include <linux/wireless.h>
37
 
#include <net/mac80211.h>
38
 
#include <linux/etherdevice.h>
39
 
#include <asm/unaligned.h>
40
 
 
41
 
#include "iwl-eeprom.h"
42
 
#include "iwl-dev.h"
43
 
#include "iwl-core.h"
44
 
#include "iwl-io.h"
45
 
#include "iwl-helpers.h"
46
 
#include "iwl-agn-calib.h"
47
 
#include "iwl-sta.h"
48
 
#include "iwl-agn-led.h"
49
 
#include "iwl-agn.h"
50
 
#include "iwl-agn-debugfs.h"
51
 
#include "iwl-legacy.h"
52
 
 
53
 
static int iwl4965_send_tx_power(struct iwl_priv *priv);
54
 
static int iwl4965_hw_get_temperature(struct iwl_priv *priv);
55
 
 
56
 
/* Highest firmware API version supported */
57
 
#define IWL4965_UCODE_API_MAX 2
58
 
 
59
 
/* Lowest firmware API version supported */
60
 
#define IWL4965_UCODE_API_MIN 2
61
 
 
62
 
#define IWL4965_FW_PRE "iwlwifi-4965-"
63
 
#define _IWL4965_MODULE_FIRMWARE(api) IWL4965_FW_PRE #api ".ucode"
64
 
#define IWL4965_MODULE_FIRMWARE(api) _IWL4965_MODULE_FIRMWARE(api)
65
 
 
66
 
/* check contents of special bootstrap uCode SRAM */
67
 
static int iwl4965_verify_bsm(struct iwl_priv *priv)
68
 
{
69
 
        __le32 *image = priv->ucode_boot.v_addr;
70
 
        u32 len = priv->ucode_boot.len;
71
 
        u32 reg;
72
 
        u32 val;
73
 
 
74
 
        IWL_DEBUG_INFO(priv, "Begin verify bsm\n");
75
 
 
76
 
        /* verify BSM SRAM contents */
77
 
        val = iwl_read_prph(priv, BSM_WR_DWCOUNT_REG);
78
 
        for (reg = BSM_SRAM_LOWER_BOUND;
79
 
             reg < BSM_SRAM_LOWER_BOUND + len;
80
 
             reg += sizeof(u32), image++) {
81
 
                val = iwl_read_prph(priv, reg);
82
 
                if (val != le32_to_cpu(*image)) {
83
 
                        IWL_ERR(priv, "BSM uCode verification failed at "
84
 
                                  "addr 0x%08X+%u (of %u), is 0x%x, s/b 0x%x\n",
85
 
                                  BSM_SRAM_LOWER_BOUND,
86
 
                                  reg - BSM_SRAM_LOWER_BOUND, len,
87
 
                                  val, le32_to_cpu(*image));
88
 
                        return -EIO;
89
 
                }
90
 
        }
91
 
 
92
 
        IWL_DEBUG_INFO(priv, "BSM bootstrap uCode image OK\n");
93
 
 
94
 
        return 0;
95
 
}
96
 
 
97
 
/**
98
 
 * iwl4965_load_bsm - Load bootstrap instructions
99
 
 *
100
 
 * BSM operation:
101
 
 *
102
 
 * The Bootstrap State Machine (BSM) stores a short bootstrap uCode program
103
 
 * in special SRAM that does not power down during RFKILL.  When powering back
104
 
 * up after power-saving sleeps (or during initial uCode load), the BSM loads
105
 
 * the bootstrap program into the on-board processor, and starts it.
106
 
 *
107
 
 * The bootstrap program loads (via DMA) instructions and data for a new
108
 
 * program from host DRAM locations indicated by the host driver in the
109
 
 * BSM_DRAM_* registers.  Once the new program is loaded, it starts
110
 
 * automatically.
111
 
 *
112
 
 * When initializing the NIC, the host driver points the BSM to the
113
 
 * "initialize" uCode image.  This uCode sets up some internal data, then
114
 
 * notifies host via "initialize alive" that it is complete.
115
 
 *
116
 
 * The host then replaces the BSM_DRAM_* pointer values to point to the
117
 
 * normal runtime uCode instructions and a backup uCode data cache buffer
118
 
 * (filled initially with starting data values for the on-board processor),
119
 
 * then triggers the "initialize" uCode to load and launch the runtime uCode,
120
 
 * which begins normal operation.
121
 
 *
122
 
 * When doing a power-save shutdown, runtime uCode saves data SRAM into
123
 
 * the backup data cache in DRAM before SRAM is powered down.
124
 
 *
125
 
 * When powering back up, the BSM loads the bootstrap program.  This reloads
126
 
 * the runtime uCode instructions and the backup data cache into SRAM,
127
 
 * and re-launches the runtime uCode from where it left off.
128
 
 */
129
 
static int iwl4965_load_bsm(struct iwl_priv *priv)
130
 
{
131
 
        __le32 *image = priv->ucode_boot.v_addr;
132
 
        u32 len = priv->ucode_boot.len;
133
 
        dma_addr_t pinst;
134
 
        dma_addr_t pdata;
135
 
        u32 inst_len;
136
 
        u32 data_len;
137
 
        int i;
138
 
        u32 done;
139
 
        u32 reg_offset;
140
 
        int ret;
141
 
 
142
 
        IWL_DEBUG_INFO(priv, "Begin load bsm\n");
143
 
 
144
 
        priv->ucode_type = UCODE_RT;
145
 
 
146
 
        /* make sure bootstrap program is no larger than BSM's SRAM size */
147
 
        if (len > IWL49_MAX_BSM_SIZE)
148
 
                return -EINVAL;
149
 
 
150
 
        /* Tell bootstrap uCode where to find the "Initialize" uCode
151
 
         *   in host DRAM ... host DRAM physical address bits 35:4 for 4965.
152
 
         * NOTE:  iwl_init_alive_start() will replace these values,
153
 
         *        after the "initialize" uCode has run, to point to
154
 
         *        runtime/protocol instructions and backup data cache.
155
 
         */
156
 
        pinst = priv->ucode_init.p_addr >> 4;
157
 
        pdata = priv->ucode_init_data.p_addr >> 4;
158
 
        inst_len = priv->ucode_init.len;
159
 
        data_len = priv->ucode_init_data.len;
160
 
 
161
 
        iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
162
 
        iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
163
 
        iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG, inst_len);
164
 
        iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG, data_len);
165
 
 
166
 
        /* Fill BSM memory with bootstrap instructions */
167
 
        for (reg_offset = BSM_SRAM_LOWER_BOUND;
168
 
             reg_offset < BSM_SRAM_LOWER_BOUND + len;
169
 
             reg_offset += sizeof(u32), image++)
170
 
                _iwl_write_prph(priv, reg_offset, le32_to_cpu(*image));
171
 
 
172
 
        ret = iwl4965_verify_bsm(priv);
173
 
        if (ret)
174
 
                return ret;
175
 
 
176
 
        /* Tell BSM to copy from BSM SRAM into instruction SRAM, when asked */
177
 
        iwl_write_prph(priv, BSM_WR_MEM_SRC_REG, 0x0);
178
 
        iwl_write_prph(priv, BSM_WR_MEM_DST_REG, IWL49_RTC_INST_LOWER_BOUND);
179
 
        iwl_write_prph(priv, BSM_WR_DWCOUNT_REG, len / sizeof(u32));
180
 
 
181
 
        /* Load bootstrap code into instruction SRAM now,
182
 
         *   to prepare to load "initialize" uCode */
183
 
        iwl_write_prph(priv, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START);
184
 
 
185
 
        /* Wait for load of bootstrap uCode to finish */
186
 
        for (i = 0; i < 100; i++) {
187
 
                done = iwl_read_prph(priv, BSM_WR_CTRL_REG);
188
 
                if (!(done & BSM_WR_CTRL_REG_BIT_START))
189
 
                        break;
190
 
                udelay(10);
191
 
        }
192
 
        if (i < 100)
193
 
                IWL_DEBUG_INFO(priv, "BSM write complete, poll %d iterations\n", i);
194
 
        else {
195
 
                IWL_ERR(priv, "BSM write did not complete!\n");
196
 
                return -EIO;
197
 
        }
198
 
 
199
 
        /* Enable future boot loads whenever power management unit triggers it
200
 
         *   (e.g. when powering back up after power-save shutdown) */
201
 
        iwl_write_prph(priv, BSM_WR_CTRL_REG, BSM_WR_CTRL_REG_BIT_START_EN);
202
 
 
203
 
 
204
 
        return 0;
205
 
}
206
 
 
207
 
/**
208
 
 * iwl4965_set_ucode_ptrs - Set uCode address location
209
 
 *
210
 
 * Tell initialization uCode where to find runtime uCode.
211
 
 *
212
 
 * BSM registers initially contain pointers to initialization uCode.
213
 
 * We need to replace them to load runtime uCode inst and data,
214
 
 * and to save runtime data when powering down.
215
 
 */
216
 
static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv)
217
 
{
218
 
        dma_addr_t pinst;
219
 
        dma_addr_t pdata;
220
 
        int ret = 0;
221
 
 
222
 
        /* bits 35:4 for 4965 */
223
 
        pinst = priv->ucode_code.p_addr >> 4;
224
 
        pdata = priv->ucode_data_backup.p_addr >> 4;
225
 
 
226
 
        /* Tell bootstrap uCode where to find image to load */
227
 
        iwl_write_prph(priv, BSM_DRAM_INST_PTR_REG, pinst);
228
 
        iwl_write_prph(priv, BSM_DRAM_DATA_PTR_REG, pdata);
229
 
        iwl_write_prph(priv, BSM_DRAM_DATA_BYTECOUNT_REG,
230
 
                                 priv->ucode_data.len);
231
 
 
232
 
        /* Inst byte count must be last to set up, bit 31 signals uCode
233
 
         *   that all new ptr/size info is in place */
234
 
        iwl_write_prph(priv, BSM_DRAM_INST_BYTECOUNT_REG,
235
 
                                 priv->ucode_code.len | BSM_DRAM_INST_LOAD);
236
 
        IWL_DEBUG_INFO(priv, "Runtime uCode pointers are set.\n");
237
 
 
238
 
        return ret;
239
 
}
240
 
 
241
 
/**
242
 
 * iwl4965_init_alive_start - Called after REPLY_ALIVE notification received
243
 
 *
244
 
 * Called after REPLY_ALIVE notification received from "initialize" uCode.
245
 
 *
246
 
 * The 4965 "initialize" ALIVE reply contains calibration data for:
247
 
 *   Voltage, temperature, and MIMO tx gain correction, now stored in priv
248
 
 *   (3945 does not contain this data).
249
 
 *
250
 
 * Tell "initialize" uCode to go ahead and load the runtime uCode.
251
 
*/
252
 
static void iwl4965_init_alive_start(struct iwl_priv *priv)
253
 
{
254
 
        /* Check alive response for "valid" sign from uCode */
255
 
        if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
256
 
                /* We had an error bringing up the hardware, so take it
257
 
                 * all the way back down so we can try again */
258
 
                IWL_DEBUG_INFO(priv, "Initialize Alive failed.\n");
259
 
                goto restart;
260
 
        }
261
 
 
262
 
        /* Bootstrap uCode has loaded initialize uCode ... verify inst image.
263
 
         * This is a paranoid check, because we would not have gotten the
264
 
         * "initialize" alive if code weren't properly loaded.  */
265
 
        if (iwl_verify_ucode(priv)) {
266
 
                /* Runtime instruction load was bad;
267
 
                 * take it all the way back down so we can try again */
268
 
                IWL_DEBUG_INFO(priv, "Bad \"initialize\" uCode load.\n");
269
 
                goto restart;
270
 
        }
271
 
 
272
 
        /* Calculate temperature */
273
 
        priv->temperature = iwl4965_hw_get_temperature(priv);
274
 
 
275
 
        /* Send pointers to protocol/runtime uCode image ... init code will
276
 
         * load and launch runtime uCode, which will send us another "Alive"
277
 
         * notification. */
278
 
        IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
279
 
        if (iwl4965_set_ucode_ptrs(priv)) {
280
 
                /* Runtime instruction load won't happen;
281
 
                 * take it all the way back down so we can try again */
282
 
                IWL_DEBUG_INFO(priv, "Couldn't set up uCode pointers.\n");
283
 
                goto restart;
284
 
        }
285
 
        return;
286
 
 
287
 
restart:
288
 
        queue_work(priv->workqueue, &priv->restart);
289
 
}
290
 
 
291
 
static bool is_ht40_channel(__le32 rxon_flags)
292
 
{
293
 
        int chan_mod = le32_to_cpu(rxon_flags & RXON_FLG_CHANNEL_MODE_MSK)
294
 
                                    >> RXON_FLG_CHANNEL_MODE_POS;
295
 
        return ((chan_mod == CHANNEL_MODE_PURE_40) ||
296
 
                  (chan_mod == CHANNEL_MODE_MIXED));
297
 
}
298
 
 
299
 
/*
300
 
 * EEPROM handlers
301
 
 */
302
 
static u16 iwl4965_eeprom_calib_version(struct iwl_priv *priv)
303
 
{
304
 
        return iwl_eeprom_query16(priv, EEPROM_4965_CALIB_VERSION_OFFSET);
305
 
}
306
 
 
307
 
/*
308
 
 * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
309
 
 * must be called under priv->lock and mac access
310
 
 */
311
 
static void iwl4965_txq_set_sched(struct iwl_priv *priv, u32 mask)
312
 
{
313
 
        iwl_write_prph(priv, IWL49_SCD_TXFACT, mask);
314
 
}
315
 
 
316
 
static void iwl4965_nic_config(struct iwl_priv *priv)
317
 
{
318
 
        unsigned long flags;
319
 
        u16 radio_cfg;
320
 
 
321
 
        spin_lock_irqsave(&priv->lock, flags);
322
 
 
323
 
        radio_cfg = iwl_eeprom_query16(priv, EEPROM_RADIO_CONFIG);
324
 
 
325
 
        /* write radio config values to register */
326
 
        if (EEPROM_RF_CFG_TYPE_MSK(radio_cfg) == EEPROM_4965_RF_CFG_TYPE_MAX)
327
 
                iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
328
 
                            EEPROM_RF_CFG_TYPE_MSK(radio_cfg) |
329
 
                            EEPROM_RF_CFG_STEP_MSK(radio_cfg) |
330
 
                            EEPROM_RF_CFG_DASH_MSK(radio_cfg));
331
 
 
332
 
        /* set CSR_HW_CONFIG_REG for uCode use */
333
 
        iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
334
 
                    CSR_HW_IF_CONFIG_REG_BIT_RADIO_SI |
335
 
                    CSR_HW_IF_CONFIG_REG_BIT_MAC_SI);
336
 
 
337
 
        priv->calib_info = (struct iwl_eeprom_calib_info *)
338
 
                iwl_eeprom_query_addr(priv, EEPROM_4965_CALIB_TXPOWER_OFFSET);
339
 
 
340
 
        spin_unlock_irqrestore(&priv->lock, flags);
341
 
}
342
 
 
343
 
/* Reset differential Rx gains in NIC to prepare for chain noise calibration.
344
 
 * Called after every association, but this runs only once!
345
 
 *  ... once chain noise is calibrated the first time, it's good forever.  */
346
 
static void iwl4965_chain_noise_reset(struct iwl_priv *priv)
347
 
{
348
 
        struct iwl_chain_noise_data *data = &(priv->chain_noise_data);
349
 
 
350
 
        if ((data->state == IWL_CHAIN_NOISE_ALIVE) &&
351
 
            iwl_is_any_associated(priv)) {
352
 
                struct iwl_calib_diff_gain_cmd cmd;
353
 
 
354
 
                /* clear data for chain noise calibration algorithm */
355
 
                data->chain_noise_a = 0;
356
 
                data->chain_noise_b = 0;
357
 
                data->chain_noise_c = 0;
358
 
                data->chain_signal_a = 0;
359
 
                data->chain_signal_b = 0;
360
 
                data->chain_signal_c = 0;
361
 
                data->beacon_count = 0;
362
 
 
363
 
                memset(&cmd, 0, sizeof(cmd));
364
 
                cmd.hdr.op_code = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD;
365
 
                cmd.diff_gain_a = 0;
366
 
                cmd.diff_gain_b = 0;
367
 
                cmd.diff_gain_c = 0;
368
 
                if (iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
369
 
                                 sizeof(cmd), &cmd))
370
 
                        IWL_ERR(priv,
371
 
                                "Could not send REPLY_PHY_CALIBRATION_CMD\n");
372
 
                data->state = IWL_CHAIN_NOISE_ACCUMULATE;
373
 
                IWL_DEBUG_CALIB(priv, "Run chain_noise_calibrate\n");
374
 
        }
375
 
}
376
 
 
377
 
static void iwl4965_gain_computation(struct iwl_priv *priv,
378
 
                u32 *average_noise,
379
 
                u16 min_average_noise_antenna_i,
380
 
                u32 min_average_noise,
381
 
                u8 default_chain)
382
 
{
383
 
        int i, ret;
384
 
        struct iwl_chain_noise_data *data = &priv->chain_noise_data;
385
 
 
386
 
        data->delta_gain_code[min_average_noise_antenna_i] = 0;
387
 
 
388
 
        for (i = default_chain; i < NUM_RX_CHAINS; i++) {
389
 
                s32 delta_g = 0;
390
 
 
391
 
                if (!(data->disconn_array[i]) &&
392
 
                    (data->delta_gain_code[i] ==
393
 
                             CHAIN_NOISE_DELTA_GAIN_INIT_VAL)) {
394
 
                        delta_g = average_noise[i] - min_average_noise;
395
 
                        data->delta_gain_code[i] = (u8)((delta_g * 10) / 15);
396
 
                        data->delta_gain_code[i] =
397
 
                                min(data->delta_gain_code[i],
398
 
                                (u8) CHAIN_NOISE_MAX_DELTA_GAIN_CODE);
399
 
 
400
 
                        data->delta_gain_code[i] =
401
 
                                (data->delta_gain_code[i] | (1 << 2));
402
 
                } else {
403
 
                        data->delta_gain_code[i] = 0;
404
 
                }
405
 
        }
406
 
        IWL_DEBUG_CALIB(priv, "delta_gain_codes: a %d b %d c %d\n",
407
 
                     data->delta_gain_code[0],
408
 
                     data->delta_gain_code[1],
409
 
                     data->delta_gain_code[2]);
410
 
 
411
 
        /* Differential gain gets sent to uCode only once */
412
 
        if (!data->radio_write) {
413
 
                struct iwl_calib_diff_gain_cmd cmd;
414
 
                data->radio_write = 1;
415
 
 
416
 
                memset(&cmd, 0, sizeof(cmd));
417
 
                cmd.hdr.op_code = IWL_PHY_CALIBRATE_DIFF_GAIN_CMD;
418
 
                cmd.diff_gain_a = data->delta_gain_code[0];
419
 
                cmd.diff_gain_b = data->delta_gain_code[1];
420
 
                cmd.diff_gain_c = data->delta_gain_code[2];
421
 
                ret = iwl_send_cmd_pdu(priv, REPLY_PHY_CALIBRATION_CMD,
422
 
                                      sizeof(cmd), &cmd);
423
 
                if (ret)
424
 
                        IWL_DEBUG_CALIB(priv, "fail sending cmd "
425
 
                                     "REPLY_PHY_CALIBRATION_CMD\n");
426
 
 
427
 
                /* TODO we might want recalculate
428
 
                 * rx_chain in rxon cmd */
429
 
 
430
 
                /* Mark so we run this algo only once! */
431
 
                data->state = IWL_CHAIN_NOISE_CALIBRATED;
432
 
        }
433
 
}
434
 
 
435
 
static void iwl4965_bg_txpower_work(struct work_struct *work)
436
 
{
437
 
        struct iwl_priv *priv = container_of(work, struct iwl_priv,
438
 
                        txpower_work);
439
 
 
440
 
        /* If a scan happened to start before we got here
441
 
         * then just return; the statistics notification will
442
 
         * kick off another scheduled work to compensate for
443
 
         * any temperature delta we missed here. */
444
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status) ||
445
 
            test_bit(STATUS_SCANNING, &priv->status))
446
 
                return;
447
 
 
448
 
        mutex_lock(&priv->mutex);
449
 
 
450
 
        /* Regardless of if we are associated, we must reconfigure the
451
 
         * TX power since frames can be sent on non-radar channels while
452
 
         * not associated */
453
 
        iwl4965_send_tx_power(priv);
454
 
 
455
 
        /* Update last_temperature to keep is_calib_needed from running
456
 
         * when it isn't needed... */
457
 
        priv->last_temperature = priv->temperature;
458
 
 
459
 
        mutex_unlock(&priv->mutex);
460
 
}
461
 
 
462
 
/*
463
 
 * Acquire priv->lock before calling this function !
464
 
 */
465
 
static void iwl4965_set_wr_ptrs(struct iwl_priv *priv, int txq_id, u32 index)
466
 
{
467
 
        iwl_write_direct32(priv, HBUS_TARG_WRPTR,
468
 
                             (index & 0xff) | (txq_id << 8));
469
 
        iwl_write_prph(priv, IWL49_SCD_QUEUE_RDPTR(txq_id), index);
470
 
}
471
 
 
472
 
/**
473
 
 * iwl4965_tx_queue_set_status - (optionally) start Tx/Cmd queue
474
 
 * @tx_fifo_id: Tx DMA/FIFO channel (range 0-7) that the queue will feed
475
 
 * @scd_retry: (1) Indicates queue will be used in aggregation mode
476
 
 *
477
 
 * NOTE:  Acquire priv->lock before calling this function !
478
 
 */
479
 
static void iwl4965_tx_queue_set_status(struct iwl_priv *priv,
480
 
                                        struct iwl_tx_queue *txq,
481
 
                                        int tx_fifo_id, int scd_retry)
482
 
{
483
 
        int txq_id = txq->q.id;
484
 
 
485
 
        /* Find out whether to activate Tx queue */
486
 
        int active = test_bit(txq_id, &priv->txq_ctx_active_msk) ? 1 : 0;
487
 
 
488
 
        /* Set up and activate */
489
 
        iwl_write_prph(priv, IWL49_SCD_QUEUE_STATUS_BITS(txq_id),
490
 
                         (active << IWL49_SCD_QUEUE_STTS_REG_POS_ACTIVE) |
491
 
                         (tx_fifo_id << IWL49_SCD_QUEUE_STTS_REG_POS_TXF) |
492
 
                         (scd_retry << IWL49_SCD_QUEUE_STTS_REG_POS_WSL) |
493
 
                         (scd_retry << IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACK) |
494
 
                         IWL49_SCD_QUEUE_STTS_REG_MSK);
495
 
 
496
 
        txq->sched_retry = scd_retry;
497
 
 
498
 
        IWL_DEBUG_INFO(priv, "%s %s Queue %d on AC %d\n",
499
 
                       active ? "Activate" : "Deactivate",
500
 
                       scd_retry ? "BA" : "AC", txq_id, tx_fifo_id);
501
 
}
502
 
 
503
 
static const s8 default_queue_to_tx_fifo[] = {
504
 
        IWL_TX_FIFO_VO,
505
 
        IWL_TX_FIFO_VI,
506
 
        IWL_TX_FIFO_BE,
507
 
        IWL_TX_FIFO_BK,
508
 
        IWL49_CMD_FIFO_NUM,
509
 
        IWL_TX_FIFO_UNUSED,
510
 
        IWL_TX_FIFO_UNUSED,
511
 
};
512
 
 
513
 
static int iwl4965_alive_notify(struct iwl_priv *priv)
514
 
{
515
 
        u32 a;
516
 
        unsigned long flags;
517
 
        int i, chan;
518
 
        u32 reg_val;
519
 
 
520
 
        spin_lock_irqsave(&priv->lock, flags);
521
 
 
522
 
        /* Clear 4965's internal Tx Scheduler data base */
523
 
        priv->scd_base_addr = iwl_read_prph(priv, IWL49_SCD_SRAM_BASE_ADDR);
524
 
        a = priv->scd_base_addr + IWL49_SCD_CONTEXT_DATA_OFFSET;
525
 
        for (; a < priv->scd_base_addr + IWL49_SCD_TX_STTS_BITMAP_OFFSET; a += 4)
526
 
                iwl_write_targ_mem(priv, a, 0);
527
 
        for (; a < priv->scd_base_addr + IWL49_SCD_TRANSLATE_TBL_OFFSET; a += 4)
528
 
                iwl_write_targ_mem(priv, a, 0);
529
 
        for (; a < priv->scd_base_addr +
530
 
               IWL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(priv->hw_params.max_txq_num); a += 4)
531
 
                iwl_write_targ_mem(priv, a, 0);
532
 
 
533
 
        /* Tel 4965 where to find Tx byte count tables */
534
 
        iwl_write_prph(priv, IWL49_SCD_DRAM_BASE_ADDR,
535
 
                        priv->scd_bc_tbls.dma >> 10);
536
 
 
537
 
        /* Enable DMA channel */
538
 
        for (chan = 0; chan < FH49_TCSR_CHNL_NUM ; chan++)
539
 
                iwl_write_direct32(priv, FH_TCSR_CHNL_TX_CONFIG_REG(chan),
540
 
                                FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE |
541
 
                                FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE);
542
 
 
543
 
        /* Update FH chicken bits */
544
 
        reg_val = iwl_read_direct32(priv, FH_TX_CHICKEN_BITS_REG);
545
 
        iwl_write_direct32(priv, FH_TX_CHICKEN_BITS_REG,
546
 
                           reg_val | FH_TX_CHICKEN_BITS_SCD_AUTO_RETRY_EN);
547
 
 
548
 
        /* Disable chain mode for all queues */
549
 
        iwl_write_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, 0);
550
 
 
551
 
        /* Initialize each Tx queue (including the command queue) */
552
 
        for (i = 0; i < priv->hw_params.max_txq_num; i++) {
553
 
 
554
 
                /* TFD circular buffer read/write indexes */
555
 
                iwl_write_prph(priv, IWL49_SCD_QUEUE_RDPTR(i), 0);
556
 
                iwl_write_direct32(priv, HBUS_TARG_WRPTR, 0 | (i << 8));
557
 
 
558
 
                /* Max Tx Window size for Scheduler-ACK mode */
559
 
                iwl_write_targ_mem(priv, priv->scd_base_addr +
560
 
                                IWL49_SCD_CONTEXT_QUEUE_OFFSET(i),
561
 
                                (SCD_WIN_SIZE <<
562
 
                                IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) &
563
 
                                IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK);
564
 
 
565
 
                /* Frame limit */
566
 
                iwl_write_targ_mem(priv, priv->scd_base_addr +
567
 
                                IWL49_SCD_CONTEXT_QUEUE_OFFSET(i) +
568
 
                                sizeof(u32),
569
 
                                (SCD_FRAME_LIMIT <<
570
 
                                IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS) &
571
 
                                IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK);
572
 
 
573
 
        }
574
 
        iwl_write_prph(priv, IWL49_SCD_INTERRUPT_MASK,
575
 
                                 (1 << priv->hw_params.max_txq_num) - 1);
576
 
 
577
 
        /* Activate all Tx DMA/FIFO channels */
578
 
        priv->cfg->ops->lib->txq_set_sched(priv, IWL_MASK(0, 6));
579
 
 
580
 
        iwl4965_set_wr_ptrs(priv, IWL_DEFAULT_CMD_QUEUE_NUM, 0);
581
 
 
582
 
        /* make sure all queue are not stopped */
583
 
        memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped));
584
 
        for (i = 0; i < 4; i++)
585
 
                atomic_set(&priv->queue_stop_count[i], 0);
586
 
 
587
 
        /* reset to 0 to enable all the queue first */
588
 
        priv->txq_ctx_active_msk = 0;
589
 
        /* Map each Tx/cmd queue to its corresponding fifo */
590
 
        BUILD_BUG_ON(ARRAY_SIZE(default_queue_to_tx_fifo) != 7);
591
 
 
592
 
        for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) {
593
 
                int ac = default_queue_to_tx_fifo[i];
594
 
 
595
 
                iwl_txq_ctx_activate(priv, i);
596
 
 
597
 
                if (ac == IWL_TX_FIFO_UNUSED)
598
 
                        continue;
599
 
 
600
 
                iwl4965_tx_queue_set_status(priv, &priv->txq[i], ac, 0);
601
 
        }
602
 
 
603
 
        spin_unlock_irqrestore(&priv->lock, flags);
604
 
 
605
 
        return 0;
606
 
}
607
 
 
608
 
static struct iwl_sensitivity_ranges iwl4965_sensitivity = {
609
 
        .min_nrg_cck = 97,
610
 
        .max_nrg_cck = 0, /* not used, set to 0 */
611
 
 
612
 
        .auto_corr_min_ofdm = 85,
613
 
        .auto_corr_min_ofdm_mrc = 170,
614
 
        .auto_corr_min_ofdm_x1 = 105,
615
 
        .auto_corr_min_ofdm_mrc_x1 = 220,
616
 
 
617
 
        .auto_corr_max_ofdm = 120,
618
 
        .auto_corr_max_ofdm_mrc = 210,
619
 
        .auto_corr_max_ofdm_x1 = 140,
620
 
        .auto_corr_max_ofdm_mrc_x1 = 270,
621
 
 
622
 
        .auto_corr_min_cck = 125,
623
 
        .auto_corr_max_cck = 200,
624
 
        .auto_corr_min_cck_mrc = 200,
625
 
        .auto_corr_max_cck_mrc = 400,
626
 
 
627
 
        .nrg_th_cck = 100,
628
 
        .nrg_th_ofdm = 100,
629
 
 
630
 
        .barker_corr_th_min = 190,
631
 
        .barker_corr_th_min_mrc = 390,
632
 
        .nrg_th_cca = 62,
633
 
};
634
 
 
635
 
static void iwl4965_set_ct_threshold(struct iwl_priv *priv)
636
 
{
637
 
        /* want Kelvin */
638
 
        priv->hw_params.ct_kill_threshold =
639
 
                CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY);
640
 
}
641
 
 
642
 
/**
643
 
 * iwl4965_hw_set_hw_params
644
 
 *
645
 
 * Called when initializing driver
646
 
 */
647
 
static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
648
 
{
649
 
        if (priv->cfg->mod_params->num_of_queues >= IWL_MIN_NUM_QUEUES &&
650
 
            priv->cfg->mod_params->num_of_queues <= IWL49_NUM_QUEUES)
651
 
                priv->cfg->base_params->num_of_queues =
652
 
                        priv->cfg->mod_params->num_of_queues;
653
 
 
654
 
        priv->hw_params.max_txq_num = priv->cfg->base_params->num_of_queues;
655
 
        priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM;
656
 
        priv->hw_params.scd_bc_tbls_size =
657
 
                        priv->cfg->base_params->num_of_queues *
658
 
                        sizeof(struct iwl4965_scd_bc_tbl);
659
 
        priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
660
 
        priv->hw_params.max_stations = IWL4965_STATION_COUNT;
661
 
        priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWL4965_BROADCAST_ID;
662
 
        priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE;
663
 
        priv->hw_params.max_inst_size = IWL49_RTC_INST_SIZE;
664
 
        priv->hw_params.max_bsm_size = BSM_SRAM_SIZE;
665
 
        priv->hw_params.ht40_channel = BIT(IEEE80211_BAND_5GHZ);
666
 
 
667
 
        priv->hw_params.rx_wrt_ptr_reg = FH_RSCSR_CHNL0_WPTR;
668
 
 
669
 
        priv->hw_params.tx_chains_num = num_of_ant(priv->cfg->valid_tx_ant);
670
 
        priv->hw_params.rx_chains_num = num_of_ant(priv->cfg->valid_rx_ant);
671
 
        priv->hw_params.valid_tx_ant = priv->cfg->valid_tx_ant;
672
 
        priv->hw_params.valid_rx_ant = priv->cfg->valid_rx_ant;
673
 
 
674
 
        iwl4965_set_ct_threshold(priv);
675
 
 
676
 
        priv->hw_params.sens = &iwl4965_sensitivity;
677
 
        priv->hw_params.beacon_time_tsf_bits = IWLAGN_EXT_BEACON_TIME_POS;
678
 
 
679
 
        return 0;
680
 
}
681
 
 
682
 
static s32 iwl4965_math_div_round(s32 num, s32 denom, s32 *res)
683
 
{
684
 
        s32 sign = 1;
685
 
 
686
 
        if (num < 0) {
687
 
                sign = -sign;
688
 
                num = -num;
689
 
        }
690
 
        if (denom < 0) {
691
 
                sign = -sign;
692
 
                denom = -denom;
693
 
        }
694
 
        *res = 1;
695
 
        *res = ((num * 2 + denom) / (denom * 2)) * sign;
696
 
 
697
 
        return 1;
698
 
}
699
 
 
700
 
/**
701
 
 * iwl4965_get_voltage_compensation - Power supply voltage comp for txpower
702
 
 *
703
 
 * Determines power supply voltage compensation for txpower calculations.
704
 
 * Returns number of 1/2-dB steps to subtract from gain table index,
705
 
 * to compensate for difference between power supply voltage during
706
 
 * factory measurements, vs. current power supply voltage.
707
 
 *
708
 
 * Voltage indication is higher for lower voltage.
709
 
 * Lower voltage requires more gain (lower gain table index).
710
 
 */
711
 
static s32 iwl4965_get_voltage_compensation(s32 eeprom_voltage,
712
 
                                            s32 current_voltage)
713
 
{
714
 
        s32 comp = 0;
715
 
 
716
 
        if ((TX_POWER_IWL_ILLEGAL_VOLTAGE == eeprom_voltage) ||
717
 
            (TX_POWER_IWL_ILLEGAL_VOLTAGE == current_voltage))
718
 
                return 0;
719
 
 
720
 
        iwl4965_math_div_round(current_voltage - eeprom_voltage,
721
 
                               TX_POWER_IWL_VOLTAGE_CODES_PER_03V, &comp);
722
 
 
723
 
        if (current_voltage > eeprom_voltage)
724
 
                comp *= 2;
725
 
        if ((comp < -2) || (comp > 2))
726
 
                comp = 0;
727
 
 
728
 
        return comp;
729
 
}
730
 
 
731
 
static s32 iwl4965_get_tx_atten_grp(u16 channel)
732
 
{
733
 
        if (channel >= CALIB_IWL_TX_ATTEN_GR5_FCH &&
734
 
            channel <= CALIB_IWL_TX_ATTEN_GR5_LCH)
735
 
                return CALIB_CH_GROUP_5;
736
 
 
737
 
        if (channel >= CALIB_IWL_TX_ATTEN_GR1_FCH &&
738
 
            channel <= CALIB_IWL_TX_ATTEN_GR1_LCH)
739
 
                return CALIB_CH_GROUP_1;
740
 
 
741
 
        if (channel >= CALIB_IWL_TX_ATTEN_GR2_FCH &&
742
 
            channel <= CALIB_IWL_TX_ATTEN_GR2_LCH)
743
 
                return CALIB_CH_GROUP_2;
744
 
 
745
 
        if (channel >= CALIB_IWL_TX_ATTEN_GR3_FCH &&
746
 
            channel <= CALIB_IWL_TX_ATTEN_GR3_LCH)
747
 
                return CALIB_CH_GROUP_3;
748
 
 
749
 
        if (channel >= CALIB_IWL_TX_ATTEN_GR4_FCH &&
750
 
            channel <= CALIB_IWL_TX_ATTEN_GR4_LCH)
751
 
                return CALIB_CH_GROUP_4;
752
 
 
753
 
        return -1;
754
 
}
755
 
 
756
 
static u32 iwl4965_get_sub_band(const struct iwl_priv *priv, u32 channel)
757
 
{
758
 
        s32 b = -1;
759
 
 
760
 
        for (b = 0; b < EEPROM_TX_POWER_BANDS; b++) {
761
 
                if (priv->calib_info->band_info[b].ch_from == 0)
762
 
                        continue;
763
 
 
764
 
                if ((channel >= priv->calib_info->band_info[b].ch_from)
765
 
                    && (channel <= priv->calib_info->band_info[b].ch_to))
766
 
                        break;
767
 
        }
768
 
 
769
 
        return b;
770
 
}
771
 
 
772
 
static s32 iwl4965_interpolate_value(s32 x, s32 x1, s32 y1, s32 x2, s32 y2)
773
 
{
774
 
        s32 val;
775
 
 
776
 
        if (x2 == x1)
777
 
                return y1;
778
 
        else {
779
 
                iwl4965_math_div_round((x2 - x) * (y1 - y2), (x2 - x1), &val);
780
 
                return val + y2;
781
 
        }
782
 
}
783
 
 
784
 
/**
785
 
 * iwl4965_interpolate_chan - Interpolate factory measurements for one channel
786
 
 *
787
 
 * Interpolates factory measurements from the two sample channels within a
788
 
 * sub-band, to apply to channel of interest.  Interpolation is proportional to
789
 
 * differences in channel frequencies, which is proportional to differences
790
 
 * in channel number.
791
 
 */
792
 
static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel,
793
 
                                    struct iwl_eeprom_calib_ch_info *chan_info)
794
 
{
795
 
        s32 s = -1;
796
 
        u32 c;
797
 
        u32 m;
798
 
        const struct iwl_eeprom_calib_measure *m1;
799
 
        const struct iwl_eeprom_calib_measure *m2;
800
 
        struct iwl_eeprom_calib_measure *omeas;
801
 
        u32 ch_i1;
802
 
        u32 ch_i2;
803
 
 
804
 
        s = iwl4965_get_sub_band(priv, channel);
805
 
        if (s >= EEPROM_TX_POWER_BANDS) {
806
 
                IWL_ERR(priv, "Tx Power can not find channel %d\n", channel);
807
 
                return -1;
808
 
        }
809
 
 
810
 
        ch_i1 = priv->calib_info->band_info[s].ch1.ch_num;
811
 
        ch_i2 = priv->calib_info->band_info[s].ch2.ch_num;
812
 
        chan_info->ch_num = (u8) channel;
813
 
 
814
 
        IWL_DEBUG_TXPOWER(priv, "channel %d subband %d factory cal ch %d & %d\n",
815
 
                          channel, s, ch_i1, ch_i2);
816
 
 
817
 
        for (c = 0; c < EEPROM_TX_POWER_TX_CHAINS; c++) {
818
 
                for (m = 0; m < EEPROM_TX_POWER_MEASUREMENTS; m++) {
819
 
                        m1 = &(priv->calib_info->band_info[s].ch1.
820
 
                               measurements[c][m]);
821
 
                        m2 = &(priv->calib_info->band_info[s].ch2.
822
 
                               measurements[c][m]);
823
 
                        omeas = &(chan_info->measurements[c][m]);
824
 
 
825
 
                        omeas->actual_pow =
826
 
                            (u8) iwl4965_interpolate_value(channel, ch_i1,
827
 
                                                           m1->actual_pow,
828
 
                                                           ch_i2,
829
 
                                                           m2->actual_pow);
830
 
                        omeas->gain_idx =
831
 
                            (u8) iwl4965_interpolate_value(channel, ch_i1,
832
 
                                                           m1->gain_idx, ch_i2,
833
 
                                                           m2->gain_idx);
834
 
                        omeas->temperature =
835
 
                            (u8) iwl4965_interpolate_value(channel, ch_i1,
836
 
                                                           m1->temperature,
837
 
                                                           ch_i2,
838
 
                                                           m2->temperature);
839
 
                        omeas->pa_det =
840
 
                            (s8) iwl4965_interpolate_value(channel, ch_i1,
841
 
                                                           m1->pa_det, ch_i2,
842
 
                                                           m2->pa_det);
843
 
 
844
 
                        IWL_DEBUG_TXPOWER(priv,
845
 
                                "chain %d meas %d AP1=%d AP2=%d AP=%d\n", c, m,
846
 
                                m1->actual_pow, m2->actual_pow, omeas->actual_pow);
847
 
                        IWL_DEBUG_TXPOWER(priv,
848
 
                                "chain %d meas %d NI1=%d NI2=%d NI=%d\n", c, m,
849
 
                                m1->gain_idx, m2->gain_idx, omeas->gain_idx);
850
 
                        IWL_DEBUG_TXPOWER(priv,
851
 
                                "chain %d meas %d PA1=%d PA2=%d PA=%d\n", c, m,
852
 
                                m1->pa_det, m2->pa_det, omeas->pa_det);
853
 
                        IWL_DEBUG_TXPOWER(priv,
854
 
                                "chain %d meas %d  T1=%d  T2=%d  T=%d\n", c, m,
855
 
                                m1->temperature, m2->temperature,
856
 
                                omeas->temperature);
857
 
                }
858
 
        }
859
 
 
860
 
        return 0;
861
 
}
862
 
 
863
 
/* bit-rate-dependent table to prevent Tx distortion, in half-dB units,
864
 
 * for OFDM 6, 12, 18, 24, 36, 48, 54, 60 MBit, and CCK all rates. */
865
 
static s32 back_off_table[] = {
866
 
        10, 10, 10, 10, 10, 15, 17, 20, /* OFDM SISO 20 MHz */
867
 
        10, 10, 10, 10, 10, 15, 17, 20, /* OFDM MIMO 20 MHz */
868
 
        10, 10, 10, 10, 10, 15, 17, 20, /* OFDM SISO 40 MHz */
869
 
        10, 10, 10, 10, 10, 15, 17, 20, /* OFDM MIMO 40 MHz */
870
 
        10                      /* CCK */
871
 
};
872
 
 
873
 
/* Thermal compensation values for txpower for various frequency ranges ...
874
 
 *   ratios from 3:1 to 4.5:1 of degrees (Celsius) per half-dB gain adjust */
875
 
static struct iwl4965_txpower_comp_entry {
876
 
        s32 degrees_per_05db_a;
877
 
        s32 degrees_per_05db_a_denom;
878
 
} tx_power_cmp_tble[CALIB_CH_GROUP_MAX] = {
879
 
        {9, 2},                 /* group 0 5.2, ch  34-43 */
880
 
        {4, 1},                 /* group 1 5.2, ch  44-70 */
881
 
        {4, 1},                 /* group 2 5.2, ch  71-124 */
882
 
        {4, 1},                 /* group 3 5.2, ch 125-200 */
883
 
        {3, 1}                  /* group 4 2.4, ch   all */
884
 
};
885
 
 
886
 
static s32 get_min_power_index(s32 rate_power_index, u32 band)
887
 
{
888
 
        if (!band) {
889
 
                if ((rate_power_index & 7) <= 4)
890
 
                        return MIN_TX_GAIN_INDEX_52GHZ_EXT;
891
 
        }
892
 
        return MIN_TX_GAIN_INDEX;
893
 
}
894
 
 
895
 
struct gain_entry {
896
 
        u8 dsp;
897
 
        u8 radio;
898
 
};
899
 
 
900
 
static const struct gain_entry gain_table[2][108] = {
901
 
        /* 5.2GHz power gain index table */
902
 
        {
903
 
         {123, 0x3F},           /* highest txpower */
904
 
         {117, 0x3F},
905
 
         {110, 0x3F},
906
 
         {104, 0x3F},
907
 
         {98, 0x3F},
908
 
         {110, 0x3E},
909
 
         {104, 0x3E},
910
 
         {98, 0x3E},
911
 
         {110, 0x3D},
912
 
         {104, 0x3D},
913
 
         {98, 0x3D},
914
 
         {110, 0x3C},
915
 
         {104, 0x3C},
916
 
         {98, 0x3C},
917
 
         {110, 0x3B},
918
 
         {104, 0x3B},
919
 
         {98, 0x3B},
920
 
         {110, 0x3A},
921
 
         {104, 0x3A},
922
 
         {98, 0x3A},
923
 
         {110, 0x39},
924
 
         {104, 0x39},
925
 
         {98, 0x39},
926
 
         {110, 0x38},
927
 
         {104, 0x38},
928
 
         {98, 0x38},
929
 
         {110, 0x37},
930
 
         {104, 0x37},
931
 
         {98, 0x37},
932
 
         {110, 0x36},
933
 
         {104, 0x36},
934
 
         {98, 0x36},
935
 
         {110, 0x35},
936
 
         {104, 0x35},
937
 
         {98, 0x35},
938
 
         {110, 0x34},
939
 
         {104, 0x34},
940
 
         {98, 0x34},
941
 
         {110, 0x33},
942
 
         {104, 0x33},
943
 
         {98, 0x33},
944
 
         {110, 0x32},
945
 
         {104, 0x32},
946
 
         {98, 0x32},
947
 
         {110, 0x31},
948
 
         {104, 0x31},
949
 
         {98, 0x31},
950
 
         {110, 0x30},
951
 
         {104, 0x30},
952
 
         {98, 0x30},
953
 
         {110, 0x25},
954
 
         {104, 0x25},
955
 
         {98, 0x25},
956
 
         {110, 0x24},
957
 
         {104, 0x24},
958
 
         {98, 0x24},
959
 
         {110, 0x23},
960
 
         {104, 0x23},
961
 
         {98, 0x23},
962
 
         {110, 0x22},
963
 
         {104, 0x18},
964
 
         {98, 0x18},
965
 
         {110, 0x17},
966
 
         {104, 0x17},
967
 
         {98, 0x17},
968
 
         {110, 0x16},
969
 
         {104, 0x16},
970
 
         {98, 0x16},
971
 
         {110, 0x15},
972
 
         {104, 0x15},
973
 
         {98, 0x15},
974
 
         {110, 0x14},
975
 
         {104, 0x14},
976
 
         {98, 0x14},
977
 
         {110, 0x13},
978
 
         {104, 0x13},
979
 
         {98, 0x13},
980
 
         {110, 0x12},
981
 
         {104, 0x08},
982
 
         {98, 0x08},
983
 
         {110, 0x07},
984
 
         {104, 0x07},
985
 
         {98, 0x07},
986
 
         {110, 0x06},
987
 
         {104, 0x06},
988
 
         {98, 0x06},
989
 
         {110, 0x05},
990
 
         {104, 0x05},
991
 
         {98, 0x05},
992
 
         {110, 0x04},
993
 
         {104, 0x04},
994
 
         {98, 0x04},
995
 
         {110, 0x03},
996
 
         {104, 0x03},
997
 
         {98, 0x03},
998
 
         {110, 0x02},
999
 
         {104, 0x02},
1000
 
         {98, 0x02},
1001
 
         {110, 0x01},
1002
 
         {104, 0x01},
1003
 
         {98, 0x01},
1004
 
         {110, 0x00},
1005
 
         {104, 0x00},
1006
 
         {98, 0x00},
1007
 
         {93, 0x00},
1008
 
         {88, 0x00},
1009
 
         {83, 0x00},
1010
 
         {78, 0x00},
1011
 
         },
1012
 
        /* 2.4GHz power gain index table */
1013
 
        {
1014
 
         {110, 0x3f},           /* highest txpower */
1015
 
         {104, 0x3f},
1016
 
         {98, 0x3f},
1017
 
         {110, 0x3e},
1018
 
         {104, 0x3e},
1019
 
         {98, 0x3e},
1020
 
         {110, 0x3d},
1021
 
         {104, 0x3d},
1022
 
         {98, 0x3d},
1023
 
         {110, 0x3c},
1024
 
         {104, 0x3c},
1025
 
         {98, 0x3c},
1026
 
         {110, 0x3b},
1027
 
         {104, 0x3b},
1028
 
         {98, 0x3b},
1029
 
         {110, 0x3a},
1030
 
         {104, 0x3a},
1031
 
         {98, 0x3a},
1032
 
         {110, 0x39},
1033
 
         {104, 0x39},
1034
 
         {98, 0x39},
1035
 
         {110, 0x38},
1036
 
         {104, 0x38},
1037
 
         {98, 0x38},
1038
 
         {110, 0x37},
1039
 
         {104, 0x37},
1040
 
         {98, 0x37},
1041
 
         {110, 0x36},
1042
 
         {104, 0x36},
1043
 
         {98, 0x36},
1044
 
         {110, 0x35},
1045
 
         {104, 0x35},
1046
 
         {98, 0x35},
1047
 
         {110, 0x34},
1048
 
         {104, 0x34},
1049
 
         {98, 0x34},
1050
 
         {110, 0x33},
1051
 
         {104, 0x33},
1052
 
         {98, 0x33},
1053
 
         {110, 0x32},
1054
 
         {104, 0x32},
1055
 
         {98, 0x32},
1056
 
         {110, 0x31},
1057
 
         {104, 0x31},
1058
 
         {98, 0x31},
1059
 
         {110, 0x30},
1060
 
         {104, 0x30},
1061
 
         {98, 0x30},
1062
 
         {110, 0x6},
1063
 
         {104, 0x6},
1064
 
         {98, 0x6},
1065
 
         {110, 0x5},
1066
 
         {104, 0x5},
1067
 
         {98, 0x5},
1068
 
         {110, 0x4},
1069
 
         {104, 0x4},
1070
 
         {98, 0x4},
1071
 
         {110, 0x3},
1072
 
         {104, 0x3},
1073
 
         {98, 0x3},
1074
 
         {110, 0x2},
1075
 
         {104, 0x2},
1076
 
         {98, 0x2},
1077
 
         {110, 0x1},
1078
 
         {104, 0x1},
1079
 
         {98, 0x1},
1080
 
         {110, 0x0},
1081
 
         {104, 0x0},
1082
 
         {98, 0x0},
1083
 
         {97, 0},
1084
 
         {96, 0},
1085
 
         {95, 0},
1086
 
         {94, 0},
1087
 
         {93, 0},
1088
 
         {92, 0},
1089
 
         {91, 0},
1090
 
         {90, 0},
1091
 
         {89, 0},
1092
 
         {88, 0},
1093
 
         {87, 0},
1094
 
         {86, 0},
1095
 
         {85, 0},
1096
 
         {84, 0},
1097
 
         {83, 0},
1098
 
         {82, 0},
1099
 
         {81, 0},
1100
 
         {80, 0},
1101
 
         {79, 0},
1102
 
         {78, 0},
1103
 
         {77, 0},
1104
 
         {76, 0},
1105
 
         {75, 0},
1106
 
         {74, 0},
1107
 
         {73, 0},
1108
 
         {72, 0},
1109
 
         {71, 0},
1110
 
         {70, 0},
1111
 
         {69, 0},
1112
 
         {68, 0},
1113
 
         {67, 0},
1114
 
         {66, 0},
1115
 
         {65, 0},
1116
 
         {64, 0},
1117
 
         {63, 0},
1118
 
         {62, 0},
1119
 
         {61, 0},
1120
 
         {60, 0},
1121
 
         {59, 0},
1122
 
         }
1123
 
};
1124
 
 
1125
 
static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
1126
 
                                    u8 is_ht40, u8 ctrl_chan_high,
1127
 
                                    struct iwl4965_tx_power_db *tx_power_tbl)
1128
 
{
1129
 
        u8 saturation_power;
1130
 
        s32 target_power;
1131
 
        s32 user_target_power;
1132
 
        s32 power_limit;
1133
 
        s32 current_temp;
1134
 
        s32 reg_limit;
1135
 
        s32 current_regulatory;
1136
 
        s32 txatten_grp = CALIB_CH_GROUP_MAX;
1137
 
        int i;
1138
 
        int c;
1139
 
        const struct iwl_channel_info *ch_info = NULL;
1140
 
        struct iwl_eeprom_calib_ch_info ch_eeprom_info;
1141
 
        const struct iwl_eeprom_calib_measure *measurement;
1142
 
        s16 voltage;
1143
 
        s32 init_voltage;
1144
 
        s32 voltage_compensation;
1145
 
        s32 degrees_per_05db_num;
1146
 
        s32 degrees_per_05db_denom;
1147
 
        s32 factory_temp;
1148
 
        s32 temperature_comp[2];
1149
 
        s32 factory_gain_index[2];
1150
 
        s32 factory_actual_pwr[2];
1151
 
        s32 power_index;
1152
 
 
1153
 
        /* tx_power_user_lmt is in dBm, convert to half-dBm (half-dB units
1154
 
         *   are used for indexing into txpower table) */
1155
 
        user_target_power = 2 * priv->tx_power_user_lmt;
1156
 
 
1157
 
        /* Get current (RXON) channel, band, width */
1158
 
        IWL_DEBUG_TXPOWER(priv, "chan %d band %d is_ht40 %d\n", channel, band,
1159
 
                          is_ht40);
1160
 
 
1161
 
        ch_info = iwl_get_channel_info(priv, priv->band, channel);
1162
 
 
1163
 
        if (!is_channel_valid(ch_info))
1164
 
                return -EINVAL;
1165
 
 
1166
 
        /* get txatten group, used to select 1) thermal txpower adjustment
1167
 
         *   and 2) mimo txpower balance between Tx chains. */
1168
 
        txatten_grp = iwl4965_get_tx_atten_grp(channel);
1169
 
        if (txatten_grp < 0) {
1170
 
                IWL_ERR(priv, "Can't find txatten group for channel %d.\n",
1171
 
                          channel);
1172
 
                return -EINVAL;
1173
 
        }
1174
 
 
1175
 
        IWL_DEBUG_TXPOWER(priv, "channel %d belongs to txatten group %d\n",
1176
 
                          channel, txatten_grp);
1177
 
 
1178
 
        if (is_ht40) {
1179
 
                if (ctrl_chan_high)
1180
 
                        channel -= 2;
1181
 
                else
1182
 
                        channel += 2;
1183
 
        }
1184
 
 
1185
 
        /* hardware txpower limits ...
1186
 
         * saturation (clipping distortion) txpowers are in half-dBm */
1187
 
        if (band)
1188
 
                saturation_power = priv->calib_info->saturation_power24;
1189
 
        else
1190
 
                saturation_power = priv->calib_info->saturation_power52;
1191
 
 
1192
 
        if (saturation_power < IWL_TX_POWER_SATURATION_MIN ||
1193
 
            saturation_power > IWL_TX_POWER_SATURATION_MAX) {
1194
 
                if (band)
1195
 
                        saturation_power = IWL_TX_POWER_DEFAULT_SATURATION_24;
1196
 
                else
1197
 
                        saturation_power = IWL_TX_POWER_DEFAULT_SATURATION_52;
1198
 
        }
1199
 
 
1200
 
        /* regulatory txpower limits ... reg_limit values are in half-dBm,
1201
 
         *   max_power_avg values are in dBm, convert * 2 */
1202
 
        if (is_ht40)
1203
 
                reg_limit = ch_info->ht40_max_power_avg * 2;
1204
 
        else
1205
 
                reg_limit = ch_info->max_power_avg * 2;
1206
 
 
1207
 
        if ((reg_limit < IWL_TX_POWER_REGULATORY_MIN) ||
1208
 
            (reg_limit > IWL_TX_POWER_REGULATORY_MAX)) {
1209
 
                if (band)
1210
 
                        reg_limit = IWL_TX_POWER_DEFAULT_REGULATORY_24;
1211
 
                else
1212
 
                        reg_limit = IWL_TX_POWER_DEFAULT_REGULATORY_52;
1213
 
        }
1214
 
 
1215
 
        /* Interpolate txpower calibration values for this channel,
1216
 
         *   based on factory calibration tests on spaced channels. */
1217
 
        iwl4965_interpolate_chan(priv, channel, &ch_eeprom_info);
1218
 
 
1219
 
        /* calculate tx gain adjustment based on power supply voltage */
1220
 
        voltage = le16_to_cpu(priv->calib_info->voltage);
1221
 
        init_voltage = (s32)le32_to_cpu(priv->card_alive_init.voltage);
1222
 
        voltage_compensation =
1223
 
            iwl4965_get_voltage_compensation(voltage, init_voltage);
1224
 
 
1225
 
        IWL_DEBUG_TXPOWER(priv, "curr volt %d eeprom volt %d volt comp %d\n",
1226
 
                          init_voltage,
1227
 
                          voltage, voltage_compensation);
1228
 
 
1229
 
        /* get current temperature (Celsius) */
1230
 
        current_temp = max(priv->temperature, IWL_TX_POWER_TEMPERATURE_MIN);
1231
 
        current_temp = min(priv->temperature, IWL_TX_POWER_TEMPERATURE_MAX);
1232
 
        current_temp = KELVIN_TO_CELSIUS(current_temp);
1233
 
 
1234
 
        /* select thermal txpower adjustment params, based on channel group
1235
 
         *   (same frequency group used for mimo txatten adjustment) */
1236
 
        degrees_per_05db_num =
1237
 
            tx_power_cmp_tble[txatten_grp].degrees_per_05db_a;
1238
 
        degrees_per_05db_denom =
1239
 
            tx_power_cmp_tble[txatten_grp].degrees_per_05db_a_denom;
1240
 
 
1241
 
        /* get per-chain txpower values from factory measurements */
1242
 
        for (c = 0; c < 2; c++) {
1243
 
                measurement = &ch_eeprom_info.measurements[c][1];
1244
 
 
1245
 
                /* txgain adjustment (in half-dB steps) based on difference
1246
 
                 *   between factory and current temperature */
1247
 
                factory_temp = measurement->temperature;
1248
 
                iwl4965_math_div_round((current_temp - factory_temp) *
1249
 
                                       degrees_per_05db_denom,
1250
 
                                       degrees_per_05db_num,
1251
 
                                       &temperature_comp[c]);
1252
 
 
1253
 
                factory_gain_index[c] = measurement->gain_idx;
1254
 
                factory_actual_pwr[c] = measurement->actual_pow;
1255
 
 
1256
 
                IWL_DEBUG_TXPOWER(priv, "chain = %d\n", c);
1257
 
                IWL_DEBUG_TXPOWER(priv, "fctry tmp %d, "
1258
 
                                  "curr tmp %d, comp %d steps\n",
1259
 
                                  factory_temp, current_temp,
1260
 
                                  temperature_comp[c]);
1261
 
 
1262
 
                IWL_DEBUG_TXPOWER(priv, "fctry idx %d, fctry pwr %d\n",
1263
 
                                  factory_gain_index[c],
1264
 
                                  factory_actual_pwr[c]);
1265
 
        }
1266
 
 
1267
 
        /* for each of 33 bit-rates (including 1 for CCK) */
1268
 
        for (i = 0; i < POWER_TABLE_NUM_ENTRIES; i++) {
1269
 
                u8 is_mimo_rate;
1270
 
                union iwl4965_tx_power_dual_stream tx_power;
1271
 
 
1272
 
                /* for mimo, reduce each chain's txpower by half
1273
 
                 * (3dB, 6 steps), so total output power is regulatory
1274
 
                 * compliant. */
1275
 
                if (i & 0x8) {
1276
 
                        current_regulatory = reg_limit -
1277
 
                            IWL_TX_POWER_MIMO_REGULATORY_COMPENSATION;
1278
 
                        is_mimo_rate = 1;
1279
 
                } else {
1280
 
                        current_regulatory = reg_limit;
1281
 
                        is_mimo_rate = 0;
1282
 
                }
1283
 
 
1284
 
                /* find txpower limit, either hardware or regulatory */
1285
 
                power_limit = saturation_power - back_off_table[i];
1286
 
                if (power_limit > current_regulatory)
1287
 
                        power_limit = current_regulatory;
1288
 
 
1289
 
                /* reduce user's txpower request if necessary
1290
 
                 * for this rate on this channel */
1291
 
                target_power = user_target_power;
1292
 
                if (target_power > power_limit)
1293
 
                        target_power = power_limit;
1294
 
 
1295
 
                IWL_DEBUG_TXPOWER(priv, "rate %d sat %d reg %d usr %d tgt %d\n",
1296
 
                                  i, saturation_power - back_off_table[i],
1297
 
                                  current_regulatory, user_target_power,
1298
 
                                  target_power);
1299
 
 
1300
 
                /* for each of 2 Tx chains (radio transmitters) */
1301
 
                for (c = 0; c < 2; c++) {
1302
 
                        s32 atten_value;
1303
 
 
1304
 
                        if (is_mimo_rate)
1305
 
                                atten_value =
1306
 
                                    (s32)le32_to_cpu(priv->card_alive_init.
1307
 
                                    tx_atten[txatten_grp][c]);
1308
 
                        else
1309
 
                                atten_value = 0;
1310
 
 
1311
 
                        /* calculate index; higher index means lower txpower */
1312
 
                        power_index = (u8) (factory_gain_index[c] -
1313
 
                                            (target_power -
1314
 
                                             factory_actual_pwr[c]) -
1315
 
                                            temperature_comp[c] -
1316
 
                                            voltage_compensation +
1317
 
                                            atten_value);
1318
 
 
1319
 
/*                      IWL_DEBUG_TXPOWER(priv, "calculated txpower index %d\n",
1320
 
                                                power_index); */
1321
 
 
1322
 
                        if (power_index < get_min_power_index(i, band))
1323
 
                                power_index = get_min_power_index(i, band);
1324
 
 
1325
 
                        /* adjust 5 GHz index to support negative indexes */
1326
 
                        if (!band)
1327
 
                                power_index += 9;
1328
 
 
1329
 
                        /* CCK, rate 32, reduce txpower for CCK */
1330
 
                        if (i == POWER_TABLE_CCK_ENTRY)
1331
 
                                power_index +=
1332
 
                                    IWL_TX_POWER_CCK_COMPENSATION_C_STEP;
1333
 
 
1334
 
                        /* stay within the table! */
1335
 
                        if (power_index > 107) {
1336
 
                                IWL_WARN(priv, "txpower index %d > 107\n",
1337
 
                                            power_index);
1338
 
                                power_index = 107;
1339
 
                        }
1340
 
                        if (power_index < 0) {
1341
 
                                IWL_WARN(priv, "txpower index %d < 0\n",
1342
 
                                            power_index);
1343
 
                                power_index = 0;
1344
 
                        }
1345
 
 
1346
 
                        /* fill txpower command for this rate/chain */
1347
 
                        tx_power.s.radio_tx_gain[c] =
1348
 
                                gain_table[band][power_index].radio;
1349
 
                        tx_power.s.dsp_predis_atten[c] =
1350
 
                                gain_table[band][power_index].dsp;
1351
 
 
1352
 
                        IWL_DEBUG_TXPOWER(priv, "chain %d mimo %d index %d "
1353
 
                                          "gain 0x%02x dsp %d\n",
1354
 
                                          c, atten_value, power_index,
1355
 
                                        tx_power.s.radio_tx_gain[c],
1356
 
                                        tx_power.s.dsp_predis_atten[c]);
1357
 
                } /* for each chain */
1358
 
 
1359
 
                tx_power_tbl->power_tbl[i].dw = cpu_to_le32(tx_power.dw);
1360
 
 
1361
 
        } /* for each rate */
1362
 
 
1363
 
        return 0;
1364
 
}
1365
 
 
1366
 
/**
1367
 
 * iwl4965_send_tx_power - Configure the TXPOWER level user limit
1368
 
 *
1369
 
 * Uses the active RXON for channel, band, and characteristics (ht40, high)
1370
 
 * The power limit is taken from priv->tx_power_user_lmt.
1371
 
 */
1372
 
static int iwl4965_send_tx_power(struct iwl_priv *priv)
1373
 
{
1374
 
        struct iwl4965_txpowertable_cmd cmd = { 0 };
1375
 
        int ret;
1376
 
        u8 band = 0;
1377
 
        bool is_ht40 = false;
1378
 
        u8 ctrl_chan_high = 0;
1379
 
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
1380
 
 
1381
 
        if (WARN_ONCE(test_bit(STATUS_SCAN_HW, &priv->status),
1382
 
                      "TX Power requested while scanning!\n"))
1383
 
                return -EAGAIN;
1384
 
 
1385
 
        band = priv->band == IEEE80211_BAND_2GHZ;
1386
 
 
1387
 
        is_ht40 = is_ht40_channel(ctx->active.flags);
1388
 
 
1389
 
        if (is_ht40 && (ctx->active.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
1390
 
                ctrl_chan_high = 1;
1391
 
 
1392
 
        cmd.band = band;
1393
 
        cmd.channel = ctx->active.channel;
1394
 
 
1395
 
        ret = iwl4965_fill_txpower_tbl(priv, band,
1396
 
                                le16_to_cpu(ctx->active.channel),
1397
 
                                is_ht40, ctrl_chan_high, &cmd.tx_power);
1398
 
        if (ret)
1399
 
                goto out;
1400
 
 
1401
 
        ret = iwl_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD, sizeof(cmd), &cmd);
1402
 
 
1403
 
out:
1404
 
        return ret;
1405
 
}
1406
 
 
1407
 
static int iwl4965_send_rxon_assoc(struct iwl_priv *priv,
1408
 
                                   struct iwl_rxon_context *ctx)
1409
 
{
1410
 
        int ret = 0;
1411
 
        struct iwl4965_rxon_assoc_cmd rxon_assoc;
1412
 
        const struct iwl_rxon_cmd *rxon1 = &ctx->staging;
1413
 
        const struct iwl_rxon_cmd *rxon2 = &ctx->active;
1414
 
 
1415
 
        if ((rxon1->flags == rxon2->flags) &&
1416
 
            (rxon1->filter_flags == rxon2->filter_flags) &&
1417
 
            (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
1418
 
            (rxon1->ofdm_ht_single_stream_basic_rates ==
1419
 
             rxon2->ofdm_ht_single_stream_basic_rates) &&
1420
 
            (rxon1->ofdm_ht_dual_stream_basic_rates ==
1421
 
             rxon2->ofdm_ht_dual_stream_basic_rates) &&
1422
 
            (rxon1->rx_chain == rxon2->rx_chain) &&
1423
 
            (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
1424
 
                IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC.  Not resending.\n");
1425
 
                return 0;
1426
 
        }
1427
 
 
1428
 
        rxon_assoc.flags = ctx->staging.flags;
1429
 
        rxon_assoc.filter_flags = ctx->staging.filter_flags;
1430
 
        rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
1431
 
        rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
1432
 
        rxon_assoc.reserved = 0;
1433
 
        rxon_assoc.ofdm_ht_single_stream_basic_rates =
1434
 
            ctx->staging.ofdm_ht_single_stream_basic_rates;
1435
 
        rxon_assoc.ofdm_ht_dual_stream_basic_rates =
1436
 
            ctx->staging.ofdm_ht_dual_stream_basic_rates;
1437
 
        rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain;
1438
 
 
1439
 
        ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC,
1440
 
                                     sizeof(rxon_assoc), &rxon_assoc, NULL);
1441
 
        if (ret)
1442
 
                return ret;
1443
 
 
1444
 
        return ret;
1445
 
}
1446
 
 
1447
 
static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
1448
 
{
1449
 
        /* cast away the const for active_rxon in this function */
1450
 
        struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active;
1451
 
        int ret;
1452
 
        bool new_assoc =
1453
 
                !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
1454
 
 
1455
 
        if (!iwl_is_alive(priv))
1456
 
                return -EBUSY;
1457
 
 
1458
 
        if (!ctx->is_active)
1459
 
                return 0;
1460
 
 
1461
 
        /* always get timestamp with Rx frame */
1462
 
        ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
1463
 
 
1464
 
        ret = iwl_check_rxon_cmd(priv, ctx);
1465
 
        if (ret) {
1466
 
                IWL_ERR(priv, "Invalid RXON configuration.  Not committing.\n");
1467
 
                return -EINVAL;
1468
 
        }
1469
 
 
1470
 
        /*
1471
 
         * receive commit_rxon request
1472
 
         * abort any previous channel switch if still in process
1473
 
         */
1474
 
        if (priv->switch_rxon.switch_in_progress &&
1475
 
            (priv->switch_rxon.channel != ctx->staging.channel)) {
1476
 
                IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
1477
 
                      le16_to_cpu(priv->switch_rxon.channel));
1478
 
                iwl_chswitch_done(priv, false);
1479
 
        }
1480
 
 
1481
 
        /* If we don't need to send a full RXON, we can use
1482
 
         * iwl_rxon_assoc_cmd which is used to reconfigure filter
1483
 
         * and other flags for the current radio configuration. */
1484
 
        if (!iwl_full_rxon_required(priv, ctx)) {
1485
 
                ret = iwl_send_rxon_assoc(priv, ctx);
1486
 
                if (ret) {
1487
 
                        IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
1488
 
                        return ret;
1489
 
                }
1490
 
 
1491
 
                memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
1492
 
                iwl_print_rx_config_cmd(priv, ctx);
1493
 
                return 0;
1494
 
        }
1495
 
 
1496
 
        /* If we are currently associated and the new config requires
1497
 
         * an RXON_ASSOC and the new config wants the associated mask enabled,
1498
 
         * we must clear the associated from the active configuration
1499
 
         * before we apply the new config */
1500
 
        if (iwl_is_associated_ctx(ctx) && new_assoc) {
1501
 
                IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
1502
 
                active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1503
 
 
1504
 
                ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
1505
 
                                       sizeof(struct iwl_rxon_cmd),
1506
 
                                       active_rxon);
1507
 
 
1508
 
                /* If the mask clearing failed then we set
1509
 
                 * active_rxon back to what it was previously */
1510
 
                if (ret) {
1511
 
                        active_rxon->filter_flags |= RXON_FILTER_ASSOC_MSK;
1512
 
                        IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret);
1513
 
                        return ret;
1514
 
                }
1515
 
                iwl_clear_ucode_stations(priv, ctx);
1516
 
                iwl_restore_stations(priv, ctx);
1517
 
                ret = iwl_restore_default_wep_keys(priv, ctx);
1518
 
                if (ret) {
1519
 
                        IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
1520
 
                        return ret;
1521
 
                }
1522
 
        }
1523
 
 
1524
 
        IWL_DEBUG_INFO(priv, "Sending RXON\n"
1525
 
                       "* with%s RXON_FILTER_ASSOC_MSK\n"
1526
 
                       "* channel = %d\n"
1527
 
                       "* bssid = %pM\n",
1528
 
                       (new_assoc ? "" : "out"),
1529
 
                       le16_to_cpu(ctx->staging.channel),
1530
 
                       ctx->staging.bssid_addr);
1531
 
 
1532
 
        iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);
1533
 
 
1534
 
        /* Apply the new configuration
1535
 
         * RXON unassoc clears the station table in uCode so restoration of
1536
 
         * stations is needed after it (the RXON command) completes
1537
 
         */
1538
 
        if (!new_assoc) {
1539
 
                ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
1540
 
                              sizeof(struct iwl_rxon_cmd), &ctx->staging);
1541
 
                if (ret) {
1542
 
                        IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
1543
 
                        return ret;
1544
 
                }
1545
 
                IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n");
1546
 
                memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
1547
 
                iwl_clear_ucode_stations(priv, ctx);
1548
 
                iwl_restore_stations(priv, ctx);
1549
 
                ret = iwl_restore_default_wep_keys(priv, ctx);
1550
 
                if (ret) {
1551
 
                        IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
1552
 
                        return ret;
1553
 
                }
1554
 
        }
1555
 
        if (new_assoc) {
1556
 
                priv->start_calib = 0;
1557
 
                /* Apply the new configuration
1558
 
                 * RXON assoc doesn't clear the station table in uCode,
1559
 
                 */
1560
 
                ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
1561
 
                              sizeof(struct iwl_rxon_cmd), &ctx->staging);
1562
 
                if (ret) {
1563
 
                        IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
1564
 
                        return ret;
1565
 
                }
1566
 
                memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
1567
 
        }
1568
 
        iwl_print_rx_config_cmd(priv, ctx);
1569
 
 
1570
 
        iwl_init_sensitivity(priv);
1571
 
 
1572
 
        /* If we issue a new RXON command which required a tune then we must
1573
 
         * send a new TXPOWER command or we won't be able to Tx any frames */
1574
 
        ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
1575
 
        if (ret) {
1576
 
                IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
1577
 
                return ret;
1578
 
        }
1579
 
 
1580
 
        return 0;
1581
 
}
1582
 
 
1583
 
static int iwl4965_hw_channel_switch(struct iwl_priv *priv,
1584
 
                                     struct ieee80211_channel_switch *ch_switch)
1585
 
{
1586
 
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
1587
 
        int rc;
1588
 
        u8 band = 0;
1589
 
        bool is_ht40 = false;
1590
 
        u8 ctrl_chan_high = 0;
1591
 
        struct iwl4965_channel_switch_cmd cmd;
1592
 
        const struct iwl_channel_info *ch_info;
1593
 
        u32 switch_time_in_usec, ucode_switch_time;
1594
 
        u16 ch;
1595
 
        u32 tsf_low;
1596
 
        u8 switch_count;
1597
 
        u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
1598
 
        struct ieee80211_vif *vif = ctx->vif;
1599
 
        band = priv->band == IEEE80211_BAND_2GHZ;
1600
 
 
1601
 
        is_ht40 = is_ht40_channel(ctx->staging.flags);
1602
 
 
1603
 
        if (is_ht40 &&
1604
 
            (ctx->staging.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
1605
 
                ctrl_chan_high = 1;
1606
 
 
1607
 
        cmd.band = band;
1608
 
        cmd.expect_beacon = 0;
1609
 
        ch = ch_switch->channel->hw_value;
1610
 
        cmd.channel = cpu_to_le16(ch);
1611
 
        cmd.rxon_flags = ctx->staging.flags;
1612
 
        cmd.rxon_filter_flags = ctx->staging.filter_flags;
1613
 
        switch_count = ch_switch->count;
1614
 
        tsf_low = ch_switch->timestamp & 0x0ffffffff;
1615
 
        /*
1616
 
         * calculate the ucode channel switch time
1617
 
         * adding TSF as one of the factor for when to switch
1618
 
         */
1619
 
        if ((priv->ucode_beacon_time > tsf_low) && beacon_interval) {
1620
 
                if (switch_count > ((priv->ucode_beacon_time - tsf_low) /
1621
 
                    beacon_interval)) {
1622
 
                        switch_count -= (priv->ucode_beacon_time -
1623
 
                                tsf_low) / beacon_interval;
1624
 
                } else
1625
 
                        switch_count = 0;
1626
 
        }
1627
 
        if (switch_count <= 1)
1628
 
                cmd.switch_time = cpu_to_le32(priv->ucode_beacon_time);
1629
 
        else {
1630
 
                switch_time_in_usec =
1631
 
                        vif->bss_conf.beacon_int * switch_count * TIME_UNIT;
1632
 
                ucode_switch_time = iwl_usecs_to_beacons(priv,
1633
 
                                                         switch_time_in_usec,
1634
 
                                                         beacon_interval);
1635
 
                cmd.switch_time = iwl_add_beacon_time(priv,
1636
 
                                                      priv->ucode_beacon_time,
1637
 
                                                      ucode_switch_time,
1638
 
                                                      beacon_interval);
1639
 
        }
1640
 
        IWL_DEBUG_11H(priv, "uCode time for the switch is 0x%x\n",
1641
 
                      cmd.switch_time);
1642
 
        ch_info = iwl_get_channel_info(priv, priv->band, ch);
1643
 
        if (ch_info)
1644
 
                cmd.expect_beacon = is_channel_radar(ch_info);
1645
 
        else {
1646
 
                IWL_ERR(priv, "invalid channel switch from %u to %u\n",
1647
 
                        ctx->active.channel, ch);
1648
 
                return -EFAULT;
1649
 
        }
1650
 
 
1651
 
        rc = iwl4965_fill_txpower_tbl(priv, band, ch, is_ht40,
1652
 
                                      ctrl_chan_high, &cmd.tx_power);
1653
 
        if (rc) {
1654
 
                IWL_DEBUG_11H(priv, "error:%d  fill txpower_tbl\n", rc);
1655
 
                return rc;
1656
 
        }
1657
 
 
1658
 
        priv->switch_rxon.channel = cmd.channel;
1659
 
        priv->switch_rxon.switch_in_progress = true;
1660
 
 
1661
 
        return iwl_send_cmd_pdu(priv, REPLY_CHANNEL_SWITCH, sizeof(cmd), &cmd);
1662
 
}
1663
 
 
1664
 
/**
1665
 
 * iwl4965_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
1666
 
 */
1667
 
static void iwl4965_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
1668
 
                                            struct iwl_tx_queue *txq,
1669
 
                                            u16 byte_cnt)
1670
 
{
1671
 
        struct iwl4965_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
1672
 
        int txq_id = txq->q.id;
1673
 
        int write_ptr = txq->q.write_ptr;
1674
 
        int len = byte_cnt + IWL_TX_CRC_SIZE + IWL_TX_DELIMITER_SIZE;
1675
 
        __le16 bc_ent;
1676
 
 
1677
 
        WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX);
1678
 
 
1679
 
        bc_ent = cpu_to_le16(len & 0xFFF);
1680
 
        /* Set up byte count within first 256 entries */
1681
 
        scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
1682
 
 
1683
 
        /* If within first 64 entries, duplicate at end */
1684
 
        if (write_ptr < TFD_QUEUE_SIZE_BC_DUP)
1685
 
                scd_bc_tbl[txq_id].
1686
 
                        tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
1687
 
}
1688
 
 
1689
 
/**
1690
 
 * iwl4965_hw_get_temperature - return the calibrated temperature (in Kelvin)
1691
 
 * @statistics: Provides the temperature reading from the uCode
1692
 
 *
1693
 
 * A return of <0 indicates bogus data in the statistics
1694
 
 */
1695
 
static int iwl4965_hw_get_temperature(struct iwl_priv *priv)
1696
 
{
1697
 
        s32 temperature;
1698
 
        s32 vt;
1699
 
        s32 R1, R2, R3;
1700
 
        u32 R4;
1701
 
 
1702
 
        if (test_bit(STATUS_TEMPERATURE, &priv->status) &&
1703
 
            (priv->_agn.statistics.flag &
1704
 
                        STATISTICS_REPLY_FLG_HT40_MODE_MSK)) {
1705
 
                IWL_DEBUG_TEMP(priv, "Running HT40 temperature calibration\n");
1706
 
                R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[1]);
1707
 
                R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[1]);
1708
 
                R3 = (s32)le32_to_cpu(priv->card_alive_init.therm_r3[1]);
1709
 
                R4 = le32_to_cpu(priv->card_alive_init.therm_r4[1]);
1710
 
        } else {
1711
 
                IWL_DEBUG_TEMP(priv, "Running temperature calibration\n");
1712
 
                R1 = (s32)le32_to_cpu(priv->card_alive_init.therm_r1[0]);
1713
 
                R2 = (s32)le32_to_cpu(priv->card_alive_init.therm_r2[0]);
1714
 
                R3 = (s32)le32_to_cpu(priv->card_alive_init.therm_r3[0]);
1715
 
                R4 = le32_to_cpu(priv->card_alive_init.therm_r4[0]);
1716
 
        }
1717
 
 
1718
 
        /*
1719
 
         * Temperature is only 23 bits, so sign extend out to 32.
1720
 
         *
1721
 
         * NOTE If we haven't received a statistics notification yet
1722
 
         * with an updated temperature, use R4 provided to us in the
1723
 
         * "initialize" ALIVE response.
1724
 
         */
1725
 
        if (!test_bit(STATUS_TEMPERATURE, &priv->status))
1726
 
                vt = sign_extend32(R4, 23);
1727
 
        else
1728
 
                vt = sign_extend32(le32_to_cpu(priv->_agn.statistics.
1729
 
                                 general.common.temperature), 23);
1730
 
 
1731
 
        IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt);
1732
 
 
1733
 
        if (R3 == R1) {
1734
 
                IWL_ERR(priv, "Calibration conflict R1 == R3\n");
1735
 
                return -1;
1736
 
        }
1737
 
 
1738
 
        /* Calculate temperature in degrees Kelvin, adjust by 97%.
1739
 
         * Add offset to center the adjustment around 0 degrees Centigrade. */
1740
 
        temperature = TEMPERATURE_CALIB_A_VAL * (vt - R2);
1741
 
        temperature /= (R3 - R1);
1742
 
        temperature = (temperature * 97) / 100 + TEMPERATURE_CALIB_KELVIN_OFFSET;
1743
 
 
1744
 
        IWL_DEBUG_TEMP(priv, "Calibrated temperature: %dK, %dC\n",
1745
 
                        temperature, KELVIN_TO_CELSIUS(temperature));
1746
 
 
1747
 
        return temperature;
1748
 
}
1749
 
 
1750
 
/* Adjust Txpower only if temperature variance is greater than threshold. */
1751
 
#define IWL_TEMPERATURE_THRESHOLD   3
1752
 
 
1753
 
/**
1754
 
 * iwl4965_is_temp_calib_needed - determines if new calibration is needed
1755
 
 *
1756
 
 * If the temperature changed has changed sufficiently, then a recalibration
1757
 
 * is needed.
1758
 
 *
1759
 
 * Assumes caller will replace priv->last_temperature once calibration
1760
 
 * executed.
1761
 
 */
1762
 
static int iwl4965_is_temp_calib_needed(struct iwl_priv *priv)
1763
 
{
1764
 
        int temp_diff;
1765
 
 
1766
 
        if (!test_bit(STATUS_STATISTICS, &priv->status)) {
1767
 
                IWL_DEBUG_TEMP(priv, "Temperature not updated -- no statistics.\n");
1768
 
                return 0;
1769
 
        }
1770
 
 
1771
 
        temp_diff = priv->temperature - priv->last_temperature;
1772
 
 
1773
 
        /* get absolute value */
1774
 
        if (temp_diff < 0) {
1775
 
                IWL_DEBUG_POWER(priv, "Getting cooler, delta %d\n", temp_diff);
1776
 
                temp_diff = -temp_diff;
1777
 
        } else if (temp_diff == 0)
1778
 
                IWL_DEBUG_POWER(priv, "Temperature unchanged\n");
1779
 
        else
1780
 
                IWL_DEBUG_POWER(priv, "Getting warmer, delta %d\n", temp_diff);
1781
 
 
1782
 
        if (temp_diff < IWL_TEMPERATURE_THRESHOLD) {
1783
 
                IWL_DEBUG_POWER(priv, " => thermal txpower calib not needed\n");
1784
 
                return 0;
1785
 
        }
1786
 
 
1787
 
        IWL_DEBUG_POWER(priv, " => thermal txpower calib needed\n");
1788
 
 
1789
 
        return 1;
1790
 
}
1791
 
 
1792
 
static void iwl4965_temperature_calib(struct iwl_priv *priv)
1793
 
{
1794
 
        s32 temp;
1795
 
 
1796
 
        temp = iwl4965_hw_get_temperature(priv);
1797
 
        if (temp < 0)
1798
 
                return;
1799
 
 
1800
 
        if (priv->temperature != temp) {
1801
 
                if (priv->temperature)
1802
 
                        IWL_DEBUG_TEMP(priv, "Temperature changed "
1803
 
                                       "from %dC to %dC\n",
1804
 
                                       KELVIN_TO_CELSIUS(priv->temperature),
1805
 
                                       KELVIN_TO_CELSIUS(temp));
1806
 
                else
1807
 
                        IWL_DEBUG_TEMP(priv, "Temperature "
1808
 
                                       "initialized to %dC\n",
1809
 
                                       KELVIN_TO_CELSIUS(temp));
1810
 
        }
1811
 
 
1812
 
        priv->temperature = temp;
1813
 
        iwl_tt_handler(priv);
1814
 
        set_bit(STATUS_TEMPERATURE, &priv->status);
1815
 
 
1816
 
        if (!priv->disable_tx_power_cal &&
1817
 
             unlikely(!test_bit(STATUS_SCANNING, &priv->status)) &&
1818
 
             iwl4965_is_temp_calib_needed(priv))
1819
 
                queue_work(priv->workqueue, &priv->txpower_work);
1820
 
}
1821
 
 
1822
 
/**
1823
 
 * iwl4965_tx_queue_stop_scheduler - Stop queue, but keep configuration
1824
 
 */
1825
 
static void iwl4965_tx_queue_stop_scheduler(struct iwl_priv *priv,
1826
 
                                            u16 txq_id)
1827
 
{
1828
 
        /* Simply stop the queue, but don't change any configuration;
1829
 
         * the SCD_ACT_EN bit is the write-enable mask for the ACTIVE bit. */
1830
 
        iwl_write_prph(priv,
1831
 
                IWL49_SCD_QUEUE_STATUS_BITS(txq_id),
1832
 
                (0 << IWL49_SCD_QUEUE_STTS_REG_POS_ACTIVE)|
1833
 
                (1 << IWL49_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
1834
 
}
1835
 
 
1836
 
/**
1837
 
 * txq_id must be greater than IWL49_FIRST_AMPDU_QUEUE
1838
 
 * priv->lock must be held by the caller
1839
 
 */
1840
 
static int iwl4965_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
1841
 
                                   u16 ssn_idx, u8 tx_fifo)
1842
 
{
1843
 
        if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
1844
 
            (IWL49_FIRST_AMPDU_QUEUE +
1845
 
                priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
1846
 
                IWL_WARN(priv,
1847
 
                        "queue number out of range: %d, must be %d to %d\n",
1848
 
                        txq_id, IWL49_FIRST_AMPDU_QUEUE,
1849
 
                        IWL49_FIRST_AMPDU_QUEUE +
1850
 
                        priv->cfg->base_params->num_of_ampdu_queues - 1);
1851
 
                return -EINVAL;
1852
 
        }
1853
 
 
1854
 
        iwl4965_tx_queue_stop_scheduler(priv, txq_id);
1855
 
 
1856
 
        iwl_clear_bits_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, (1 << txq_id));
1857
 
 
1858
 
        priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
1859
 
        priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
1860
 
        /* supposes that ssn_idx is valid (!= 0xFFF) */
1861
 
        iwl4965_set_wr_ptrs(priv, txq_id, ssn_idx);
1862
 
 
1863
 
        iwl_clear_bits_prph(priv, IWL49_SCD_INTERRUPT_MASK, (1 << txq_id));
1864
 
        iwl_txq_ctx_deactivate(priv, txq_id);
1865
 
        iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 0);
1866
 
 
1867
 
        return 0;
1868
 
}
1869
 
 
1870
 
/**
1871
 
 * iwl4965_tx_queue_set_q2ratid - Map unique receiver/tid combination to a queue
1872
 
 */
1873
 
static int iwl4965_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
1874
 
                                        u16 txq_id)
1875
 
{
1876
 
        u32 tbl_dw_addr;
1877
 
        u32 tbl_dw;
1878
 
        u16 scd_q2ratid;
1879
 
 
1880
 
        scd_q2ratid = ra_tid & IWL_SCD_QUEUE_RA_TID_MAP_RATID_MSK;
1881
 
 
1882
 
        tbl_dw_addr = priv->scd_base_addr +
1883
 
                        IWL49_SCD_TRANSLATE_TBL_OFFSET_QUEUE(txq_id);
1884
 
 
1885
 
        tbl_dw = iwl_read_targ_mem(priv, tbl_dw_addr);
1886
 
 
1887
 
        if (txq_id & 0x1)
1888
 
                tbl_dw = (scd_q2ratid << 16) | (tbl_dw & 0x0000FFFF);
1889
 
        else
1890
 
                tbl_dw = scd_q2ratid | (tbl_dw & 0xFFFF0000);
1891
 
 
1892
 
        iwl_write_targ_mem(priv, tbl_dw_addr, tbl_dw);
1893
 
 
1894
 
        return 0;
1895
 
}
1896
 
 
1897
 
 
1898
 
/**
1899
 
 * iwl4965_tx_queue_agg_enable - Set up & enable aggregation for selected queue
1900
 
 *
1901
 
 * NOTE:  txq_id must be greater than IWL49_FIRST_AMPDU_QUEUE,
1902
 
 *        i.e. it must be one of the higher queues used for aggregation
1903
 
 */
1904
 
static int iwl4965_txq_agg_enable(struct iwl_priv *priv, int txq_id,
1905
 
                                  int tx_fifo, int sta_id, int tid, u16 ssn_idx)
1906
 
{
1907
 
        unsigned long flags;
1908
 
        u16 ra_tid;
1909
 
        int ret;
1910
 
 
1911
 
        if ((IWL49_FIRST_AMPDU_QUEUE > txq_id) ||
1912
 
            (IWL49_FIRST_AMPDU_QUEUE +
1913
 
                priv->cfg->base_params->num_of_ampdu_queues <= txq_id)) {
1914
 
                IWL_WARN(priv,
1915
 
                        "queue number out of range: %d, must be %d to %d\n",
1916
 
                        txq_id, IWL49_FIRST_AMPDU_QUEUE,
1917
 
                        IWL49_FIRST_AMPDU_QUEUE +
1918
 
                        priv->cfg->base_params->num_of_ampdu_queues - 1);
1919
 
                return -EINVAL;
1920
 
        }
1921
 
 
1922
 
        ra_tid = BUILD_RAxTID(sta_id, tid);
1923
 
 
1924
 
        /* Modify device's station table to Tx this TID */
1925
 
        ret = iwl_sta_tx_modify_enable_tid(priv, sta_id, tid);
1926
 
        if (ret)
1927
 
                return ret;
1928
 
 
1929
 
        spin_lock_irqsave(&priv->lock, flags);
1930
 
 
1931
 
        /* Stop this Tx queue before configuring it */
1932
 
        iwl4965_tx_queue_stop_scheduler(priv, txq_id);
1933
 
 
1934
 
        /* Map receiver-address / traffic-ID to this queue */
1935
 
        iwl4965_tx_queue_set_q2ratid(priv, ra_tid, txq_id);
1936
 
 
1937
 
        /* Set this queue as a chain-building queue */
1938
 
        iwl_set_bits_prph(priv, IWL49_SCD_QUEUECHAIN_SEL, (1 << txq_id));
1939
 
 
1940
 
        /* Place first TFD at index corresponding to start sequence number.
1941
 
         * Assumes that ssn_idx is valid (!= 0xFFF) */
1942
 
        priv->txq[txq_id].q.read_ptr = (ssn_idx & 0xff);
1943
 
        priv->txq[txq_id].q.write_ptr = (ssn_idx & 0xff);
1944
 
        iwl4965_set_wr_ptrs(priv, txq_id, ssn_idx);
1945
 
 
1946
 
        /* Set up Tx window size and frame limit for this queue */
1947
 
        iwl_write_targ_mem(priv,
1948
 
                priv->scd_base_addr + IWL49_SCD_CONTEXT_QUEUE_OFFSET(txq_id),
1949
 
                (SCD_WIN_SIZE << IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_POS) &
1950
 
                IWL49_SCD_QUEUE_CTX_REG1_WIN_SIZE_MSK);
1951
 
 
1952
 
        iwl_write_targ_mem(priv, priv->scd_base_addr +
1953
 
                IWL49_SCD_CONTEXT_QUEUE_OFFSET(txq_id) + sizeof(u32),
1954
 
                (SCD_FRAME_LIMIT << IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_POS)
1955
 
                & IWL49_SCD_QUEUE_CTX_REG2_FRAME_LIMIT_MSK);
1956
 
 
1957
 
        iwl_set_bits_prph(priv, IWL49_SCD_INTERRUPT_MASK, (1 << txq_id));
1958
 
 
1959
 
        /* Set up Status area in SRAM, map to Tx DMA/FIFO, activate the queue */
1960
 
        iwl4965_tx_queue_set_status(priv, &priv->txq[txq_id], tx_fifo, 1);
1961
 
 
1962
 
        spin_unlock_irqrestore(&priv->lock, flags);
1963
 
 
1964
 
        return 0;
1965
 
}
1966
 
 
1967
 
 
1968
 
static u16 iwl4965_get_hcmd_size(u8 cmd_id, u16 len)
1969
 
{
1970
 
        switch (cmd_id) {
1971
 
        case REPLY_RXON:
1972
 
                return (u16) sizeof(struct iwl4965_rxon_cmd);
1973
 
        default:
1974
 
                return len;
1975
 
        }
1976
 
}
1977
 
 
1978
 
static u16 iwl4965_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
1979
 
{
1980
 
        struct iwl4965_addsta_cmd *addsta = (struct iwl4965_addsta_cmd *)data;
1981
 
        addsta->mode = cmd->mode;
1982
 
        memcpy(&addsta->sta, &cmd->sta, sizeof(struct sta_id_modify));
1983
 
        memcpy(&addsta->key, &cmd->key, sizeof(struct iwl4965_keyinfo));
1984
 
        addsta->station_flags = cmd->station_flags;
1985
 
        addsta->station_flags_msk = cmd->station_flags_msk;
1986
 
        addsta->tid_disable_tx = cmd->tid_disable_tx;
1987
 
        addsta->add_immediate_ba_tid = cmd->add_immediate_ba_tid;
1988
 
        addsta->remove_immediate_ba_tid = cmd->remove_immediate_ba_tid;
1989
 
        addsta->add_immediate_ba_ssn = cmd->add_immediate_ba_ssn;
1990
 
        addsta->sleep_tx_count = cmd->sleep_tx_count;
1991
 
        addsta->reserved1 = cpu_to_le16(0);
1992
 
        addsta->reserved2 = cpu_to_le16(0);
1993
 
 
1994
 
        return (u16)sizeof(struct iwl4965_addsta_cmd);
1995
 
}
1996
 
 
1997
 
static inline u32 iwl4965_get_scd_ssn(struct iwl4965_tx_resp *tx_resp)
1998
 
{
1999
 
        return le32_to_cpup(&tx_resp->u.status + tx_resp->frame_count) & MAX_SN;
2000
 
}
2001
 
 
2002
 
/**
2003
 
 * iwl4965_tx_status_reply_tx - Handle Tx response for frames in aggregation queue
2004
 
 */
2005
 
static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
2006
 
                                      struct iwl_ht_agg *agg,
2007
 
                                      struct iwl4965_tx_resp *tx_resp,
2008
 
                                      int txq_id, u16 start_idx)
2009
 
{
2010
 
        u16 status;
2011
 
        struct agg_tx_status *frame_status = tx_resp->u.agg_status;
2012
 
        struct ieee80211_tx_info *info = NULL;
2013
 
        struct ieee80211_hdr *hdr = NULL;
2014
 
        u32 rate_n_flags = le32_to_cpu(tx_resp->rate_n_flags);
2015
 
        int i, sh, idx;
2016
 
        u16 seq;
2017
 
        if (agg->wait_for_ba)
2018
 
                IWL_DEBUG_TX_REPLY(priv, "got tx response w/o block-ack\n");
2019
 
 
2020
 
        agg->frame_count = tx_resp->frame_count;
2021
 
        agg->start_idx = start_idx;
2022
 
        agg->rate_n_flags = rate_n_flags;
2023
 
        agg->bitmap = 0;
2024
 
 
2025
 
        /* num frames attempted by Tx command */
2026
 
        if (agg->frame_count == 1) {
2027
 
                /* Only one frame was attempted; no block-ack will arrive */
2028
 
                status = le16_to_cpu(frame_status[0].status);
2029
 
                idx = start_idx;
2030
 
 
2031
 
                /* FIXME: code repetition */
2032
 
                IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, StartIdx=%d idx=%d\n",
2033
 
                                   agg->frame_count, agg->start_idx, idx);
2034
 
 
2035
 
                info = IEEE80211_SKB_CB(priv->txq[txq_id].txb[idx].skb);
2036
 
                info->status.rates[0].count = tx_resp->failure_frame + 1;
2037
 
                info->flags &= ~IEEE80211_TX_CTL_AMPDU;
2038
 
                info->flags |= iwl_tx_status_to_mac80211(status);
2039
 
                iwlagn_hwrate_to_tx_control(priv, rate_n_flags, info);
2040
 
                /* FIXME: code repetition end */
2041
 
 
2042
 
                IWL_DEBUG_TX_REPLY(priv, "1 Frame 0x%x failure :%d\n",
2043
 
                                    status & 0xff, tx_resp->failure_frame);
2044
 
                IWL_DEBUG_TX_REPLY(priv, "Rate Info rate_n_flags=%x\n", rate_n_flags);
2045
 
 
2046
 
                agg->wait_for_ba = 0;
2047
 
        } else {
2048
 
                /* Two or more frames were attempted; expect block-ack */
2049
 
                u64 bitmap = 0;
2050
 
                int start = agg->start_idx;
2051
 
 
2052
 
                /* Construct bit-map of pending frames within Tx window */
2053
 
                for (i = 0; i < agg->frame_count; i++) {
2054
 
                        u16 sc;
2055
 
                        status = le16_to_cpu(frame_status[i].status);
2056
 
                        seq  = le16_to_cpu(frame_status[i].sequence);
2057
 
                        idx = SEQ_TO_INDEX(seq);
2058
 
                        txq_id = SEQ_TO_QUEUE(seq);
2059
 
 
2060
 
                        if (status & (AGG_TX_STATE_FEW_BYTES_MSK |
2061
 
                                      AGG_TX_STATE_ABORT_MSK))
2062
 
                                continue;
2063
 
 
2064
 
                        IWL_DEBUG_TX_REPLY(priv, "FrameCnt = %d, txq_id=%d idx=%d\n",
2065
 
                                           agg->frame_count, txq_id, idx);
2066
 
 
2067
 
                        hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx);
2068
 
                        if (!hdr) {
2069
 
                                IWL_ERR(priv,
2070
 
                                        "BUG_ON idx doesn't point to valid skb"
2071
 
                                        " idx=%d, txq_id=%d\n", idx, txq_id);
2072
 
                                return -1;
2073
 
                        }
2074
 
 
2075
 
                        sc = le16_to_cpu(hdr->seq_ctrl);
2076
 
                        if (idx != (SEQ_TO_SN(sc) & 0xff)) {
2077
 
                                IWL_ERR(priv,
2078
 
                                        "BUG_ON idx doesn't match seq control"
2079
 
                                        " idx=%d, seq_idx=%d, seq=%d\n",
2080
 
                                        idx, SEQ_TO_SN(sc), hdr->seq_ctrl);
2081
 
                                return -1;
2082
 
                        }
2083
 
 
2084
 
                        IWL_DEBUG_TX_REPLY(priv, "AGG Frame i=%d idx %d seq=%d\n",
2085
 
                                           i, idx, SEQ_TO_SN(sc));
2086
 
 
2087
 
                        sh = idx - start;
2088
 
                        if (sh > 64) {
2089
 
                                sh = (start - idx) + 0xff;
2090
 
                                bitmap = bitmap << sh;
2091
 
                                sh = 0;
2092
 
                                start = idx;
2093
 
                        } else if (sh < -64)
2094
 
                                sh  = 0xff - (start - idx);
2095
 
                        else if (sh < 0) {
2096
 
                                sh = start - idx;
2097
 
                                start = idx;
2098
 
                                bitmap = bitmap << sh;
2099
 
                                sh = 0;
2100
 
                        }
2101
 
                        bitmap |= 1ULL << sh;
2102
 
                        IWL_DEBUG_TX_REPLY(priv, "start=%d bitmap=0x%llx\n",
2103
 
                                           start, (unsigned long long)bitmap);
2104
 
                }
2105
 
 
2106
 
                agg->bitmap = bitmap;
2107
 
                agg->start_idx = start;
2108
 
                IWL_DEBUG_TX_REPLY(priv, "Frames %d start_idx=%d bitmap=0x%llx\n",
2109
 
                                   agg->frame_count, agg->start_idx,
2110
 
                                   (unsigned long long)agg->bitmap);
2111
 
 
2112
 
                if (bitmap)
2113
 
                        agg->wait_for_ba = 1;
2114
 
        }
2115
 
        return 0;
2116
 
}
2117
 
 
2118
 
static u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
2119
 
{
2120
 
        int i;
2121
 
        int start = 0;
2122
 
        int ret = IWL_INVALID_STATION;
2123
 
        unsigned long flags;
2124
 
 
2125
 
        if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) ||
2126
 
            (priv->iw_mode == NL80211_IFTYPE_AP))
2127
 
                start = IWL_STA_ID;
2128
 
 
2129
 
        if (is_broadcast_ether_addr(addr))
2130
 
                return priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id;
2131
 
 
2132
 
        spin_lock_irqsave(&priv->sta_lock, flags);
2133
 
        for (i = start; i < priv->hw_params.max_stations; i++)
2134
 
                if (priv->stations[i].used &&
2135
 
                    (!compare_ether_addr(priv->stations[i].sta.sta.addr,
2136
 
                                         addr))) {
2137
 
                        ret = i;
2138
 
                        goto out;
2139
 
                }
2140
 
 
2141
 
        IWL_DEBUG_ASSOC_LIMIT(priv, "can not find STA %pM total %d\n",
2142
 
                              addr, priv->num_stations);
2143
 
 
2144
 
 out:
2145
 
        /*
2146
 
         * It may be possible that more commands interacting with stations
2147
 
         * arrive before we completed processing the adding of
2148
 
         * station
2149
 
         */
2150
 
        if (ret != IWL_INVALID_STATION &&
2151
 
            (!(priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) ||
2152
 
             ((priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) &&
2153
 
              (priv->stations[ret].used & IWL_STA_UCODE_INPROGRESS)))) {
2154
 
                IWL_ERR(priv, "Requested station info for sta %d before ready.\n",
2155
 
                        ret);
2156
 
                ret = IWL_INVALID_STATION;
2157
 
        }
2158
 
        spin_unlock_irqrestore(&priv->sta_lock, flags);
2159
 
        return ret;
2160
 
}
2161
 
 
2162
 
static int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
2163
 
{
2164
 
        if (priv->iw_mode == NL80211_IFTYPE_STATION) {
2165
 
                return IWL_AP_ID;
2166
 
        } else {
2167
 
                u8 *da = ieee80211_get_DA(hdr);
2168
 
                return iwl_find_station(priv, da);
2169
 
        }
2170
 
}
2171
 
 
2172
 
/**
2173
 
 * iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response
2174
 
 */
2175
 
static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2176
 
                                struct iwl_rx_mem_buffer *rxb)
2177
 
{
2178
 
        struct iwl_rx_packet *pkt = rxb_addr(rxb);
2179
 
        u16 sequence = le16_to_cpu(pkt->hdr.sequence);
2180
 
        int txq_id = SEQ_TO_QUEUE(sequence);
2181
 
        int index = SEQ_TO_INDEX(sequence);
2182
 
        struct iwl_tx_queue *txq = &priv->txq[txq_id];
2183
 
        struct ieee80211_hdr *hdr;
2184
 
        struct ieee80211_tx_info *info;
2185
 
        struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
2186
 
        u32  status = le32_to_cpu(tx_resp->u.status);
2187
 
        int uninitialized_var(tid);
2188
 
        int sta_id;
2189
 
        int freed;
2190
 
        u8 *qc = NULL;
2191
 
        unsigned long flags;
2192
 
 
2193
 
        if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
2194
 
                IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
2195
 
                          "is out of range [0-%d] %d %d\n", txq_id,
2196
 
                          index, txq->q.n_bd, txq->q.write_ptr,
2197
 
                          txq->q.read_ptr);
2198
 
                return;
2199
 
        }
2200
 
 
2201
 
        txq->time_stamp = jiffies;
2202
 
        info = IEEE80211_SKB_CB(txq->txb[txq->q.read_ptr].skb);
2203
 
        memset(&info->status, 0, sizeof(info->status));
2204
 
 
2205
 
        hdr = iwl_tx_queue_get_hdr(priv, txq_id, index);
2206
 
        if (ieee80211_is_data_qos(hdr->frame_control)) {
2207
 
                qc = ieee80211_get_qos_ctl(hdr);
2208
 
                tid = qc[0] & 0xf;
2209
 
        }
2210
 
 
2211
 
        sta_id = iwl_get_ra_sta_id(priv, hdr);
2212
 
        if (txq->sched_retry && unlikely(sta_id == IWL_INVALID_STATION)) {
2213
 
                IWL_ERR(priv, "Station not known\n");
2214
 
                return;
2215
 
        }
2216
 
 
2217
 
        spin_lock_irqsave(&priv->sta_lock, flags);
2218
 
        if (txq->sched_retry) {
2219
 
                const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp);
2220
 
                struct iwl_ht_agg *agg = NULL;
2221
 
                WARN_ON(!qc);
2222
 
 
2223
 
                agg = &priv->stations[sta_id].tid[tid].agg;
2224
 
 
2225
 
                iwl4965_tx_status_reply_tx(priv, agg, tx_resp, txq_id, index);
2226
 
 
2227
 
                /* check if BAR is needed */
2228
 
                if ((tx_resp->frame_count == 1) && !iwl_is_tx_success(status))
2229
 
                        info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
2230
 
 
2231
 
                if (txq->q.read_ptr != (scd_ssn & 0xff)) {
2232
 
                        index = iwl_queue_dec_wrap(scd_ssn & 0xff, txq->q.n_bd);
2233
 
                        IWL_DEBUG_TX_REPLY(priv, "Retry scheduler reclaim scd_ssn "
2234
 
                                           "%d index %d\n", scd_ssn , index);
2235
 
                        freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
2236
 
                        if (qc)
2237
 
                                iwl_free_tfds_in_queue(priv, sta_id,
2238
 
                                                       tid, freed);
2239
 
 
2240
 
                        if (priv->mac80211_registered &&
2241
 
                            (iwl_queue_space(&txq->q) > txq->q.low_mark) &&
2242
 
                            (agg->state != IWL_EMPTYING_HW_QUEUE_DELBA))
2243
 
                                iwl_wake_queue(priv, txq);
2244
 
                }
2245
 
        } else {
2246
 
                info->status.rates[0].count = tx_resp->failure_frame + 1;
2247
 
                info->flags |= iwl_tx_status_to_mac80211(status);
2248
 
                iwlagn_hwrate_to_tx_control(priv,
2249
 
                                        le32_to_cpu(tx_resp->rate_n_flags),
2250
 
                                        info);
2251
 
 
2252
 
                IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) "
2253
 
                                   "rate_n_flags 0x%x retries %d\n",
2254
 
                                   txq_id,
2255
 
                                   iwl_get_tx_fail_reason(status), status,
2256
 
                                   le32_to_cpu(tx_resp->rate_n_flags),
2257
 
                                   tx_resp->failure_frame);
2258
 
 
2259
 
                freed = iwlagn_tx_queue_reclaim(priv, txq_id, index);
2260
 
                if (qc && likely(sta_id != IWL_INVALID_STATION))
2261
 
                        iwl_free_tfds_in_queue(priv, sta_id, tid, freed);
2262
 
                else if (sta_id == IWL_INVALID_STATION)
2263
 
                        IWL_DEBUG_TX_REPLY(priv, "Station not known\n");
2264
 
 
2265
 
                if (priv->mac80211_registered &&
2266
 
                    (iwl_queue_space(&txq->q) > txq->q.low_mark))
2267
 
                        iwl_wake_queue(priv, txq);
2268
 
        }
2269
 
        if (qc && likely(sta_id != IWL_INVALID_STATION))
2270
 
                iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
2271
 
 
2272
 
        iwl_check_abort_status(priv, tx_resp->frame_count, status);
2273
 
 
2274
 
        spin_unlock_irqrestore(&priv->sta_lock, flags);
2275
 
}
2276
 
 
2277
 
static int iwl4965_calc_rssi(struct iwl_priv *priv,
2278
 
                             struct iwl_rx_phy_res *rx_resp)
2279
 
{
2280
 
        /* data from PHY/DSP regarding signal strength, etc.,
2281
 
         *   contents are always there, not configurable by host.  */
2282
 
        struct iwl4965_rx_non_cfg_phy *ncphy =
2283
 
            (struct iwl4965_rx_non_cfg_phy *)rx_resp->non_cfg_phy_buf;
2284
 
        u32 agc = (le16_to_cpu(ncphy->agc_info) & IWL49_AGC_DB_MASK)
2285
 
                        >> IWL49_AGC_DB_POS;
2286
 
 
2287
 
        u32 valid_antennae =
2288
 
            (le16_to_cpu(rx_resp->phy_flags) & IWL49_RX_PHY_FLAGS_ANTENNAE_MASK)
2289
 
                        >> IWL49_RX_PHY_FLAGS_ANTENNAE_OFFSET;
2290
 
        u8 max_rssi = 0;
2291
 
        u32 i;
2292
 
 
2293
 
        /* Find max rssi among 3 possible receivers.
2294
 
         * These values are measured by the digital signal processor (DSP).
2295
 
         * They should stay fairly constant even as the signal strength varies,
2296
 
         *   if the radio's automatic gain control (AGC) is working right.
2297
 
         * AGC value (see below) will provide the "interesting" info. */
2298
 
        for (i = 0; i < 3; i++)
2299
 
                if (valid_antennae & (1 << i))
2300
 
                        max_rssi = max(ncphy->rssi_info[i << 1], max_rssi);
2301
 
 
2302
 
        IWL_DEBUG_STATS(priv, "Rssi In A %d B %d C %d Max %d AGC dB %d\n",
2303
 
                ncphy->rssi_info[0], ncphy->rssi_info[2], ncphy->rssi_info[4],
2304
 
                max_rssi, agc);
2305
 
 
2306
 
        /* dBm = max_rssi dB - agc dB - constant.
2307
 
         * Higher AGC (higher radio gain) means lower signal. */
2308
 
        return max_rssi - agc - IWLAGN_RSSI_OFFSET;
2309
 
}
2310
 
 
2311
 
 
2312
 
/* Set up 4965-specific Rx frame reply handlers */
2313
 
static void iwl4965_rx_handler_setup(struct iwl_priv *priv)
2314
 
{
2315
 
        /* Legacy Rx frames */
2316
 
        priv->rx_handlers[REPLY_RX] = iwlagn_rx_reply_rx;
2317
 
        /* Tx response */
2318
 
        priv->rx_handlers[REPLY_TX] = iwl4965_rx_reply_tx;
2319
 
}
2320
 
 
2321
 
static void iwl4965_setup_deferred_work(struct iwl_priv *priv)
2322
 
{
2323
 
        INIT_WORK(&priv->txpower_work, iwl4965_bg_txpower_work);
2324
 
}
2325
 
 
2326
 
static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
2327
 
{
2328
 
        cancel_work_sync(&priv->txpower_work);
2329
 
}
2330
 
 
2331
 
static struct iwl_hcmd_ops iwl4965_hcmd = {
2332
 
        .rxon_assoc = iwl4965_send_rxon_assoc,
2333
 
        .commit_rxon = iwl4965_commit_rxon,
2334
 
        .set_rxon_chain = iwlagn_set_rxon_chain,
2335
 
        .send_bt_config = iwl_send_bt_config,
2336
 
};
2337
 
 
2338
 
static void iwl4965_post_scan(struct iwl_priv *priv)
2339
 
{
2340
 
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
2341
 
 
2342
 
        /*
2343
 
         * Since setting the RXON may have been deferred while
2344
 
         * performing the scan, fire one off if needed
2345
 
         */
2346
 
        if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
2347
 
                iwlcore_commit_rxon(priv, ctx);
2348
 
}
2349
 
 
2350
 
static void iwl4965_post_associate(struct iwl_priv *priv)
2351
 
{
2352
 
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
2353
 
        struct ieee80211_vif *vif = ctx->vif;
2354
 
        struct ieee80211_conf *conf = NULL;
2355
 
        int ret = 0;
2356
 
 
2357
 
        if (!vif || !priv->is_open)
2358
 
                return;
2359
 
 
2360
 
        if (vif->type == NL80211_IFTYPE_AP) {
2361
 
                IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
2362
 
                return;
2363
 
        }
2364
 
 
2365
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2366
 
                return;
2367
 
 
2368
 
        iwl_scan_cancel_timeout(priv, 200);
2369
 
 
2370
 
        conf = ieee80211_get_hw_conf(priv->hw);
2371
 
 
2372
 
        ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2373
 
        iwlcore_commit_rxon(priv, ctx);
2374
 
 
2375
 
        ret = iwl_send_rxon_timing(priv, ctx);
2376
 
        if (ret)
2377
 
                IWL_WARN(priv, "RXON timing - "
2378
 
                            "Attempting to continue.\n");
2379
 
 
2380
 
        ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
2381
 
 
2382
 
        iwl_set_rxon_ht(priv, &priv->current_ht_config);
2383
 
 
2384
 
        if (priv->cfg->ops->hcmd->set_rxon_chain)
2385
 
                priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
2386
 
 
2387
 
        ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
2388
 
 
2389
 
        IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
2390
 
                        vif->bss_conf.aid, vif->bss_conf.beacon_int);
2391
 
 
2392
 
        if (vif->bss_conf.use_short_preamble)
2393
 
                ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
2394
 
        else
2395
 
                ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
2396
 
 
2397
 
        if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
2398
 
                if (vif->bss_conf.use_short_slot)
2399
 
                        ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
2400
 
                else
2401
 
                        ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
2402
 
        }
2403
 
 
2404
 
        iwlcore_commit_rxon(priv, ctx);
2405
 
 
2406
 
        IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
2407
 
                        vif->bss_conf.aid, ctx->active.bssid_addr);
2408
 
 
2409
 
        switch (vif->type) {
2410
 
        case NL80211_IFTYPE_STATION:
2411
 
                break;
2412
 
        case NL80211_IFTYPE_ADHOC:
2413
 
                iwlagn_send_beacon_cmd(priv);
2414
 
                break;
2415
 
        default:
2416
 
                IWL_ERR(priv, "%s Should not be called in %d mode\n",
2417
 
                          __func__, vif->type);
2418
 
                break;
2419
 
        }
2420
 
 
2421
 
        /* the chain noise calibration will enabled PM upon completion
2422
 
         * If chain noise has already been run, then we need to enable
2423
 
         * power management here */
2424
 
        if (priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE)
2425
 
                iwl_power_update_mode(priv, false);
2426
 
 
2427
 
        /* Enable Rx differential gain and sensitivity calibrations */
2428
 
        iwl_chain_noise_reset(priv);
2429
 
        priv->start_calib = 1;
2430
 
}
2431
 
 
2432
 
static void iwl4965_config_ap(struct iwl_priv *priv)
2433
 
{
2434
 
        struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
2435
 
        struct ieee80211_vif *vif = ctx->vif;
2436
 
        int ret = 0;
2437
 
 
2438
 
        lockdep_assert_held(&priv->mutex);
2439
 
 
2440
 
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2441
 
                return;
2442
 
 
2443
 
        /* The following should be done only at AP bring up */
2444
 
        if (!iwl_is_associated_ctx(ctx)) {
2445
 
 
2446
 
                /* RXON - unassoc (to set timing command) */
2447
 
                ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2448
 
                iwlcore_commit_rxon(priv, ctx);
2449
 
 
2450
 
                /* RXON Timing */
2451
 
                ret = iwl_send_rxon_timing(priv, ctx);
2452
 
                if (ret)
2453
 
                        IWL_WARN(priv, "RXON timing failed - "
2454
 
                                        "Attempting to continue.\n");
2455
 
 
2456
 
                /* AP has all antennas */
2457
 
                priv->chain_noise_data.active_chains =
2458
 
                        priv->hw_params.valid_rx_ant;
2459
 
                iwl_set_rxon_ht(priv, &priv->current_ht_config);
2460
 
                if (priv->cfg->ops->hcmd->set_rxon_chain)
2461
 
                        priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
2462
 
 
2463
 
                ctx->staging.assoc_id = 0;
2464
 
 
2465
 
                if (vif->bss_conf.use_short_preamble)
2466
 
                        ctx->staging.flags |=
2467
 
                                RXON_FLG_SHORT_PREAMBLE_MSK;
2468
 
                else
2469
 
                        ctx->staging.flags &=
2470
 
                                ~RXON_FLG_SHORT_PREAMBLE_MSK;
2471
 
 
2472
 
                if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
2473
 
                        if (vif->bss_conf.use_short_slot)
2474
 
                                ctx->staging.flags |=
2475
 
                                        RXON_FLG_SHORT_SLOT_MSK;
2476
 
                        else
2477
 
                                ctx->staging.flags &=
2478
 
                                        ~RXON_FLG_SHORT_SLOT_MSK;
2479
 
                }
2480
 
                /* need to send beacon cmd before committing assoc RXON! */
2481
 
                iwlagn_send_beacon_cmd(priv);
2482
 
                /* restore RXON assoc */
2483
 
                ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
2484
 
                iwlcore_commit_rxon(priv, ctx);
2485
 
        }
2486
 
        iwlagn_send_beacon_cmd(priv);
2487
 
 
2488
 
        /* FIXME - we need to add code here to detect a totally new
2489
 
         * configuration, reset the AP, unassoc, rxon timing, assoc,
2490
 
         * clear sta table, add BCAST sta... */
2491
 
}
2492
 
 
2493
 
static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
2494
 
        .get_hcmd_size = iwl4965_get_hcmd_size,
2495
 
        .build_addsta_hcmd = iwl4965_build_addsta_hcmd,
2496
 
        .chain_noise_reset = iwl4965_chain_noise_reset,
2497
 
        .gain_computation = iwl4965_gain_computation,
2498
 
        .tx_cmd_protection = iwl_legacy_tx_cmd_protection,
2499
 
        .calc_rssi = iwl4965_calc_rssi,
2500
 
        .request_scan = iwlagn_request_scan,
2501
 
        .post_scan = iwl4965_post_scan,
2502
 
};
2503
 
 
2504
 
static struct iwl_lib_ops iwl4965_lib = {
2505
 
        .set_hw_params = iwl4965_hw_set_hw_params,
2506
 
        .txq_update_byte_cnt_tbl = iwl4965_txq_update_byte_cnt_tbl,
2507
 
        .txq_set_sched = iwl4965_txq_set_sched,
2508
 
        .txq_agg_enable = iwl4965_txq_agg_enable,
2509
 
        .txq_agg_disable = iwl4965_txq_agg_disable,
2510
 
        .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
2511
 
        .txq_free_tfd = iwl_hw_txq_free_tfd,
2512
 
        .txq_init = iwl_hw_tx_queue_init,
2513
 
        .rx_handler_setup = iwl4965_rx_handler_setup,
2514
 
        .setup_deferred_work = iwl4965_setup_deferred_work,
2515
 
        .cancel_deferred_work = iwl4965_cancel_deferred_work,
2516
 
        .is_valid_rtc_data_addr = iwl4965_hw_valid_rtc_data_addr,
2517
 
        .alive_notify = iwl4965_alive_notify,
2518
 
        .init_alive_start = iwl4965_init_alive_start,
2519
 
        .load_ucode = iwl4965_load_bsm,
2520
 
        .dump_nic_event_log = iwl_dump_nic_event_log,
2521
 
        .dump_nic_error_log = iwl_dump_nic_error_log,
2522
 
        .dump_fh = iwl_dump_fh,
2523
 
        .set_channel_switch = iwl4965_hw_channel_switch,
2524
 
        .apm_ops = {
2525
 
                .init = iwl_apm_init,
2526
 
                .config = iwl4965_nic_config,
2527
 
        },
2528
 
        .eeprom_ops = {
2529
 
                .regulatory_bands = {
2530
 
                        EEPROM_REGULATORY_BAND_1_CHANNELS,
2531
 
                        EEPROM_REGULATORY_BAND_2_CHANNELS,
2532
 
                        EEPROM_REGULATORY_BAND_3_CHANNELS,
2533
 
                        EEPROM_REGULATORY_BAND_4_CHANNELS,
2534
 
                        EEPROM_REGULATORY_BAND_5_CHANNELS,
2535
 
                        EEPROM_4965_REGULATORY_BAND_24_HT40_CHANNELS,
2536
 
                        EEPROM_4965_REGULATORY_BAND_52_HT40_CHANNELS
2537
 
                },
2538
 
                .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
2539
 
                .release_semaphore = iwlcore_eeprom_release_semaphore,
2540
 
                .calib_version = iwl4965_eeprom_calib_version,
2541
 
                .query_addr = iwlcore_eeprom_query_addr,
2542
 
        },
2543
 
        .send_tx_power  = iwl4965_send_tx_power,
2544
 
        .update_chain_flags = iwl_update_chain_flags,
2545
 
        .isr_ops = {
2546
 
                .isr = iwl_isr_legacy,
2547
 
        },
2548
 
        .temp_ops = {
2549
 
                .temperature = iwl4965_temperature_calib,
2550
 
        },
2551
 
        .debugfs_ops = {
2552
 
                .rx_stats_read = iwl_ucode_rx_stats_read,
2553
 
                .tx_stats_read = iwl_ucode_tx_stats_read,
2554
 
                .general_stats_read = iwl_ucode_general_stats_read,
2555
 
                .bt_stats_read = iwl_ucode_bt_stats_read,
2556
 
                .reply_tx_error = iwl_reply_tx_error_read,
2557
 
        },
2558
 
        .check_plcp_health = iwl_good_plcp_health,
2559
 
};
2560
 
 
2561
 
static const struct iwl_legacy_ops iwl4965_legacy_ops = {
2562
 
        .post_associate = iwl4965_post_associate,
2563
 
        .config_ap = iwl4965_config_ap,
2564
 
        .manage_ibss_station = iwlagn_manage_ibss_station,
2565
 
        .update_bcast_stations = iwl_update_bcast_stations,
2566
 
};
2567
 
 
2568
 
struct ieee80211_ops iwl4965_hw_ops = {
2569
 
        .tx = iwlagn_mac_tx,
2570
 
        .start = iwlagn_mac_start,
2571
 
        .stop = iwlagn_mac_stop,
2572
 
        .add_interface = iwl_mac_add_interface,
2573
 
        .remove_interface = iwl_mac_remove_interface,
2574
 
        .change_interface = iwl_mac_change_interface,
2575
 
        .config = iwl_legacy_mac_config,
2576
 
        .configure_filter = iwlagn_configure_filter,
2577
 
        .set_key = iwlagn_mac_set_key,
2578
 
        .update_tkip_key = iwlagn_mac_update_tkip_key,
2579
 
        .conf_tx = iwl_mac_conf_tx,
2580
 
        .reset_tsf = iwl_legacy_mac_reset_tsf,
2581
 
        .bss_info_changed = iwl_legacy_mac_bss_info_changed,
2582
 
        .ampdu_action = iwlagn_mac_ampdu_action,
2583
 
        .hw_scan = iwl_mac_hw_scan,
2584
 
        .sta_add = iwlagn_mac_sta_add,
2585
 
        .sta_remove = iwl_mac_sta_remove,
2586
 
        .channel_switch = iwlagn_mac_channel_switch,
2587
 
        .flush = iwlagn_mac_flush,
2588
 
        .tx_last_beacon = iwl_mac_tx_last_beacon,
2589
 
};
2590
 
 
2591
 
static const struct iwl_ops iwl4965_ops = {
2592
 
        .lib = &iwl4965_lib,
2593
 
        .hcmd = &iwl4965_hcmd,
2594
 
        .utils = &iwl4965_hcmd_utils,
2595
 
        .led = &iwlagn_led_ops,
2596
 
        .legacy = &iwl4965_legacy_ops,
2597
 
        .ieee80211_ops = &iwl4965_hw_ops,
2598
 
};
2599
 
 
2600
 
static struct iwl_base_params iwl4965_base_params = {
2601
 
        .eeprom_size = IWL4965_EEPROM_IMG_SIZE,
2602
 
        .num_of_queues = IWL49_NUM_QUEUES,
2603
 
        .num_of_ampdu_queues = IWL49_NUM_AMPDU_QUEUES,
2604
 
        .pll_cfg_val = 0,
2605
 
        .set_l0s = true,
2606
 
        .use_bsm = true,
2607
 
        .use_isr_legacy = true,
2608
 
        .broken_powersave = true,
2609
 
        .led_compensation = 61,
2610
 
        .chain_noise_num_beacons = IWL4965_CAL_NUM_BEACONS,
2611
 
        .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
2612
 
        .wd_timeout = IWL_DEF_WD_TIMEOUT,
2613
 
        .temperature_kelvin = true,
2614
 
        .max_event_log_size = 512,
2615
 
        .tx_power_by_driver = true,
2616
 
        .ucode_tracing = true,
2617
 
        .sensitivity_calib_by_driver = true,
2618
 
        .chain_noise_calib_by_driver = true,
2619
 
        .no_agg_framecnt_info = true,
2620
 
};
2621
 
 
2622
 
struct iwl_cfg iwl4965_agn_cfg = {
2623
 
        .name = "Intel(R) Wireless WiFi Link 4965AGN",
2624
 
        .fw_name_pre = IWL4965_FW_PRE,
2625
 
        .ucode_api_max = IWL4965_UCODE_API_MAX,
2626
 
        .ucode_api_min = IWL4965_UCODE_API_MIN,
2627
 
        .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
2628
 
        .valid_tx_ant = ANT_AB,
2629
 
        .valid_rx_ant = ANT_ABC,
2630
 
        .eeprom_ver = EEPROM_4965_EEPROM_VERSION,
2631
 
        .eeprom_calib_ver = EEPROM_4965_TX_POWER_VERSION,
2632
 
        .ops = &iwl4965_ops,
2633
 
        .mod_params = &iwlagn_mod_params,
2634
 
        .base_params = &iwl4965_base_params,
2635
 
        .led_mode = IWL_LED_BLINK,
2636
 
        /*
2637
 
         * Force use of chains B and C for scan RX on 5 GHz band
2638
 
         * because the device has off-channel reception on chain A.
2639
 
         */
2640
 
        .scan_rx_antennas[IEEE80211_BAND_5GHZ] = ANT_BC,
2641
 
};
2642
 
 
2643
 
/* Module firmware */
2644
 
MODULE_FIRMWARE(IWL4965_MODULE_FIRMWARE(IWL4965_UCODE_API_MAX));
2645