~ubuntu-branches/ubuntu/hardy/linux-backports-modules-2.6.24/hardy-security

« back to all changes in this revision

Viewing changes to updates/wireless/iwlwifi/iwlwifi/origin/iwl-3945.c

  • Committer: Bazaar Package Importer
  • Author(s): , Ben Collins
  • Date: 2008-04-02 06:59:04 UTC
  • Revision ID: james.westby@ubuntu.com-20080402065904-e5knh2gn2hms3xbb
Tags: 2.6.24-14.11
[Ben Collins]

* iwlwifi: Update to iwlwifi-1.2.25 and mac80211-10.0.4
  - LP: #200950
* ubuntu: Slight cleanups to module hiearchy and Makefiles
* mac80211: Enable LED triggers
* iwlwifi: Add LED trigger support (rx and tx only)
  - LP: #176090

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************************************
 
2
 *
 
3
 * Copyright(c) 2003 - 2007 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
 * James P. Ketrenos <ipw2100-admin@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/version.h>
 
30
#include <linux/init.h>
 
31
#include <linux/pci.h>
 
32
#include <linux/dma-mapping.h>
 
33
#include <linux/delay.h>
 
34
#include <linux/skbuff.h>
 
35
#include <linux/netdevice.h>
 
36
#include <linux/wireless.h>
 
37
#include <linux/firmware.h>
 
38
#include <net/mac80211.h>
 
39
 
 
40
#include <linux/etherdevice.h>
 
41
#include <linux/delay.h>
 
42
 
 
43
#include "iwl-3945.h"
 
44
#include "iwl-helpers.h"
 
45
#include "iwl-3945-rs.h"
 
46
 
 
47
#define IWL_DECLARE_RATE_INFO(r, ip, in, rp, rn, pp, np)    \
 
48
        [IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP,   \
 
49
                                    IWL_RATE_##r##M_IEEE,   \
 
50
                                    IWL_RATE_##ip##M_INDEX, \
 
51
                                    IWL_RATE_##in##M_INDEX, \
 
52
                                    IWL_RATE_##rp##M_INDEX, \
 
53
                                    IWL_RATE_##rn##M_INDEX, \
 
54
                                    IWL_RATE_##pp##M_INDEX, \
 
55
                                    IWL_RATE_##np##M_INDEX, \
 
56
                                    IWL_RATE_##r##M_INDEX_TABLE, \
 
57
                                    IWL_RATE_##ip##M_INDEX_TABLE }
 
58
 
 
59
/*
 
60
 * Parameter order:
 
61
 *   rate, prev rate, next rate, prev tgg rate, next tgg rate
 
62
 *
 
63
 * If there isn't a valid next or previous rate then INV is used which
 
64
 * maps to IWL_RATE_INVALID
 
65
 *
 
66
 */
 
67
const struct iwl3945_rate_info iwl3945_rates[IWL_RATE_COUNT] = {
 
68
        IWL_DECLARE_RATE_INFO(1, INV, 2, INV, 2, INV, 2),    /*  1mbps */
 
69
        IWL_DECLARE_RATE_INFO(2, 1, 5, 1, 5, 1, 5),          /*  2mbps */
 
70
        IWL_DECLARE_RATE_INFO(5, 2, 6, 2, 11, 2, 11),        /*5.5mbps */
 
71
        IWL_DECLARE_RATE_INFO(11, 9, 12, 5, 12, 5, 18),      /* 11mbps */
 
72
        IWL_DECLARE_RATE_INFO(6, 5, 9, 5, 11, 5, 11),        /*  6mbps */
 
73
        IWL_DECLARE_RATE_INFO(9, 6, 11, 5, 11, 5, 11),       /*  9mbps */
 
74
        IWL_DECLARE_RATE_INFO(12, 11, 18, 11, 18, 11, 18),   /* 12mbps */
 
75
        IWL_DECLARE_RATE_INFO(18, 12, 24, 12, 24, 11, 24),   /* 18mbps */
 
76
        IWL_DECLARE_RATE_INFO(24, 18, 36, 18, 36, 18, 36),   /* 24mbps */
 
77
        IWL_DECLARE_RATE_INFO(36, 24, 48, 24, 48, 24, 48),   /* 36mbps */
 
78
        IWL_DECLARE_RATE_INFO(48, 36, 54, 36, 54, 36, 54),   /* 48mbps */
 
79
        IWL_DECLARE_RATE_INFO(54, 48, INV, 48, INV, 48, INV),/* 54mbps */
 
80
};
 
81
 
 
82
/* 1 = enable the iwl3945_disable_events() function */
 
83
#define IWL_EVT_DISABLE (0)
 
84
#define IWL_EVT_DISABLE_SIZE (1532/32)
 
85
 
 
86
/**
 
87
 * iwl3945_disable_events - Disable selected events in uCode event log
 
88
 *
 
89
 * Disable an event by writing "1"s into "disable"
 
90
 *   bitmap in SRAM.  Bit position corresponds to Event # (id/type).
 
91
 *   Default values of 0 enable uCode events to be logged.
 
92
 * Use for only special debugging.  This function is just a placeholder as-is,
 
93
 *   you'll need to provide the special bits! ...
 
94
 *   ... and set IWL_EVT_DISABLE to 1. */
 
95
void iwl3945_disable_events(struct iwl3945_priv *priv)
 
96
{
 
97
        int ret;
 
98
        int i;
 
99
        u32 base;               /* SRAM address of event log header */
 
100
        u32 disable_ptr;        /* SRAM address of event-disable bitmap array */
 
101
        u32 array_size;         /* # of u32 entries in array */
 
102
        u32 evt_disable[IWL_EVT_DISABLE_SIZE] = {
 
103
                0x00000000,     /*   31 -    0  Event id numbers */
 
104
                0x00000000,     /*   63 -   32 */
 
105
                0x00000000,     /*   95 -   64 */
 
106
                0x00000000,     /*  127 -   96 */
 
107
                0x00000000,     /*  159 -  128 */
 
108
                0x00000000,     /*  191 -  160 */
 
109
                0x00000000,     /*  223 -  192 */
 
110
                0x00000000,     /*  255 -  224 */
 
111
                0x00000000,     /*  287 -  256 */
 
112
                0x00000000,     /*  319 -  288 */
 
113
                0x00000000,     /*  351 -  320 */
 
114
                0x00000000,     /*  383 -  352 */
 
115
                0x00000000,     /*  415 -  384 */
 
116
                0x00000000,     /*  447 -  416 */
 
117
                0x00000000,     /*  479 -  448 */
 
118
                0x00000000,     /*  511 -  480 */
 
119
                0x00000000,     /*  543 -  512 */
 
120
                0x00000000,     /*  575 -  544 */
 
121
                0x00000000,     /*  607 -  576 */
 
122
                0x00000000,     /*  639 -  608 */
 
123
                0x00000000,     /*  671 -  640 */
 
124
                0x00000000,     /*  703 -  672 */
 
125
                0x00000000,     /*  735 -  704 */
 
126
                0x00000000,     /*  767 -  736 */
 
127
                0x00000000,     /*  799 -  768 */
 
128
                0x00000000,     /*  831 -  800 */
 
129
                0x00000000,     /*  863 -  832 */
 
130
                0x00000000,     /*  895 -  864 */
 
131
                0x00000000,     /*  927 -  896 */
 
132
                0x00000000,     /*  959 -  928 */
 
133
                0x00000000,     /*  991 -  960 */
 
134
                0x00000000,     /* 1023 -  992 */
 
135
                0x00000000,     /* 1055 - 1024 */
 
136
                0x00000000,     /* 1087 - 1056 */
 
137
                0x00000000,     /* 1119 - 1088 */
 
138
                0x00000000,     /* 1151 - 1120 */
 
139
                0x00000000,     /* 1183 - 1152 */
 
140
                0x00000000,     /* 1215 - 1184 */
 
141
                0x00000000,     /* 1247 - 1216 */
 
142
                0x00000000,     /* 1279 - 1248 */
 
143
                0x00000000,     /* 1311 - 1280 */
 
144
                0x00000000,     /* 1343 - 1312 */
 
145
                0x00000000,     /* 1375 - 1344 */
 
146
                0x00000000,     /* 1407 - 1376 */
 
147
                0x00000000,     /* 1439 - 1408 */
 
148
                0x00000000,     /* 1471 - 1440 */
 
149
                0x00000000,     /* 1503 - 1472 */
 
150
        };
 
151
 
 
152
        base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
 
153
        if (!iwl3945_hw_valid_rtc_data_addr(base)) {
 
154
                IWL_ERROR("Invalid event log pointer 0x%08X\n", base);
 
155
                return;
 
156
        }
 
157
 
 
158
        ret = iwl3945_grab_nic_access(priv);
 
159
        if (ret) {
 
160
                IWL_WARNING("Can not read from adapter at this time.\n");
 
161
                return;
 
162
        }
 
163
 
 
164
        disable_ptr = iwl3945_read_targ_mem(priv, base + (4 * sizeof(u32)));
 
165
        array_size = iwl3945_read_targ_mem(priv, base + (5 * sizeof(u32)));
 
166
        iwl3945_release_nic_access(priv);
 
167
 
 
168
        if (IWL_EVT_DISABLE && (array_size == IWL_EVT_DISABLE_SIZE)) {
 
169
                IWL_DEBUG_INFO("Disabling selected uCode log events at 0x%x\n",
 
170
                               disable_ptr);
 
171
                ret = iwl3945_grab_nic_access(priv);
 
172
                for (i = 0; i < IWL_EVT_DISABLE_SIZE; i++)
 
173
                        iwl3945_write_targ_mem(priv,
 
174
                                           disable_ptr + (i * sizeof(u32)),
 
175
                                           evt_disable[i]);
 
176
 
 
177
                iwl3945_release_nic_access(priv);
 
178
        } else {
 
179
                IWL_DEBUG_INFO("Selected uCode log events may be disabled\n");
 
180
                IWL_DEBUG_INFO("  by writing \"1\"s into disable bitmap\n");
 
181
                IWL_DEBUG_INFO("  in SRAM at 0x%x, size %d u32s\n",
 
182
                               disable_ptr, array_size);
 
183
        }
 
184
 
 
185
}
 
186
 
 
187
/**
 
188
 * iwl3945_get_antenna_flags - Get antenna flags for RXON command
 
189
 * @priv: eeprom and antenna fields are used to determine antenna flags
 
190
 *
 
191
 * priv->eeprom  is used to determine if antenna AUX/MAIN are reversed
 
192
 * priv->antenna specifies the antenna diversity mode:
 
193
 *
 
194
 * IWL_ANTENNA_DIVERISTY - NIC selects best antenna by itself
 
195
 * IWL_ANTENNA_MAIN      - Force MAIN antenna
 
196
 * IWL_ANTENNA_AUX       - Force AUX antenna
 
197
 */
 
198
__le32 iwl3945_get_antenna_flags(const struct iwl3945_priv *priv)
 
199
{
 
200
        switch (priv->antenna) {
 
201
        case IWL_ANTENNA_DIVERSITY:
 
202
                return 0;
 
203
 
 
204
        case IWL_ANTENNA_MAIN:
 
205
                if (priv->eeprom.antenna_switch_type)
 
206
                        return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
 
207
                return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;
 
208
 
 
209
        case IWL_ANTENNA_AUX:
 
210
                if (priv->eeprom.antenna_switch_type)
 
211
                        return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;
 
212
                return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
 
213
        }
 
214
 
 
215
        /* bad antenna selector value */
 
216
        IWL_ERROR("Bad antenna selector value (0x%x)\n", priv->antenna);
 
217
        return 0;               /* "diversity" is default if error */
 
218
}
 
219
 
 
220
/*****************************************************************************
 
221
 *
 
222
 * Intel PRO/Wireless 3945ABG/BG Network Connection
 
223
 *
 
224
 *  RX handler implementations
 
225
 *
 
226
 *  Used by iwl-base.c
 
227
 *
 
228
 *****************************************************************************/
 
229
 
 
230
void iwl3945_hw_rx_statistics(struct iwl3945_priv *priv, struct iwl3945_rx_mem_buffer *rxb)
 
231
{
 
232
        struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
 
233
        IWL_DEBUG_RX("Statistics notification received (%d vs %d).\n",
 
234
                     (int)sizeof(struct iwl3945_notif_statistics),
 
235
                     le32_to_cpu(pkt->len));
 
236
 
 
237
        memcpy(&priv->statistics, pkt->u.raw, sizeof(priv->statistics));
 
238
 
 
239
        priv->last_statistics_time = jiffies;
 
240
}
 
241
 
 
242
static void iwl3945_handle_data_packet(struct iwl3945_priv *priv, int is_data,
 
243
                                   struct iwl3945_rx_mem_buffer *rxb,
 
244
                                   struct ieee80211_rx_status *stats,
 
245
                                   u16 phy_flags)
 
246
{
 
247
        struct ieee80211_hdr *hdr;
 
248
        struct iwl3945_rx_packet *pkt = (struct iwl3945_rx_packet *)rxb->skb->data;
 
249
        struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
 
250
        struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
 
251
        short len = le16_to_cpu(rx_hdr->len);
 
252
 
 
253
        /* We received data from the HW, so stop the watchdog */
 
254
        if (unlikely((len + IWL_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) {
 
255
                IWL_DEBUG_DROP("Corruption detected!\n");
 
256
                return;
 
257
        }
 
258
 
 
259
        /* We only process data packets if the interface is open */
 
260
        if (unlikely(!priv->is_open)) {
 
261
                IWL_DEBUG_DROP_LIMIT
 
262
                    ("Dropping packet while interface is not open.\n");
 
263
                return;
 
264
        }
 
265
        if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
 
266
                if (iwl3945_param_hwcrypto)
 
267
                        iwl3945_set_decrypted_flag(priv, rxb->skb,
 
268
                                               le32_to_cpu(rx_end->status),
 
269
                                               stats);
 
270
                iwl3945_handle_data_packet_monitor(priv, rxb, IWL_RX_DATA(pkt),
 
271
                                               len, stats, phy_flags);
 
272
                return;
 
273
        }
 
274
 
 
275
        skb_reserve(rxb->skb, (void *)rx_hdr->payload - (void *)pkt);
 
276
        /* Set the size of the skb to the size of the frame */
 
277
        skb_put(rxb->skb, le16_to_cpu(rx_hdr->len));
 
278
 
 
279
        hdr = (void *)rxb->skb->data;
 
280
 
 
281
        if (iwl3945_param_hwcrypto)
 
282
                iwl3945_set_decrypted_flag(priv, rxb->skb,
 
283
                                       le32_to_cpu(rx_end->status), stats);
 
284
 
 
285
        iwlwifi_ieee80211_rx_irqsafe(priv->hw, rxb->skb, stats);
 
286
        rxb->skb = NULL;
 
287
}
 
288
 
 
289
#define IWL_DELAY_NEXT_SCAN_AFTER_ASSOC (HZ*6)
 
290
 
 
291
static void iwl3945_rx_reply_rx(struct iwl3945_priv *priv,
 
292
                                struct iwl3945_rx_mem_buffer *rxb)
 
293
{
 
294
        struct iwl3945_rx_packet *pkt = (void *)rxb->skb->data;
 
295
        struct iwl3945_rx_frame_stats *rx_stats = IWL_RX_STATS(pkt);
 
296
        struct iwl3945_rx_frame_hdr *rx_hdr = IWL_RX_HDR(pkt);
 
297
        struct iwl3945_rx_frame_end *rx_end = IWL_RX_END(pkt);
 
298
        struct ieee80211_hdr *header;
 
299
        u16 phy_flags = le16_to_cpu(rx_hdr->phy_flags);
 
300
        u16 rx_stats_sig_avg = le16_to_cpu(rx_stats->sig_avg);
 
301
        u16 rx_stats_noise_diff = le16_to_cpu(rx_stats->noise_diff);
 
302
        struct ieee80211_rx_status stats = {
 
303
                .mactime = le64_to_cpu(rx_end->timestamp),
 
304
                .freq = ieee80211chan2mhz(le16_to_cpu(rx_hdr->channel)),
 
305
                .channel = le16_to_cpu(rx_hdr->channel),
 
306
                .phymode = (rx_hdr->phy_flags & RX_RES_PHY_FLAGS_BAND_24_MSK) ?
 
307
                MODE_IEEE80211G : MODE_IEEE80211A,
 
308
                .antenna = 0,
 
309
                .rate = rx_hdr->rate,
 
310
                .flag = 0,
 
311
        };
 
312
        u8 network_packet;
 
313
        int snr;
 
314
 
 
315
        if ((unlikely(rx_stats->phy_count > 20))) {
 
316
                IWL_DEBUG_DROP
 
317
                    ("dsp size out of range [0,20]: "
 
318
                     "%d/n", rx_stats->phy_count);
 
319
                return;
 
320
        }
 
321
 
 
322
        if (!(rx_end->status & RX_RES_STATUS_NO_CRC32_ERROR)
 
323
            || !(rx_end->status & RX_RES_STATUS_NO_RXE_OVERFLOW)) {
 
324
                IWL_DEBUG_RX("Bad CRC or FIFO: 0x%08X.\n", rx_end->status);
 
325
                return;
 
326
        }
 
327
 
 
328
        if (priv->iw_mode == IEEE80211_IF_TYPE_MNTR) {
 
329
                iwl3945_handle_data_packet(priv, 1, rxb, &stats, phy_flags);
 
330
                return;
 
331
        }
 
332
 
 
333
        /* Convert 3945's rssi indicator to dBm */
 
334
        stats.ssi = rx_stats->rssi - IWL_RSSI_OFFSET;
 
335
 
 
336
        /* Set default noise value to -127 */
 
337
        if (priv->last_rx_noise == 0)
 
338
                priv->last_rx_noise = IWL_NOISE_MEAS_NOT_AVAILABLE;
 
339
 
 
340
        /* 3945 provides noise info for OFDM frames only.
 
341
         * sig_avg and noise_diff are measured by the 3945's digital signal
 
342
         *   processor (DSP), and indicate linear levels of signal level and
 
343
         *   distortion/noise within the packet preamble after
 
344
         *   automatic gain control (AGC).  sig_avg should stay fairly
 
345
         *   constant if the radio's AGC is working well.
 
346
         * Since these values are linear (not dB or dBm), linear
 
347
         *   signal-to-noise ratio (SNR) is (sig_avg / noise_diff).
 
348
         * Convert linear SNR to dB SNR, then subtract that from rssi dBm
 
349
         *   to obtain noise level in dBm.
 
350
         * Calculate stats.signal (quality indicator in %) based on SNR. */
 
351
        if (rx_stats_noise_diff) {
 
352
                snr = rx_stats_sig_avg / rx_stats_noise_diff;
 
353
                stats.noise = stats.ssi - iwl3945_calc_db_from_ratio(snr);
 
354
                stats.signal = iwl3945_calc_sig_qual(stats.ssi, stats.noise);
 
355
 
 
356
        /* If noise info not available, calculate signal quality indicator (%)
 
357
         *   using just the dBm signal level. */
 
358
        } else {
 
359
                stats.noise = priv->last_rx_noise;
 
360
                stats.signal = iwl3945_calc_sig_qual(stats.ssi, 0);
 
361
        }
 
362
 
 
363
 
 
364
        IWL_DEBUG_STATS("Rssi %d noise %d qual %d sig_avg %d noise_diff %d\n",
 
365
                        stats.ssi, stats.noise, stats.signal,
 
366
                        rx_stats_sig_avg, rx_stats_noise_diff);
 
367
 
 
368
        stats.freq = ieee80211chan2mhz(stats.channel);
 
369
 
 
370
        /* can be covered by iwl3945_report_frame() in most cases */
 
371
/*      IWL_DEBUG_RX("RX status: 0x%08X\n", rx_end->status); */
 
372
 
 
373
        header = (struct ieee80211_hdr *)IWL_RX_DATA(pkt);
 
374
 
 
375
        network_packet = iwl3945_is_network_packet(priv, header);
 
376
 
 
377
#ifdef CONFIG_IWL3945_DEBUG
 
378
        if (iwl3945_debug_level & IWL_DL_STATS && net_ratelimit())
 
379
                IWL_DEBUG_STATS
 
380
                    ("[%c] %d RSSI: %d Signal: %u, Noise: %u, Rate: %u\n",
 
381
                     network_packet ? '*' : ' ',
 
382
                     stats.channel, stats.ssi, stats.ssi,
 
383
                     stats.ssi, stats.rate);
 
384
 
 
385
        if (iwl3945_debug_level & (IWL_DL_RX))
 
386
                /* Set "1" to report good data frames in groups of 100 */
 
387
                iwl3945_report_frame(priv, pkt, header, 1);
 
388
#endif
 
389
 
 
390
        if (network_packet) {
 
391
                priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp);
 
392
                priv->last_tsf = le64_to_cpu(rx_end->timestamp);
 
393
                priv->last_rx_rssi = stats.ssi;
 
394
                priv->last_rx_noise = stats.noise;
 
395
        }
 
396
 
 
397
        switch (le16_to_cpu(header->frame_control) & IEEE80211_FCTL_FTYPE) {
 
398
        case IEEE80211_FTYPE_MGMT:
 
399
                switch (le16_to_cpu(header->frame_control) &
 
400
                        IEEE80211_FCTL_STYPE) {
 
401
                case IEEE80211_STYPE_PROBE_RESP:
 
402
                case IEEE80211_STYPE_BEACON:{
 
403
                                /* If this is a beacon or probe response for
 
404
                                 * our network then cache the beacon
 
405
                                 * timestamp */
 
406
                                if ((((priv->iw_mode == IEEE80211_IF_TYPE_STA)
 
407
                                      && !compare_ether_addr(header->addr2,
 
408
                                                             priv->bssid)) ||
 
409
                                     ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
 
410
                                      && !compare_ether_addr(header->addr3,
 
411
                                                             priv->bssid)))) {
 
412
                                        struct ieee80211_mgmt *mgmt =
 
413
                                            (struct ieee80211_mgmt *)header;
 
414
                                        __le32 *pos;
 
415
                                        pos =
 
416
                                            (__le32 *) & mgmt->u.beacon.
 
417
                                            timestamp;
 
418
                                        priv->timestamp0 = le32_to_cpu(pos[0]);
 
419
                                        priv->timestamp1 = le32_to_cpu(pos[1]);
 
420
                                        priv->beacon_int = le16_to_cpu(
 
421
                                            mgmt->u.beacon.beacon_int);
 
422
                                        if (priv->call_post_assoc_from_beacon &&
 
423
                                            (priv->iw_mode ==
 
424
                                                IEEE80211_IF_TYPE_STA))
 
425
                                                queue_work(priv->workqueue,
 
426
                                                    &priv->post_associate.work);
 
427
 
 
428
                                        priv->call_post_assoc_from_beacon = 0;
 
429
                                }
 
430
 
 
431
                                break;
 
432
                        }
 
433
 
 
434
                case IEEE80211_STYPE_ACTION:
 
435
                        /* TODO: Parse 802.11h frames for CSA... */
 
436
                        break;
 
437
 
 
438
                        /*
 
439
                         * TODO: There is no callback function from upper
 
440
                         * stack to inform us when associated status. this
 
441
                         * work around to sniff assoc_resp management frame
 
442
                         * and finish the association process.
 
443
                         */
 
444
                case IEEE80211_STYPE_ASSOC_RESP:
 
445
                case IEEE80211_STYPE_REASSOC_RESP:{
 
446
                                struct ieee80211_mgmt *mgnt =
 
447
                                    (struct ieee80211_mgmt *)header;
 
448
 
 
449
                                /* We have just associated, give some
 
450
                                 * time for the 4-way handshake if
 
451
                                 * any. Don't start scan too early. */
 
452
                                priv->next_scan_jiffies = jiffies +
 
453
                                        IWL_DELAY_NEXT_SCAN_AFTER_ASSOC;
 
454
 
 
455
                                priv->assoc_id = (~((1 << 15) | (1 << 14)) &
 
456
                                                  le16_to_cpu(mgnt->u.
 
457
                                                              assoc_resp.aid));
 
458
                                priv->assoc_capability =
 
459
                                    le16_to_cpu(mgnt->u.assoc_resp.capab_info);
 
460
                                if (priv->beacon_int)
 
461
                                        queue_work(priv->workqueue,
 
462
                                            &priv->post_associate.work);
 
463
                                else
 
464
                                        priv->call_post_assoc_from_beacon = 1;
 
465
                                break;
 
466
                        }
 
467
 
 
468
                case IEEE80211_STYPE_PROBE_REQ:{
 
469
                                if (priv->iw_mode == IEEE80211_IF_TYPE_IBSS)
 
470
                                        IWL_DEBUG_DROP
 
471
                                            ("Dropping (non network): " MAC_FMT
 
472
                                             ", " MAC_FMT ", " MAC_FMT "\n",
 
473
                                             MAC_ARG(header->addr1),
 
474
                                             MAC_ARG(header->addr2),
 
475
                                             MAC_ARG(header->addr3));
 
476
                                return;
 
477
                        }
 
478
                }
 
479
 
 
480
                iwl3945_handle_data_packet(priv, 0, rxb, &stats, phy_flags);
 
481
                break;
 
482
 
 
483
        case IEEE80211_FTYPE_CTL:
 
484
                break;
 
485
 
 
486
        case IEEE80211_FTYPE_DATA:
 
487
                if (unlikely(iwl3945_is_duplicate_packet(priv, header)))
 
488
                        IWL_DEBUG_DROP("Dropping (dup): " MAC_FMT ", "
 
489
                                       MAC_FMT ", " MAC_FMT "\n",
 
490
                                       MAC_ARG(header->addr1),
 
491
                                       MAC_ARG(header->addr2),
 
492
                                       MAC_ARG(header->addr3));
 
493
                else
 
494
                        iwl3945_handle_data_packet(priv, 1, rxb, &stats,
 
495
                                                   phy_flags);
 
496
                break;
 
497
        }
 
498
}
 
499
 
 
500
int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl3945_priv *priv, void *ptr,
 
501
                                 dma_addr_t addr, u16 len)
 
502
{
 
503
        int count;
 
504
        u32 pad;
 
505
        struct iwl3945_tfd_frame *tfd = (struct iwl3945_tfd_frame *)ptr;
 
506
 
 
507
        count = TFD_CTL_COUNT_GET(le32_to_cpu(tfd->control_flags));
 
508
        pad = TFD_CTL_PAD_GET(le32_to_cpu(tfd->control_flags));
 
509
 
 
510
        if ((count >= NUM_TFD_CHUNKS) || (count < 0)) {
 
511
                IWL_ERROR("Error can not send more than %d chunks\n",
 
512
                          NUM_TFD_CHUNKS);
 
513
                return -EINVAL;
 
514
        }
 
515
 
 
516
        tfd->pa[count].addr = cpu_to_le32(addr);
 
517
        tfd->pa[count].len = cpu_to_le32(len);
 
518
 
 
519
        count++;
 
520
 
 
521
        tfd->control_flags = cpu_to_le32(TFD_CTL_COUNT_SET(count) |
 
522
                                         TFD_CTL_PAD_SET(pad));
 
523
 
 
524
        return 0;
 
525
}
 
526
 
 
527
/**
 
528
 * iwl3945_hw_txq_free_tfd - Free one TFD, those at index [txq->q.read_ptr]
 
529
 *
 
530
 * Does NOT advance any indexes
 
531
 */
 
532
int iwl3945_hw_txq_free_tfd(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq)
 
533
{
 
534
        struct iwl3945_tfd_frame *bd_tmp = (struct iwl3945_tfd_frame *)&txq->bd[0];
 
535
        struct iwl3945_tfd_frame *bd = &bd_tmp[txq->q.read_ptr];
 
536
        struct pci_dev *dev = priv->pci_dev;
 
537
        int i;
 
538
        int counter;
 
539
 
 
540
        /* classify bd */
 
541
        if (txq->q.id == IWL_CMD_QUEUE_NUM)
 
542
                /* nothing to cleanup after for host commands */
 
543
                return 0;
 
544
 
 
545
        /* sanity check */
 
546
        counter = TFD_CTL_COUNT_GET(le32_to_cpu(bd->control_flags));
 
547
        if (counter > NUM_TFD_CHUNKS) {
 
548
                IWL_ERROR("Too many chunks: %i\n", counter);
 
549
                /* @todo issue fatal error, it is quite serious situation */
 
550
                return 0;
 
551
        }
 
552
 
 
553
        /* unmap chunks if any */
 
554
 
 
555
        for (i = 1; i < counter; i++) {
 
556
                pci_unmap_single(dev, le32_to_cpu(bd->pa[i].addr),
 
557
                                 le32_to_cpu(bd->pa[i].len), PCI_DMA_TODEVICE);
 
558
                if (txq->txb[txq->q.read_ptr].skb[0]) {
 
559
                        struct sk_buff *skb = txq->txb[txq->q.read_ptr].skb[0];
 
560
                        if (txq->txb[txq->q.read_ptr].skb[0]) {
 
561
                                /* Can be called from interrupt context */
 
562
                                dev_kfree_skb_any(skb);
 
563
                                txq->txb[txq->q.read_ptr].skb[0] = NULL;
 
564
                        }
 
565
                }
 
566
        }
 
567
        return 0;
 
568
}
 
569
 
 
570
u8 iwl3945_hw_find_station(struct iwl3945_priv *priv, const u8 *addr)
 
571
{
 
572
        int i;
 
573
        int ret = IWL_INVALID_STATION;
 
574
        unsigned long flags;
 
575
 
 
576
        spin_lock_irqsave(&priv->sta_lock, flags);
 
577
        for (i = IWL_STA_ID; i < priv->hw_setting.max_stations; i++)
 
578
                if ((priv->stations[i].used) &&
 
579
                    (!compare_ether_addr
 
580
                     (priv->stations[i].sta.sta.addr, addr))) {
 
581
                        ret = i;
 
582
                        goto out;
 
583
                }
 
584
 
 
585
        IWL_DEBUG_INFO("can not find STA " MAC_FMT " (total %d)\n",
 
586
                       MAC_ARG(addr), priv->num_stations);
 
587
 out:
 
588
        spin_unlock_irqrestore(&priv->sta_lock, flags);
 
589
        return ret;
 
590
}
 
591
 
 
592
/**
 
593
 * iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD:
 
594
 *
 
595
*/
 
596
void iwl3945_hw_build_tx_cmd_rate(struct iwl3945_priv *priv,
 
597
                              struct iwl3945_cmd *cmd,
 
598
                              struct ieee80211_tx_control *ctrl,
 
599
                              struct ieee80211_hdr *hdr, int sta_id, int tx_id)
 
600
{
 
601
        unsigned long flags;
 
602
        u16 rate_index = min(ctrl->tx_rate & 0xffff, IWL_RATE_COUNT - 1);
 
603
        u16 rate_mask;
 
604
        int rate;
 
605
        u8 rts_retry_limit;
 
606
        u8 data_retry_limit;
 
607
        __le32 tx_flags;
 
608
        u16 fc = le16_to_cpu(hdr->frame_control);
 
609
 
 
610
        rate = iwl3945_rates[rate_index].plcp;
 
611
        tx_flags = cmd->cmd.tx.tx_flags;
 
612
 
 
613
        /* We need to figure out how to get the sta->supp_rates while
 
614
         * in this running context; perhaps encoding into ctrl->tx_rate? */
 
615
        rate_mask = IWL_RATES_MASK;
 
616
 
 
617
        spin_lock_irqsave(&priv->sta_lock, flags);
 
618
 
 
619
        priv->stations[sta_id].current_rate.rate_n_flags = rate;
 
620
 
 
621
        if ((priv->iw_mode == IEEE80211_IF_TYPE_IBSS) &&
 
622
            (sta_id != IWL3945_BROADCAST_ID) &&
 
623
                (sta_id != IWL_MULTICAST_ID))
 
624
                priv->stations[IWL_STA_ID].current_rate.rate_n_flags = rate;
 
625
 
 
626
        spin_unlock_irqrestore(&priv->sta_lock, flags);
 
627
 
 
628
        if (tx_id >= IWL_CMD_QUEUE_NUM)
 
629
                rts_retry_limit = 3;
 
630
        else
 
631
                rts_retry_limit = 7;
 
632
 
 
633
        if (ieee80211_is_probe_response(fc)) {
 
634
                data_retry_limit = 3;
 
635
                if (data_retry_limit < rts_retry_limit)
 
636
                        rts_retry_limit = data_retry_limit;
 
637
        } else
 
638
                data_retry_limit = IWL_DEFAULT_TX_RETRY;
 
639
 
 
640
        if (priv->data_retry_limit != -1)
 
641
                data_retry_limit = priv->data_retry_limit;
 
642
 
 
643
        if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) {
 
644
                switch (fc & IEEE80211_FCTL_STYPE) {
 
645
                case IEEE80211_STYPE_AUTH:
 
646
                case IEEE80211_STYPE_DEAUTH:
 
647
                case IEEE80211_STYPE_ASSOC_REQ:
 
648
                case IEEE80211_STYPE_REASSOC_REQ:
 
649
                        if (tx_flags & TX_CMD_FLG_RTS_MSK) {
 
650
                                tx_flags &= ~TX_CMD_FLG_RTS_MSK;
 
651
                                tx_flags |= TX_CMD_FLG_CTS_MSK;
 
652
                        }
 
653
                        break;
 
654
                default:
 
655
                        break;
 
656
                }
 
657
        }
 
658
 
 
659
        cmd->cmd.tx.rts_retry_limit = rts_retry_limit;
 
660
        cmd->cmd.tx.data_retry_limit = data_retry_limit;
 
661
        cmd->cmd.tx.rate = rate;
 
662
        cmd->cmd.tx.tx_flags = tx_flags;
 
663
 
 
664
        /* OFDM */
 
665
        cmd->cmd.tx.supp_rates[0] =
 
666
           ((rate_mask & IWL_OFDM_RATES_MASK) >> IWL_FIRST_OFDM_RATE) & 0xFF;
 
667
 
 
668
        /* CCK */
 
669
        cmd->cmd.tx.supp_rates[1] = (rate_mask & 0xF);
 
670
 
 
671
        IWL_DEBUG_RATE("Tx sta id: %d, rate: %d (plcp), flags: 0x%4X "
 
672
                       "cck/ofdm mask: 0x%x/0x%x\n", sta_id,
 
673
                       cmd->cmd.tx.rate, le32_to_cpu(cmd->cmd.tx.tx_flags),
 
674
                       cmd->cmd.tx.supp_rates[1], cmd->cmd.tx.supp_rates[0]);
 
675
}
 
676
 
 
677
u8 iwl3945_sync_sta(struct iwl3945_priv *priv, int sta_id, u16 tx_rate, u8 flags)
 
678
{
 
679
        unsigned long flags_spin;
 
680
        struct iwl3945_station_entry *station;
 
681
 
 
682
        if (sta_id == IWL_INVALID_STATION)
 
683
                return IWL_INVALID_STATION;
 
684
 
 
685
        spin_lock_irqsave(&priv->sta_lock, flags_spin);
 
686
        station = &priv->stations[sta_id];
 
687
 
 
688
        station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK;
 
689
        station->sta.rate_n_flags = cpu_to_le16(tx_rate);
 
690
        station->current_rate.rate_n_flags = tx_rate;
 
691
        station->sta.mode = STA_CONTROL_MODIFY_MSK;
 
692
 
 
693
        spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
 
694
 
 
695
        iwl3945_send_add_station(priv, &station->sta, flags);
 
696
        IWL_DEBUG_RATE("SCALE sync station %d to rate %d\n",
 
697
                        sta_id, tx_rate);
 
698
        return sta_id;
 
699
}
 
700
 
 
701
static int iwl3945_nic_set_pwr_src(struct iwl3945_priv *priv, int pwr_max)
 
702
{
 
703
        int rc;
 
704
        unsigned long flags;
 
705
 
 
706
        spin_lock_irqsave(&priv->lock, flags);
 
707
        rc = iwl3945_grab_nic_access(priv);
 
708
        if (rc) {
 
709
                spin_unlock_irqrestore(&priv->lock, flags);
 
710
                return rc;
 
711
        }
 
712
 
 
713
        if (!pwr_max) {
 
714
                u32 val;
 
715
 
 
716
                rc = pci_read_config_dword(priv->pci_dev,
 
717
                                PCI_POWER_SOURCE, &val);
 
718
                if (val & PCI_CFG_PMC_PME_FROM_D3COLD_SUPPORT) {
 
719
                        iwl3945_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
 
720
                                        APMG_PS_CTRL_VAL_PWR_SRC_VAUX,
 
721
                                        ~APMG_PS_CTRL_MSK_PWR_SRC);
 
722
                        iwl3945_release_nic_access(priv);
 
723
 
 
724
                        iwl3945_poll_bit(priv, CSR_GPIO_IN,
 
725
                                     CSR_GPIO_IN_VAL_VAUX_PWR_SRC,
 
726
                                     CSR_GPIO_IN_BIT_AUX_POWER, 5000);
 
727
                } else
 
728
                        iwl3945_release_nic_access(priv);
 
729
        } else {
 
730
                iwl3945_set_bits_mask_prph(priv, APMG_PS_CTRL_REG,
 
731
                                APMG_PS_CTRL_VAL_PWR_SRC_VMAIN,
 
732
                                ~APMG_PS_CTRL_MSK_PWR_SRC);
 
733
 
 
734
                iwl3945_release_nic_access(priv);
 
735
                iwl3945_poll_bit(priv, CSR_GPIO_IN, CSR_GPIO_IN_VAL_VMAIN_PWR_SRC,
 
736
                             CSR_GPIO_IN_BIT_AUX_POWER, 5000);  /* uS */
 
737
        }
 
738
        spin_unlock_irqrestore(&priv->lock, flags);
 
739
 
 
740
        return rc;
 
741
}
 
742
 
 
743
static int iwl3945_rx_init(struct iwl3945_priv *priv, struct iwl3945_rx_queue *rxq)
 
744
{
 
745
        int rc;
 
746
        unsigned long flags;
 
747
 
 
748
        spin_lock_irqsave(&priv->lock, flags);
 
749
        rc = iwl3945_grab_nic_access(priv);
 
750
        if (rc) {
 
751
                spin_unlock_irqrestore(&priv->lock, flags);
 
752
                return rc;
 
753
        }
 
754
 
 
755
        iwl3945_write_direct32(priv, FH_RCSR_RBD_BASE(0), rxq->dma_addr);
 
756
        iwl3945_write_direct32(priv, FH_RCSR_RPTR_ADDR(0),
 
757
                             priv->hw_setting.shared_phys +
 
758
                             offsetof(struct iwl3945_shared, rx_read_ptr[0]));
 
759
        iwl3945_write_direct32(priv, FH_RCSR_WPTR(0), 0);
 
760
        iwl3945_write_direct32(priv, FH_RCSR_CONFIG(0),
 
761
                ALM_FH_RCSR_RX_CONFIG_REG_VAL_DMA_CHNL_EN_ENABLE |
 
762
                ALM_FH_RCSR_RX_CONFIG_REG_VAL_RDRBD_EN_ENABLE |
 
763
                ALM_FH_RCSR_RX_CONFIG_REG_BIT_WR_STTS_EN |
 
764
                ALM_FH_RCSR_RX_CONFIG_REG_VAL_MAX_FRAG_SIZE_128 |
 
765
                (RX_QUEUE_SIZE_LOG << ALM_FH_RCSR_RX_CONFIG_REG_POS_RBDC_SIZE) |
 
766
                ALM_FH_RCSR_RX_CONFIG_REG_VAL_IRQ_DEST_INT_HOST |
 
767
                (1 << ALM_FH_RCSR_RX_CONFIG_REG_POS_IRQ_RBTH) |
 
768
                ALM_FH_RCSR_RX_CONFIG_REG_VAL_MSG_MODE_FH);
 
769
 
 
770
        /* fake read to flush all prev I/O */
 
771
        iwl3945_read_direct32(priv, FH_RSSR_CTRL);
 
772
 
 
773
        iwl3945_release_nic_access(priv);
 
774
        spin_unlock_irqrestore(&priv->lock, flags);
 
775
 
 
776
        return 0;
 
777
}
 
778
 
 
779
static int iwl3945_tx_reset(struct iwl3945_priv *priv)
 
780
{
 
781
        int rc;
 
782
        unsigned long flags;
 
783
 
 
784
        spin_lock_irqsave(&priv->lock, flags);
 
785
        rc = iwl3945_grab_nic_access(priv);
 
786
        if (rc) {
 
787
                spin_unlock_irqrestore(&priv->lock, flags);
 
788
                return rc;
 
789
        }
 
790
 
 
791
        /* bypass mode */
 
792
        iwl3945_write_prph(priv, ALM_SCD_MODE_REG, 0x2);
 
793
 
 
794
        /* RA 0 is active */
 
795
        iwl3945_write_prph(priv, ALM_SCD_ARASTAT_REG, 0x01);
 
796
 
 
797
        /* all 6 fifo are active */
 
798
        iwl3945_write_prph(priv, ALM_SCD_TXFACT_REG, 0x3f);
 
799
 
 
800
        iwl3945_write_prph(priv, ALM_SCD_SBYP_MODE_1_REG, 0x010000);
 
801
        iwl3945_write_prph(priv, ALM_SCD_SBYP_MODE_2_REG, 0x030002);
 
802
        iwl3945_write_prph(priv, ALM_SCD_TXF4MF_REG, 0x000004);
 
803
        iwl3945_write_prph(priv, ALM_SCD_TXF5MF_REG, 0x000005);
 
804
 
 
805
        iwl3945_write_direct32(priv, FH_TSSR_CBB_BASE,
 
806
                             priv->hw_setting.shared_phys);
 
807
 
 
808
        iwl3945_write_direct32(priv, FH_TSSR_MSG_CONFIG,
 
809
                ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TXPD_ON |
 
810
                ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_TXPD_ON |
 
811
                ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_MAX_FRAG_SIZE_128B |
 
812
                ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_SNOOP_RD_TFD_ON |
 
813
                ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RD_CBB_ON |
 
814
                ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_ORDER_RSP_WAIT_TH |
 
815
                ALM_FH_TSSR_TX_MSG_CONFIG_REG_VAL_RSP_WAIT_TH);
 
816
 
 
817
        iwl3945_release_nic_access(priv);
 
818
        spin_unlock_irqrestore(&priv->lock, flags);
 
819
 
 
820
        return 0;
 
821
}
 
822
 
 
823
/**
 
824
 * iwl3945_txq_ctx_reset - Reset TX queue context
 
825
 *
 
826
 * Destroys all DMA structures and initialize them again
 
827
 */
 
828
static int iwl3945_txq_ctx_reset(struct iwl3945_priv *priv)
 
829
{
 
830
        int rc;
 
831
        int txq_id, slots_num;
 
832
 
 
833
        iwl3945_hw_txq_ctx_free(priv);
 
834
 
 
835
        /* Tx CMD queue */
 
836
        rc = iwl3945_tx_reset(priv);
 
837
        if (rc)
 
838
                goto error;
 
839
 
 
840
        /* Tx queue(s) */
 
841
        for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++) {
 
842
                slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
 
843
                                TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
 
844
                rc = iwl3945_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
 
845
                                txq_id);
 
846
                if (rc) {
 
847
                        IWL_ERROR("Tx %d queue init failed\n", txq_id);
 
848
                        goto error;
 
849
                }
 
850
        }
 
851
 
 
852
        return rc;
 
853
 
 
854
 error:
 
855
        iwl3945_hw_txq_ctx_free(priv);
 
856
        return rc;
 
857
}
 
858
 
 
859
int iwl3945_hw_nic_init(struct iwl3945_priv *priv)
 
860
{
 
861
        u8 rev_id;
 
862
        int rc;
 
863
        unsigned long flags;
 
864
        struct iwl3945_rx_queue *rxq = &priv->rxq;
 
865
 
 
866
        iwl3945_power_init_handle(priv);
 
867
 
 
868
        spin_lock_irqsave(&priv->lock, flags);
 
869
        iwl3945_set_bit(priv, CSR_ANA_PLL_CFG, (1 << 24));
 
870
        iwl3945_set_bit(priv, CSR_GIO_CHICKEN_BITS,
 
871
                    CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX);
 
872
 
 
873
        iwl3945_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
 
874
        rc = iwl3945_poll_bit(priv, CSR_GP_CNTRL,
 
875
                          CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
 
876
                          CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
 
877
        if (rc < 0) {
 
878
                spin_unlock_irqrestore(&priv->lock, flags);
 
879
                IWL_DEBUG_INFO("Failed to init the card\n");
 
880
                return rc;
 
881
        }
 
882
 
 
883
        rc = iwl3945_grab_nic_access(priv);
 
884
        if (rc) {
 
885
                spin_unlock_irqrestore(&priv->lock, flags);
 
886
                return rc;
 
887
        }
 
888
        iwl3945_write_prph(priv, APMG_CLK_EN_REG,
 
889
                                 APMG_CLK_VAL_DMA_CLK_RQT |
 
890
                                 APMG_CLK_VAL_BSM_CLK_RQT);
 
891
        udelay(20);
 
892
        iwl3945_set_bits_prph(priv, APMG_PCIDEV_STT_REG,
 
893
                                    APMG_PCIDEV_STT_VAL_L1_ACT_DIS);
 
894
        iwl3945_release_nic_access(priv);
 
895
        spin_unlock_irqrestore(&priv->lock, flags);
 
896
 
 
897
        /* Determine HW type */
 
898
        rc = pci_read_config_byte(priv->pci_dev, PCI_REVISION_ID, &rev_id);
 
899
        if (rc)
 
900
                return rc;
 
901
        IWL_DEBUG_INFO("HW Revision ID = 0x%X\n", rev_id);
 
902
 
 
903
        iwl3945_nic_set_pwr_src(priv, 1);
 
904
        spin_lock_irqsave(&priv->lock, flags);
 
905
 
 
906
        if (rev_id & PCI_CFG_REV_ID_BIT_RTP)
 
907
                IWL_DEBUG_INFO("RTP type \n");
 
908
        else if (rev_id & PCI_CFG_REV_ID_BIT_BASIC_SKU) {
 
909
                IWL_DEBUG_INFO("ALM-MB type\n");
 
910
                iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 
911
                            CSR_HW_IF_CONFIG_REG_BIT_ALMAGOR_MB);
 
912
        } else {
 
913
                IWL_DEBUG_INFO("ALM-MM type\n");
 
914
                iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 
915
                            CSR_HW_IF_CONFIG_REG_BIT_ALMAGOR_MM);
 
916
        }
 
917
 
 
918
        if (EEPROM_SKU_CAP_OP_MODE_MRC == priv->eeprom.sku_cap) {
 
919
                IWL_DEBUG_INFO("SKU OP mode is mrc\n");
 
920
                iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 
921
                            CSR_HW_IF_CONFIG_REG_BIT_SKU_MRC);
 
922
        } else
 
923
                IWL_DEBUG_INFO("SKU OP mode is basic\n");
 
924
 
 
925
        if ((priv->eeprom.board_revision & 0xF0) == 0xD0) {
 
926
                IWL_DEBUG_INFO("3945ABG revision is 0x%X\n",
 
927
                               priv->eeprom.board_revision);
 
928
                iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 
929
                            CSR_HW_IF_CONFIG_REG_BIT_BOARD_TYPE);
 
930
        } else {
 
931
                IWL_DEBUG_INFO("3945ABG revision is 0x%X\n",
 
932
                               priv->eeprom.board_revision);
 
933
                iwl3945_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
 
934
                              CSR_HW_IF_CONFIG_REG_BIT_BOARD_TYPE);
 
935
        }
 
936
 
 
937
        if (priv->eeprom.almgor_m_version <= 1) {
 
938
                iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 
939
                            CSR_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A);
 
940
                IWL_DEBUG_INFO("Card M type A version is 0x%X\n",
 
941
                               priv->eeprom.almgor_m_version);
 
942
        } else {
 
943
                IWL_DEBUG_INFO("Card M type B version is 0x%X\n",
 
944
                               priv->eeprom.almgor_m_version);
 
945
                iwl3945_set_bit(priv, CSR_HW_IF_CONFIG_REG,
 
946
                            CSR_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B);
 
947
        }
 
948
        spin_unlock_irqrestore(&priv->lock, flags);
 
949
 
 
950
        if (priv->eeprom.sku_cap & EEPROM_SKU_CAP_SW_RF_KILL_ENABLE)
 
951
                IWL_DEBUG_RF_KILL("SW RF KILL supported in EEPROM.\n");
 
952
 
 
953
        if (priv->eeprom.sku_cap & EEPROM_SKU_CAP_HW_RF_KILL_ENABLE)
 
954
                IWL_DEBUG_RF_KILL("HW RF KILL supported in EEPROM.\n");
 
955
 
 
956
        /* Allocate the RX queue, or reset if it is already allocated */
 
957
        if (!rxq->bd) {
 
958
                rc = iwl3945_rx_queue_alloc(priv);
 
959
                if (rc) {
 
960
                        IWL_ERROR("Unable to initialize Rx queue\n");
 
961
                        return -ENOMEM;
 
962
                }
 
963
        } else
 
964
                iwl3945_rx_queue_reset(priv, rxq);
 
965
 
 
966
        iwl3945_rx_replenish(priv);
 
967
 
 
968
        iwl3945_rx_init(priv, rxq);
 
969
 
 
970
        spin_lock_irqsave(&priv->lock, flags);
 
971
 
 
972
        /* Look at using this instead:
 
973
        rxq->need_update = 1;
 
974
        iwl3945_rx_queue_update_write_ptr(priv, rxq);
 
975
        */
 
976
 
 
977
        rc = iwl3945_grab_nic_access(priv);
 
978
        if (rc) {
 
979
                spin_unlock_irqrestore(&priv->lock, flags);
 
980
                return rc;
 
981
        }
 
982
        iwl3945_write_direct32(priv, FH_RCSR_WPTR(0), rxq->write & ~7);
 
983
        iwl3945_release_nic_access(priv);
 
984
 
 
985
        spin_unlock_irqrestore(&priv->lock, flags);
 
986
 
 
987
        rc = iwl3945_txq_ctx_reset(priv);
 
988
        if (rc)
 
989
                return rc;
 
990
 
 
991
        set_bit(STATUS_INIT, &priv->status);
 
992
 
 
993
        return 0;
 
994
}
 
995
 
 
996
/**
 
997
 * iwl3945_hw_txq_ctx_free - Free TXQ Context
 
998
 *
 
999
 * Destroy all TX DMA queues and structures
 
1000
 */
 
1001
void iwl3945_hw_txq_ctx_free(struct iwl3945_priv *priv)
 
1002
{
 
1003
        int txq_id;
 
1004
 
 
1005
        /* Tx queues */
 
1006
        for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++)
 
1007
                iwl3945_tx_queue_free(priv, &priv->txq[txq_id]);
 
1008
}
 
1009
 
 
1010
void iwl3945_hw_txq_ctx_stop(struct iwl3945_priv *priv)
 
1011
{
 
1012
        int queue;
 
1013
        unsigned long flags;
 
1014
 
 
1015
        spin_lock_irqsave(&priv->lock, flags);
 
1016
        if (iwl3945_grab_nic_access(priv)) {
 
1017
                spin_unlock_irqrestore(&priv->lock, flags);
 
1018
                iwl3945_hw_txq_ctx_free(priv);
 
1019
                return;
 
1020
        }
 
1021
 
 
1022
        /* stop SCD */
 
1023
        iwl3945_write_prph(priv, ALM_SCD_MODE_REG, 0);
 
1024
 
 
1025
        /* reset TFD queues */
 
1026
        for (queue = TFD_QUEUE_MIN; queue < TFD_QUEUE_MAX; queue++) {
 
1027
                iwl3945_write_direct32(priv, FH_TCSR_CONFIG(queue), 0x0);
 
1028
                iwl3945_poll_direct_bit(priv, FH_TSSR_TX_STATUS,
 
1029
                                ALM_FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(queue),
 
1030
                                1000);
 
1031
        }
 
1032
 
 
1033
        iwl3945_release_nic_access(priv);
 
1034
        spin_unlock_irqrestore(&priv->lock, flags);
 
1035
 
 
1036
        iwl3945_hw_txq_ctx_free(priv);
 
1037
}
 
1038
 
 
1039
int iwl3945_hw_nic_stop_master(struct iwl3945_priv *priv)
 
1040
{
 
1041
        int rc = 0;
 
1042
        u32 reg_val;
 
1043
        unsigned long flags;
 
1044
 
 
1045
        spin_lock_irqsave(&priv->lock, flags);
 
1046
 
 
1047
        /* set stop master bit */
 
1048
        iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_STOP_MASTER);
 
1049
 
 
1050
        reg_val = iwl3945_read32(priv, CSR_GP_CNTRL);
 
1051
 
 
1052
        if (CSR_GP_CNTRL_REG_FLAG_MAC_POWER_SAVE ==
 
1053
            (reg_val & CSR_GP_CNTRL_REG_MSK_POWER_SAVE_TYPE))
 
1054
                IWL_DEBUG_INFO("Card in power save, master is already "
 
1055
                               "stopped\n");
 
1056
        else {
 
1057
                rc = iwl3945_poll_bit(priv, CSR_RESET,
 
1058
                                  CSR_RESET_REG_FLAG_MASTER_DISABLED,
 
1059
                                  CSR_RESET_REG_FLAG_MASTER_DISABLED, 100);
 
1060
                if (rc < 0) {
 
1061
                        spin_unlock_irqrestore(&priv->lock, flags);
 
1062
                        return rc;
 
1063
                }
 
1064
        }
 
1065
 
 
1066
        spin_unlock_irqrestore(&priv->lock, flags);
 
1067
        IWL_DEBUG_INFO("stop master\n");
 
1068
 
 
1069
        return rc;
 
1070
}
 
1071
 
 
1072
int iwl3945_hw_nic_reset(struct iwl3945_priv *priv)
 
1073
{
 
1074
        int rc;
 
1075
        unsigned long flags;
 
1076
 
 
1077
        iwl3945_hw_nic_stop_master(priv);
 
1078
 
 
1079
        spin_lock_irqsave(&priv->lock, flags);
 
1080
 
 
1081
        iwl3945_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
 
1082
 
 
1083
        rc = iwl3945_poll_bit(priv, CSR_GP_CNTRL,
 
1084
                          CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
 
1085
                          CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY, 25000);
 
1086
 
 
1087
        rc = iwl3945_grab_nic_access(priv);
 
1088
        if (!rc) {
 
1089
                iwl3945_write_prph(priv, APMG_CLK_CTRL_REG,
 
1090
                                         APMG_CLK_VAL_BSM_CLK_RQT);
 
1091
 
 
1092
                udelay(10);
 
1093
 
 
1094
                iwl3945_set_bit(priv, CSR_GP_CNTRL,
 
1095
                            CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
 
1096
 
 
1097
                iwl3945_write_prph(priv, APMG_RTC_INT_MSK_REG, 0x0);
 
1098
                iwl3945_write_prph(priv, APMG_RTC_INT_STT_REG,
 
1099
                                        0xFFFFFFFF);
 
1100
 
 
1101
                /* enable DMA */
 
1102
                iwl3945_write_prph(priv, APMG_CLK_EN_REG,
 
1103
                                         APMG_CLK_VAL_DMA_CLK_RQT |
 
1104
                                         APMG_CLK_VAL_BSM_CLK_RQT);
 
1105
                udelay(10);
 
1106
 
 
1107
                iwl3945_set_bits_prph(priv, APMG_PS_CTRL_REG,
 
1108
                                APMG_PS_CTRL_VAL_RESET_REQ);
 
1109
                udelay(5);
 
1110
                iwl3945_clear_bits_prph(priv, APMG_PS_CTRL_REG,
 
1111
                                APMG_PS_CTRL_VAL_RESET_REQ);
 
1112
                iwl3945_release_nic_access(priv);
 
1113
        }
 
1114
 
 
1115
        /* Clear the 'host command active' bit... */
 
1116
        clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
 
1117
 
 
1118
        wake_up_interruptible(&priv->wait_command_queue);
 
1119
        spin_unlock_irqrestore(&priv->lock, flags);
 
1120
 
 
1121
        return rc;
 
1122
}
 
1123
 
 
1124
/**
 
1125
 * iwl3945_hw_reg_adjust_power_by_temp
 
1126
 * return index delta into power gain settings table
 
1127
*/
 
1128
static int iwl3945_hw_reg_adjust_power_by_temp(int new_reading, int old_reading)
 
1129
{
 
1130
        return (new_reading - old_reading) * (-11) / 100;
 
1131
}
 
1132
 
 
1133
/**
 
1134
 * iwl3945_hw_reg_temp_out_of_range - Keep temperature in sane range
 
1135
 */
 
1136
static inline int iwl3945_hw_reg_temp_out_of_range(int temperature)
 
1137
{
 
1138
        return (((temperature < -260) || (temperature > 25)) ? 1 : 0);
 
1139
}
 
1140
 
 
1141
int iwl3945_hw_get_temperature(struct iwl3945_priv *priv)
 
1142
{
 
1143
        return iwl3945_read32(priv, CSR_UCODE_DRV_GP2);
 
1144
}
 
1145
 
 
1146
/**
 
1147
 * iwl3945_hw_reg_txpower_get_temperature
 
1148
 * get the current temperature by reading from NIC
 
1149
*/
 
1150
static int iwl3945_hw_reg_txpower_get_temperature(struct iwl3945_priv *priv)
 
1151
{
 
1152
        int temperature;
 
1153
 
 
1154
        temperature = iwl3945_hw_get_temperature(priv);
 
1155
 
 
1156
        /* driver's okay range is -260 to +25.
 
1157
         *   human readable okay range is 0 to +285 */
 
1158
        IWL_DEBUG_INFO("Temperature: %d\n", temperature + IWL_TEMP_CONVERT);
 
1159
 
 
1160
        /* handle insane temp reading */
 
1161
        if (iwl3945_hw_reg_temp_out_of_range(temperature)) {
 
1162
                IWL_ERROR("Error bad temperature value  %d\n", temperature);
 
1163
 
 
1164
                /* if really really hot(?),
 
1165
                 *   substitute the 3rd band/group's temp measured at factory */
 
1166
                if (priv->last_temperature > 100)
 
1167
                        temperature = priv->eeprom.groups[2].temperature;
 
1168
                else /* else use most recent "sane" value from driver */
 
1169
                        temperature = priv->last_temperature;
 
1170
        }
 
1171
 
 
1172
        return temperature;     /* raw, not "human readable" */
 
1173
}
 
1174
 
 
1175
/* Adjust Txpower only if temperature variance is greater than threshold.
 
1176
 *
 
1177
 * Both are lower than older versions' 9 degrees */
 
1178
#define IWL_TEMPERATURE_LIMIT_TIMER   6
 
1179
 
 
1180
/**
 
1181
 * is_temp_calib_needed - determines if new calibration is needed
 
1182
 *
 
1183
 * records new temperature in tx_mgr->temperature.
 
1184
 * replaces tx_mgr->last_temperature *only* if calib needed
 
1185
 *    (assumes caller will actually do the calibration!). */
 
1186
static int is_temp_calib_needed(struct iwl3945_priv *priv)
 
1187
{
 
1188
        int temp_diff;
 
1189
 
 
1190
        priv->temperature = iwl3945_hw_reg_txpower_get_temperature(priv);
 
1191
        temp_diff = priv->temperature - priv->last_temperature;
 
1192
 
 
1193
        /* get absolute value */
 
1194
        if (temp_diff < 0) {
 
1195
                IWL_DEBUG_POWER("Getting cooler, delta %d,\n", temp_diff);
 
1196
                temp_diff = -temp_diff;
 
1197
        } else if (temp_diff == 0)
 
1198
                IWL_DEBUG_POWER("Same temp,\n");
 
1199
        else
 
1200
                IWL_DEBUG_POWER("Getting warmer, delta %d,\n", temp_diff);
 
1201
 
 
1202
        /* if we don't need calibration, *don't* update last_temperature */
 
1203
        if (temp_diff < IWL_TEMPERATURE_LIMIT_TIMER) {
 
1204
                IWL_DEBUG_POWER("Timed thermal calib not needed\n");
 
1205
                return 0;
 
1206
        }
 
1207
 
 
1208
        IWL_DEBUG_POWER("Timed thermal calib needed\n");
 
1209
 
 
1210
        /* assume that caller will actually do calib ...
 
1211
         *   update the "last temperature" value */
 
1212
        priv->last_temperature = priv->temperature;
 
1213
        return 1;
 
1214
}
 
1215
 
 
1216
#define IWL_MAX_GAIN_ENTRIES 78
 
1217
#define IWL_CCK_FROM_OFDM_POWER_DIFF  -5
 
1218
#define IWL_CCK_FROM_OFDM_INDEX_DIFF (10)
 
1219
 
 
1220
/* radio and DSP power table, each step is 1/2 dB.
 
1221
 * 1st number is for RF analog gain, 2nd number is for DSP pre-DAC gain. */
 
1222
static struct iwl3945_tx_power power_gain_table[2][IWL_MAX_GAIN_ENTRIES] = {
 
1223
        {
 
1224
         {251, 127},            /* 2.4 GHz, highest power */
 
1225
         {251, 127},
 
1226
         {251, 127},
 
1227
         {251, 127},
 
1228
         {251, 125},
 
1229
         {251, 110},
 
1230
         {251, 105},
 
1231
         {251, 98},
 
1232
         {187, 125},
 
1233
         {187, 115},
 
1234
         {187, 108},
 
1235
         {187, 99},
 
1236
         {243, 119},
 
1237
         {243, 111},
 
1238
         {243, 105},
 
1239
         {243, 97},
 
1240
         {243, 92},
 
1241
         {211, 106},
 
1242
         {211, 100},
 
1243
         {179, 120},
 
1244
         {179, 113},
 
1245
         {179, 107},
 
1246
         {147, 125},
 
1247
         {147, 119},
 
1248
         {147, 112},
 
1249
         {147, 106},
 
1250
         {147, 101},
 
1251
         {147, 97},
 
1252
         {147, 91},
 
1253
         {115, 107},
 
1254
         {235, 121},
 
1255
         {235, 115},
 
1256
         {235, 109},
 
1257
         {203, 127},
 
1258
         {203, 121},
 
1259
         {203, 115},
 
1260
         {203, 108},
 
1261
         {203, 102},
 
1262
         {203, 96},
 
1263
         {203, 92},
 
1264
         {171, 110},
 
1265
         {171, 104},
 
1266
         {171, 98},
 
1267
         {139, 116},
 
1268
         {227, 125},
 
1269
         {227, 119},
 
1270
         {227, 113},
 
1271
         {227, 107},
 
1272
         {227, 101},
 
1273
         {227, 96},
 
1274
         {195, 113},
 
1275
         {195, 106},
 
1276
         {195, 102},
 
1277
         {195, 95},
 
1278
         {163, 113},
 
1279
         {163, 106},
 
1280
         {163, 102},
 
1281
         {163, 95},
 
1282
         {131, 113},
 
1283
         {131, 106},
 
1284
         {131, 102},
 
1285
         {131, 95},
 
1286
         {99, 113},
 
1287
         {99, 106},
 
1288
         {99, 102},
 
1289
         {99, 95},
 
1290
         {67, 113},
 
1291
         {67, 106},
 
1292
         {67, 102},
 
1293
         {67, 95},
 
1294
         {35, 113},
 
1295
         {35, 106},
 
1296
         {35, 102},
 
1297
         {35, 95},
 
1298
         {3, 113},
 
1299
         {3, 106},
 
1300
         {3, 102},
 
1301
         {3, 95} },             /* 2.4 GHz, lowest power */
 
1302
        {
 
1303
         {251, 127},            /* 5.x GHz, highest power */
 
1304
         {251, 120},
 
1305
         {251, 114},
 
1306
         {219, 119},
 
1307
         {219, 101},
 
1308
         {187, 113},
 
1309
         {187, 102},
 
1310
         {155, 114},
 
1311
         {155, 103},
 
1312
         {123, 117},
 
1313
         {123, 107},
 
1314
         {123, 99},
 
1315
         {123, 92},
 
1316
         {91, 108},
 
1317
         {59, 125},
 
1318
         {59, 118},
 
1319
         {59, 109},
 
1320
         {59, 102},
 
1321
         {59, 96},
 
1322
         {59, 90},
 
1323
         {27, 104},
 
1324
         {27, 98},
 
1325
         {27, 92},
 
1326
         {115, 118},
 
1327
         {115, 111},
 
1328
         {115, 104},
 
1329
         {83, 126},
 
1330
         {83, 121},
 
1331
         {83, 113},
 
1332
         {83, 105},
 
1333
         {83, 99},
 
1334
         {51, 118},
 
1335
         {51, 111},
 
1336
         {51, 104},
 
1337
         {51, 98},
 
1338
         {19, 116},
 
1339
         {19, 109},
 
1340
         {19, 102},
 
1341
         {19, 98},
 
1342
         {19, 93},
 
1343
         {171, 113},
 
1344
         {171, 107},
 
1345
         {171, 99},
 
1346
         {139, 120},
 
1347
         {139, 113},
 
1348
         {139, 107},
 
1349
         {139, 99},
 
1350
         {107, 120},
 
1351
         {107, 113},
 
1352
         {107, 107},
 
1353
         {107, 99},
 
1354
         {75, 120},
 
1355
         {75, 113},
 
1356
         {75, 107},
 
1357
         {75, 99},
 
1358
         {43, 120},
 
1359
         {43, 113},
 
1360
         {43, 107},
 
1361
         {43, 99},
 
1362
         {11, 120},
 
1363
         {11, 113},
 
1364
         {11, 107},
 
1365
         {11, 99},
 
1366
         {131, 107},
 
1367
         {131, 99},
 
1368
         {99, 120},
 
1369
         {99, 113},
 
1370
         {99, 107},
 
1371
         {99, 99},
 
1372
         {67, 120},
 
1373
         {67, 113},
 
1374
         {67, 107},
 
1375
         {67, 99},
 
1376
         {35, 120},
 
1377
         {35, 113},
 
1378
         {35, 107},
 
1379
         {35, 99},
 
1380
         {3, 120} }             /* 5.x GHz, lowest power */
 
1381
};
 
1382
 
 
1383
static inline u8 iwl3945_hw_reg_fix_power_index(int index)
 
1384
{
 
1385
        if (index < 0)
 
1386
                return 0;
 
1387
        if (index >= IWL_MAX_GAIN_ENTRIES)
 
1388
                return IWL_MAX_GAIN_ENTRIES - 1;
 
1389
        return (u8) index;
 
1390
}
 
1391
 
 
1392
/* Kick off thermal recalibration check every 60 seconds */
 
1393
#define REG_RECALIB_PERIOD (60)
 
1394
 
 
1395
/**
 
1396
 * iwl3945_hw_reg_set_scan_power - Set Tx power for scan probe requests
 
1397
 *
 
1398
 * Set (in our channel info database) the direct scan Tx power for 1 Mbit (CCK)
 
1399
 * or 6 Mbit (OFDM) rates.
 
1400
 */
 
1401
static void iwl3945_hw_reg_set_scan_power(struct iwl3945_priv *priv, u32 scan_tbl_index,
 
1402
                               s32 rate_index, const s8 *clip_pwrs,
 
1403
                               struct iwl3945_channel_info *ch_info,
 
1404
                               int band_index)
 
1405
{
 
1406
        struct iwl3945_scan_power_info *scan_power_info;
 
1407
        s8 power;
 
1408
        u8 power_index;
 
1409
 
 
1410
        scan_power_info = &ch_info->scan_pwr_info[scan_tbl_index];
 
1411
 
 
1412
        /* use this channel group's 6Mbit clipping/saturation pwr,
 
1413
         *   but cap at regulatory scan power restriction (set during init
 
1414
         *   based on eeprom channel data) for this channel.  */
 
1415
        power = min(ch_info->scan_power, clip_pwrs[IWL_RATE_6M_INDEX_TABLE]);
 
1416
 
 
1417
        /* further limit to user's max power preference.
 
1418
         * FIXME:  Other spectrum management power limitations do not
 
1419
         *   seem to apply?? */
 
1420
        power = min(power, priv->user_txpower_limit);
 
1421
        scan_power_info->requested_power = power;
 
1422
 
 
1423
        /* find difference between new scan *power* and current "normal"
 
1424
         *   Tx *power* for 6Mb.  Use this difference (x2) to adjust the
 
1425
         *   current "normal" temperature-compensated Tx power *index* for
 
1426
         *   this rate (1Mb or 6Mb) to yield new temp-compensated scan power
 
1427
         *   *index*. */
 
1428
        power_index = ch_info->power_info[rate_index].power_table_index
 
1429
            - (power - ch_info->power_info
 
1430
               [IWL_RATE_6M_INDEX_TABLE].requested_power) * 2;
 
1431
 
 
1432
        /* store reference index that we use when adjusting *all* scan
 
1433
         *   powers.  So we can accommodate user (all channel) or spectrum
 
1434
         *   management (single channel) power changes "between" temperature
 
1435
         *   feedback compensation procedures.
 
1436
         * don't force fit this reference index into gain table; it may be a
 
1437
         *   negative number.  This will help avoid errors when we're at
 
1438
         *   the lower bounds (highest gains, for warmest temperatures)
 
1439
         *   of the table. */
 
1440
 
 
1441
        /* don't exceed table bounds for "real" setting */
 
1442
        power_index = iwl3945_hw_reg_fix_power_index(power_index);
 
1443
 
 
1444
        scan_power_info->power_table_index = power_index;
 
1445
        scan_power_info->tpc.tx_gain =
 
1446
            power_gain_table[band_index][power_index].tx_gain;
 
1447
        scan_power_info->tpc.dsp_atten =
 
1448
            power_gain_table[band_index][power_index].dsp_atten;
 
1449
}
 
1450
 
 
1451
/**
 
1452
 * iwl3945_hw_reg_send_txpower - fill in Tx Power command with gain settings
 
1453
 *
 
1454
 * Configures power settings for all rates for the current channel,
 
1455
 * using values from channel info struct, and send to NIC
 
1456
 */
 
1457
int iwl3945_hw_reg_send_txpower(struct iwl3945_priv *priv)
 
1458
{
 
1459
        int rate_idx, i;
 
1460
        const struct iwl3945_channel_info *ch_info = NULL;
 
1461
        struct iwl3945_txpowertable_cmd txpower = {
 
1462
                .channel = priv->active_rxon.channel,
 
1463
        };
 
1464
 
 
1465
        txpower.band = (priv->phymode == MODE_IEEE80211A) ? 0 : 1;
 
1466
        ch_info = iwl3945_get_channel_info(priv,
 
1467
                                       priv->phymode,
 
1468
                                       le16_to_cpu(priv->active_rxon.channel));
 
1469
        if (!ch_info) {
 
1470
                IWL_ERROR
 
1471
                    ("Failed to get channel info for channel %d [%d]\n",
 
1472
                     le16_to_cpu(priv->active_rxon.channel), priv->phymode);
 
1473
                return -EINVAL;
 
1474
        }
 
1475
 
 
1476
        if (!is_channel_valid(ch_info)) {
 
1477
                IWL_DEBUG_POWER("Not calling TX_PWR_TABLE_CMD on "
 
1478
                                "non-Tx channel.\n");
 
1479
                return 0;
 
1480
        }
 
1481
 
 
1482
        /* fill cmd with power settings for all rates for current channel */
 
1483
        /* Fill OFDM rate */
 
1484
        for (rate_idx = IWL_FIRST_OFDM_RATE, i = 0;
 
1485
             rate_idx <= IWL_LAST_OFDM_RATE; rate_idx++, i++) {
 
1486
 
 
1487
                txpower.power[i].tpc = ch_info->power_info[i].tpc;
 
1488
                txpower.power[i].rate = iwl3945_rates[rate_idx].plcp;
 
1489
 
 
1490
                IWL_DEBUG_POWER("ch %d:%d rf %d dsp %3d rate code 0x%02x\n",
 
1491
                                le16_to_cpu(txpower.channel),
 
1492
                                txpower.band,
 
1493
                                txpower.power[i].tpc.tx_gain,
 
1494
                                txpower.power[i].tpc.dsp_atten,
 
1495
                                txpower.power[i].rate);
 
1496
        }
 
1497
        /* Fill CCK rates */
 
1498
        for (rate_idx = IWL_FIRST_CCK_RATE;
 
1499
             rate_idx <= IWL_LAST_CCK_RATE; rate_idx++, i++) {
 
1500
                txpower.power[i].tpc = ch_info->power_info[i].tpc;
 
1501
                txpower.power[i].rate = iwl3945_rates[rate_idx].plcp;
 
1502
 
 
1503
                IWL_DEBUG_POWER("ch %d:%d rf %d dsp %3d rate code 0x%02x\n",
 
1504
                                le16_to_cpu(txpower.channel),
 
1505
                                txpower.band,
 
1506
                                txpower.power[i].tpc.tx_gain,
 
1507
                                txpower.power[i].tpc.dsp_atten,
 
1508
                                txpower.power[i].rate);
 
1509
        }
 
1510
 
 
1511
        return iwl3945_send_cmd_pdu(priv, REPLY_TX_PWR_TABLE_CMD,
 
1512
                        sizeof(struct iwl3945_txpowertable_cmd), &txpower);
 
1513
 
 
1514
}
 
1515
 
 
1516
/**
 
1517
 * iwl3945_hw_reg_set_new_power - Configures power tables at new levels
 
1518
 * @ch_info: Channel to update.  Uses power_info.requested_power.
 
1519
 *
 
1520
 * Replace requested_power and base_power_index ch_info fields for
 
1521
 * one channel.
 
1522
 *
 
1523
 * Called if user or spectrum management changes power preferences.
 
1524
 * Takes into account h/w and modulation limitations (clip power).
 
1525
 *
 
1526
 * This does *not* send anything to NIC, just sets up ch_info for one channel.
 
1527
 *
 
1528
 * NOTE: reg_compensate_for_temperature_dif() *must* be run after this to
 
1529
 *       properly fill out the scan powers, and actual h/w gain settings,
 
1530
 *       and send changes to NIC
 
1531
 */
 
1532
static int iwl3945_hw_reg_set_new_power(struct iwl3945_priv *priv,
 
1533
                             struct iwl3945_channel_info *ch_info)
 
1534
{
 
1535
        struct iwl3945_channel_power_info *power_info;
 
1536
        int power_changed = 0;
 
1537
        int i;
 
1538
        const s8 *clip_pwrs;
 
1539
        int power;
 
1540
 
 
1541
        /* Get this chnlgrp's rate-to-max/clip-powers table */
 
1542
        clip_pwrs = priv->clip_groups[ch_info->group_index].clip_powers;
 
1543
 
 
1544
        /* Get this channel's rate-to-current-power settings table */
 
1545
        power_info = ch_info->power_info;
 
1546
 
 
1547
        /* update OFDM Txpower settings */
 
1548
        for (i = IWL_RATE_6M_INDEX_TABLE; i <= IWL_RATE_54M_INDEX_TABLE;
 
1549
             i++, ++power_info) {
 
1550
                int delta_idx;
 
1551
 
 
1552
                /* limit new power to be no more than h/w capability */
 
1553
                power = min(ch_info->curr_txpow, clip_pwrs[i]);
 
1554
                if (power == power_info->requested_power)
 
1555
                        continue;
 
1556
 
 
1557
                /* find difference between old and new requested powers,
 
1558
                 *    update base (non-temp-compensated) power index */
 
1559
                delta_idx = (power - power_info->requested_power) * 2;
 
1560
                power_info->base_power_index -= delta_idx;
 
1561
 
 
1562
                /* save new requested power value */
 
1563
                power_info->requested_power = power;
 
1564
 
 
1565
                power_changed = 1;
 
1566
        }
 
1567
 
 
1568
        /* update CCK Txpower settings, based on OFDM 12M setting ...
 
1569
         *    ... all CCK power settings for a given channel are the *same*. */
 
1570
        if (power_changed) {
 
1571
                power =
 
1572
                    ch_info->power_info[IWL_RATE_12M_INDEX_TABLE].
 
1573
                    requested_power + IWL_CCK_FROM_OFDM_POWER_DIFF;
 
1574
 
 
1575
                /* do all CCK rates' iwl3945_channel_power_info structures */
 
1576
                for (i = IWL_RATE_1M_INDEX_TABLE; i <= IWL_RATE_11M_INDEX_TABLE; i++) {
 
1577
                        power_info->requested_power = power;
 
1578
                        power_info->base_power_index =
 
1579
                            ch_info->power_info[IWL_RATE_12M_INDEX_TABLE].
 
1580
                            base_power_index + IWL_CCK_FROM_OFDM_INDEX_DIFF;
 
1581
                        ++power_info;
 
1582
                }
 
1583
        }
 
1584
 
 
1585
        return 0;
 
1586
}
 
1587
 
 
1588
/**
 
1589
 * iwl3945_hw_reg_get_ch_txpower_limit - returns new power limit for channel
 
1590
 *
 
1591
 * NOTE: Returned power limit may be less (but not more) than requested,
 
1592
 *       based strictly on regulatory (eeprom and spectrum mgt) limitations
 
1593
 *       (no consideration for h/w clipping limitations).
 
1594
 */
 
1595
static int iwl3945_hw_reg_get_ch_txpower_limit(struct iwl3945_channel_info *ch_info)
 
1596
{
 
1597
        s8 max_power;
 
1598
 
 
1599
#if 0
 
1600
        /* if we're using TGd limits, use lower of TGd or EEPROM */
 
1601
        if (ch_info->tgd_data.max_power != 0)
 
1602
                max_power = min(ch_info->tgd_data.max_power,
 
1603
                                ch_info->eeprom.max_power_avg);
 
1604
 
 
1605
        /* else just use EEPROM limits */
 
1606
        else
 
1607
#endif
 
1608
                max_power = ch_info->eeprom.max_power_avg;
 
1609
 
 
1610
        return min(max_power, ch_info->max_power_avg);
 
1611
}
 
1612
 
 
1613
/**
 
1614
 * iwl3945_hw_reg_comp_txpower_temp - Compensate for temperature
 
1615
 *
 
1616
 * Compensate txpower settings of *all* channels for temperature.
 
1617
 * This only accounts for the difference between current temperature
 
1618
 *   and the factory calibration temperatures, and bases the new settings
 
1619
 *   on the channel's base_power_index.
 
1620
 *
 
1621
 * If RxOn is "associated", this sends the new Txpower to NIC!
 
1622
 */
 
1623
static int iwl3945_hw_reg_comp_txpower_temp(struct iwl3945_priv *priv)
 
1624
{
 
1625
        struct iwl3945_channel_info *ch_info = NULL;
 
1626
        int delta_index;
 
1627
        const s8 *clip_pwrs; /* array of h/w max power levels for each rate */
 
1628
        u8 a_band;
 
1629
        u8 rate_index;
 
1630
        u8 scan_tbl_index;
 
1631
        u8 i;
 
1632
        int ref_temp;
 
1633
        int temperature = priv->temperature;
 
1634
 
 
1635
        /* set up new Tx power info for each and every channel, 2.4 and 5.x */
 
1636
        for (i = 0; i < priv->channel_count; i++) {
 
1637
                ch_info = &priv->channel_info[i];
 
1638
                a_band = is_channel_a_band(ch_info);
 
1639
 
 
1640
                /* Get this chnlgrp's factory calibration temperature */
 
1641
                ref_temp = (s16)priv->eeprom.groups[ch_info->group_index].
 
1642
                    temperature;
 
1643
 
 
1644
                /* get power index adjustment based on curr and factory
 
1645
                 * temps */
 
1646
                delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature,
 
1647
                                                              ref_temp);
 
1648
 
 
1649
                /* set tx power value for all rates, OFDM and CCK */
 
1650
                for (rate_index = 0; rate_index < IWL_RATE_COUNT;
 
1651
                     rate_index++) {
 
1652
                        int power_idx =
 
1653
                            ch_info->power_info[rate_index].base_power_index;
 
1654
 
 
1655
                        /* temperature compensate */
 
1656
                        power_idx += delta_index;
 
1657
 
 
1658
                        /* stay within table range */
 
1659
                        power_idx = iwl3945_hw_reg_fix_power_index(power_idx);
 
1660
                        ch_info->power_info[rate_index].
 
1661
                            power_table_index = (u8) power_idx;
 
1662
                        ch_info->power_info[rate_index].tpc =
 
1663
                            power_gain_table[a_band][power_idx];
 
1664
                }
 
1665
 
 
1666
                /* Get this chnlgrp's rate-to-max/clip-powers table */
 
1667
                clip_pwrs = priv->clip_groups[ch_info->group_index].clip_powers;
 
1668
 
 
1669
                /* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */
 
1670
                for (scan_tbl_index = 0;
 
1671
                     scan_tbl_index < IWL_NUM_SCAN_RATES; scan_tbl_index++) {
 
1672
                        s32 actual_index = (scan_tbl_index == 0) ?
 
1673
                            IWL_RATE_1M_INDEX_TABLE : IWL_RATE_6M_INDEX_TABLE;
 
1674
                        iwl3945_hw_reg_set_scan_power(priv, scan_tbl_index,
 
1675
                                           actual_index, clip_pwrs,
 
1676
                                           ch_info, a_band);
 
1677
                }
 
1678
        }
 
1679
 
 
1680
        /* send Txpower command for current channel to ucode */
 
1681
        return iwl3945_hw_reg_send_txpower(priv);
 
1682
}
 
1683
 
 
1684
int iwl3945_hw_reg_set_txpower(struct iwl3945_priv *priv, s8 power)
 
1685
{
 
1686
        struct iwl3945_channel_info *ch_info;
 
1687
        s8 max_power;
 
1688
        u8 a_band;
 
1689
        u8 i;
 
1690
 
 
1691
        if (priv->user_txpower_limit == power) {
 
1692
                IWL_DEBUG_POWER("Requested Tx power same as current "
 
1693
                                "limit: %ddBm.\n", power);
 
1694
                return 0;
 
1695
        }
 
1696
 
 
1697
        IWL_DEBUG_POWER("Setting upper limit clamp to %ddBm.\n", power);
 
1698
        priv->user_txpower_limit = power;
 
1699
 
 
1700
        /* set up new Tx powers for each and every channel, 2.4 and 5.x */
 
1701
 
 
1702
        for (i = 0; i < priv->channel_count; i++) {
 
1703
                ch_info = &priv->channel_info[i];
 
1704
                a_band = is_channel_a_band(ch_info);
 
1705
 
 
1706
                /* find minimum power of all user and regulatory constraints
 
1707
                 *    (does not consider h/w clipping limitations) */
 
1708
                max_power = iwl3945_hw_reg_get_ch_txpower_limit(ch_info);
 
1709
                max_power = min(power, max_power);
 
1710
                if (max_power != ch_info->curr_txpow) {
 
1711
                        ch_info->curr_txpow = max_power;
 
1712
 
 
1713
                        /* this considers the h/w clipping limitations */
 
1714
                        iwl3945_hw_reg_set_new_power(priv, ch_info);
 
1715
                }
 
1716
        }
 
1717
 
 
1718
        /* update txpower settings for all channels,
 
1719
         *   send to NIC if associated. */
 
1720
        is_temp_calib_needed(priv);
 
1721
        iwl3945_hw_reg_comp_txpower_temp(priv);
 
1722
 
 
1723
        return 0;
 
1724
}
 
1725
 
 
1726
/* will add 3945 channel switch cmd handling later */
 
1727
int iwl3945_hw_channel_switch(struct iwl3945_priv *priv, u16 channel)
 
1728
{
 
1729
        return 0;
 
1730
}
 
1731
 
 
1732
/**
 
1733
 * iwl3945_reg_txpower_periodic -  called when time to check our temperature.
 
1734
 *
 
1735
 * -- reset periodic timer
 
1736
 * -- see if temp has changed enough to warrant re-calibration ... if so:
 
1737
 *     -- correct coeffs for temp (can reset temp timer)
 
1738
 *     -- save this temp as "last",
 
1739
 *     -- send new set of gain settings to NIC
 
1740
 * NOTE:  This should continue working, even when we're not associated,
 
1741
 *   so we can keep our internal table of scan powers current. */
 
1742
void iwl3945_reg_txpower_periodic(struct iwl3945_priv *priv)
 
1743
{
 
1744
        /* This will kick in the "brute force"
 
1745
         * iwl3945_hw_reg_comp_txpower_temp() below */
 
1746
        if (!is_temp_calib_needed(priv))
 
1747
                goto reschedule;
 
1748
 
 
1749
        /* Set up a new set of temp-adjusted TxPowers, send to NIC.
 
1750
         * This is based *only* on current temperature,
 
1751
         * ignoring any previous power measurements */
 
1752
        iwl3945_hw_reg_comp_txpower_temp(priv);
 
1753
 
 
1754
 reschedule:
 
1755
        queue_delayed_work(priv->workqueue,
 
1756
                           &priv->thermal_periodic, REG_RECALIB_PERIOD * HZ);
 
1757
}
 
1758
 
 
1759
static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work)
 
1760
{
 
1761
        struct iwl3945_priv *priv = container_of(work, struct iwl3945_priv,
 
1762
                                             thermal_periodic.work);
 
1763
 
 
1764
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
 
1765
                return;
 
1766
 
 
1767
        mutex_lock(&priv->mutex);
 
1768
        iwl3945_reg_txpower_periodic(priv);
 
1769
        mutex_unlock(&priv->mutex);
 
1770
}
 
1771
 
 
1772
/**
 
1773
 * iwl3945_hw_reg_get_ch_grp_index - find the channel-group index (0-4)
 
1774
 *                                 for the channel.
 
1775
 *
 
1776
 * This function is used when initializing channel-info structs.
 
1777
 *
 
1778
 * NOTE: These channel groups do *NOT* match the bands above!
 
1779
 *       These channel groups are based on factory-tested channels;
 
1780
 *       on A-band, EEPROM's "group frequency" entries represent the top
 
1781
 *       channel in each group 1-4.  Group 5 All B/G channels are in group 0.
 
1782
 */
 
1783
static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl3945_priv *priv,
 
1784
                                       const struct iwl3945_channel_info *ch_info)
 
1785
{
 
1786
        struct iwl3945_eeprom_txpower_group *ch_grp = &priv->eeprom.groups[0];
 
1787
        u8 group;
 
1788
        u16 group_index = 0;    /* based on factory calib frequencies */
 
1789
        u8 grp_channel;
 
1790
 
 
1791
        /* Find the group index for the channel ... don't use index 1(?) */
 
1792
        if (is_channel_a_band(ch_info)) {
 
1793
                for (group = 1; group < 5; group++) {
 
1794
                        grp_channel = ch_grp[group].group_channel;
 
1795
                        if (ch_info->channel <= grp_channel) {
 
1796
                                group_index = group;
 
1797
                                break;
 
1798
                        }
 
1799
                }
 
1800
                /* group 4 has a few channels *above* its factory cal freq */
 
1801
                if (group == 5)
 
1802
                        group_index = 4;
 
1803
        } else
 
1804
                group_index = 0;        /* 2.4 GHz, group 0 */
 
1805
 
 
1806
        IWL_DEBUG_POWER("Chnl %d mapped to grp %d\n", ch_info->channel,
 
1807
                        group_index);
 
1808
        return group_index;
 
1809
}
 
1810
 
 
1811
/**
 
1812
 * iwl3945_hw_reg_get_matched_power_index - Interpolate to get nominal index
 
1813
 *
 
1814
 * Interpolate to get nominal (i.e. at factory calibration temperature) index
 
1815
 *   into radio/DSP gain settings table for requested power.
 
1816
 */
 
1817
static int iwl3945_hw_reg_get_matched_power_index(struct iwl3945_priv *priv,
 
1818
                                       s8 requested_power,
 
1819
                                       s32 setting_index, s32 *new_index)
 
1820
{
 
1821
        const struct iwl3945_eeprom_txpower_group *chnl_grp = NULL;
 
1822
        s32 index0, index1;
 
1823
        s32 power = 2 * requested_power;
 
1824
        s32 i;
 
1825
        const struct iwl3945_eeprom_txpower_sample *samples;
 
1826
        s32 gains0, gains1;
 
1827
        s32 res;
 
1828
        s32 denominator;
 
1829
 
 
1830
        chnl_grp = &priv->eeprom.groups[setting_index];
 
1831
        samples = chnl_grp->samples;
 
1832
        for (i = 0; i < 5; i++) {
 
1833
                if (power == samples[i].power) {
 
1834
                        *new_index = samples[i].gain_index;
 
1835
                        return 0;
 
1836
                }
 
1837
        }
 
1838
 
 
1839
        if (power > samples[1].power) {
 
1840
                index0 = 0;
 
1841
                index1 = 1;
 
1842
        } else if (power > samples[2].power) {
 
1843
                index0 = 1;
 
1844
                index1 = 2;
 
1845
        } else if (power > samples[3].power) {
 
1846
                index0 = 2;
 
1847
                index1 = 3;
 
1848
        } else {
 
1849
                index0 = 3;
 
1850
                index1 = 4;
 
1851
        }
 
1852
 
 
1853
        denominator = (s32) samples[index1].power - (s32) samples[index0].power;
 
1854
        if (denominator == 0)
 
1855
                return -EINVAL;
 
1856
        gains0 = (s32) samples[index0].gain_index * (1 << 19);
 
1857
        gains1 = (s32) samples[index1].gain_index * (1 << 19);
 
1858
        res = gains0 + (gains1 - gains0) *
 
1859
            ((s32) power - (s32) samples[index0].power) / denominator +
 
1860
            (1 << 18);
 
1861
        *new_index = res >> 19;
 
1862
        return 0;
 
1863
}
 
1864
 
 
1865
static void iwl3945_hw_reg_init_channel_groups(struct iwl3945_priv *priv)
 
1866
{
 
1867
        u32 i;
 
1868
        s32 rate_index;
 
1869
        const struct iwl3945_eeprom_txpower_group *group;
 
1870
 
 
1871
        IWL_DEBUG_POWER("Initializing factory calib info from EEPROM\n");
 
1872
 
 
1873
        for (i = 0; i < IWL_NUM_TX_CALIB_GROUPS; i++) {
 
1874
                s8 *clip_pwrs;  /* table of power levels for each rate */
 
1875
                s8 satur_pwr;   /* saturation power for each chnl group */
 
1876
                group = &priv->eeprom.groups[i];
 
1877
 
 
1878
                /* sanity check on factory saturation power value */
 
1879
                if (group->saturation_power < 40) {
 
1880
                        IWL_WARNING("Error: saturation power is %d, "
 
1881
                                    "less than minimum expected 40\n",
 
1882
                                    group->saturation_power);
 
1883
                        return;
 
1884
                }
 
1885
 
 
1886
                /*
 
1887
                 * Derive requested power levels for each rate, based on
 
1888
                 *   hardware capabilities (saturation power for band).
 
1889
                 * Basic value is 3dB down from saturation, with further
 
1890
                 *   power reductions for highest 3 data rates.  These
 
1891
                 *   backoffs provide headroom for high rate modulation
 
1892
                 *   power peaks, without too much distortion (clipping).
 
1893
                 */
 
1894
                /* we'll fill in this array with h/w max power levels */
 
1895
                clip_pwrs = (s8 *) priv->clip_groups[i].clip_powers;
 
1896
 
 
1897
                /* divide factory saturation power by 2 to find -3dB level */
 
1898
                satur_pwr = (s8) (group->saturation_power >> 1);
 
1899
 
 
1900
                /* fill in channel group's nominal powers for each rate */
 
1901
                for (rate_index = 0;
 
1902
                     rate_index < IWL_RATE_COUNT; rate_index++, clip_pwrs++) {
 
1903
                        switch (rate_index) {
 
1904
                        case IWL_RATE_36M_INDEX_TABLE:
 
1905
                                if (i == 0)     /* B/G */
 
1906
                                        *clip_pwrs = satur_pwr;
 
1907
                                else    /* A */
 
1908
                                        *clip_pwrs = satur_pwr - 5;
 
1909
                                break;
 
1910
                        case IWL_RATE_48M_INDEX_TABLE:
 
1911
                                if (i == 0)
 
1912
                                        *clip_pwrs = satur_pwr - 7;
 
1913
                                else
 
1914
                                        *clip_pwrs = satur_pwr - 10;
 
1915
                                break;
 
1916
                        case IWL_RATE_54M_INDEX_TABLE:
 
1917
                                if (i == 0)
 
1918
                                        *clip_pwrs = satur_pwr - 9;
 
1919
                                else
 
1920
                                        *clip_pwrs = satur_pwr - 12;
 
1921
                                break;
 
1922
                        default:
 
1923
                                *clip_pwrs = satur_pwr;
 
1924
                                break;
 
1925
                        }
 
1926
                }
 
1927
        }
 
1928
}
 
1929
 
 
1930
/**
 
1931
 * iwl3945_txpower_set_from_eeprom - Set channel power info based on EEPROM
 
1932
 *
 
1933
 * Second pass (during init) to set up priv->channel_info
 
1934
 *
 
1935
 * Set up Tx-power settings in our channel info database for each VALID
 
1936
 * (for this geo/SKU) channel, at all Tx data rates, based on eeprom values
 
1937
 * and current temperature.
 
1938
 *
 
1939
 * Since this is based on current temperature (at init time), these values may
 
1940
 * not be valid for very long, but it gives us a starting/default point,
 
1941
 * and allows us to active (i.e. using Tx) scan.
 
1942
 *
 
1943
 * This does *not* write values to NIC, just sets up our internal table.
 
1944
 */
 
1945
int iwl3945_txpower_set_from_eeprom(struct iwl3945_priv *priv)
 
1946
{
 
1947
        struct iwl3945_channel_info *ch_info = NULL;
 
1948
        struct iwl3945_channel_power_info *pwr_info;
 
1949
        int delta_index;
 
1950
        u8 rate_index;
 
1951
        u8 scan_tbl_index;
 
1952
        const s8 *clip_pwrs;    /* array of power levels for each rate */
 
1953
        u8 gain, dsp_atten;
 
1954
        s8 power;
 
1955
        u8 pwr_index, base_pwr_index, a_band;
 
1956
        u8 i;
 
1957
        int temperature;
 
1958
 
 
1959
        /* save temperature reference,
 
1960
         *   so we can determine next time to calibrate */
 
1961
        temperature = iwl3945_hw_reg_txpower_get_temperature(priv);
 
1962
        priv->last_temperature = temperature;
 
1963
 
 
1964
        iwl3945_hw_reg_init_channel_groups(priv);
 
1965
 
 
1966
        /* initialize Tx power info for each and every channel, 2.4 and 5.x */
 
1967
        for (i = 0, ch_info = priv->channel_info; i < priv->channel_count;
 
1968
             i++, ch_info++) {
 
1969
                a_band = is_channel_a_band(ch_info);
 
1970
                if (!is_channel_valid(ch_info))
 
1971
                        continue;
 
1972
 
 
1973
                /* find this channel's channel group (*not* "band") index */
 
1974
                ch_info->group_index =
 
1975
                        iwl3945_hw_reg_get_ch_grp_index(priv, ch_info);
 
1976
 
 
1977
                /* Get this chnlgrp's rate->max/clip-powers table */
 
1978
                clip_pwrs = priv->clip_groups[ch_info->group_index].clip_powers;
 
1979
 
 
1980
                /* calculate power index *adjustment* value according to
 
1981
                 *  diff between current temperature and factory temperature */
 
1982
                delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature,
 
1983
                                priv->eeprom.groups[ch_info->group_index].
 
1984
                                temperature);
 
1985
 
 
1986
                IWL_DEBUG_POWER("Delta index for channel %d: %d [%d]\n",
 
1987
                                ch_info->channel, delta_index, temperature +
 
1988
                                IWL_TEMP_CONVERT);
 
1989
 
 
1990
                /* set tx power value for all OFDM rates */
 
1991
                for (rate_index = 0; rate_index < IWL_OFDM_RATES;
 
1992
                     rate_index++) {
 
1993
                        s32 power_idx;
 
1994
                        int rc;
 
1995
 
 
1996
                        /* use channel group's clip-power table,
 
1997
                         *   but don't exceed channel's max power */
 
1998
                        s8 pwr = min(ch_info->max_power_avg,
 
1999
                                     clip_pwrs[rate_index]);
 
2000
 
 
2001
                        pwr_info = &ch_info->power_info[rate_index];
 
2002
 
 
2003
                        /* get base (i.e. at factory-measured temperature)
 
2004
                         *    power table index for this rate's power */
 
2005
                        rc = iwl3945_hw_reg_get_matched_power_index(priv, pwr,
 
2006
                                                         ch_info->group_index,
 
2007
                                                         &power_idx);
 
2008
                        if (rc) {
 
2009
                                IWL_ERROR("Invalid power index\n");
 
2010
                                return rc;
 
2011
                        }
 
2012
                        pwr_info->base_power_index = (u8) power_idx;
 
2013
 
 
2014
                        /* temperature compensate */
 
2015
                        power_idx += delta_index;
 
2016
 
 
2017
                        /* stay within range of gain table */
 
2018
                        power_idx = iwl3945_hw_reg_fix_power_index(power_idx);
 
2019
 
 
2020
                        /* fill 1 OFDM rate's iwl3945_channel_power_info struct */
 
2021
                        pwr_info->requested_power = pwr;
 
2022
                        pwr_info->power_table_index = (u8) power_idx;
 
2023
                        pwr_info->tpc.tx_gain =
 
2024
                            power_gain_table[a_band][power_idx].tx_gain;
 
2025
                        pwr_info->tpc.dsp_atten =
 
2026
                            power_gain_table[a_band][power_idx].dsp_atten;
 
2027
                }
 
2028
 
 
2029
                /* set tx power for CCK rates, based on OFDM 12 Mbit settings*/
 
2030
                pwr_info = &ch_info->power_info[IWL_RATE_12M_INDEX_TABLE];
 
2031
                power = pwr_info->requested_power +
 
2032
                        IWL_CCK_FROM_OFDM_POWER_DIFF;
 
2033
                pwr_index = pwr_info->power_table_index +
 
2034
                        IWL_CCK_FROM_OFDM_INDEX_DIFF;
 
2035
                base_pwr_index = pwr_info->base_power_index +
 
2036
                        IWL_CCK_FROM_OFDM_INDEX_DIFF;
 
2037
 
 
2038
                /* stay within table range */
 
2039
                pwr_index = iwl3945_hw_reg_fix_power_index(pwr_index);
 
2040
                gain = power_gain_table[a_band][pwr_index].tx_gain;
 
2041
                dsp_atten = power_gain_table[a_band][pwr_index].dsp_atten;
 
2042
 
 
2043
                /* fill each CCK rate's iwl3945_channel_power_info structure
 
2044
                 * NOTE:  All CCK-rate Txpwrs are the same for a given chnl!
 
2045
                 * NOTE:  CCK rates start at end of OFDM rates! */
 
2046
                for (rate_index = 0;
 
2047
                     rate_index < IWL_CCK_RATES; rate_index++) {
 
2048
                        pwr_info = &ch_info->power_info[rate_index+IWL_OFDM_RATES];
 
2049
                        pwr_info->requested_power = power;
 
2050
                        pwr_info->power_table_index = pwr_index;
 
2051
                        pwr_info->base_power_index = base_pwr_index;
 
2052
                        pwr_info->tpc.tx_gain = gain;
 
2053
                        pwr_info->tpc.dsp_atten = dsp_atten;
 
2054
                }
 
2055
 
 
2056
                /* set scan tx power, 1Mbit for CCK, 6Mbit for OFDM */
 
2057
                for (scan_tbl_index = 0;
 
2058
                     scan_tbl_index < IWL_NUM_SCAN_RATES; scan_tbl_index++) {
 
2059
                        s32 actual_index = (scan_tbl_index == 0) ?
 
2060
                                IWL_RATE_1M_INDEX_TABLE : IWL_RATE_6M_INDEX_TABLE;
 
2061
                        iwl3945_hw_reg_set_scan_power(priv, scan_tbl_index,
 
2062
                                actual_index, clip_pwrs, ch_info, a_band);
 
2063
                }
 
2064
        }
 
2065
 
 
2066
        return 0;
 
2067
}
 
2068
 
 
2069
int iwl3945_hw_rxq_stop(struct iwl3945_priv *priv)
 
2070
{
 
2071
        int rc;
 
2072
        unsigned long flags;
 
2073
 
 
2074
        spin_lock_irqsave(&priv->lock, flags);
 
2075
        rc = iwl3945_grab_nic_access(priv);
 
2076
        if (rc) {
 
2077
                spin_unlock_irqrestore(&priv->lock, flags);
 
2078
                return rc;
 
2079
        }
 
2080
 
 
2081
        iwl3945_write_direct32(priv, FH_RCSR_CONFIG(0), 0);
 
2082
        rc = iwl3945_poll_direct_bit(priv, FH_RSSR_STATUS, (1 << 24), 1000);
 
2083
        if (rc < 0)
 
2084
                IWL_ERROR("Can't stop Rx DMA.\n");
 
2085
 
 
2086
        iwl3945_release_nic_access(priv);
 
2087
        spin_unlock_irqrestore(&priv->lock, flags);
 
2088
 
 
2089
        return 0;
 
2090
}
 
2091
 
 
2092
int iwl3945_hw_tx_queue_init(struct iwl3945_priv *priv, struct iwl3945_tx_queue *txq)
 
2093
{
 
2094
        int rc;
 
2095
        unsigned long flags;
 
2096
        int txq_id = txq->q.id;
 
2097
 
 
2098
        struct iwl3945_shared *shared_data = priv->hw_setting.shared_virt;
 
2099
 
 
2100
        shared_data->tx_base_ptr[txq_id] = cpu_to_le32((u32)txq->q.dma_addr);
 
2101
 
 
2102
        spin_lock_irqsave(&priv->lock, flags);
 
2103
        rc = iwl3945_grab_nic_access(priv);
 
2104
        if (rc) {
 
2105
                spin_unlock_irqrestore(&priv->lock, flags);
 
2106
                return rc;
 
2107
        }
 
2108
        iwl3945_write_direct32(priv, FH_CBCC_CTRL(txq_id), 0);
 
2109
        iwl3945_write_direct32(priv, FH_CBCC_BASE(txq_id), 0);
 
2110
 
 
2111
        iwl3945_write_direct32(priv, FH_TCSR_CONFIG(txq_id),
 
2112
                ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_RTC_NOINT |
 
2113
                ALM_FH_TCSR_TX_CONFIG_REG_VAL_MSG_MODE_TXF |
 
2114
                ALM_FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_IFTFD |
 
2115
                ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_ENABLE_VAL |
 
2116
                ALM_FH_TCSR_TX_CONFIG_REG_VAL_DMA_CHNL_ENABLE);
 
2117
        iwl3945_release_nic_access(priv);
 
2118
 
 
2119
        /* fake read to flush all prev. writes */
 
2120
        iwl3945_read32(priv, FH_TSSR_CBB_BASE);
 
2121
        spin_unlock_irqrestore(&priv->lock, flags);
 
2122
 
 
2123
        return 0;
 
2124
}
 
2125
 
 
2126
int iwl3945_hw_get_rx_read(struct iwl3945_priv *priv)
 
2127
{
 
2128
        struct iwl3945_shared *shared_data = priv->hw_setting.shared_virt;
 
2129
 
 
2130
        return le32_to_cpu(shared_data->rx_read_ptr[0]);
 
2131
}
 
2132
 
 
2133
/**
 
2134
 * iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table
 
2135
 */
 
2136
int iwl3945_init_hw_rate_table(struct iwl3945_priv *priv)
 
2137
{
 
2138
        int rc, i, index, prev_index;
 
2139
        struct iwl3945_rate_scaling_cmd rate_cmd = {
 
2140
                .reserved = {0, 0, 0},
 
2141
        };
 
2142
        struct iwl3945_rate_scaling_info *table = rate_cmd.table;
 
2143
 
 
2144
        for (i = 0; i < ARRAY_SIZE(iwl3945_rates); i++) {
 
2145
                index = iwl3945_rates[i].table_rs_index;
 
2146
 
 
2147
                table[index].rate_n_flags =
 
2148
                        iwl3945_hw_set_rate_n_flags(iwl3945_rates[i].plcp, 0);
 
2149
                table[index].try_cnt = priv->retry_rate;
 
2150
                prev_index = iwl3945_get_prev_ieee_rate(i);
 
2151
                table[index].next_rate_index = iwl3945_rates[prev_index].table_rs_index;
 
2152
        }
 
2153
 
 
2154
        switch (priv->phymode) {
 
2155
        case MODE_IEEE80211A:
 
2156
                IWL_DEBUG_RATE("Select A mode rate scale\n");
 
2157
                /* If one of the following CCK rates is used,
 
2158
                 * have it fall back to the 6M OFDM rate */
 
2159
                for (i = IWL_RATE_1M_INDEX_TABLE; i <= IWL_RATE_11M_INDEX_TABLE; i++)
 
2160
                        table[i].next_rate_index = iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index;
 
2161
 
 
2162
                /* Don't fall back to CCK rates */
 
2163
                table[IWL_RATE_12M_INDEX_TABLE].next_rate_index = IWL_RATE_9M_INDEX_TABLE;
 
2164
 
 
2165
                /* Don't drop out of OFDM rates */
 
2166
                table[IWL_RATE_6M_INDEX_TABLE].next_rate_index =
 
2167
                    iwl3945_rates[IWL_FIRST_OFDM_RATE].table_rs_index;
 
2168
                break;
 
2169
 
 
2170
        case MODE_IEEE80211B:
 
2171
                IWL_DEBUG_RATE("Select B mode rate scale\n");
 
2172
                /* If an OFDM rate is used, have it fall back to the
 
2173
                 * 1M CCK rates */
 
2174
                for (i = IWL_RATE_6M_INDEX_TABLE; i <= IWL_RATE_54M_INDEX_TABLE; i++)
 
2175
                        table[i].next_rate_index = iwl3945_rates[IWL_FIRST_CCK_RATE].table_rs_index;
 
2176
 
 
2177
                /* CCK shouldn't fall back to OFDM... */
 
2178
                table[IWL_RATE_11M_INDEX_TABLE].next_rate_index = IWL_RATE_5M_INDEX_TABLE;
 
2179
                break;
 
2180
 
 
2181
        default:
 
2182
                IWL_DEBUG_RATE("Select G mode rate scale\n");
 
2183
                break;
 
2184
        }
 
2185
 
 
2186
        /* Update the rate scaling for control frame Tx */
 
2187
        rate_cmd.table_id = 0;
 
2188
        rc = iwl3945_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
 
2189
                              &rate_cmd);
 
2190
        if (rc)
 
2191
                return rc;
 
2192
 
 
2193
        /* Update the rate scaling for data frame Tx */
 
2194
        rate_cmd.table_id = 1;
 
2195
        return iwl3945_send_cmd_pdu(priv, REPLY_RATE_SCALE, sizeof(rate_cmd),
 
2196
                                &rate_cmd);
 
2197
}
 
2198
 
 
2199
/* Called when initializing driver */
 
2200
int iwl3945_hw_set_hw_setting(struct iwl3945_priv *priv)
 
2201
{
 
2202
        memset((void *)&priv->hw_setting, 0,
 
2203
               sizeof(struct iwl3945_driver_hw_info));
 
2204
 
 
2205
        priv->hw_setting.shared_virt =
 
2206
            pci_alloc_consistent(priv->pci_dev,
 
2207
                                 sizeof(struct iwl3945_shared),
 
2208
                                 &priv->hw_setting.shared_phys);
 
2209
 
 
2210
        if (!priv->hw_setting.shared_virt) {
 
2211
                IWL_ERROR("failed to allocate pci memory\n");
 
2212
                mutex_unlock(&priv->mutex);
 
2213
                return -ENOMEM;
 
2214
        }
 
2215
 
 
2216
        priv->hw_setting.ac_queue_count = AC_NUM;
 
2217
        priv->hw_setting.rx_buffer_size = IWL_RX_BUF_SIZE;
 
2218
        priv->hw_setting.tx_cmd_len = sizeof(struct iwl3945_tx_cmd);
 
2219
        priv->hw_setting.max_rxq_size = RX_QUEUE_SIZE;
 
2220
        priv->hw_setting.max_rxq_log = RX_QUEUE_SIZE_LOG;
 
2221
        priv->hw_setting.max_stations = IWL3945_STATION_COUNT;
 
2222
        priv->hw_setting.bcast_sta_id = IWL3945_BROADCAST_ID;
 
2223
        return 0;
 
2224
}
 
2225
 
 
2226
unsigned int iwl3945_hw_get_beacon_cmd(struct iwl3945_priv *priv,
 
2227
                          struct iwl3945_frame *frame, u8 rate)
 
2228
{
 
2229
        struct iwl3945_tx_beacon_cmd *tx_beacon_cmd;
 
2230
        unsigned int frame_size;
 
2231
 
 
2232
        tx_beacon_cmd = (struct iwl3945_tx_beacon_cmd *)&frame->u;
 
2233
        memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
 
2234
 
 
2235
        tx_beacon_cmd->tx.sta_id = IWL3945_BROADCAST_ID;
 
2236
        tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
 
2237
 
 
2238
        frame_size = iwl3945_fill_beacon_frame(priv,
 
2239
                                tx_beacon_cmd->frame,
 
2240
                                iwl3945_broadcast_addr,
 
2241
                                sizeof(frame->u) - sizeof(*tx_beacon_cmd));
 
2242
 
 
2243
        BUG_ON(frame_size > MAX_MPDU_SIZE);
 
2244
        tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
 
2245
 
 
2246
        tx_beacon_cmd->tx.rate = rate;
 
2247
        tx_beacon_cmd->tx.tx_flags = (TX_CMD_FLG_SEQ_CTL_MSK |
 
2248
                                      TX_CMD_FLG_TSF_MSK);
 
2249
 
 
2250
        /* supp_rates[0] == OFDM start at IWL_FIRST_OFDM_RATE*/
 
2251
        tx_beacon_cmd->tx.supp_rates[0] =
 
2252
                (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
 
2253
 
 
2254
        tx_beacon_cmd->tx.supp_rates[1] =
 
2255
                (IWL_CCK_BASIC_RATES_MASK & 0xF);
 
2256
 
 
2257
        return (sizeof(struct iwl3945_tx_beacon_cmd) + frame_size);
 
2258
}
 
2259
 
 
2260
void iwl3945_hw_rx_handler_setup(struct iwl3945_priv *priv)
 
2261
{
 
2262
        priv->rx_handlers[REPLY_3945_RX] = iwl3945_rx_reply_rx;
 
2263
}
 
2264
 
 
2265
void iwl3945_hw_setup_deferred_work(struct iwl3945_priv *priv)
 
2266
{
 
2267
        INIT_DELAYED_WORK(&priv->thermal_periodic,
 
2268
                          iwl3945_bg_reg_txpower_periodic);
 
2269
}
 
2270
 
 
2271
void iwl3945_hw_cancel_deferred_work(struct iwl3945_priv *priv)
 
2272
{
 
2273
        cancel_delayed_work(&priv->thermal_periodic);
 
2274
}
 
2275
 
 
2276
struct pci_device_id iwl3945_hw_card_ids[] = {
 
2277
        {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4222)},
 
2278
        {PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x4227)},
 
2279
        {0}
 
2280
};
 
2281
 
 
2282
/*
 
2283
 * Clear the OWNER_MSK, to establish driver (instead of uCode running on
 
2284
 * embedded controller) as EEPROM reader; each read is a series of pulses
 
2285
 * to/from the EEPROM chip, not a single event, so even reads could conflict
 
2286
 * if they weren't arbitrated by some ownership mechanism.  Here, the driver
 
2287
 * simply claims ownership, which should be safe when this function is called
 
2288
 * (i.e. before loading uCode!).
 
2289
 */
 
2290
inline int iwl3945_eeprom_acquire_semaphore(struct iwl3945_priv *priv)
 
2291
{
 
2292
        _iwl3945_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
 
2293
        return 0;
 
2294
}
 
2295
 
 
2296
MODULE_DEVICE_TABLE(pci, iwl3945_hw_card_ids);