]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/net/wireless/ipw2100.c
[PATCH] ieee80211: Updated ipw2100 to be compatible with ieee80211_hdr changes
[mirror_ubuntu-artful-kernel.git] / drivers / net / wireless / ipw2100.c
CommitLineData
2c86c275
JK
1/******************************************************************************
2
3 Copyright(c) 2003 - 2005 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., 59
16 Temple Place - Suite 330, Boston, MA 02111-1307, 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 Portions of this file are based on the sample_* files provided by Wireless
26 Extensions 0.26 package and copyright (c) 1997-2003 Jean Tourrilhes
27 <jt@hpl.hp.com>
28
29 Portions of this file are based on the Host AP project,
30 Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
31 <jkmaline@cc.hut.fi>
32 Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
33
34 Portions of ipw2100_mod_firmware_load, ipw2100_do_mod_firmware_load, and
35 ipw2100_fw_load are loosely based on drivers/sound/sound_firmware.c
36 available in the 2.4.25 kernel sources, and are copyright (c) Alan Cox
37
38******************************************************************************/
39/*
40
41 Initial driver on which this is based was developed by Janusz Gorycki,
42 Maciej Urbaniak, and Maciej Sosnowski.
43
44 Promiscuous mode support added by Jacek Wysoczynski and Maciej Urbaniak.
45
46Theory of Operation
47
48Tx - Commands and Data
49
50Firmware and host share a circular queue of Transmit Buffer Descriptors (TBDs)
51Each TBD contains a pointer to the physical (dma_addr_t) address of data being
52sent to the firmware as well as the length of the data.
53
54The host writes to the TBD queue at the WRITE index. The WRITE index points
55to the _next_ packet to be written and is advanced when after the TBD has been
56filled.
57
58The firmware pulls from the TBD queue at the READ index. The READ index points
59to the currently being read entry, and is advanced once the firmware is
60done with a packet.
61
62When data is sent to the firmware, the first TBD is used to indicate to the
63firmware if a Command or Data is being sent. If it is Command, all of the
64command information is contained within the physical address referred to by the
65TBD. If it is Data, the first TBD indicates the type of data packet, number
66of fragments, etc. The next TBD then referrs to the actual packet location.
67
68The Tx flow cycle is as follows:
69
701) ipw2100_tx() is called by kernel with SKB to transmit
712) Packet is move from the tx_free_list and appended to the transmit pending
72 list (tx_pend_list)
733) work is scheduled to move pending packets into the shared circular queue.
744) when placing packet in the circular queue, the incoming SKB is DMA mapped
75 to a physical address. That address is entered into a TBD. Two TBDs are
76 filled out. The first indicating a data packet, the second referring to the
77 actual payload data.
785) the packet is removed from tx_pend_list and placed on the end of the
79 firmware pending list (fw_pend_list)
806) firmware is notified that the WRITE index has
817) Once the firmware has processed the TBD, INTA is triggered.
828) For each Tx interrupt received from the firmware, the READ index is checked
83 to see which TBDs are done being processed.
849) For each TBD that has been processed, the ISR pulls the oldest packet
85 from the fw_pend_list.
8610)The packet structure contained in the fw_pend_list is then used
87 to unmap the DMA address and to free the SKB originally passed to the driver
88 from the kernel.
8911)The packet structure is placed onto the tx_free_list
90
91The above steps are the same for commands, only the msg_free_list/msg_pend_list
92are used instead of tx_free_list/tx_pend_list
93
94...
95
96Critical Sections / Locking :
97
98There are two locks utilized. The first is the low level lock (priv->low_lock)
99that protects the following:
100
101- Access to the Tx/Rx queue lists via priv->low_lock. The lists are as follows:
102
103 tx_free_list : Holds pre-allocated Tx buffers.
104 TAIL modified in __ipw2100_tx_process()
105 HEAD modified in ipw2100_tx()
106
107 tx_pend_list : Holds used Tx buffers waiting to go into the TBD ring
108 TAIL modified ipw2100_tx()
19f7f742 109 HEAD modified by ipw2100_tx_send_data()
2c86c275
JK
110
111 msg_free_list : Holds pre-allocated Msg (Command) buffers
112 TAIL modified in __ipw2100_tx_process()
113 HEAD modified in ipw2100_hw_send_command()
114
115 msg_pend_list : Holds used Msg buffers waiting to go into the TBD ring
116 TAIL modified in ipw2100_hw_send_command()
19f7f742 117 HEAD modified in ipw2100_tx_send_commands()
2c86c275
JK
118
119 The flow of data on the TX side is as follows:
120
121 MSG_FREE_LIST + COMMAND => MSG_PEND_LIST => TBD => MSG_FREE_LIST
122 TX_FREE_LIST + DATA => TX_PEND_LIST => TBD => TX_FREE_LIST
123
124 The methods that work on the TBD ring are protected via priv->low_lock.
125
126- The internal data state of the device itself
127- Access to the firmware read/write indexes for the BD queues
128 and associated logic
129
130All external entry functions are locked with the priv->action_lock to ensure
131that only one external action is invoked at a time.
132
133
134*/
135
136#include <linux/compiler.h>
137#include <linux/config.h>
138#include <linux/errno.h>
139#include <linux/if_arp.h>
140#include <linux/in6.h>
141#include <linux/in.h>
142#include <linux/ip.h>
143#include <linux/kernel.h>
144#include <linux/kmod.h>
145#include <linux/module.h>
146#include <linux/netdevice.h>
147#include <linux/ethtool.h>
148#include <linux/pci.h>
05743d16 149#include <linux/dma-mapping.h>
2c86c275
JK
150#include <linux/proc_fs.h>
151#include <linux/skbuff.h>
152#include <asm/uaccess.h>
153#include <asm/io.h>
154#define __KERNEL_SYSCALLS__
155#include <linux/fs.h>
156#include <linux/mm.h>
157#include <linux/slab.h>
158#include <linux/unistd.h>
159#include <linux/stringify.h>
160#include <linux/tcp.h>
161#include <linux/types.h>
162#include <linux/version.h>
163#include <linux/time.h>
164#include <linux/firmware.h>
165#include <linux/acpi.h>
166#include <linux/ctype.h>
167
168#include "ipw2100.h"
169
170#define IPW2100_VERSION "1.1.0"
171
172#define DRV_NAME "ipw2100"
173#define DRV_VERSION IPW2100_VERSION
174#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2100 Network Driver"
175#define DRV_COPYRIGHT "Copyright(c) 2003-2004 Intel Corporation"
176
177
178/* Debugging stuff */
179#ifdef CONFIG_IPW_DEBUG
180#define CONFIG_IPW2100_RX_DEBUG /* Reception debugging */
181#endif
182
183MODULE_DESCRIPTION(DRV_DESCRIPTION);
184MODULE_VERSION(DRV_VERSION);
185MODULE_AUTHOR(DRV_COPYRIGHT);
186MODULE_LICENSE("GPL");
187
188static int debug = 0;
189static int mode = 0;
190static int channel = 0;
191static int associate = 1;
192static int disable = 0;
193#ifdef CONFIG_PM
194static struct ipw2100_fw ipw2100_firmware;
195#endif
196
197#include <linux/moduleparam.h>
198module_param(debug, int, 0444);
199module_param(mode, int, 0444);
200module_param(channel, int, 0444);
201module_param(associate, int, 0444);
202module_param(disable, int, 0444);
203
204MODULE_PARM_DESC(debug, "debug level");
205MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)");
206MODULE_PARM_DESC(channel, "channel");
207MODULE_PARM_DESC(associate, "auto associate when scanning (default on)");
208MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");
209
c4aee8c2
JB
210static u32 ipw2100_debug_level = IPW_DL_NONE;
211
212#ifdef CONFIG_IPW_DEBUG
213#define IPW_DEBUG(level, message...) \
214do { \
215 if (ipw2100_debug_level & (level)) { \
216 printk(KERN_DEBUG "ipw2100: %c %s ", \
217 in_interrupt() ? 'I' : 'U', __FUNCTION__); \
218 printk(message); \
219 } \
220} while (0)
221#else
222#define IPW_DEBUG(level, message...) do {} while (0)
223#endif /* CONFIG_IPW_DEBUG */
2c86c275
JK
224
225#ifdef CONFIG_IPW_DEBUG
226static const char *command_types[] = {
227 "undefined",
228 "unused", /* HOST_ATTENTION */
229 "HOST_COMPLETE",
230 "unused", /* SLEEP */
231 "unused", /* HOST_POWER_DOWN */
232 "unused",
233 "SYSTEM_CONFIG",
234 "unused", /* SET_IMR */
235 "SSID",
236 "MANDATORY_BSSID",
237 "AUTHENTICATION_TYPE",
238 "ADAPTER_ADDRESS",
239 "PORT_TYPE",
240 "INTERNATIONAL_MODE",
241 "CHANNEL",
242 "RTS_THRESHOLD",
243 "FRAG_THRESHOLD",
244 "POWER_MODE",
245 "TX_RATES",
246 "BASIC_TX_RATES",
247 "WEP_KEY_INFO",
248 "unused",
249 "unused",
250 "unused",
251 "unused",
252 "WEP_KEY_INDEX",
253 "WEP_FLAGS",
254 "ADD_MULTICAST",
255 "CLEAR_ALL_MULTICAST",
256 "BEACON_INTERVAL",
257 "ATIM_WINDOW",
258 "CLEAR_STATISTICS",
259 "undefined",
260 "undefined",
261 "undefined",
262 "undefined",
263 "TX_POWER_INDEX",
264 "undefined",
265 "undefined",
266 "undefined",
267 "undefined",
268 "undefined",
269 "undefined",
270 "BROADCAST_SCAN",
271 "CARD_DISABLE",
272 "PREFERRED_BSSID",
273 "SET_SCAN_OPTIONS",
274 "SCAN_DWELL_TIME",
275 "SWEEP_TABLE",
276 "AP_OR_STATION_TABLE",
277 "GROUP_ORDINALS",
278 "SHORT_RETRY_LIMIT",
279 "LONG_RETRY_LIMIT",
280 "unused", /* SAVE_CALIBRATION */
281 "unused", /* RESTORE_CALIBRATION */
282 "undefined",
283 "undefined",
284 "undefined",
285 "HOST_PRE_POWER_DOWN",
286 "unused", /* HOST_INTERRUPT_COALESCING */
287 "undefined",
288 "CARD_DISABLE_PHY_OFF",
289 "MSDU_TX_RATES"
290 "undefined",
291 "undefined",
292 "SET_STATION_STAT_BITS",
293 "CLEAR_STATIONS_STAT_BITS",
294 "LEAP_ROGUE_MODE",
295 "SET_SECURITY_INFORMATION",
296 "DISASSOCIATION_BSSID",
297 "SET_WPA_ASS_IE"
298};
299#endif
300
301
302/* Pre-decl until we get the code solid and then we can clean it up */
19f7f742
JB
303static void ipw2100_tx_send_commands(struct ipw2100_priv *priv);
304static void ipw2100_tx_send_data(struct ipw2100_priv *priv);
2c86c275
JK
305static int ipw2100_adapter_setup(struct ipw2100_priv *priv);
306
307static void ipw2100_queues_initialize(struct ipw2100_priv *priv);
308static void ipw2100_queues_free(struct ipw2100_priv *priv);
309static int ipw2100_queues_allocate(struct ipw2100_priv *priv);
310
c4aee8c2
JB
311static int ipw2100_fw_download(struct ipw2100_priv *priv,
312 struct ipw2100_fw *fw);
313static int ipw2100_get_firmware(struct ipw2100_priv *priv,
314 struct ipw2100_fw *fw);
315static int ipw2100_get_fwversion(struct ipw2100_priv *priv, char *buf,
316 size_t max);
317static int ipw2100_get_ucodeversion(struct ipw2100_priv *priv, char *buf,
318 size_t max);
319static void ipw2100_release_firmware(struct ipw2100_priv *priv,
320 struct ipw2100_fw *fw);
321static int ipw2100_ucode_download(struct ipw2100_priv *priv,
322 struct ipw2100_fw *fw);
323static void ipw2100_wx_event_work(struct ipw2100_priv *priv);
324static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev);
325static struct iw_handler_def ipw2100_wx_handler_def;
326
2c86c275
JK
327
328static inline void read_register(struct net_device *dev, u32 reg, u32 *val)
329{
2be041a7 330 *val = readl((void __iomem *)(dev->base_addr + reg));
2c86c275
JK
331 IPW_DEBUG_IO("r: 0x%08X => 0x%08X\n", reg, *val);
332}
333
334static inline void write_register(struct net_device *dev, u32 reg, u32 val)
335{
2be041a7 336 writel(val, (void __iomem *)(dev->base_addr + reg));
2c86c275
JK
337 IPW_DEBUG_IO("w: 0x%08X <= 0x%08X\n", reg, val);
338}
339
340static inline void read_register_word(struct net_device *dev, u32 reg, u16 *val)
341{
2be041a7 342 *val = readw((void __iomem *)(dev->base_addr + reg));
2c86c275
JK
343 IPW_DEBUG_IO("r: 0x%08X => %04X\n", reg, *val);
344}
345
346static inline void read_register_byte(struct net_device *dev, u32 reg, u8 *val)
347{
2be041a7 348 *val = readb((void __iomem *)(dev->base_addr + reg));
2c86c275
JK
349 IPW_DEBUG_IO("r: 0x%08X => %02X\n", reg, *val);
350}
351
352static inline void write_register_word(struct net_device *dev, u32 reg, u16 val)
353{
2be041a7 354 writew(val, (void __iomem *)(dev->base_addr + reg));
2c86c275
JK
355 IPW_DEBUG_IO("w: 0x%08X <= %04X\n", reg, val);
356}
357
358
359static inline void write_register_byte(struct net_device *dev, u32 reg, u8 val)
360{
2be041a7 361 writeb(val, (void __iomem *)(dev->base_addr + reg));
2c86c275
JK
362 IPW_DEBUG_IO("w: 0x%08X =< %02X\n", reg, val);
363}
364
365static inline void read_nic_dword(struct net_device *dev, u32 addr, u32 *val)
366{
367 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
368 addr & IPW_REG_INDIRECT_ADDR_MASK);
369 read_register(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
370}
371
372static inline void write_nic_dword(struct net_device *dev, u32 addr, u32 val)
373{
374 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
375 addr & IPW_REG_INDIRECT_ADDR_MASK);
376 write_register(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
377}
378
379static inline void read_nic_word(struct net_device *dev, u32 addr, u16 *val)
380{
381 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
382 addr & IPW_REG_INDIRECT_ADDR_MASK);
383 read_register_word(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
384}
385
386static inline void write_nic_word(struct net_device *dev, u32 addr, u16 val)
387{
388 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
389 addr & IPW_REG_INDIRECT_ADDR_MASK);
390 write_register_word(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
391}
392
393static inline void read_nic_byte(struct net_device *dev, u32 addr, u8 *val)
394{
395 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
396 addr & IPW_REG_INDIRECT_ADDR_MASK);
397 read_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
398}
399
400static inline void write_nic_byte(struct net_device *dev, u32 addr, u8 val)
401{
402 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
403 addr & IPW_REG_INDIRECT_ADDR_MASK);
404 write_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
405}
406
407static inline void write_nic_auto_inc_address(struct net_device *dev, u32 addr)
408{
409 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS,
410 addr & IPW_REG_INDIRECT_ADDR_MASK);
411}
412
413static inline void write_nic_dword_auto_inc(struct net_device *dev, u32 val)
414{
415 write_register(dev, IPW_REG_AUTOINCREMENT_DATA, val);
416}
417
418static inline void write_nic_memory(struct net_device *dev, u32 addr, u32 len,
419 const u8 *buf)
420{
421 u32 aligned_addr;
422 u32 aligned_len;
423 u32 dif_len;
424 u32 i;
425
426 /* read first nibble byte by byte */
427 aligned_addr = addr & (~0x3);
428 dif_len = addr - aligned_addr;
429 if (dif_len) {
430 /* Start reading at aligned_addr + dif_len */
431 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
432 aligned_addr);
433 for (i = dif_len; i < 4; i++, buf++)
434 write_register_byte(
435 dev, IPW_REG_INDIRECT_ACCESS_DATA + i,
436 *buf);
437
438 len -= dif_len;
439 aligned_addr += 4;
440 }
441
442 /* read DWs through autoincrement registers */
443 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS,
444 aligned_addr);
445 aligned_len = len & (~0x3);
446 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
447 write_register(
448 dev, IPW_REG_AUTOINCREMENT_DATA, *(u32 *)buf);
449
450 /* copy the last nibble */
451 dif_len = len - aligned_len;
452 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, aligned_addr);
453 for (i = 0; i < dif_len; i++, buf++)
454 write_register_byte(
455 dev, IPW_REG_INDIRECT_ACCESS_DATA + i, *buf);
456}
457
458static inline void read_nic_memory(struct net_device *dev, u32 addr, u32 len,
459 u8 *buf)
460{
461 u32 aligned_addr;
462 u32 aligned_len;
463 u32 dif_len;
464 u32 i;
465
466 /* read first nibble byte by byte */
467 aligned_addr = addr & (~0x3);
468 dif_len = addr - aligned_addr;
469 if (dif_len) {
470 /* Start reading at aligned_addr + dif_len */
471 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
472 aligned_addr);
473 for (i = dif_len; i < 4; i++, buf++)
474 read_register_byte(
475 dev, IPW_REG_INDIRECT_ACCESS_DATA + i, buf);
476
477 len -= dif_len;
478 aligned_addr += 4;
479 }
480
481 /* read DWs through autoincrement registers */
482 write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS,
483 aligned_addr);
484 aligned_len = len & (~0x3);
485 for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
486 read_register(dev, IPW_REG_AUTOINCREMENT_DATA,
487 (u32 *)buf);
488
489 /* copy the last nibble */
490 dif_len = len - aligned_len;
491 write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
492 aligned_addr);
493 for (i = 0; i < dif_len; i++, buf++)
494 read_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA +
495 i, buf);
496}
497
498static inline int ipw2100_hw_is_adapter_in_system(struct net_device *dev)
499{
500 return (dev->base_addr &&
2be041a7 501 (readl((void __iomem *)(dev->base_addr + IPW_REG_DOA_DEBUG_AREA_START))
2c86c275
JK
502 == IPW_DATA_DOA_DEBUG_VALUE));
503}
504
c4aee8c2
JB
505static int ipw2100_get_ordinal(struct ipw2100_priv *priv, u32 ord,
506 void *val, u32 *len)
2c86c275
JK
507{
508 struct ipw2100_ordinals *ordinals = &priv->ordinals;
509 u32 addr;
510 u32 field_info;
511 u16 field_len;
512 u16 field_count;
513 u32 total_length;
514
515 if (ordinals->table1_addr == 0) {
797b4f76 516 printk(KERN_WARNING DRV_NAME ": attempt to use fw ordinals "
2c86c275
JK
517 "before they have been loaded.\n");
518 return -EINVAL;
519 }
520
521 if (IS_ORDINAL_TABLE_ONE(ordinals, ord)) {
522 if (*len < IPW_ORD_TAB_1_ENTRY_SIZE) {
523 *len = IPW_ORD_TAB_1_ENTRY_SIZE;
524
797b4f76 525 printk(KERN_WARNING DRV_NAME
aaa4d308 526 ": ordinal buffer length too small, need %zd\n",
2c86c275
JK
527 IPW_ORD_TAB_1_ENTRY_SIZE);
528
529 return -EINVAL;
530 }
531
532 read_nic_dword(priv->net_dev, ordinals->table1_addr + (ord << 2),
533 &addr);
534 read_nic_dword(priv->net_dev, addr, val);
535
536 *len = IPW_ORD_TAB_1_ENTRY_SIZE;
537
538 return 0;
539 }
540
541 if (IS_ORDINAL_TABLE_TWO(ordinals, ord)) {
542
543 ord -= IPW_START_ORD_TAB_2;
544
545 /* get the address of statistic */
546 read_nic_dword(priv->net_dev, ordinals->table2_addr + (ord << 3),
547 &addr);
548
549 /* get the second DW of statistics ;
550 * two 16-bit words - first is length, second is count */
551 read_nic_dword(priv->net_dev,
552 ordinals->table2_addr + (ord << 3) + sizeof(u32),
553 &field_info);
554
555 /* get each entry length */
556 field_len = *((u16 *)&field_info);
557
558 /* get number of entries */
559 field_count = *(((u16 *)&field_info) + 1);
560
561 /* abort if no enought memory */
562 total_length = field_len * field_count;
563 if (total_length > *len) {
564 *len = total_length;
565 return -EINVAL;
566 }
567
568 *len = total_length;
569 if (!total_length)
570 return 0;
571
572 /* read the ordinal data from the SRAM */
573 read_nic_memory(priv->net_dev, addr, total_length, val);
574
575 return 0;
576 }
577
797b4f76 578 printk(KERN_WARNING DRV_NAME ": ordinal %d neither in table 1 nor "
2c86c275
JK
579 "in table 2\n", ord);
580
581 return -EINVAL;
582}
583
584static int ipw2100_set_ordinal(struct ipw2100_priv *priv, u32 ord, u32 *val,
585 u32 *len)
586{
587 struct ipw2100_ordinals *ordinals = &priv->ordinals;
588 u32 addr;
589
590 if (IS_ORDINAL_TABLE_ONE(ordinals, ord)) {
591 if (*len != IPW_ORD_TAB_1_ENTRY_SIZE) {
592 *len = IPW_ORD_TAB_1_ENTRY_SIZE;
593 IPW_DEBUG_INFO("wrong size\n");
594 return -EINVAL;
595 }
596
597 read_nic_dword(priv->net_dev, ordinals->table1_addr + (ord << 2),
598 &addr);
599
600 write_nic_dword(priv->net_dev, addr, *val);
601
602 *len = IPW_ORD_TAB_1_ENTRY_SIZE;
603
604 return 0;
605 }
606
607 IPW_DEBUG_INFO("wrong table\n");
608 if (IS_ORDINAL_TABLE_TWO(ordinals, ord))
609 return -EINVAL;
610
611 return -EINVAL;
612}
613
614static char *snprint_line(char *buf, size_t count,
615 const u8 *data, u32 len, u32 ofs)
616{
617 int out, i, j, l;
618 char c;
619
620 out = snprintf(buf, count, "%08X", ofs);
621
622 for (l = 0, i = 0; i < 2; i++) {
623 out += snprintf(buf + out, count - out, " ");
624 for (j = 0; j < 8 && l < len; j++, l++)
625 out += snprintf(buf + out, count - out, "%02X ",
626 data[(i * 8 + j)]);
627 for (; j < 8; j++)
628 out += snprintf(buf + out, count - out, " ");
629 }
630
631 out += snprintf(buf + out, count - out, " ");
632 for (l = 0, i = 0; i < 2; i++) {
633 out += snprintf(buf + out, count - out, " ");
634 for (j = 0; j < 8 && l < len; j++, l++) {
635 c = data[(i * 8 + j)];
636 if (!isascii(c) || !isprint(c))
637 c = '.';
638
639 out += snprintf(buf + out, count - out, "%c", c);
640 }
641
642 for (; j < 8; j++)
643 out += snprintf(buf + out, count - out, " ");
644 }
645
646 return buf;
647}
648
649static void printk_buf(int level, const u8 *data, u32 len)
650{
651 char line[81];
652 u32 ofs = 0;
653 if (!(ipw2100_debug_level & level))
654 return;
655
656 while (len) {
657 printk(KERN_DEBUG "%s\n",
658 snprint_line(line, sizeof(line), &data[ofs],
659 min(len, 16U), ofs));
660 ofs += 16;
661 len -= min(len, 16U);
662 }
663}
664
665
666
667#define MAX_RESET_BACKOFF 10
668
669static inline void schedule_reset(struct ipw2100_priv *priv)
670{
671 unsigned long now = get_seconds();
672
673 /* If we haven't received a reset request within the backoff period,
674 * then we can reset the backoff interval so this reset occurs
675 * immediately */
676 if (priv->reset_backoff &&
677 (now - priv->last_reset > priv->reset_backoff))
678 priv->reset_backoff = 0;
679
680 priv->last_reset = get_seconds();
681
682 if (!(priv->status & STATUS_RESET_PENDING)) {
683 IPW_DEBUG_INFO("%s: Scheduling firmware restart (%ds).\n",
684 priv->net_dev->name, priv->reset_backoff);
685 netif_carrier_off(priv->net_dev);
686 netif_stop_queue(priv->net_dev);
687 priv->status |= STATUS_RESET_PENDING;
688 if (priv->reset_backoff)
689 queue_delayed_work(priv->workqueue, &priv->reset_work,
690 priv->reset_backoff * HZ);
691 else
692 queue_work(priv->workqueue, &priv->reset_work);
693
694 if (priv->reset_backoff < MAX_RESET_BACKOFF)
695 priv->reset_backoff++;
696
697 wake_up_interruptible(&priv->wait_command_queue);
698 } else
699 IPW_DEBUG_INFO("%s: Firmware restart already in progress.\n",
700 priv->net_dev->name);
701
702}
703
704#define HOST_COMPLETE_TIMEOUT (2 * HZ)
705static int ipw2100_hw_send_command(struct ipw2100_priv *priv,
706 struct host_command * cmd)
707{
708 struct list_head *element;
709 struct ipw2100_tx_packet *packet;
710 unsigned long flags;
711 int err = 0;
712
713 IPW_DEBUG_HC("Sending %s command (#%d), %d bytes\n",
714 command_types[cmd->host_command], cmd->host_command,
715 cmd->host_command_length);
716 printk_buf(IPW_DL_HC, (u8*)cmd->host_command_parameters,
717 cmd->host_command_length);
718
719 spin_lock_irqsave(&priv->low_lock, flags);
720
721 if (priv->fatal_error) {
722 IPW_DEBUG_INFO("Attempt to send command while hardware in fatal error condition.\n");
723 err = -EIO;
724 goto fail_unlock;
725 }
726
727 if (!(priv->status & STATUS_RUNNING)) {
728 IPW_DEBUG_INFO("Attempt to send command while hardware is not running.\n");
729 err = -EIO;
730 goto fail_unlock;
731 }
732
733 if (priv->status & STATUS_CMD_ACTIVE) {
734 IPW_DEBUG_INFO("Attempt to send command while another command is pending.\n");
735 err = -EBUSY;
736 goto fail_unlock;
737 }
738
739 if (list_empty(&priv->msg_free_list)) {
740 IPW_DEBUG_INFO("no available msg buffers\n");
741 goto fail_unlock;
742 }
743
744 priv->status |= STATUS_CMD_ACTIVE;
745 priv->messages_sent++;
746
747 element = priv->msg_free_list.next;
748
749 packet = list_entry(element, struct ipw2100_tx_packet, list);
750 packet->jiffy_start = jiffies;
751
752 /* initialize the firmware command packet */
753 packet->info.c_struct.cmd->host_command_reg = cmd->host_command;
754 packet->info.c_struct.cmd->host_command_reg1 = cmd->host_command1;
755 packet->info.c_struct.cmd->host_command_len_reg = cmd->host_command_length;
756 packet->info.c_struct.cmd->sequence = cmd->host_command_sequence;
757
758 memcpy(packet->info.c_struct.cmd->host_command_params_reg,
759 cmd->host_command_parameters,
760 sizeof(packet->info.c_struct.cmd->host_command_params_reg));
761
762 list_del(element);
763 DEC_STAT(&priv->msg_free_stat);
764
765 list_add_tail(element, &priv->msg_pend_list);
766 INC_STAT(&priv->msg_pend_stat);
767
19f7f742
JB
768 ipw2100_tx_send_commands(priv);
769 ipw2100_tx_send_data(priv);
2c86c275
JK
770
771 spin_unlock_irqrestore(&priv->low_lock, flags);
772
773 /*
774 * We must wait for this command to complete before another
775 * command can be sent... but if we wait more than 3 seconds
776 * then there is a problem.
777 */
778
779 err = wait_event_interruptible_timeout(
780 priv->wait_command_queue, !(priv->status & STATUS_CMD_ACTIVE),
781 HOST_COMPLETE_TIMEOUT);
782
783 if (err == 0) {
784 IPW_DEBUG_INFO("Command completion failed out after %dms.\n",
785 HOST_COMPLETE_TIMEOUT / (HZ / 100));
786 priv->fatal_error = IPW2100_ERR_MSG_TIMEOUT;
787 priv->status &= ~STATUS_CMD_ACTIVE;
788 schedule_reset(priv);
789 return -EIO;
790 }
791
792 if (priv->fatal_error) {
797b4f76 793 printk(KERN_WARNING DRV_NAME ": %s: firmware fatal error\n",
2c86c275
JK
794 priv->net_dev->name);
795 return -EIO;
796 }
797
798 /* !!!!! HACK TEST !!!!!
799 * When lots of debug trace statements are enabled, the driver
800 * doesn't seem to have as many firmware restart cycles...
801 *
802 * As a test, we're sticking in a 1/100s delay here */
3173c890 803 schedule_timeout_uninterruptible(msecs_to_jiffies(10));
2c86c275
JK
804
805 return 0;
806
807 fail_unlock:
808 spin_unlock_irqrestore(&priv->low_lock, flags);
809
810 return err;
811}
812
813
814/*
815 * Verify the values and data access of the hardware
816 * No locks needed or used. No functions called.
817 */
818static int ipw2100_verify(struct ipw2100_priv *priv)
819{
820 u32 data1, data2;
821 u32 address;
822
823 u32 val1 = 0x76543210;
824 u32 val2 = 0xFEDCBA98;
825
826 /* Domain 0 check - all values should be DOA_DEBUG */
827 for (address = IPW_REG_DOA_DEBUG_AREA_START;
828 address < IPW_REG_DOA_DEBUG_AREA_END;
829 address += sizeof(u32)) {
830 read_register(priv->net_dev, address, &data1);
831 if (data1 != IPW_DATA_DOA_DEBUG_VALUE)
832 return -EIO;
833 }
834
835 /* Domain 1 check - use arbitrary read/write compare */
836 for (address = 0; address < 5; address++) {
837 /* The memory area is not used now */
838 write_register(priv->net_dev, IPW_REG_DOMAIN_1_OFFSET + 0x32,
839 val1);
840 write_register(priv->net_dev, IPW_REG_DOMAIN_1_OFFSET + 0x36,
841 val2);
842 read_register(priv->net_dev, IPW_REG_DOMAIN_1_OFFSET + 0x32,
843 &data1);
844 read_register(priv->net_dev, IPW_REG_DOMAIN_1_OFFSET + 0x36,
845 &data2);
846 if (val1 == data1 && val2 == data2)
847 return 0;
848 }
849
850 return -EIO;
851}
852
853/*
854 *
855 * Loop until the CARD_DISABLED bit is the same value as the
856 * supplied parameter
857 *
858 * TODO: See if it would be more efficient to do a wait/wake
859 * cycle and have the completion event trigger the wakeup
860 *
861 */
862#define IPW_CARD_DISABLE_COMPLETE_WAIT 100 // 100 milli
863static int ipw2100_wait_for_card_state(struct ipw2100_priv *priv, int state)
864{
865 int i;
866 u32 card_state;
867 u32 len = sizeof(card_state);
868 int err;
869
870 for (i = 0; i <= IPW_CARD_DISABLE_COMPLETE_WAIT * 1000; i += 50) {
871 err = ipw2100_get_ordinal(priv, IPW_ORD_CARD_DISABLED,
872 &card_state, &len);
873 if (err) {
874 IPW_DEBUG_INFO("Query of CARD_DISABLED ordinal "
875 "failed.\n");
876 return 0;
877 }
878
879 /* We'll break out if either the HW state says it is
880 * in the state we want, or if HOST_COMPLETE command
881 * finishes */
882 if ((card_state == state) ||
883 ((priv->status & STATUS_ENABLED) ?
884 IPW_HW_STATE_ENABLED : IPW_HW_STATE_DISABLED) == state) {
885 if (state == IPW_HW_STATE_ENABLED)
886 priv->status |= STATUS_ENABLED;
887 else
888 priv->status &= ~STATUS_ENABLED;
889
890 return 0;
891 }
892
893 udelay(50);
894 }
895
896 IPW_DEBUG_INFO("ipw2100_wait_for_card_state to %s state timed out\n",
897 state ? "DISABLED" : "ENABLED");
898 return -EIO;
899}
900
901
902/*********************************************************************
903 Procedure : sw_reset_and_clock
904 Purpose : Asserts s/w reset, asserts clock initialization
905 and waits for clock stabilization
906 ********************************************************************/
907static int sw_reset_and_clock(struct ipw2100_priv *priv)
908{
909 int i;
910 u32 r;
911
912 // assert s/w reset
913 write_register(priv->net_dev, IPW_REG_RESET_REG,
914 IPW_AUX_HOST_RESET_REG_SW_RESET);
915
916 // wait for clock stabilization
917 for (i = 0; i < 1000; i++) {
918 udelay(IPW_WAIT_RESET_ARC_COMPLETE_DELAY);
919
920 // check clock ready bit
921 read_register(priv->net_dev, IPW_REG_RESET_REG, &r);
922 if (r & IPW_AUX_HOST_RESET_REG_PRINCETON_RESET)
923 break;
924 }
925
926 if (i == 1000)
927 return -EIO; // TODO: better error value
928
929 /* set "initialization complete" bit to move adapter to
930 * D0 state */
931 write_register(priv->net_dev, IPW_REG_GP_CNTRL,
932 IPW_AUX_HOST_GP_CNTRL_BIT_INIT_DONE);
933
934 /* wait for clock stabilization */
935 for (i = 0; i < 10000; i++) {
936 udelay(IPW_WAIT_CLOCK_STABILIZATION_DELAY * 4);
937
938 /* check clock ready bit */
939 read_register(priv->net_dev, IPW_REG_GP_CNTRL, &r);
940 if (r & IPW_AUX_HOST_GP_CNTRL_BIT_CLOCK_READY)
941 break;
942 }
943
944 if (i == 10000)
945 return -EIO; /* TODO: better error value */
946
2c86c275
JK
947 /* set D0 standby bit */
948 read_register(priv->net_dev, IPW_REG_GP_CNTRL, &r);
949 write_register(priv->net_dev, IPW_REG_GP_CNTRL,
950 r | IPW_AUX_HOST_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY);
2c86c275
JK
951
952 return 0;
953}
954
955/*********************************************************************
8724a118 956 Procedure : ipw2100_download_firmware
2c86c275
JK
957 Purpose : Initiaze adapter after power on.
958 The sequence is:
959 1. assert s/w reset first!
960 2. awake clocks & wait for clock stabilization
961 3. hold ARC (don't ask me why...)
962 4. load Dino ucode and reset/clock init again
963 5. zero-out shared mem
964 6. download f/w
965 *******************************************************************/
966static int ipw2100_download_firmware(struct ipw2100_priv *priv)
967{
968 u32 address;
969 int err;
970
971#ifndef CONFIG_PM
972 /* Fetch the firmware and microcode */
973 struct ipw2100_fw ipw2100_firmware;
974#endif
975
976 if (priv->fatal_error) {
977 IPW_DEBUG_ERROR("%s: ipw2100_download_firmware called after "
978 "fatal error %d. Interface must be brought down.\n",
979 priv->net_dev->name, priv->fatal_error);
980 return -EINVAL;
981 }
982
983#ifdef CONFIG_PM
984 if (!ipw2100_firmware.version) {
985 err = ipw2100_get_firmware(priv, &ipw2100_firmware);
986 if (err) {
987 IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n",
988 priv->net_dev->name, err);
989 priv->fatal_error = IPW2100_ERR_FW_LOAD;
990 goto fail;
991 }
992 }
993#else
994 err = ipw2100_get_firmware(priv, &ipw2100_firmware);
995 if (err) {
996 IPW_DEBUG_ERROR("%s: ipw2100_get_firmware failed: %d\n",
997 priv->net_dev->name, err);
998 priv->fatal_error = IPW2100_ERR_FW_LOAD;
999 goto fail;
1000 }
1001#endif
1002 priv->firmware_version = ipw2100_firmware.version;
1003
1004 /* s/w reset and clock stabilization */
1005 err = sw_reset_and_clock(priv);
1006 if (err) {
1007 IPW_DEBUG_ERROR("%s: sw_reset_and_clock failed: %d\n",
1008 priv->net_dev->name, err);
1009 goto fail;
1010 }
1011
1012 err = ipw2100_verify(priv);
1013 if (err) {
1014 IPW_DEBUG_ERROR("%s: ipw2100_verify failed: %d\n",
1015 priv->net_dev->name, err);
1016 goto fail;
1017 }
1018
1019 /* Hold ARC */
1020 write_nic_dword(priv->net_dev,
1021 IPW_INTERNAL_REGISTER_HALT_AND_RESET,
1022 0x80000000);
1023
1024 /* allow ARC to run */
1025 write_register(priv->net_dev, IPW_REG_RESET_REG, 0);
1026
1027 /* load microcode */
1028 err = ipw2100_ucode_download(priv, &ipw2100_firmware);
1029 if (err) {
797b4f76 1030 printk(KERN_ERR DRV_NAME ": %s: Error loading microcode: %d\n",
2c86c275
JK
1031 priv->net_dev->name, err);
1032 goto fail;
1033 }
1034
1035 /* release ARC */
1036 write_nic_dword(priv->net_dev,
1037 IPW_INTERNAL_REGISTER_HALT_AND_RESET,
1038 0x00000000);
1039
1040 /* s/w reset and clock stabilization (again!!!) */
1041 err = sw_reset_and_clock(priv);
1042 if (err) {
797b4f76 1043 printk(KERN_ERR DRV_NAME ": %s: sw_reset_and_clock failed: %d\n",
2c86c275
JK
1044 priv->net_dev->name, err);
1045 goto fail;
1046 }
1047
1048 /* load f/w */
1049 err = ipw2100_fw_download(priv, &ipw2100_firmware);
1050 if (err) {
1051 IPW_DEBUG_ERROR("%s: Error loading firmware: %d\n",
1052 priv->net_dev->name, err);
1053 goto fail;
1054 }
1055
1056#ifndef CONFIG_PM
1057 /*
1058 * When the .resume method of the driver is called, the other
1059 * part of the system, i.e. the ide driver could still stay in
1060 * the suspend stage. This prevents us from loading the firmware
1061 * from the disk. --YZ
1062 */
1063
1064 /* free any storage allocated for firmware image */
1065 ipw2100_release_firmware(priv, &ipw2100_firmware);
1066#endif
1067
1068 /* zero out Domain 1 area indirectly (Si requirement) */
1069 for (address = IPW_HOST_FW_SHARED_AREA0;
1070 address < IPW_HOST_FW_SHARED_AREA0_END; address += 4)
1071 write_nic_dword(priv->net_dev, address, 0);
1072 for (address = IPW_HOST_FW_SHARED_AREA1;
1073 address < IPW_HOST_FW_SHARED_AREA1_END; address += 4)
1074 write_nic_dword(priv->net_dev, address, 0);
1075 for (address = IPW_HOST_FW_SHARED_AREA2;
1076 address < IPW_HOST_FW_SHARED_AREA2_END; address += 4)
1077 write_nic_dword(priv->net_dev, address, 0);
1078 for (address = IPW_HOST_FW_SHARED_AREA3;
1079 address < IPW_HOST_FW_SHARED_AREA3_END; address += 4)
1080 write_nic_dword(priv->net_dev, address, 0);
1081 for (address = IPW_HOST_FW_INTERRUPT_AREA;
1082 address < IPW_HOST_FW_INTERRUPT_AREA_END; address += 4)
1083 write_nic_dword(priv->net_dev, address, 0);
1084
1085 return 0;
1086
1087 fail:
1088 ipw2100_release_firmware(priv, &ipw2100_firmware);
1089 return err;
1090}
1091
1092static inline void ipw2100_enable_interrupts(struct ipw2100_priv *priv)
1093{
1094 if (priv->status & STATUS_INT_ENABLED)
1095 return;
1096 priv->status |= STATUS_INT_ENABLED;
1097 write_register(priv->net_dev, IPW_REG_INTA_MASK, IPW_INTERRUPT_MASK);
1098}
1099
1100static inline void ipw2100_disable_interrupts(struct ipw2100_priv *priv)
1101{
1102 if (!(priv->status & STATUS_INT_ENABLED))
1103 return;
1104 priv->status &= ~STATUS_INT_ENABLED;
1105 write_register(priv->net_dev, IPW_REG_INTA_MASK, 0x0);
1106}
1107
1108
1109static void ipw2100_initialize_ordinals(struct ipw2100_priv *priv)
1110{
1111 struct ipw2100_ordinals *ord = &priv->ordinals;
1112
1113 IPW_DEBUG_INFO("enter\n");
1114
1115 read_register(priv->net_dev, IPW_MEM_HOST_SHARED_ORDINALS_TABLE_1,
1116 &ord->table1_addr);
1117
1118 read_register(priv->net_dev, IPW_MEM_HOST_SHARED_ORDINALS_TABLE_2,
1119 &ord->table2_addr);
1120
1121 read_nic_dword(priv->net_dev, ord->table1_addr, &ord->table1_size);
1122 read_nic_dword(priv->net_dev, ord->table2_addr, &ord->table2_size);
1123
1124 ord->table2_size &= 0x0000FFFF;
1125
1126 IPW_DEBUG_INFO("table 1 size: %d\n", ord->table1_size);
1127 IPW_DEBUG_INFO("table 2 size: %d\n", ord->table2_size);
1128 IPW_DEBUG_INFO("exit\n");
1129}
1130
1131static inline void ipw2100_hw_set_gpio(struct ipw2100_priv *priv)
1132{
1133 u32 reg = 0;
1134 /*
1135 * Set GPIO 3 writable by FW; GPIO 1 writable
1136 * by driver and enable clock
1137 */
1138 reg = (IPW_BIT_GPIO_GPIO3_MASK | IPW_BIT_GPIO_GPIO1_ENABLE |
1139 IPW_BIT_GPIO_LED_OFF);
1140 write_register(priv->net_dev, IPW_REG_GPIO, reg);
1141}
1142
1143static inline int rf_kill_active(struct ipw2100_priv *priv)
1144{
1145#define MAX_RF_KILL_CHECKS 5
1146#define RF_KILL_CHECK_DELAY 40
2c86c275
JK
1147
1148 unsigned short value = 0;
1149 u32 reg = 0;
1150 int i;
1151
1152 if (!(priv->hw_features & HW_FEATURE_RFKILL)) {
1153 priv->status &= ~STATUS_RF_KILL_HW;
1154 return 0;
1155 }
1156
1157 for (i = 0; i < MAX_RF_KILL_CHECKS; i++) {
1158 udelay(RF_KILL_CHECK_DELAY);
1159 read_register(priv->net_dev, IPW_REG_GPIO, &reg);
1160 value = (value << 1) | ((reg & IPW_BIT_GPIO_RF_KILL) ? 0 : 1);
1161 }
1162
1163 if (value == 0)
1164 priv->status |= STATUS_RF_KILL_HW;
1165 else
1166 priv->status &= ~STATUS_RF_KILL_HW;
1167
1168 return (value == 0);
1169}
1170
1171static int ipw2100_get_hw_features(struct ipw2100_priv *priv)
1172{
1173 u32 addr, len;
1174 u32 val;
1175
1176 /*
1177 * EEPROM_SRAM_DB_START_ADDRESS using ordinal in ordinal table 1
1178 */
1179 len = sizeof(addr);
1180 if (ipw2100_get_ordinal(
1181 priv, IPW_ORD_EEPROM_SRAM_DB_BLOCK_START_ADDRESS,
1182 &addr, &len)) {
1183 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1184 __LINE__);
1185 return -EIO;
1186 }
1187
1188 IPW_DEBUG_INFO("EEPROM address: %08X\n", addr);
1189
1190 /*
1191 * EEPROM version is the byte at offset 0xfd in firmware
1192 * We read 4 bytes, then shift out the byte we actually want */
1193 read_nic_dword(priv->net_dev, addr + 0xFC, &val);
1194 priv->eeprom_version = (val >> 24) & 0xFF;
1195 IPW_DEBUG_INFO("EEPROM version: %d\n", priv->eeprom_version);
1196
1197 /*
1198 * HW RF Kill enable is bit 0 in byte at offset 0x21 in firmware
1199 *
1200 * notice that the EEPROM bit is reverse polarity, i.e.
1201 * bit = 0 signifies HW RF kill switch is supported
1202 * bit = 1 signifies HW RF kill switch is NOT supported
1203 */
1204 read_nic_dword(priv->net_dev, addr + 0x20, &val);
1205 if (!((val >> 24) & 0x01))
1206 priv->hw_features |= HW_FEATURE_RFKILL;
1207
1208 IPW_DEBUG_INFO("HW RF Kill: %ssupported.\n",
1209 (priv->hw_features & HW_FEATURE_RFKILL) ?
1210 "" : "not ");
1211
1212 return 0;
1213}
1214
1215/*
1216 * Start firmware execution after power on and intialization
1217 * The sequence is:
1218 * 1. Release ARC
1219 * 2. Wait for f/w initialization completes;
1220 */
1221static int ipw2100_start_adapter(struct ipw2100_priv *priv)
1222{
2c86c275
JK
1223 int i;
1224 u32 inta, inta_mask, gpio;
1225
1226 IPW_DEBUG_INFO("enter\n");
1227
1228 if (priv->status & STATUS_RUNNING)
1229 return 0;
1230
1231 /*
1232 * Initialize the hw - drive adapter to DO state by setting
1233 * init_done bit. Wait for clk_ready bit and Download
1234 * fw & dino ucode
1235 */
1236 if (ipw2100_download_firmware(priv)) {
797b4f76 1237 printk(KERN_ERR DRV_NAME ": %s: Failed to power on the adapter.\n",
2c86c275
JK
1238 priv->net_dev->name);
1239 return -EIO;
1240 }
1241
1242 /* Clear the Tx, Rx and Msg queues and the r/w indexes
1243 * in the firmware RBD and TBD ring queue */
1244 ipw2100_queues_initialize(priv);
1245
1246 ipw2100_hw_set_gpio(priv);
1247
1248 /* TODO -- Look at disabling interrupts here to make sure none
1249 * get fired during FW initialization */
1250
1251 /* Release ARC - clear reset bit */
1252 write_register(priv->net_dev, IPW_REG_RESET_REG, 0);
1253
1254 /* wait for f/w intialization complete */
1255 IPW_DEBUG_FW("Waiting for f/w initialization to complete...\n");
1256 i = 5000;
1257 do {
3173c890 1258 schedule_timeout_uninterruptible(msecs_to_jiffies(40));
2c86c275
JK
1259 /* Todo... wait for sync command ... */
1260
1261 read_register(priv->net_dev, IPW_REG_INTA, &inta);
1262
1263 /* check "init done" bit */
1264 if (inta & IPW2100_INTA_FW_INIT_DONE) {
1265 /* reset "init done" bit */
1266 write_register(priv->net_dev, IPW_REG_INTA,
1267 IPW2100_INTA_FW_INIT_DONE);
1268 break;
1269 }
1270
1271 /* check error conditions : we check these after the firmware
1272 * check so that if there is an error, the interrupt handler
1273 * will see it and the adapter will be reset */
1274 if (inta &
1275 (IPW2100_INTA_FATAL_ERROR | IPW2100_INTA_PARITY_ERROR)) {
1276 /* clear error conditions */
1277 write_register(priv->net_dev, IPW_REG_INTA,
1278 IPW2100_INTA_FATAL_ERROR |
1279 IPW2100_INTA_PARITY_ERROR);
1280 }
1281 } while (i--);
1282
1283 /* Clear out any pending INTAs since we aren't supposed to have
1284 * interrupts enabled at this point... */
1285 read_register(priv->net_dev, IPW_REG_INTA, &inta);
1286 read_register(priv->net_dev, IPW_REG_INTA_MASK, &inta_mask);
1287 inta &= IPW_INTERRUPT_MASK;
1288 /* Clear out any pending interrupts */
1289 if (inta & inta_mask)
1290 write_register(priv->net_dev, IPW_REG_INTA, inta);
1291
1292 IPW_DEBUG_FW("f/w initialization complete: %s\n",
1293 i ? "SUCCESS" : "FAILED");
1294
1295 if (!i) {
797b4f76 1296 printk(KERN_WARNING DRV_NAME ": %s: Firmware did not initialize.\n",
2c86c275
JK
1297 priv->net_dev->name);
1298 return -EIO;
1299 }
1300
1301 /* allow firmware to write to GPIO1 & GPIO3 */
1302 read_register(priv->net_dev, IPW_REG_GPIO, &gpio);
1303
1304 gpio |= (IPW_BIT_GPIO_GPIO1_MASK | IPW_BIT_GPIO_GPIO3_MASK);
1305
1306 write_register(priv->net_dev, IPW_REG_GPIO, gpio);
1307
1308 /* Ready to receive commands */
1309 priv->status |= STATUS_RUNNING;
1310
1311 /* The adapter has been reset; we are not associated */
1312 priv->status &= ~(STATUS_ASSOCIATING | STATUS_ASSOCIATED);
1313
1314 IPW_DEBUG_INFO("exit\n");
1315
1316 return 0;
1317}
1318
1319static inline void ipw2100_reset_fatalerror(struct ipw2100_priv *priv)
1320{
1321 if (!priv->fatal_error)
1322 return;
1323
1324 priv->fatal_errors[priv->fatal_index++] = priv->fatal_error;
1325 priv->fatal_index %= IPW2100_ERROR_QUEUE;
1326 priv->fatal_error = 0;
1327}
1328
1329
1330/* NOTE: Our interrupt is disabled when this method is called */
1331static int ipw2100_power_cycle_adapter(struct ipw2100_priv *priv)
1332{
1333 u32 reg;
1334 int i;
1335
1336 IPW_DEBUG_INFO("Power cycling the hardware.\n");
1337
1338 ipw2100_hw_set_gpio(priv);
1339
1340 /* Step 1. Stop Master Assert */
1341 write_register(priv->net_dev, IPW_REG_RESET_REG,
1342 IPW_AUX_HOST_RESET_REG_STOP_MASTER);
1343
1344 /* Step 2. Wait for stop Master Assert
1345 * (not more then 50us, otherwise ret error */
1346 i = 5;
1347 do {
1348 udelay(IPW_WAIT_RESET_MASTER_ASSERT_COMPLETE_DELAY);
1349 read_register(priv->net_dev, IPW_REG_RESET_REG, &reg);
1350
1351 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
1352 break;
1353 } while(i--);
1354
1355 priv->status &= ~STATUS_RESET_PENDING;
1356
1357 if (!i) {
1358 IPW_DEBUG_INFO("exit - waited too long for master assert stop\n");
1359 return -EIO;
1360 }
1361
1362 write_register(priv->net_dev, IPW_REG_RESET_REG,
1363 IPW_AUX_HOST_RESET_REG_SW_RESET);
1364
1365
1366 /* Reset any fatal_error conditions */
1367 ipw2100_reset_fatalerror(priv);
1368
1369 /* At this point, the adapter is now stopped and disabled */
1370 priv->status &= ~(STATUS_RUNNING | STATUS_ASSOCIATING |
1371 STATUS_ASSOCIATED | STATUS_ENABLED);
1372
1373 return 0;
1374}
1375
1376/*
1377 * Send the CARD_DISABLE_PHY_OFF comamnd to the card to disable it
1378 *
1379 * After disabling, if the card was associated, a STATUS_ASSN_LOST will be sent.
1380 *
1381 * STATUS_CARD_DISABLE_NOTIFICATION will be sent regardless of
1382 * if STATUS_ASSN_LOST is sent.
1383 */
1384static int ipw2100_hw_phy_off(struct ipw2100_priv *priv)
1385{
1386
1387#define HW_PHY_OFF_LOOP_DELAY (HZ / 5000)
1388
1389 struct host_command cmd = {
1390 .host_command = CARD_DISABLE_PHY_OFF,
1391 .host_command_sequence = 0,
1392 .host_command_length = 0,
1393 };
1394 int err, i;
1395 u32 val1, val2;
1396
1397 IPW_DEBUG_HC("CARD_DISABLE_PHY_OFF\n");
1398
1399 /* Turn off the radio */
1400 err = ipw2100_hw_send_command(priv, &cmd);
1401 if (err)
1402 return err;
1403
1404 for (i = 0; i < 2500; i++) {
1405 read_nic_dword(priv->net_dev, IPW2100_CONTROL_REG, &val1);
1406 read_nic_dword(priv->net_dev, IPW2100_COMMAND, &val2);
1407
1408 if ((val1 & IPW2100_CONTROL_PHY_OFF) &&
1409 (val2 & IPW2100_COMMAND_PHY_OFF))
1410 return 0;
1411
3173c890 1412 schedule_timeout_uninterruptible(HW_PHY_OFF_LOOP_DELAY);
2c86c275
JK
1413 }
1414
1415 return -EIO;
1416}
1417
1418
1419static int ipw2100_enable_adapter(struct ipw2100_priv *priv)
1420{
1421 struct host_command cmd = {
1422 .host_command = HOST_COMPLETE,
1423 .host_command_sequence = 0,
1424 .host_command_length = 0
1425 };
1426 int err = 0;
1427
1428 IPW_DEBUG_HC("HOST_COMPLETE\n");
1429
1430 if (priv->status & STATUS_ENABLED)
1431 return 0;
1432
1433 down(&priv->adapter_sem);
1434
1435 if (rf_kill_active(priv)) {
1436 IPW_DEBUG_HC("Command aborted due to RF kill active.\n");
1437 goto fail_up;
1438 }
1439
1440 err = ipw2100_hw_send_command(priv, &cmd);
1441 if (err) {
1442 IPW_DEBUG_INFO("Failed to send HOST_COMPLETE command\n");
1443 goto fail_up;
1444 }
1445
1446 err = ipw2100_wait_for_card_state(priv, IPW_HW_STATE_ENABLED);
1447 if (err) {
1448 IPW_DEBUG_INFO(
1449 "%s: card not responding to init command.\n",
1450 priv->net_dev->name);
1451 goto fail_up;
1452 }
1453
1454 if (priv->stop_hang_check) {
1455 priv->stop_hang_check = 0;
1456 queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2);
1457 }
1458
1459fail_up:
1460 up(&priv->adapter_sem);
1461 return err;
1462}
1463
1464static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
1465{
3173c890 1466#define HW_POWER_DOWN_DELAY (msecs_to_jiffies(100))
2c86c275
JK
1467
1468 struct host_command cmd = {
1469 .host_command = HOST_PRE_POWER_DOWN,
1470 .host_command_sequence = 0,
1471 .host_command_length = 0,
1472 };
1473 int err, i;
1474 u32 reg;
1475
1476 if (!(priv->status & STATUS_RUNNING))
1477 return 0;
1478
1479 priv->status |= STATUS_STOPPING;
1480
1481 /* We can only shut down the card if the firmware is operational. So,
1482 * if we haven't reset since a fatal_error, then we can not send the
1483 * shutdown commands. */
1484 if (!priv->fatal_error) {
1485 /* First, make sure the adapter is enabled so that the PHY_OFF
1486 * command can shut it down */
1487 ipw2100_enable_adapter(priv);
1488
1489 err = ipw2100_hw_phy_off(priv);
1490 if (err)
797b4f76 1491 printk(KERN_WARNING DRV_NAME ": Error disabling radio %d\n", err);
2c86c275
JK
1492
1493 /*
1494 * If in D0-standby mode going directly to D3 may cause a
1495 * PCI bus violation. Therefore we must change out of the D0
1496 * state.
1497 *
1498 * Sending the PREPARE_FOR_POWER_DOWN will restrict the
1499 * hardware from going into standby mode and will transition
1500 * out of D0-standy if it is already in that state.
1501 *
1502 * STATUS_PREPARE_POWER_DOWN_COMPLETE will be sent by the
1503 * driver upon completion. Once received, the driver can
1504 * proceed to the D3 state.
1505 *
1506 * Prepare for power down command to fw. This command would
1507 * take HW out of D0-standby and prepare it for D3 state.
1508 *
1509 * Currently FW does not support event notification for this
1510 * event. Therefore, skip waiting for it. Just wait a fixed
1511 * 100ms
1512 */
1513 IPW_DEBUG_HC("HOST_PRE_POWER_DOWN\n");
1514
1515 err = ipw2100_hw_send_command(priv, &cmd);
1516 if (err)
797b4f76 1517 printk(KERN_WARNING DRV_NAME ": "
2c86c275
JK
1518 "%s: Power down command failed: Error %d\n",
1519 priv->net_dev->name, err);
3173c890
NA
1520 else
1521 schedule_timeout_uninterruptible(HW_POWER_DOWN_DELAY);
2c86c275
JK
1522 }
1523
1524 priv->status &= ~STATUS_ENABLED;
1525
1526 /*
1527 * Set GPIO 3 writable by FW; GPIO 1 writable
1528 * by driver and enable clock
1529 */
1530 ipw2100_hw_set_gpio(priv);
1531
1532 /*
1533 * Power down adapter. Sequence:
1534 * 1. Stop master assert (RESET_REG[9]=1)
1535 * 2. Wait for stop master (RESET_REG[8]==1)
1536 * 3. S/w reset assert (RESET_REG[7] = 1)
1537 */
1538
1539 /* Stop master assert */
1540 write_register(priv->net_dev, IPW_REG_RESET_REG,
1541 IPW_AUX_HOST_RESET_REG_STOP_MASTER);
1542
1543 /* wait stop master not more than 50 usec.
1544 * Otherwise return error. */
1545 for (i = 5; i > 0; i--) {
1546 udelay(10);
1547
1548 /* Check master stop bit */
1549 read_register(priv->net_dev, IPW_REG_RESET_REG, &reg);
1550
1551 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
1552 break;
1553 }
1554
1555 if (i == 0)
797b4f76 1556 printk(KERN_WARNING DRV_NAME
2c86c275
JK
1557 ": %s: Could now power down adapter.\n",
1558 priv->net_dev->name);
1559
1560 /* assert s/w reset */
1561 write_register(priv->net_dev, IPW_REG_RESET_REG,
1562 IPW_AUX_HOST_RESET_REG_SW_RESET);
1563
1564 priv->status &= ~(STATUS_RUNNING | STATUS_STOPPING);
1565
1566 return 0;
1567}
1568
1569
1570static int ipw2100_disable_adapter(struct ipw2100_priv *priv)
1571{
1572 struct host_command cmd = {
1573 .host_command = CARD_DISABLE,
1574 .host_command_sequence = 0,
1575 .host_command_length = 0
1576 };
1577 int err = 0;
1578
1579 IPW_DEBUG_HC("CARD_DISABLE\n");
1580
1581 if (!(priv->status & STATUS_ENABLED))
1582 return 0;
1583
1584 /* Make sure we clear the associated state */
1585 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
1586
1587 if (!priv->stop_hang_check) {
1588 priv->stop_hang_check = 1;
1589 cancel_delayed_work(&priv->hang_check);
1590 }
1591
1592 down(&priv->adapter_sem);
1593
1594 err = ipw2100_hw_send_command(priv, &cmd);
1595 if (err) {
797b4f76 1596 printk(KERN_WARNING DRV_NAME ": exit - failed to send CARD_DISABLE command\n");
2c86c275
JK
1597 goto fail_up;
1598 }
1599
1600 err = ipw2100_wait_for_card_state(priv, IPW_HW_STATE_DISABLED);
1601 if (err) {
797b4f76 1602 printk(KERN_WARNING DRV_NAME ": exit - card failed to change to DISABLED\n");
2c86c275
JK
1603 goto fail_up;
1604 }
1605
1606 IPW_DEBUG_INFO("TODO: implement scan state machine\n");
1607
1608fail_up:
1609 up(&priv->adapter_sem);
1610 return err;
1611}
1612
c4aee8c2 1613static int ipw2100_set_scan_options(struct ipw2100_priv *priv)
2c86c275
JK
1614{
1615 struct host_command cmd = {
1616 .host_command = SET_SCAN_OPTIONS,
1617 .host_command_sequence = 0,
1618 .host_command_length = 8
1619 };
1620 int err;
1621
1622 IPW_DEBUG_INFO("enter\n");
1623
1624 IPW_DEBUG_SCAN("setting scan options\n");
1625
1626 cmd.host_command_parameters[0] = 0;
1627
1628 if (!(priv->config & CFG_ASSOCIATE))
1629 cmd.host_command_parameters[0] |= IPW_SCAN_NOASSOCIATE;
1630 if ((priv->sec.flags & SEC_ENABLED) && priv->sec.enabled)
1631 cmd.host_command_parameters[0] |= IPW_SCAN_MIXED_CELL;
1632 if (priv->config & CFG_PASSIVE_SCAN)
1633 cmd.host_command_parameters[0] |= IPW_SCAN_PASSIVE;
1634
1635 cmd.host_command_parameters[1] = priv->channel_mask;
1636
1637 err = ipw2100_hw_send_command(priv, &cmd);
1638
1639 IPW_DEBUG_HC("SET_SCAN_OPTIONS 0x%04X\n",
1640 cmd.host_command_parameters[0]);
1641
1642 return err;
1643}
1644
c4aee8c2 1645static int ipw2100_start_scan(struct ipw2100_priv *priv)
2c86c275
JK
1646{
1647 struct host_command cmd = {
1648 .host_command = BROADCAST_SCAN,
1649 .host_command_sequence = 0,
1650 .host_command_length = 4
1651 };
1652 int err;
1653
1654 IPW_DEBUG_HC("START_SCAN\n");
1655
1656 cmd.host_command_parameters[0] = 0;
1657
1658 /* No scanning if in monitor mode */
1659 if (priv->ieee->iw_mode == IW_MODE_MONITOR)
1660 return 1;
1661
1662 if (priv->status & STATUS_SCANNING) {
1663 IPW_DEBUG_SCAN("Scan requested while already in scan...\n");
1664 return 0;
1665 }
1666
1667 IPW_DEBUG_INFO("enter\n");
1668
1669 /* Not clearing here; doing so makes iwlist always return nothing...
1670 *
1671 * We should modify the table logic to use aging tables vs. clearing
1672 * the table on each scan start.
1673 */
1674 IPW_DEBUG_SCAN("starting scan\n");
1675
1676 priv->status |= STATUS_SCANNING;
1677 err = ipw2100_hw_send_command(priv, &cmd);
1678 if (err)
1679 priv->status &= ~STATUS_SCANNING;
1680
1681 IPW_DEBUG_INFO("exit\n");
1682
1683 return err;
1684}
1685
1686static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1687{
1688 unsigned long flags;
1689 int rc = 0;
1690 u32 lock;
1691 u32 ord_len = sizeof(lock);
1692
1693 /* Quite if manually disabled. */
1694 if (priv->status & STATUS_RF_KILL_SW) {
1695 IPW_DEBUG_INFO("%s: Radio is disabled by Manual Disable "
1696 "switch\n", priv->net_dev->name);
1697 return 0;
1698 }
1699
1700 /* If the interrupt is enabled, turn it off... */
1701 spin_lock_irqsave(&priv->low_lock, flags);
1702 ipw2100_disable_interrupts(priv);
1703
1704 /* Reset any fatal_error conditions */
1705 ipw2100_reset_fatalerror(priv);
1706 spin_unlock_irqrestore(&priv->low_lock, flags);
1707
1708 if (priv->status & STATUS_POWERED ||
1709 (priv->status & STATUS_RESET_PENDING)) {
1710 /* Power cycle the card ... */
1711 if (ipw2100_power_cycle_adapter(priv)) {
797b4f76 1712 printk(KERN_WARNING DRV_NAME ": %s: Could not cycle adapter.\n",
2c86c275
JK
1713 priv->net_dev->name);
1714 rc = 1;
1715 goto exit;
1716 }
1717 } else
1718 priv->status |= STATUS_POWERED;
1719
8724a118 1720 /* Load the firmware, start the clocks, etc. */
2c86c275 1721 if (ipw2100_start_adapter(priv)) {
797b4f76 1722 printk(KERN_ERR DRV_NAME ": %s: Failed to start the firmware.\n",
2c86c275
JK
1723 priv->net_dev->name);
1724 rc = 1;
1725 goto exit;
1726 }
1727
1728 ipw2100_initialize_ordinals(priv);
1729
1730 /* Determine capabilities of this particular HW configuration */
1731 if (ipw2100_get_hw_features(priv)) {
797b4f76 1732 printk(KERN_ERR DRV_NAME ": %s: Failed to determine HW features.\n",
2c86c275
JK
1733 priv->net_dev->name);
1734 rc = 1;
1735 goto exit;
1736 }
1737
1738 lock = LOCK_NONE;
1739 if (ipw2100_set_ordinal(priv, IPW_ORD_PERS_DB_LOCK, &lock, &ord_len)) {
797b4f76 1740 printk(KERN_ERR DRV_NAME ": %s: Failed to clear ordinal lock.\n",
2c86c275
JK
1741 priv->net_dev->name);
1742 rc = 1;
1743 goto exit;
1744 }
1745
1746 priv->status &= ~STATUS_SCANNING;
1747
1748 if (rf_kill_active(priv)) {
1749 printk(KERN_INFO "%s: Radio is disabled by RF switch.\n",
1750 priv->net_dev->name);
1751
1752 if (priv->stop_rf_kill) {
1753 priv->stop_rf_kill = 0;
1754 queue_delayed_work(priv->workqueue, &priv->rf_kill, HZ);
1755 }
1756
1757 deferred = 1;
1758 }
1759
1760 /* Turn on the interrupt so that commands can be processed */
1761 ipw2100_enable_interrupts(priv);
1762
1763 /* Send all of the commands that must be sent prior to
1764 * HOST_COMPLETE */
1765 if (ipw2100_adapter_setup(priv)) {
797b4f76 1766 printk(KERN_ERR DRV_NAME ": %s: Failed to start the card.\n",
2c86c275
JK
1767 priv->net_dev->name);
1768 rc = 1;
1769 goto exit;
1770 }
1771
1772 if (!deferred) {
1773 /* Enable the adapter - sends HOST_COMPLETE */
1774 if (ipw2100_enable_adapter(priv)) {
797b4f76 1775 printk(KERN_ERR DRV_NAME ": "
2c86c275
JK
1776 "%s: failed in call to enable adapter.\n",
1777 priv->net_dev->name);
1778 ipw2100_hw_stop_adapter(priv);
1779 rc = 1;
1780 goto exit;
1781 }
1782
1783
1784 /* Start a scan . . . */
1785 ipw2100_set_scan_options(priv);
1786 ipw2100_start_scan(priv);
1787 }
1788
1789 exit:
1790 return rc;
1791}
1792
1793/* Called by register_netdev() */
1794static int ipw2100_net_init(struct net_device *dev)
1795{
1796 struct ipw2100_priv *priv = ieee80211_priv(dev);
1797 return ipw2100_up(priv, 1);
1798}
1799
1800static void ipw2100_down(struct ipw2100_priv *priv)
1801{
1802 unsigned long flags;
1803 union iwreq_data wrqu = {
1804 .ap_addr = {
1805 .sa_family = ARPHRD_ETHER
1806 }
1807 };
1808 int associated = priv->status & STATUS_ASSOCIATED;
1809
1810 /* Kill the RF switch timer */
1811 if (!priv->stop_rf_kill) {
1812 priv->stop_rf_kill = 1;
1813 cancel_delayed_work(&priv->rf_kill);
1814 }
1815
1816 /* Kill the firmare hang check timer */
1817 if (!priv->stop_hang_check) {
1818 priv->stop_hang_check = 1;
1819 cancel_delayed_work(&priv->hang_check);
1820 }
1821
1822 /* Kill any pending resets */
1823 if (priv->status & STATUS_RESET_PENDING)
1824 cancel_delayed_work(&priv->reset_work);
1825
1826 /* Make sure the interrupt is on so that FW commands will be
1827 * processed correctly */
1828 spin_lock_irqsave(&priv->low_lock, flags);
1829 ipw2100_enable_interrupts(priv);
1830 spin_unlock_irqrestore(&priv->low_lock, flags);
1831
1832 if (ipw2100_hw_stop_adapter(priv))
797b4f76 1833 printk(KERN_ERR DRV_NAME ": %s: Error stopping adapter.\n",
2c86c275
JK
1834 priv->net_dev->name);
1835
1836 /* Do not disable the interrupt until _after_ we disable
1837 * the adaptor. Otherwise the CARD_DISABLE command will never
1838 * be ack'd by the firmware */
1839 spin_lock_irqsave(&priv->low_lock, flags);
1840 ipw2100_disable_interrupts(priv);
1841 spin_unlock_irqrestore(&priv->low_lock, flags);
1842
1843#ifdef ACPI_CSTATE_LIMIT_DEFINED
1844 if (priv->config & CFG_C3_DISABLED) {
1845 IPW_DEBUG_INFO(DRV_NAME ": Resetting C3 transitions.\n");
1846 acpi_set_cstate_limit(priv->cstate_limit);
1847 priv->config &= ~CFG_C3_DISABLED;
1848 }
1849#endif
1850
1851 /* We have to signal any supplicant if we are disassociating */
1852 if (associated)
1853 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
1854
1855 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
1856 netif_carrier_off(priv->net_dev);
1857 netif_stop_queue(priv->net_dev);
1858}
1859
c4aee8c2 1860static void ipw2100_reset_adapter(struct ipw2100_priv *priv)
2c86c275
JK
1861{
1862 unsigned long flags;
1863 union iwreq_data wrqu = {
1864 .ap_addr = {
1865 .sa_family = ARPHRD_ETHER
1866 }
1867 };
1868 int associated = priv->status & STATUS_ASSOCIATED;
1869
1870 spin_lock_irqsave(&priv->low_lock, flags);
1871 IPW_DEBUG_INFO(DRV_NAME ": %s: Restarting adapter.\n",
1872 priv->net_dev->name);
1873 priv->resets++;
1874 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
1875 priv->status |= STATUS_SECURITY_UPDATED;
1876
1877 /* Force a power cycle even if interface hasn't been opened
1878 * yet */
1879 cancel_delayed_work(&priv->reset_work);
1880 priv->status |= STATUS_RESET_PENDING;
1881 spin_unlock_irqrestore(&priv->low_lock, flags);
1882
1883 down(&priv->action_sem);
1884 /* stop timed checks so that they don't interfere with reset */
1885 priv->stop_hang_check = 1;
1886 cancel_delayed_work(&priv->hang_check);
1887
1888 /* We have to signal any supplicant if we are disassociating */
1889 if (associated)
1890 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
1891
1892 ipw2100_up(priv, 0);
1893 up(&priv->action_sem);
1894
1895}
1896
1897
1898static void isr_indicate_associated(struct ipw2100_priv *priv, u32 status)
1899{
1900
1901#define MAC_ASSOCIATION_READ_DELAY (HZ)
1902 int ret, len, essid_len;
1903 char essid[IW_ESSID_MAX_SIZE];
1904 u32 txrate;
1905 u32 chan;
1906 char *txratename;
1907 u8 bssid[ETH_ALEN];
1908
1909 /*
1910 * TBD: BSSID is usually 00:00:00:00:00:00 here and not
1911 * an actual MAC of the AP. Seems like FW sets this
1912 * address too late. Read it later and expose through
1913 * /proc or schedule a later task to query and update
1914 */
1915
1916 essid_len = IW_ESSID_MAX_SIZE;
1917 ret = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_SSID,
1918 essid, &essid_len);
1919 if (ret) {
1920 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1921 __LINE__);
1922 return;
1923 }
1924
1925 len = sizeof(u32);
1926 ret = ipw2100_get_ordinal(priv, IPW_ORD_CURRENT_TX_RATE,
1927 &txrate, &len);
1928 if (ret) {
1929 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1930 __LINE__);
1931 return;
1932 }
1933
1934 len = sizeof(u32);
1935 ret = ipw2100_get_ordinal(priv, IPW_ORD_OUR_FREQ, &chan, &len);
1936 if (ret) {
1937 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1938 __LINE__);
1939 return;
1940 }
1941 len = ETH_ALEN;
1942 ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID, &bssid, &len);
1943 if (ret) {
1944 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
1945 __LINE__);
1946 return;
1947 }
1948 memcpy(priv->ieee->bssid, bssid, ETH_ALEN);
1949
1950
1951 switch (txrate) {
1952 case TX_RATE_1_MBIT:
1953 txratename = "1Mbps";
1954 break;
1955 case TX_RATE_2_MBIT:
1956 txratename = "2Mbsp";
1957 break;
1958 case TX_RATE_5_5_MBIT:
1959 txratename = "5.5Mbps";
1960 break;
1961 case TX_RATE_11_MBIT:
1962 txratename = "11Mbps";
1963 break;
1964 default:
1965 IPW_DEBUG_INFO("Unknown rate: %d\n", txrate);
1966 txratename = "unknown rate";
1967 break;
1968 }
1969
1970 IPW_DEBUG_INFO("%s: Associated with '%s' at %s, channel %d (BSSID="
1971 MAC_FMT ")\n",
1972 priv->net_dev->name, escape_essid(essid, essid_len),
1973 txratename, chan, MAC_ARG(bssid));
1974
1975 /* now we copy read ssid into dev */
1976 if (!(priv->config & CFG_STATIC_ESSID)) {
1977 priv->essid_len = min((u8)essid_len, (u8)IW_ESSID_MAX_SIZE);
1978 memcpy(priv->essid, essid, priv->essid_len);
1979 }
1980 priv->channel = chan;
1981 memcpy(priv->bssid, bssid, ETH_ALEN);
1982
1983 priv->status |= STATUS_ASSOCIATING;
1984 priv->connect_start = get_seconds();
1985
1986 queue_delayed_work(priv->workqueue, &priv->wx_event_work, HZ / 10);
1987}
1988
1989
c4aee8c2
JB
1990static int ipw2100_set_essid(struct ipw2100_priv *priv, char *essid,
1991 int length, int batch_mode)
2c86c275
JK
1992{
1993 int ssid_len = min(length, IW_ESSID_MAX_SIZE);
1994 struct host_command cmd = {
1995 .host_command = SSID,
1996 .host_command_sequence = 0,
1997 .host_command_length = ssid_len
1998 };
1999 int err;
2000
2001 IPW_DEBUG_HC("SSID: '%s'\n", escape_essid(essid, ssid_len));
2002
2003 if (ssid_len)
2004 memcpy((char*)cmd.host_command_parameters,
2005 essid, ssid_len);
2006
2007 if (!batch_mode) {
2008 err = ipw2100_disable_adapter(priv);
2009 if (err)
2010 return err;
2011 }
2012
2013 /* Bug in FW currently doesn't honor bit 0 in SET_SCAN_OPTIONS to
2014 * disable auto association -- so we cheat by setting a bogus SSID */
2015 if (!ssid_len && !(priv->config & CFG_ASSOCIATE)) {
2016 int i;
2017 u8 *bogus = (u8*)cmd.host_command_parameters;
2018 for (i = 0; i < IW_ESSID_MAX_SIZE; i++)
2019 bogus[i] = 0x18 + i;
2020 cmd.host_command_length = IW_ESSID_MAX_SIZE;
2021 }
2022
2023 /* NOTE: We always send the SSID command even if the provided ESSID is
2024 * the same as what we currently think is set. */
2025
2026 err = ipw2100_hw_send_command(priv, &cmd);
2027 if (!err) {
2028 memset(priv->essid + ssid_len, 0,
2029 IW_ESSID_MAX_SIZE - ssid_len);
2030 memcpy(priv->essid, essid, ssid_len);
2031 priv->essid_len = ssid_len;
2032 }
2033
2034 if (!batch_mode) {
2035 if (ipw2100_enable_adapter(priv))
2036 err = -EIO;
2037 }
2038
2039 return err;
2040}
2041
2042static void isr_indicate_association_lost(struct ipw2100_priv *priv, u32 status)
2043{
2044 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE | IPW_DL_ASSOC,
2045 "disassociated: '%s' " MAC_FMT " \n",
2046 escape_essid(priv->essid, priv->essid_len),
2047 MAC_ARG(priv->bssid));
2048
2049 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
2050
2051 if (priv->status & STATUS_STOPPING) {
2052 IPW_DEBUG_INFO("Card is stopping itself, discard ASSN_LOST.\n");
2053 return;
2054 }
2055
2056 memset(priv->bssid, 0, ETH_ALEN);
2057 memset(priv->ieee->bssid, 0, ETH_ALEN);
2058
2059 netif_carrier_off(priv->net_dev);
2060 netif_stop_queue(priv->net_dev);
2061
2062 if (!(priv->status & STATUS_RUNNING))
2063 return;
2064
2065 if (priv->status & STATUS_SECURITY_UPDATED)
2066 queue_work(priv->workqueue, &priv->security_work);
2067
2068 queue_work(priv->workqueue, &priv->wx_event_work);
2069}
2070
2071static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
2072{
2073 IPW_DEBUG_INFO("%s: RF Kill state changed to radio OFF.\n",
2074 priv->net_dev->name);
2075
2076 /* RF_KILL is now enabled (else we wouldn't be here) */
2077 priv->status |= STATUS_RF_KILL_HW;
2078
2079#ifdef ACPI_CSTATE_LIMIT_DEFINED
2080 if (priv->config & CFG_C3_DISABLED) {
2081 IPW_DEBUG_INFO(DRV_NAME ": Resetting C3 transitions.\n");
2082 acpi_set_cstate_limit(priv->cstate_limit);
2083 priv->config &= ~CFG_C3_DISABLED;
2084 }
2085#endif
2086
2087 /* Make sure the RF Kill check timer is running */
2088 priv->stop_rf_kill = 0;
2089 cancel_delayed_work(&priv->rf_kill);
2090 queue_delayed_work(priv->workqueue, &priv->rf_kill, HZ);
2091}
2092
2093static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
2094{
2095 IPW_DEBUG_SCAN("scan complete\n");
2096 /* Age the scan results... */
2097 priv->ieee->scans++;
2098 priv->status &= ~STATUS_SCANNING;
2099}
2100
2101#ifdef CONFIG_IPW_DEBUG
2102#define IPW2100_HANDLER(v, f) { v, f, # v }
2103struct ipw2100_status_indicator {
2104 int status;
2105 void (*cb)(struct ipw2100_priv *priv, u32 status);
2106 char *name;
2107};
2108#else
2109#define IPW2100_HANDLER(v, f) { v, f }
2110struct ipw2100_status_indicator {
2111 int status;
2112 void (*cb)(struct ipw2100_priv *priv, u32 status);
2113};
2114#endif /* CONFIG_IPW_DEBUG */
2115
2116static void isr_indicate_scanning(struct ipw2100_priv *priv, u32 status)
2117{
2118 IPW_DEBUG_SCAN("Scanning...\n");
2119 priv->status |= STATUS_SCANNING;
2120}
2121
c4aee8c2 2122static const struct ipw2100_status_indicator status_handlers[] = {
2be041a7
AV
2123 IPW2100_HANDLER(IPW_STATE_INITIALIZED, NULL),
2124 IPW2100_HANDLER(IPW_STATE_COUNTRY_FOUND, NULL),
2c86c275
JK
2125 IPW2100_HANDLER(IPW_STATE_ASSOCIATED, isr_indicate_associated),
2126 IPW2100_HANDLER(IPW_STATE_ASSN_LOST, isr_indicate_association_lost),
2be041a7 2127 IPW2100_HANDLER(IPW_STATE_ASSN_CHANGED, NULL),
2c86c275 2128 IPW2100_HANDLER(IPW_STATE_SCAN_COMPLETE, isr_scan_complete),
2be041a7
AV
2129 IPW2100_HANDLER(IPW_STATE_ENTERED_PSP, NULL),
2130 IPW2100_HANDLER(IPW_STATE_LEFT_PSP, NULL),
2c86c275 2131 IPW2100_HANDLER(IPW_STATE_RF_KILL, isr_indicate_rf_kill),
2be041a7
AV
2132 IPW2100_HANDLER(IPW_STATE_DISABLED, NULL),
2133 IPW2100_HANDLER(IPW_STATE_POWER_DOWN, NULL),
2c86c275 2134 IPW2100_HANDLER(IPW_STATE_SCANNING, isr_indicate_scanning),
2be041a7 2135 IPW2100_HANDLER(-1, NULL)
2c86c275
JK
2136};
2137
2138
2139static void isr_status_change(struct ipw2100_priv *priv, int status)
2140{
2141 int i;
2142
2143 if (status == IPW_STATE_SCANNING &&
2144 priv->status & STATUS_ASSOCIATED &&
2145 !(priv->status & STATUS_SCANNING)) {
2146 IPW_DEBUG_INFO("Scan detected while associated, with "
2147 "no scan request. Restarting firmware.\n");
2148
2149 /* Wake up any sleeping jobs */
2150 schedule_reset(priv);
2151 }
2152
2153 for (i = 0; status_handlers[i].status != -1; i++) {
2154 if (status == status_handlers[i].status) {
2155 IPW_DEBUG_NOTIF("Status change: %s\n",
2156 status_handlers[i].name);
2157 if (status_handlers[i].cb)
2158 status_handlers[i].cb(priv, status);
2159 priv->wstats.status = status;
2160 return;
2161 }
2162 }
2163
2164 IPW_DEBUG_NOTIF("unknown status received: %04x\n", status);
2165}
2166
2167static void isr_rx_complete_command(
2168 struct ipw2100_priv *priv,
2169 struct ipw2100_cmd_header *cmd)
2170{
2171#ifdef CONFIG_IPW_DEBUG
2172 if (cmd->host_command_reg < ARRAY_SIZE(command_types)) {
2173 IPW_DEBUG_HC("Command completed '%s (%d)'\n",
2174 command_types[cmd->host_command_reg],
2175 cmd->host_command_reg);
2176 }
2177#endif
2178 if (cmd->host_command_reg == HOST_COMPLETE)
2179 priv->status |= STATUS_ENABLED;
2180
2181 if (cmd->host_command_reg == CARD_DISABLE)
2182 priv->status &= ~STATUS_ENABLED;
2183
2184 priv->status &= ~STATUS_CMD_ACTIVE;
2185
2186 wake_up_interruptible(&priv->wait_command_queue);
2187}
2188
2189#ifdef CONFIG_IPW_DEBUG
c4aee8c2 2190static const char *frame_types[] = {
2c86c275
JK
2191 "COMMAND_STATUS_VAL",
2192 "STATUS_CHANGE_VAL",
2193 "P80211_DATA_VAL",
2194 "P8023_DATA_VAL",
2195 "HOST_NOTIFICATION_VAL"
2196};
2197#endif
2198
2199
2200static inline int ipw2100_alloc_skb(
2201 struct ipw2100_priv *priv,
2202 struct ipw2100_rx_packet *packet)
2203{
2204 packet->skb = dev_alloc_skb(sizeof(struct ipw2100_rx));
2205 if (!packet->skb)
2206 return -ENOMEM;
2207
2208 packet->rxp = (struct ipw2100_rx *)packet->skb->data;
2209 packet->dma_addr = pci_map_single(priv->pci_dev, packet->skb->data,
2210 sizeof(struct ipw2100_rx),
2211 PCI_DMA_FROMDEVICE);
2212 /* NOTE: pci_map_single does not return an error code, and 0 is a valid
2213 * dma_addr */
2214
2215 return 0;
2216}
2217
2218
2219#define SEARCH_ERROR 0xffffffff
2220#define SEARCH_FAIL 0xfffffffe
2221#define SEARCH_SUCCESS 0xfffffff0
2222#define SEARCH_DISCARD 0
2223#define SEARCH_SNAPSHOT 1
2224
2225#define SNAPSHOT_ADDR(ofs) (priv->snapshot[((ofs) >> 12) & 0xff] + ((ofs) & 0xfff))
2226static inline int ipw2100_snapshot_alloc(struct ipw2100_priv *priv)
2227{
2228 int i;
2229 if (priv->snapshot[0])
2230 return 1;
2231 for (i = 0; i < 0x30; i++) {
2232 priv->snapshot[i] = (u8*)kmalloc(0x1000, GFP_ATOMIC);
2233 if (!priv->snapshot[i]) {
2234 IPW_DEBUG_INFO("%s: Error allocating snapshot "
2235 "buffer %d\n", priv->net_dev->name, i);
2236 while (i > 0)
2237 kfree(priv->snapshot[--i]);
2238 priv->snapshot[0] = NULL;
2239 return 0;
2240 }
2241 }
2242
2243 return 1;
2244}
2245
2246static inline void ipw2100_snapshot_free(struct ipw2100_priv *priv)
2247{
2248 int i;
2249 if (!priv->snapshot[0])
2250 return;
2251 for (i = 0; i < 0x30; i++)
2252 kfree(priv->snapshot[i]);
2253 priv->snapshot[0] = NULL;
2254}
2255
2256static inline u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 *in_buf,
2257 size_t len, int mode)
2258{
2259 u32 i, j;
2260 u32 tmp;
2261 u8 *s, *d;
2262 u32 ret;
2263
2264 s = in_buf;
2265 if (mode == SEARCH_SNAPSHOT) {
2266 if (!ipw2100_snapshot_alloc(priv))
2267 mode = SEARCH_DISCARD;
2268 }
2269
2270 for (ret = SEARCH_FAIL, i = 0; i < 0x30000; i += 4) {
2271 read_nic_dword(priv->net_dev, i, &tmp);
2272 if (mode == SEARCH_SNAPSHOT)
2273 *(u32 *)SNAPSHOT_ADDR(i) = tmp;
2274 if (ret == SEARCH_FAIL) {
2275 d = (u8*)&tmp;
2276 for (j = 0; j < 4; j++) {
2277 if (*s != *d) {
2278 s = in_buf;
2279 continue;
2280 }
2281
2282 s++;
2283 d++;
2284
2285 if ((s - in_buf) == len)
2286 ret = (i + j) - len + 1;
2287 }
2288 } else if (mode == SEARCH_DISCARD)
2289 return ret;
2290 }
2291
2292 return ret;
2293}
2294
2295/*
2296 *
2297 * 0) Disconnect the SKB from the firmware (just unmap)
2298 * 1) Pack the ETH header into the SKB
2299 * 2) Pass the SKB to the network stack
2300 *
2301 * When packet is provided by the firmware, it contains the following:
2302 *
2303 * . ieee80211_hdr
2304 * . ieee80211_snap_hdr
2305 *
2306 * The size of the constructed ethernet
2307 *
2308 */
2309#ifdef CONFIG_IPW2100_RX_DEBUG
c4aee8c2 2310static u8 packet_data[IPW_RX_NIC_BUFFER_LENGTH];
2c86c275
JK
2311#endif
2312
2313static inline void ipw2100_corruption_detected(struct ipw2100_priv *priv,
2314 int i)
2315{
2316#ifdef CONFIG_IPW_DEBUG_C3
2317 struct ipw2100_status *status = &priv->status_queue.drv[i];
2318 u32 match, reg;
2319 int j;
2320#endif
2321#ifdef ACPI_CSTATE_LIMIT_DEFINED
2322 int limit;
2323#endif
2324
2325 IPW_DEBUG_INFO(DRV_NAME ": PCI latency error detected at "
aaa4d308 2326 "0x%04zX.\n", i * sizeof(struct ipw2100_status));
2c86c275
JK
2327
2328#ifdef ACPI_CSTATE_LIMIT_DEFINED
2329 IPW_DEBUG_INFO(DRV_NAME ": Disabling C3 transitions.\n");
2330 limit = acpi_get_cstate_limit();
2331 if (limit > 2) {
2332 priv->cstate_limit = limit;
2333 acpi_set_cstate_limit(2);
2334 priv->config |= CFG_C3_DISABLED;
2335 }
2336#endif
2337
2338#ifdef CONFIG_IPW_DEBUG_C3
2339 /* Halt the fimrware so we can get a good image */
2340 write_register(priv->net_dev, IPW_REG_RESET_REG,
2341 IPW_AUX_HOST_RESET_REG_STOP_MASTER);
2342 j = 5;
2343 do {
2344 udelay(IPW_WAIT_RESET_MASTER_ASSERT_COMPLETE_DELAY);
2345 read_register(priv->net_dev, IPW_REG_RESET_REG, &reg);
2346
2347 if (reg & IPW_AUX_HOST_RESET_REG_MASTER_DISABLED)
2348 break;
2349 } while (j--);
2350
2351 match = ipw2100_match_buf(priv, (u8*)status,
2352 sizeof(struct ipw2100_status),
2353 SEARCH_SNAPSHOT);
2354 if (match < SEARCH_SUCCESS)
2355 IPW_DEBUG_INFO("%s: DMA status match in Firmware at "
2356 "offset 0x%06X, length %d:\n",
2357 priv->net_dev->name, match,
2358 sizeof(struct ipw2100_status));
2359 else
2360 IPW_DEBUG_INFO("%s: No DMA status match in "
2361 "Firmware.\n", priv->net_dev->name);
2362
2363 printk_buf((u8*)priv->status_queue.drv,
2364 sizeof(struct ipw2100_status) * RX_QUEUE_LENGTH);
2365#endif
2366
2367 priv->fatal_error = IPW2100_ERR_C3_CORRUPTION;
2368 priv->ieee->stats.rx_errors++;
2369 schedule_reset(priv);
2370}
2371
2372static inline void isr_rx(struct ipw2100_priv *priv, int i,
2373 struct ieee80211_rx_stats *stats)
2374{
2375 struct ipw2100_status *status = &priv->status_queue.drv[i];
2376 struct ipw2100_rx_packet *packet = &priv->rx_buffers[i];
2377
2378 IPW_DEBUG_RX("Handler...\n");
2379
2380 if (unlikely(status->frame_size > skb_tailroom(packet->skb))) {
2381 IPW_DEBUG_INFO("%s: frame_size (%u) > skb_tailroom (%u)!"
2382 " Dropping.\n",
2383 priv->net_dev->name,
2384 status->frame_size, skb_tailroom(packet->skb));
2385 priv->ieee->stats.rx_errors++;
2386 return;
2387 }
2388
2389 if (unlikely(!netif_running(priv->net_dev))) {
2390 priv->ieee->stats.rx_errors++;
2391 priv->wstats.discard.misc++;
2392 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
2393 return;
2394 }
2395
2396 if (unlikely(priv->ieee->iw_mode == IW_MODE_MONITOR &&
2397 status->flags & IPW_STATUS_FLAG_CRC_ERROR)) {
2398 IPW_DEBUG_RX("CRC error in packet. Dropping.\n");
2399 priv->ieee->stats.rx_errors++;
2400 return;
2401 }
2402
2403 if (unlikely(priv->ieee->iw_mode != IW_MODE_MONITOR &&
2404 !(priv->status & STATUS_ASSOCIATED))) {
2405 IPW_DEBUG_DROP("Dropping packet while not associated.\n");
2406 priv->wstats.discard.misc++;
2407 return;
2408 }
2409
2410
2411 pci_unmap_single(priv->pci_dev,
2412 packet->dma_addr,
2413 sizeof(struct ipw2100_rx),
2414 PCI_DMA_FROMDEVICE);
2415
2416 skb_put(packet->skb, status->frame_size);
2417
2418#ifdef CONFIG_IPW2100_RX_DEBUG
2419 /* Make a copy of the frame so we can dump it to the logs if
2420 * ieee80211_rx fails */
2421 memcpy(packet_data, packet->skb->data,
aaa4d308 2422 min_t(u32, status->frame_size, IPW_RX_NIC_BUFFER_LENGTH));
2c86c275
JK
2423#endif
2424
2425 if (!ieee80211_rx(priv->ieee, packet->skb, stats)) {
2426#ifdef CONFIG_IPW2100_RX_DEBUG
2427 IPW_DEBUG_DROP("%s: Non consumed packet:\n",
2428 priv->net_dev->name);
2429 printk_buf(IPW_DL_DROP, packet_data, status->frame_size);
2430#endif
2431 priv->ieee->stats.rx_errors++;
2432
2433 /* ieee80211_rx failed, so it didn't free the SKB */
2434 dev_kfree_skb_any(packet->skb);
2435 packet->skb = NULL;
2436 }
2437
2438 /* We need to allocate a new SKB and attach it to the RDB. */
2439 if (unlikely(ipw2100_alloc_skb(priv, packet))) {
797b4f76 2440 printk(KERN_WARNING DRV_NAME ": "
2c86c275
JK
2441 "%s: Unable to allocate SKB onto RBD ring - disabling "
2442 "adapter.\n", priv->net_dev->name);
2443 /* TODO: schedule adapter shutdown */
2444 IPW_DEBUG_INFO("TODO: Shutdown adapter...\n");
2445 }
2446
2447 /* Update the RDB entry */
2448 priv->rx_queue.drv[i].host_addr = packet->dma_addr;
2449}
2450
2451static inline int ipw2100_corruption_check(struct ipw2100_priv *priv, int i)
2452{
2453 struct ipw2100_status *status = &priv->status_queue.drv[i];
2454 struct ipw2100_rx *u = priv->rx_buffers[i].rxp;
2455 u16 frame_type = status->status_fields & STATUS_TYPE_MASK;
2456
2457 switch (frame_type) {
2458 case COMMAND_STATUS_VAL:
2459 return (status->frame_size != sizeof(u->rx_data.command));
2460 case STATUS_CHANGE_VAL:
2461 return (status->frame_size != sizeof(u->rx_data.status));
2462 case HOST_NOTIFICATION_VAL:
2463 return (status->frame_size < sizeof(u->rx_data.notification));
2464 case P80211_DATA_VAL:
2465 case P8023_DATA_VAL:
2466#ifdef CONFIG_IPW2100_MONITOR
2467 return 0;
2468#else
2469 switch (WLAN_FC_GET_TYPE(u->rx_data.header.frame_ctl)) {
2470 case IEEE80211_FTYPE_MGMT:
2471 case IEEE80211_FTYPE_CTL:
2472 return 0;
2473 case IEEE80211_FTYPE_DATA:
2474 return (status->frame_size >
2475 IPW_MAX_802_11_PAYLOAD_LENGTH);
2476 }
2477#endif
2478 }
2479
2480 return 1;
2481}
2482
2483/*
2484 * ipw2100 interrupts are disabled at this point, and the ISR
2485 * is the only code that calls this method. So, we do not need
2486 * to play with any locks.
2487 *
2488 * RX Queue works as follows:
2489 *
2490 * Read index - firmware places packet in entry identified by the
2491 * Read index and advances Read index. In this manner,
2492 * Read index will always point to the next packet to
2493 * be filled--but not yet valid.
2494 *
2495 * Write index - driver fills this entry with an unused RBD entry.
2496 * This entry has not filled by the firmware yet.
2497 *
2498 * In between the W and R indexes are the RBDs that have been received
2499 * but not yet processed.
2500 *
2501 * The process of handling packets will start at WRITE + 1 and advance
2502 * until it reaches the READ index.
2503 *
2504 * The WRITE index is cached in the variable 'priv->rx_queue.next'.
2505 *
2506 */
2507static inline void __ipw2100_rx_process(struct ipw2100_priv *priv)
2508{
2509 struct ipw2100_bd_queue *rxq = &priv->rx_queue;
2510 struct ipw2100_status_queue *sq = &priv->status_queue;
2511 struct ipw2100_rx_packet *packet;
2512 u16 frame_type;
2513 u32 r, w, i, s;
2514 struct ipw2100_rx *u;
2515 struct ieee80211_rx_stats stats = {
2516 .mac_time = jiffies,
2517 };
2518
2519 read_register(priv->net_dev, IPW_MEM_HOST_SHARED_RX_READ_INDEX, &r);
2520 read_register(priv->net_dev, IPW_MEM_HOST_SHARED_RX_WRITE_INDEX, &w);
2521
2522 if (r >= rxq->entries) {
2523 IPW_DEBUG_RX("exit - bad read index\n");
2524 return;
2525 }
2526
2527 i = (rxq->next + 1) % rxq->entries;
2528 s = i;
2529 while (i != r) {
2530 /* IPW_DEBUG_RX("r = %d : w = %d : processing = %d\n",
2531 r, rxq->next, i); */
2532
2533 packet = &priv->rx_buffers[i];
2534
2535 /* Sync the DMA for the STATUS buffer so CPU is sure to get
2536 * the correct values */
2537 pci_dma_sync_single_for_cpu(
2538 priv->pci_dev,
2539 sq->nic + sizeof(struct ipw2100_status) * i,
2540 sizeof(struct ipw2100_status),
2541 PCI_DMA_FROMDEVICE);
2542
2543 /* Sync the DMA for the RX buffer so CPU is sure to get
2544 * the correct values */
2545 pci_dma_sync_single_for_cpu(priv->pci_dev, packet->dma_addr,
2546 sizeof(struct ipw2100_rx),
2547 PCI_DMA_FROMDEVICE);
2548
2549 if (unlikely(ipw2100_corruption_check(priv, i))) {
2550 ipw2100_corruption_detected(priv, i);
2551 goto increment;
2552 }
2553
2554 u = packet->rxp;
2555 frame_type = sq->drv[i].status_fields &
2556 STATUS_TYPE_MASK;
2557 stats.rssi = sq->drv[i].rssi + IPW2100_RSSI_TO_DBM;
2558 stats.len = sq->drv[i].frame_size;
2559
2560 stats.mask = 0;
2561 if (stats.rssi != 0)
2562 stats.mask |= IEEE80211_STATMASK_RSSI;
2563 stats.freq = IEEE80211_24GHZ_BAND;
2564
2565 IPW_DEBUG_RX(
2566 "%s: '%s' frame type received (%d).\n",
2567 priv->net_dev->name, frame_types[frame_type],
2568 stats.len);
2569
2570 switch (frame_type) {
2571 case COMMAND_STATUS_VAL:
2572 /* Reset Rx watchdog */
2573 isr_rx_complete_command(
2574 priv, &u->rx_data.command);
2575 break;
2576
2577 case STATUS_CHANGE_VAL:
2578 isr_status_change(priv, u->rx_data.status);
2579 break;
2580
2581 case P80211_DATA_VAL:
2582 case P8023_DATA_VAL:
2583#ifdef CONFIG_IPW2100_MONITOR
2584 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
2585 isr_rx(priv, i, &stats);
2586 break;
2587 }
2588#endif
2589 if (stats.len < sizeof(u->rx_data.header))
2590 break;
2591 switch (WLAN_FC_GET_TYPE(u->rx_data.header.
2592 frame_ctl)) {
2593 case IEEE80211_FTYPE_MGMT:
2594 ieee80211_rx_mgt(priv->ieee,
2595 &u->rx_data.header,
2596 &stats);
2597 break;
2598
2599 case IEEE80211_FTYPE_CTL:
2600 break;
2601
2602 case IEEE80211_FTYPE_DATA:
2603 isr_rx(priv, i, &stats);
2604 break;
2605
2606 }
2607 break;
2608 }
2609
2610 increment:
2611 /* clear status field associated with this RBD */
2612 rxq->drv[i].status.info.field = 0;
2613
2614 i = (i + 1) % rxq->entries;
2615 }
2616
2617 if (i != s) {
2618 /* backtrack one entry, wrapping to end if at 0 */
2619 rxq->next = (i ? i : rxq->entries) - 1;
2620
2621 write_register(priv->net_dev,
2622 IPW_MEM_HOST_SHARED_RX_WRITE_INDEX,
2623 rxq->next);
2624 }
2625}
2626
2627
2628/*
2629 * __ipw2100_tx_process
2630 *
2631 * This routine will determine whether the next packet on
2632 * the fw_pend_list has been processed by the firmware yet.
2633 *
2634 * If not, then it does nothing and returns.
2635 *
2636 * If so, then it removes the item from the fw_pend_list, frees
2637 * any associated storage, and places the item back on the
2638 * free list of its source (either msg_free_list or tx_free_list)
2639 *
2640 * TX Queue works as follows:
2641 *
2642 * Read index - points to the next TBD that the firmware will
2643 * process. The firmware will read the data, and once
2644 * done processing, it will advance the Read index.
2645 *
2646 * Write index - driver fills this entry with an constructed TBD
2647 * entry. The Write index is not advanced until the
2648 * packet has been configured.
2649 *
2650 * In between the W and R indexes are the TBDs that have NOT been
2651 * processed. Lagging behind the R index are packets that have
2652 * been processed but have not been freed by the driver.
2653 *
2654 * In order to free old storage, an internal index will be maintained
2655 * that points to the next packet to be freed. When all used
2656 * packets have been freed, the oldest index will be the same as the
2657 * firmware's read index.
2658 *
2659 * The OLDEST index is cached in the variable 'priv->tx_queue.oldest'
2660 *
2661 * Because the TBD structure can not contain arbitrary data, the
2662 * driver must keep an internal queue of cached allocations such that
2663 * it can put that data back into the tx_free_list and msg_free_list
2664 * for use by future command and data packets.
2665 *
2666 */
2667static inline int __ipw2100_tx_process(struct ipw2100_priv *priv)
2668{
2669 struct ipw2100_bd_queue *txq = &priv->tx_queue;
2670 struct ipw2100_bd *tbd;
2671 struct list_head *element;
2672 struct ipw2100_tx_packet *packet;
2673 int descriptors_used;
2674 int e, i;
2675 u32 r, w, frag_num = 0;
2676
2677 if (list_empty(&priv->fw_pend_list))
2678 return 0;
2679
2680 element = priv->fw_pend_list.next;
2681
2682 packet = list_entry(element, struct ipw2100_tx_packet, list);
2683 tbd = &txq->drv[packet->index];
2684
2685 /* Determine how many TBD entries must be finished... */
2686 switch (packet->type) {
2687 case COMMAND:
2688 /* COMMAND uses only one slot; don't advance */
2689 descriptors_used = 1;
2690 e = txq->oldest;
2691 break;
2692
2693 case DATA:
2694 /* DATA uses two slots; advance and loop position. */
2695 descriptors_used = tbd->num_fragments;
2696 frag_num = tbd->num_fragments - 1;
2697 e = txq->oldest + frag_num;
2698 e %= txq->entries;
2699 break;
2700
2701 default:
797b4f76 2702 printk(KERN_WARNING DRV_NAME ": %s: Bad fw_pend_list entry!\n",
2c86c275
JK
2703 priv->net_dev->name);
2704 return 0;
2705 }
2706
2707 /* if the last TBD is not done by NIC yet, then packet is
2708 * not ready to be released.
2709 *
2710 */
2711 read_register(priv->net_dev, IPW_MEM_HOST_SHARED_TX_QUEUE_READ_INDEX,
2712 &r);
2713 read_register(priv->net_dev, IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX,
2714 &w);
2715 if (w != txq->next)
797b4f76 2716 printk(KERN_WARNING DRV_NAME ": %s: write index mismatch\n",
2c86c275
JK
2717 priv->net_dev->name);
2718
2719 /*
2720 * txq->next is the index of the last packet written txq->oldest is
2721 * the index of the r is the index of the next packet to be read by
2722 * firmware
2723 */
2724
2725
2726 /*
2727 * Quick graphic to help you visualize the following
2728 * if / else statement
2729 *
2730 * ===>| s---->|===============
2731 * e>|
2732 * | a | b | c | d | e | f | g | h | i | j | k | l
2733 * r---->|
2734 * w
2735 *
2736 * w - updated by driver
2737 * r - updated by firmware
2738 * s - start of oldest BD entry (txq->oldest)
2739 * e - end of oldest BD entry
2740 *
2741 */
2742 if (!((r <= w && (e < r || e >= w)) || (e < r && e >= w))) {
2743 IPW_DEBUG_TX("exit - no processed packets ready to release.\n");
2744 return 0;
2745 }
2746
2747 list_del(element);
2748 DEC_STAT(&priv->fw_pend_stat);
2749
2750#ifdef CONFIG_IPW_DEBUG
2751 {
2752 int i = txq->oldest;
2753 IPW_DEBUG_TX(
aaa4d308 2754 "TX%d V=%p P=%04X T=%04X L=%d\n", i,
2c86c275 2755 &txq->drv[i],
aaa4d308
JB
2756 (u32)(txq->nic + i * sizeof(struct ipw2100_bd)),
2757 txq->drv[i].host_addr,
2c86c275
JK
2758 txq->drv[i].buf_length);
2759
2760 if (packet->type == DATA) {
2761 i = (i + 1) % txq->entries;
2762
2763 IPW_DEBUG_TX(
aaa4d308 2764 "TX%d V=%p P=%04X T=%04X L=%d\n", i,
2c86c275 2765 &txq->drv[i],
aaa4d308
JB
2766 (u32)(txq->nic + i *
2767 sizeof(struct ipw2100_bd)),
2768 (u32)txq->drv[i].host_addr,
2c86c275
JK
2769 txq->drv[i].buf_length);
2770 }
2771 }
2772#endif
2773
2774 switch (packet->type) {
2775 case DATA:
2776 if (txq->drv[txq->oldest].status.info.fields.txType != 0)
797b4f76 2777 printk(KERN_WARNING DRV_NAME ": %s: Queue mismatch. "
2c86c275
JK
2778 "Expecting DATA TBD but pulled "
2779 "something else: ids %d=%d.\n",
2780 priv->net_dev->name, txq->oldest, packet->index);
2781
2782 /* DATA packet; we have to unmap and free the SKB */
2783 priv->ieee->stats.tx_packets++;
2784 for (i = 0; i < frag_num; i++) {
2785 tbd = &txq->drv[(packet->index + 1 + i) %
2786 txq->entries];
2787
2788 IPW_DEBUG_TX(
2789 "TX%d P=%08x L=%d\n",
2790 (packet->index + 1 + i) % txq->entries,
2791 tbd->host_addr, tbd->buf_length);
2792
2793 pci_unmap_single(priv->pci_dev,
2794 tbd->host_addr,
2795 tbd->buf_length,
2796 PCI_DMA_TODEVICE);
2797 }
2798
2799 priv->ieee->stats.tx_bytes += packet->info.d_struct.txb->payload_size;
2800 ieee80211_txb_free(packet->info.d_struct.txb);
2801 packet->info.d_struct.txb = NULL;
2802
2803 list_add_tail(element, &priv->tx_free_list);
2804 INC_STAT(&priv->tx_free_stat);
2805
2806 /* We have a free slot in the Tx queue, so wake up the
2807 * transmit layer if it is stopped. */
2808 if (priv->status & STATUS_ASSOCIATED &&
2809 netif_queue_stopped(priv->net_dev)) {
2810 IPW_DEBUG_INFO(KERN_INFO
2811 "%s: Waking net queue.\n",
2812 priv->net_dev->name);
2813 netif_wake_queue(priv->net_dev);
2814 }
2815
2816 /* A packet was processed by the hardware, so update the
2817 * watchdog */
2818 priv->net_dev->trans_start = jiffies;
2819
2820 break;
2821
2822 case COMMAND:
2823 if (txq->drv[txq->oldest].status.info.fields.txType != 1)
797b4f76 2824 printk(KERN_WARNING DRV_NAME ": %s: Queue mismatch. "
2c86c275
JK
2825 "Expecting COMMAND TBD but pulled "
2826 "something else: ids %d=%d.\n",
2827 priv->net_dev->name, txq->oldest, packet->index);
2828
2829#ifdef CONFIG_IPW_DEBUG
2830 if (packet->info.c_struct.cmd->host_command_reg <
2831 sizeof(command_types) / sizeof(*command_types))
2832 IPW_DEBUG_TX(
2833 "Command '%s (%d)' processed: %d.\n",
2834 command_types[packet->info.c_struct.cmd->host_command_reg],
2835 packet->info.c_struct.cmd->host_command_reg,
2836 packet->info.c_struct.cmd->cmd_status_reg);
2837#endif
2838
2839 list_add_tail(element, &priv->msg_free_list);
2840 INC_STAT(&priv->msg_free_stat);
2841 break;
2842 }
2843
2844 /* advance oldest used TBD pointer to start of next entry */
2845 txq->oldest = (e + 1) % txq->entries;
2846 /* increase available TBDs number */
2847 txq->available += descriptors_used;
2848 SET_STAT(&priv->txq_stat, txq->available);
2849
2850 IPW_DEBUG_TX("packet latency (send to process) %ld jiffies\n",
2851 jiffies - packet->jiffy_start);
2852
2853 return (!list_empty(&priv->fw_pend_list));
2854}
2855
2856
2857static inline void __ipw2100_tx_complete(struct ipw2100_priv *priv)
2858{
2859 int i = 0;
2860
2861 while (__ipw2100_tx_process(priv) && i < 200) i++;
2862
2863 if (i == 200) {
19f7f742 2864 printk(KERN_WARNING DRV_NAME ": "
2c86c275
JK
2865 "%s: Driver is running slow (%d iters).\n",
2866 priv->net_dev->name, i);
2867 }
2868}
2869
2870
19f7f742 2871static void ipw2100_tx_send_commands(struct ipw2100_priv *priv)
2c86c275
JK
2872{
2873 struct list_head *element;
2874 struct ipw2100_tx_packet *packet;
2875 struct ipw2100_bd_queue *txq = &priv->tx_queue;
2876 struct ipw2100_bd *tbd;
2877 int next = txq->next;
2878
2879 while (!list_empty(&priv->msg_pend_list)) {
2880 /* if there isn't enough space in TBD queue, then
2881 * don't stuff a new one in.
2882 * NOTE: 3 are needed as a command will take one,
2883 * and there is a minimum of 2 that must be
2884 * maintained between the r and w indexes
2885 */
2886 if (txq->available <= 3) {
2887 IPW_DEBUG_TX("no room in tx_queue\n");
2888 break;
2889 }
2890
2891 element = priv->msg_pend_list.next;
2892 list_del(element);
2893 DEC_STAT(&priv->msg_pend_stat);
2894
2895 packet = list_entry(element,
2896 struct ipw2100_tx_packet, list);
2897
2898 IPW_DEBUG_TX("using TBD at virt=%p, phys=%p\n",
2899 &txq->drv[txq->next],
2900 (void*)(txq->nic + txq->next *
2901 sizeof(struct ipw2100_bd)));
2902
2903 packet->index = txq->next;
2904
2905 tbd = &txq->drv[txq->next];
2906
2907 /* initialize TBD */
2908 tbd->host_addr = packet->info.c_struct.cmd_phys;
2909 tbd->buf_length = sizeof(struct ipw2100_cmd_header);
2910 /* not marking number of fragments causes problems
2911 * with f/w debug version */
2912 tbd->num_fragments = 1;
2913 tbd->status.info.field =
2914 IPW_BD_STATUS_TX_FRAME_COMMAND |
2915 IPW_BD_STATUS_TX_INTERRUPT_ENABLE;
2916
2917 /* update TBD queue counters */
2918 txq->next++;
2919 txq->next %= txq->entries;
2920 txq->available--;
2921 DEC_STAT(&priv->txq_stat);
2922
2923 list_add_tail(element, &priv->fw_pend_list);
2924 INC_STAT(&priv->fw_pend_stat);
2925 }
2926
2927 if (txq->next != next) {
2928 /* kick off the DMA by notifying firmware the
2929 * write index has moved; make sure TBD stores are sync'd */
2930 wmb();
2931 write_register(priv->net_dev,
2932 IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX,
2933 txq->next);
2934 }
2935}
2936
2937
2938/*
19f7f742 2939 * ipw2100_tx_send_data
2c86c275
JK
2940 *
2941 */
19f7f742 2942static void ipw2100_tx_send_data(struct ipw2100_priv *priv)
2c86c275
JK
2943{
2944 struct list_head *element;
2945 struct ipw2100_tx_packet *packet;
2946 struct ipw2100_bd_queue *txq = &priv->tx_queue;
2947 struct ipw2100_bd *tbd;
2948 int next = txq->next;
2949 int i = 0;
2950 struct ipw2100_data_header *ipw_hdr;
99a4b232 2951 struct ieee80211_hdr_3addr *hdr;
2c86c275
JK
2952
2953 while (!list_empty(&priv->tx_pend_list)) {
2954 /* if there isn't enough space in TBD queue, then
2955 * don't stuff a new one in.
2956 * NOTE: 4 are needed as a data will take two,
2957 * and there is a minimum of 2 that must be
2958 * maintained between the r and w indexes
2959 */
2960 element = priv->tx_pend_list.next;
2961 packet = list_entry(element, struct ipw2100_tx_packet, list);
2962
2963 if (unlikely(1 + packet->info.d_struct.txb->nr_frags >
2964 IPW_MAX_BDS)) {
2965 /* TODO: Support merging buffers if more than
2966 * IPW_MAX_BDS are used */
2967 IPW_DEBUG_INFO(
2968 "%s: Maximum BD theshold exceeded. "
2969 "Increase fragmentation level.\n",
2970 priv->net_dev->name);
2971 }
2972
2973 if (txq->available <= 3 +
2974 packet->info.d_struct.txb->nr_frags) {
2975 IPW_DEBUG_TX("no room in tx_queue\n");
2976 break;
2977 }
2978
2979 list_del(element);
2980 DEC_STAT(&priv->tx_pend_stat);
2981
2982 tbd = &txq->drv[txq->next];
2983
2984 packet->index = txq->next;
2985
2986 ipw_hdr = packet->info.d_struct.data;
99a4b232 2987 hdr = (struct ieee80211_hdr_3addr *)packet->info.d_struct.txb->
2c86c275
JK
2988 fragments[0]->data;
2989
2990 if (priv->ieee->iw_mode == IW_MODE_INFRA) {
2991 /* To DS: Addr1 = BSSID, Addr2 = SA,
2992 Addr3 = DA */
2993 memcpy(ipw_hdr->src_addr, hdr->addr2, ETH_ALEN);
2994 memcpy(ipw_hdr->dst_addr, hdr->addr3, ETH_ALEN);
2995 } else if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
2996 /* not From/To DS: Addr1 = DA, Addr2 = SA,
2997 Addr3 = BSSID */
2998 memcpy(ipw_hdr->src_addr, hdr->addr2, ETH_ALEN);
2999 memcpy(ipw_hdr->dst_addr, hdr->addr1, ETH_ALEN);
3000 }
3001
3002 ipw_hdr->host_command_reg = SEND;
3003 ipw_hdr->host_command_reg1 = 0;
3004
3005 /* For now we only support host based encryption */
3006 ipw_hdr->needs_encryption = 0;
3007 ipw_hdr->encrypted = packet->info.d_struct.txb->encrypted;
3008 if (packet->info.d_struct.txb->nr_frags > 1)
3009 ipw_hdr->fragment_size =
3010 packet->info.d_struct.txb->frag_size - IEEE80211_3ADDR_LEN;
3011 else
3012 ipw_hdr->fragment_size = 0;
3013
3014 tbd->host_addr = packet->info.d_struct.data_phys;
3015 tbd->buf_length = sizeof(struct ipw2100_data_header);
3016 tbd->num_fragments = 1 + packet->info.d_struct.txb->nr_frags;
3017 tbd->status.info.field =
3018 IPW_BD_STATUS_TX_FRAME_802_3 |
3019 IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT;
3020 txq->next++;
3021 txq->next %= txq->entries;
3022
3023 IPW_DEBUG_TX(
3024 "data header tbd TX%d P=%08x L=%d\n",
3025 packet->index, tbd->host_addr,
3026 tbd->buf_length);
3027#ifdef CONFIG_IPW_DEBUG
3028 if (packet->info.d_struct.txb->nr_frags > 1)
3029 IPW_DEBUG_FRAG("fragment Tx: %d frames\n",
3030 packet->info.d_struct.txb->nr_frags);
3031#endif
3032
3033 for (i = 0; i < packet->info.d_struct.txb->nr_frags; i++) {
3034 tbd = &txq->drv[txq->next];
3035 if (i == packet->info.d_struct.txb->nr_frags - 1)
3036 tbd->status.info.field =
3037 IPW_BD_STATUS_TX_FRAME_802_3 |
3038 IPW_BD_STATUS_TX_INTERRUPT_ENABLE;
3039 else
3040 tbd->status.info.field =
3041 IPW_BD_STATUS_TX_FRAME_802_3 |
3042 IPW_BD_STATUS_TX_FRAME_NOT_LAST_FRAGMENT;
3043
3044 tbd->buf_length = packet->info.d_struct.txb->
3045 fragments[i]->len - IEEE80211_3ADDR_LEN;
3046
3047 tbd->host_addr = pci_map_single(
3048 priv->pci_dev,
3049 packet->info.d_struct.txb->fragments[i]->data +
3050 IEEE80211_3ADDR_LEN,
3051 tbd->buf_length,
3052 PCI_DMA_TODEVICE);
3053
3054 IPW_DEBUG_TX(
3055 "data frag tbd TX%d P=%08x L=%d\n",
3056 txq->next, tbd->host_addr, tbd->buf_length);
3057
3058 pci_dma_sync_single_for_device(
3059 priv->pci_dev, tbd->host_addr,
3060 tbd->buf_length,
3061 PCI_DMA_TODEVICE);
3062
3063 txq->next++;
3064 txq->next %= txq->entries;
3065 }
3066
3067 txq->available -= 1 + packet->info.d_struct.txb->nr_frags;
3068 SET_STAT(&priv->txq_stat, txq->available);
3069
3070 list_add_tail(element, &priv->fw_pend_list);
3071 INC_STAT(&priv->fw_pend_stat);
3072 }
3073
3074 if (txq->next != next) {
3075 /* kick off the DMA by notifying firmware the
3076 * write index has moved; make sure TBD stores are sync'd */
3077 write_register(priv->net_dev,
3078 IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX,
3079 txq->next);
3080 }
3081 return;
3082}
3083
3084static void ipw2100_irq_tasklet(struct ipw2100_priv *priv)
3085{
3086 struct net_device *dev = priv->net_dev;
3087 unsigned long flags;
3088 u32 inta, tmp;
3089
3090 spin_lock_irqsave(&priv->low_lock, flags);
3091 ipw2100_disable_interrupts(priv);
3092
3093 read_register(dev, IPW_REG_INTA, &inta);
3094
3095 IPW_DEBUG_ISR("enter - INTA: 0x%08lX\n",
3096 (unsigned long)inta & IPW_INTERRUPT_MASK);
3097
3098 priv->in_isr++;
3099 priv->interrupts++;
3100
3101 /* We do not loop and keep polling for more interrupts as this
3102 * is frowned upon and doesn't play nicely with other potentially
3103 * chained IRQs */
3104 IPW_DEBUG_ISR("INTA: 0x%08lX\n",
3105 (unsigned long)inta & IPW_INTERRUPT_MASK);
3106
3107 if (inta & IPW2100_INTA_FATAL_ERROR) {
797b4f76 3108 printk(KERN_WARNING DRV_NAME
2c86c275
JK
3109 ": Fatal interrupt. Scheduling firmware restart.\n");
3110 priv->inta_other++;
3111 write_register(
3112 dev, IPW_REG_INTA,
3113 IPW2100_INTA_FATAL_ERROR);
3114
3115 read_nic_dword(dev, IPW_NIC_FATAL_ERROR, &priv->fatal_error);
3116 IPW_DEBUG_INFO("%s: Fatal error value: 0x%08X\n",
3117 priv->net_dev->name, priv->fatal_error);
3118
3119 read_nic_dword(dev, IPW_ERROR_ADDR(priv->fatal_error), &tmp);
3120 IPW_DEBUG_INFO("%s: Fatal error address value: 0x%08X\n",
3121 priv->net_dev->name, tmp);
3122
3123 /* Wake up any sleeping jobs */
3124 schedule_reset(priv);
3125 }
3126
3127 if (inta & IPW2100_INTA_PARITY_ERROR) {
797b4f76 3128 printk(KERN_ERR DRV_NAME ": ***** PARITY ERROR INTERRUPT !!!! \n");
2c86c275
JK
3129 priv->inta_other++;
3130 write_register(
3131 dev, IPW_REG_INTA,
3132 IPW2100_INTA_PARITY_ERROR);
3133 }
3134
3135 if (inta & IPW2100_INTA_RX_TRANSFER) {
3136 IPW_DEBUG_ISR("RX interrupt\n");
3137
3138 priv->rx_interrupts++;
3139
3140 write_register(
3141 dev, IPW_REG_INTA,
3142 IPW2100_INTA_RX_TRANSFER);
3143
3144 __ipw2100_rx_process(priv);
3145 __ipw2100_tx_complete(priv);
3146 }
3147
3148 if (inta & IPW2100_INTA_TX_TRANSFER) {
3149 IPW_DEBUG_ISR("TX interrupt\n");
3150
3151 priv->tx_interrupts++;
3152
3153 write_register(dev, IPW_REG_INTA,
3154 IPW2100_INTA_TX_TRANSFER);
3155
3156 __ipw2100_tx_complete(priv);
19f7f742
JB
3157 ipw2100_tx_send_commands(priv);
3158 ipw2100_tx_send_data(priv);
2c86c275
JK
3159 }
3160
3161 if (inta & IPW2100_INTA_TX_COMPLETE) {
3162 IPW_DEBUG_ISR("TX complete\n");
3163 priv->inta_other++;
3164 write_register(
3165 dev, IPW_REG_INTA,
3166 IPW2100_INTA_TX_COMPLETE);
3167
3168 __ipw2100_tx_complete(priv);
3169 }
3170
3171 if (inta & IPW2100_INTA_EVENT_INTERRUPT) {
3172 /* ipw2100_handle_event(dev); */
3173 priv->inta_other++;
3174 write_register(
3175 dev, IPW_REG_INTA,
3176 IPW2100_INTA_EVENT_INTERRUPT);
3177 }
3178
3179 if (inta & IPW2100_INTA_FW_INIT_DONE) {
3180 IPW_DEBUG_ISR("FW init done interrupt\n");
3181 priv->inta_other++;
3182
3183 read_register(dev, IPW_REG_INTA, &tmp);
3184 if (tmp & (IPW2100_INTA_FATAL_ERROR |
3185 IPW2100_INTA_PARITY_ERROR)) {
3186 write_register(
3187 dev, IPW_REG_INTA,
3188 IPW2100_INTA_FATAL_ERROR |
3189 IPW2100_INTA_PARITY_ERROR);
3190 }
3191
3192 write_register(dev, IPW_REG_INTA,
3193 IPW2100_INTA_FW_INIT_DONE);
3194 }
3195
3196 if (inta & IPW2100_INTA_STATUS_CHANGE) {
3197 IPW_DEBUG_ISR("Status change interrupt\n");
3198 priv->inta_other++;
3199 write_register(
3200 dev, IPW_REG_INTA,
3201 IPW2100_INTA_STATUS_CHANGE);
3202 }
3203
3204 if (inta & IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE) {
3205 IPW_DEBUG_ISR("slave host mode interrupt\n");
3206 priv->inta_other++;
3207 write_register(
3208 dev, IPW_REG_INTA,
3209 IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE);
3210 }
3211
3212 priv->in_isr--;
3213 ipw2100_enable_interrupts(priv);
3214
3215 spin_unlock_irqrestore(&priv->low_lock, flags);
3216
3217 IPW_DEBUG_ISR("exit\n");
3218}
3219
3220
3221static irqreturn_t ipw2100_interrupt(int irq, void *data,
3222 struct pt_regs *regs)
3223{
3224 struct ipw2100_priv *priv = data;
3225 u32 inta, inta_mask;
3226
3227 if (!data)
3228 return IRQ_NONE;
3229
3230 spin_lock(&priv->low_lock);
3231
3232 /* We check to see if we should be ignoring interrupts before
3233 * we touch the hardware. During ucode load if we try and handle
3234 * an interrupt we can cause keyboard problems as well as cause
3235 * the ucode to fail to initialize */
3236 if (!(priv->status & STATUS_INT_ENABLED)) {
3237 /* Shared IRQ */
3238 goto none;
3239 }
3240
3241 read_register(priv->net_dev, IPW_REG_INTA_MASK, &inta_mask);
3242 read_register(priv->net_dev, IPW_REG_INTA, &inta);
3243
3244 if (inta == 0xFFFFFFFF) {
3245 /* Hardware disappeared */
797b4f76 3246 printk(KERN_WARNING DRV_NAME ": IRQ INTA == 0xFFFFFFFF\n");
2c86c275
JK
3247 goto none;
3248 }
3249
3250 inta &= IPW_INTERRUPT_MASK;
3251
3252 if (!(inta & inta_mask)) {
3253 /* Shared interrupt */
3254 goto none;
3255 }
3256
3257 /* We disable the hardware interrupt here just to prevent unneeded
3258 * calls to be made. We disable this again within the actual
3259 * work tasklet, so if another part of the code re-enables the
3260 * interrupt, that is fine */
3261 ipw2100_disable_interrupts(priv);
3262
3263 tasklet_schedule(&priv->irq_tasklet);
3264 spin_unlock(&priv->low_lock);
3265
3266 return IRQ_HANDLED;
3267 none:
3268 spin_unlock(&priv->low_lock);
3269 return IRQ_NONE;
3270}
3271
3272static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev)
3273{
3274 struct ipw2100_priv *priv = ieee80211_priv(dev);
3275 struct list_head *element;
3276 struct ipw2100_tx_packet *packet;
3277 unsigned long flags;
3278
3279 spin_lock_irqsave(&priv->low_lock, flags);
3280
3281 if (!(priv->status & STATUS_ASSOCIATED)) {
3282 IPW_DEBUG_INFO("Can not transmit when not connected.\n");
3283 priv->ieee->stats.tx_carrier_errors++;
3284 netif_stop_queue(dev);
3285 goto fail_unlock;
3286 }
3287
3288 if (list_empty(&priv->tx_free_list))
3289 goto fail_unlock;
3290
3291 element = priv->tx_free_list.next;
3292 packet = list_entry(element, struct ipw2100_tx_packet, list);
3293
3294 packet->info.d_struct.txb = txb;
3295
3296 IPW_DEBUG_TX("Sending fragment (%d bytes):\n",
3297 txb->fragments[0]->len);
3298 printk_buf(IPW_DL_TX, txb->fragments[0]->data,
3299 txb->fragments[0]->len);
3300
3301 packet->jiffy_start = jiffies;
3302
3303 list_del(element);
3304 DEC_STAT(&priv->tx_free_stat);
3305
3306 list_add_tail(element, &priv->tx_pend_list);
3307 INC_STAT(&priv->tx_pend_stat);
3308
19f7f742 3309 ipw2100_tx_send_data(priv);
2c86c275
JK
3310
3311 spin_unlock_irqrestore(&priv->low_lock, flags);
3312 return 0;
3313
3314 fail_unlock:
3315 netif_stop_queue(dev);
3316 spin_unlock_irqrestore(&priv->low_lock, flags);
3317 return 1;
3318}
3319
3320
3321static int ipw2100_msg_allocate(struct ipw2100_priv *priv)
3322{
3323 int i, j, err = -EINVAL;
3324 void *v;
3325 dma_addr_t p;
3326
3327 priv->msg_buffers = (struct ipw2100_tx_packet *)kmalloc(
3328 IPW_COMMAND_POOL_SIZE * sizeof(struct ipw2100_tx_packet),
3329 GFP_KERNEL);
3330 if (!priv->msg_buffers) {
797b4f76 3331 printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for msg "
2c86c275
JK
3332 "buffers.\n", priv->net_dev->name);
3333 return -ENOMEM;
3334 }
3335
3336 for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) {
3337 v = pci_alloc_consistent(
3338 priv->pci_dev,
3339 sizeof(struct ipw2100_cmd_header),
3340 &p);
3341 if (!v) {
797b4f76 3342 printk(KERN_ERR DRV_NAME ": "
2c86c275
JK
3343 "%s: PCI alloc failed for msg "
3344 "buffers.\n",
3345 priv->net_dev->name);
3346 err = -ENOMEM;
3347 break;
3348 }
3349
3350 memset(v, 0, sizeof(struct ipw2100_cmd_header));
3351
3352 priv->msg_buffers[i].type = COMMAND;
3353 priv->msg_buffers[i].info.c_struct.cmd =
3354 (struct ipw2100_cmd_header*)v;
3355 priv->msg_buffers[i].info.c_struct.cmd_phys = p;
3356 }
3357
3358 if (i == IPW_COMMAND_POOL_SIZE)
3359 return 0;
3360
3361 for (j = 0; j < i; j++) {
3362 pci_free_consistent(
3363 priv->pci_dev,
3364 sizeof(struct ipw2100_cmd_header),
3365 priv->msg_buffers[j].info.c_struct.cmd,
3366 priv->msg_buffers[j].info.c_struct.cmd_phys);
3367 }
3368
3369 kfree(priv->msg_buffers);
3370 priv->msg_buffers = NULL;
3371
3372 return err;
3373}
3374
3375static int ipw2100_msg_initialize(struct ipw2100_priv *priv)
3376{
3377 int i;
3378
3379 INIT_LIST_HEAD(&priv->msg_free_list);
3380 INIT_LIST_HEAD(&priv->msg_pend_list);
3381
3382 for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++)
3383 list_add_tail(&priv->msg_buffers[i].list, &priv->msg_free_list);
3384 SET_STAT(&priv->msg_free_stat, i);
3385
3386 return 0;
3387}
3388
3389static void ipw2100_msg_free(struct ipw2100_priv *priv)
3390{
3391 int i;
3392
3393 if (!priv->msg_buffers)
3394 return;
3395
3396 for (i = 0; i < IPW_COMMAND_POOL_SIZE; i++) {
3397 pci_free_consistent(priv->pci_dev,
3398 sizeof(struct ipw2100_cmd_header),
3399 priv->msg_buffers[i].info.c_struct.cmd,
3400 priv->msg_buffers[i].info.c_struct.cmd_phys);
3401 }
3402
3403 kfree(priv->msg_buffers);
3404 priv->msg_buffers = NULL;
3405}
3406
edfc43f2
AM
3407static ssize_t show_pci(struct device *d, struct device_attribute *attr,
3408 char *buf)
2c86c275
JK
3409{
3410 struct pci_dev *pci_dev = container_of(d, struct pci_dev, dev);
3411 char *out = buf;
3412 int i, j;
3413 u32 val;
3414
3415 for (i = 0; i < 16; i++) {
3416 out += sprintf(out, "[%08X] ", i * 16);
3417 for (j = 0; j < 16; j += 4) {
3418 pci_read_config_dword(pci_dev, i * 16 + j, &val);
3419 out += sprintf(out, "%08X ", val);
3420 }
3421 out += sprintf(out, "\n");
3422 }
3423
3424 return out - buf;
3425}
3426static DEVICE_ATTR(pci, S_IRUGO, show_pci, NULL);
3427
edfc43f2
AM
3428static ssize_t show_cfg(struct device *d, struct device_attribute *attr,
3429 char *buf)
2c86c275 3430{
edfc43f2 3431 struct ipw2100_priv *p = d->driver_data;
2c86c275
JK
3432 return sprintf(buf, "0x%08x\n", (int)p->config);
3433}
3434static DEVICE_ATTR(cfg, S_IRUGO, show_cfg, NULL);
3435
edfc43f2
AM
3436static ssize_t show_status(struct device *d, struct device_attribute *attr,
3437 char *buf)
2c86c275 3438{
edfc43f2 3439 struct ipw2100_priv *p = d->driver_data;
2c86c275
JK
3440 return sprintf(buf, "0x%08x\n", (int)p->status);
3441}
3442static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
3443
edfc43f2
AM
3444static ssize_t show_capability(struct device *d, struct device_attribute *attr,
3445 char *buf)
2c86c275 3446{
edfc43f2 3447 struct ipw2100_priv *p = d->driver_data;
2c86c275
JK
3448 return sprintf(buf, "0x%08x\n", (int)p->capability);
3449}
3450static DEVICE_ATTR(capability, S_IRUGO, show_capability, NULL);
3451
3452
3453#define IPW2100_REG(x) { IPW_ ##x, #x }
c4aee8c2 3454static const struct {
2c86c275
JK
3455 u32 addr;
3456 const char *name;
3457} hw_data[] = {
3458 IPW2100_REG(REG_GP_CNTRL),
3459 IPW2100_REG(REG_GPIO),
3460 IPW2100_REG(REG_INTA),
3461 IPW2100_REG(REG_INTA_MASK),
3462 IPW2100_REG(REG_RESET_REG),
3463};
3464#define IPW2100_NIC(x, s) { x, #x, s }
c4aee8c2 3465static const struct {
2c86c275
JK
3466 u32 addr;
3467 const char *name;
3468 size_t size;
3469} nic_data[] = {
3470 IPW2100_NIC(IPW2100_CONTROL_REG, 2),
3471 IPW2100_NIC(0x210014, 1),
3472 IPW2100_NIC(0x210000, 1),
3473};
3474#define IPW2100_ORD(x, d) { IPW_ORD_ ##x, #x, d }
c4aee8c2 3475static const struct {
2c86c275
JK
3476 u8 index;
3477 const char *name;
3478 const char *desc;
3479} ord_data[] = {
3480 IPW2100_ORD(STAT_TX_HOST_REQUESTS, "requested Host Tx's (MSDU)"),
3481 IPW2100_ORD(STAT_TX_HOST_COMPLETE, "successful Host Tx's (MSDU)"),
3482 IPW2100_ORD(STAT_TX_DIR_DATA, "successful Directed Tx's (MSDU)"),
3483 IPW2100_ORD(STAT_TX_DIR_DATA1, "successful Directed Tx's (MSDU) @ 1MB"),
3484 IPW2100_ORD(STAT_TX_DIR_DATA2, "successful Directed Tx's (MSDU) @ 2MB"),
3485 IPW2100_ORD(STAT_TX_DIR_DATA5_5, "successful Directed Tx's (MSDU) @ 5_5MB"),
3486 IPW2100_ORD(STAT_TX_DIR_DATA11, "successful Directed Tx's (MSDU) @ 11MB"),
3487 IPW2100_ORD(STAT_TX_NODIR_DATA1, "successful Non_Directed Tx's (MSDU) @ 1MB"),
3488 IPW2100_ORD(STAT_TX_NODIR_DATA2, "successful Non_Directed Tx's (MSDU) @ 2MB"),
3489 IPW2100_ORD(STAT_TX_NODIR_DATA5_5, "successful Non_Directed Tx's (MSDU) @ 5.5MB"),
3490 IPW2100_ORD(STAT_TX_NODIR_DATA11, "successful Non_Directed Tx's (MSDU) @ 11MB"),
3491 IPW2100_ORD(STAT_NULL_DATA, "successful NULL data Tx's"),
3492 IPW2100_ORD(STAT_TX_RTS, "successful Tx RTS"),
3493 IPW2100_ORD(STAT_TX_CTS, "successful Tx CTS"),
3494 IPW2100_ORD(STAT_TX_ACK, "successful Tx ACK"),
3495 IPW2100_ORD(STAT_TX_ASSN, "successful Association Tx's"),
3496 IPW2100_ORD(STAT_TX_ASSN_RESP, "successful Association response Tx's"),
3497 IPW2100_ORD(STAT_TX_REASSN, "successful Reassociation Tx's"),
3498 IPW2100_ORD(STAT_TX_REASSN_RESP, "successful Reassociation response Tx's"),
3499 IPW2100_ORD(STAT_TX_PROBE, "probes successfully transmitted"),
3500 IPW2100_ORD(STAT_TX_PROBE_RESP, "probe responses successfully transmitted"),
3501 IPW2100_ORD(STAT_TX_BEACON, "tx beacon"),
3502 IPW2100_ORD(STAT_TX_ATIM, "Tx ATIM"),
3503 IPW2100_ORD(STAT_TX_DISASSN, "successful Disassociation TX"),
3504 IPW2100_ORD(STAT_TX_AUTH, "successful Authentication Tx"),
3505 IPW2100_ORD(STAT_TX_DEAUTH, "successful Deauthentication TX"),
3506 IPW2100_ORD(STAT_TX_TOTAL_BYTES, "Total successful Tx data bytes"),
3507 IPW2100_ORD(STAT_TX_RETRIES, "Tx retries"),
3508 IPW2100_ORD(STAT_TX_RETRY1, "Tx retries at 1MBPS"),
3509 IPW2100_ORD(STAT_TX_RETRY2, "Tx retries at 2MBPS"),
3510 IPW2100_ORD(STAT_TX_RETRY5_5, "Tx retries at 5.5MBPS"),
3511 IPW2100_ORD(STAT_TX_RETRY11, "Tx retries at 11MBPS"),
3512 IPW2100_ORD(STAT_TX_FAILURES, "Tx Failures"),
3513 IPW2100_ORD(STAT_TX_MAX_TRIES_IN_HOP,"times max tries in a hop failed"),
3514 IPW2100_ORD(STAT_TX_DISASSN_FAIL, "times disassociation failed"),
3515 IPW2100_ORD(STAT_TX_ERR_CTS, "missed/bad CTS frames"),
3516 IPW2100_ORD(STAT_TX_ERR_ACK, "tx err due to acks"),
3517 IPW2100_ORD(STAT_RX_HOST, "packets passed to host"),
3518 IPW2100_ORD(STAT_RX_DIR_DATA, "directed packets"),
3519 IPW2100_ORD(STAT_RX_DIR_DATA1, "directed packets at 1MB"),
3520 IPW2100_ORD(STAT_RX_DIR_DATA2, "directed packets at 2MB"),
3521 IPW2100_ORD(STAT_RX_DIR_DATA5_5, "directed packets at 5.5MB"),
3522 IPW2100_ORD(STAT_RX_DIR_DATA11, "directed packets at 11MB"),
3523 IPW2100_ORD(STAT_RX_NODIR_DATA,"nondirected packets"),
3524 IPW2100_ORD(STAT_RX_NODIR_DATA1, "nondirected packets at 1MB"),
3525 IPW2100_ORD(STAT_RX_NODIR_DATA2, "nondirected packets at 2MB"),
3526 IPW2100_ORD(STAT_RX_NODIR_DATA5_5, "nondirected packets at 5.5MB"),
3527 IPW2100_ORD(STAT_RX_NODIR_DATA11, "nondirected packets at 11MB"),
3528 IPW2100_ORD(STAT_RX_NULL_DATA, "null data rx's"),
3529 IPW2100_ORD(STAT_RX_RTS, "Rx RTS"),
3530 IPW2100_ORD(STAT_RX_CTS, "Rx CTS"),
3531 IPW2100_ORD(STAT_RX_ACK, "Rx ACK"),
3532 IPW2100_ORD(STAT_RX_CFEND, "Rx CF End"),
3533 IPW2100_ORD(STAT_RX_CFEND_ACK, "Rx CF End + CF Ack"),
3534 IPW2100_ORD(STAT_RX_ASSN, "Association Rx's"),
3535 IPW2100_ORD(STAT_RX_ASSN_RESP, "Association response Rx's"),
3536 IPW2100_ORD(STAT_RX_REASSN, "Reassociation Rx's"),
3537 IPW2100_ORD(STAT_RX_REASSN_RESP, "Reassociation response Rx's"),
3538 IPW2100_ORD(STAT_RX_PROBE, "probe Rx's"),
3539 IPW2100_ORD(STAT_RX_PROBE_RESP, "probe response Rx's"),
3540 IPW2100_ORD(STAT_RX_BEACON, "Rx beacon"),
3541 IPW2100_ORD(STAT_RX_ATIM, "Rx ATIM"),
3542 IPW2100_ORD(STAT_RX_DISASSN, "disassociation Rx"),
3543 IPW2100_ORD(STAT_RX_AUTH, "authentication Rx"),
3544 IPW2100_ORD(STAT_RX_DEAUTH, "deauthentication Rx"),
3545 IPW2100_ORD(STAT_RX_TOTAL_BYTES,"Total rx data bytes received"),
3546 IPW2100_ORD(STAT_RX_ERR_CRC, "packets with Rx CRC error"),
3547 IPW2100_ORD(STAT_RX_ERR_CRC1, "Rx CRC errors at 1MB"),
3548 IPW2100_ORD(STAT_RX_ERR_CRC2, "Rx CRC errors at 2MB"),
3549 IPW2100_ORD(STAT_RX_ERR_CRC5_5, "Rx CRC errors at 5.5MB"),
3550 IPW2100_ORD(STAT_RX_ERR_CRC11, "Rx CRC errors at 11MB"),
3551 IPW2100_ORD(STAT_RX_DUPLICATE1, "duplicate rx packets at 1MB"),
3552 IPW2100_ORD(STAT_RX_DUPLICATE2, "duplicate rx packets at 2MB"),
3553 IPW2100_ORD(STAT_RX_DUPLICATE5_5, "duplicate rx packets at 5.5MB"),
3554 IPW2100_ORD(STAT_RX_DUPLICATE11, "duplicate rx packets at 11MB"),
3555 IPW2100_ORD(STAT_RX_DUPLICATE, "duplicate rx packets"),
3556 IPW2100_ORD(PERS_DB_LOCK, "locking fw permanent db"),
3557 IPW2100_ORD(PERS_DB_SIZE, "size of fw permanent db"),
3558 IPW2100_ORD(PERS_DB_ADDR, "address of fw permanent db"),
3559 IPW2100_ORD(STAT_RX_INVALID_PROTOCOL, "rx frames with invalid protocol"),
3560 IPW2100_ORD(SYS_BOOT_TIME, "Boot time"),
3561 IPW2100_ORD(STAT_RX_NO_BUFFER, "rx frames rejected due to no buffer"),
3562 IPW2100_ORD(STAT_RX_MISSING_FRAG, "rx frames dropped due to missing fragment"),
3563 IPW2100_ORD(STAT_RX_ORPHAN_FRAG, "rx frames dropped due to non-sequential fragment"),
3564 IPW2100_ORD(STAT_RX_ORPHAN_FRAME, "rx frames dropped due to unmatched 1st frame"),
3565 IPW2100_ORD(STAT_RX_FRAG_AGEOUT, "rx frames dropped due to uncompleted frame"),
3566 IPW2100_ORD(STAT_RX_ICV_ERRORS, "ICV errors during decryption"),
3567 IPW2100_ORD(STAT_PSP_SUSPENSION,"times adapter suspended"),
3568 IPW2100_ORD(STAT_PSP_BCN_TIMEOUT, "beacon timeout"),
3569 IPW2100_ORD(STAT_PSP_POLL_TIMEOUT, "poll response timeouts"),
3570 IPW2100_ORD(STAT_PSP_NONDIR_TIMEOUT, "timeouts waiting for last {broad,multi}cast pkt"),
3571 IPW2100_ORD(STAT_PSP_RX_DTIMS, "PSP DTIMs received"),
3572 IPW2100_ORD(STAT_PSP_RX_TIMS, "PSP TIMs received"),
3573 IPW2100_ORD(STAT_PSP_STATION_ID,"PSP Station ID"),
3574 IPW2100_ORD(LAST_ASSN_TIME, "RTC time of last association"),
3575 IPW2100_ORD(STAT_PERCENT_MISSED_BCNS,"current calculation of % missed beacons"),
3576 IPW2100_ORD(STAT_PERCENT_RETRIES,"current calculation of % missed tx retries"),
3577 IPW2100_ORD(ASSOCIATED_AP_PTR, "0 if not associated, else pointer to AP table entry"),
3578 IPW2100_ORD(AVAILABLE_AP_CNT, "AP's decsribed in the AP table"),
3579 IPW2100_ORD(AP_LIST_PTR, "Ptr to list of available APs"),
3580 IPW2100_ORD(STAT_AP_ASSNS, "associations"),
3581 IPW2100_ORD(STAT_ASSN_FAIL, "association failures"),
3582 IPW2100_ORD(STAT_ASSN_RESP_FAIL,"failures due to response fail"),
3583 IPW2100_ORD(STAT_FULL_SCANS, "full scans"),
3584 IPW2100_ORD(CARD_DISABLED, "Card Disabled"),
3585 IPW2100_ORD(STAT_ROAM_INHIBIT, "times roaming was inhibited due to activity"),
3586 IPW2100_ORD(RSSI_AT_ASSN, "RSSI of associated AP at time of association"),
3587 IPW2100_ORD(STAT_ASSN_CAUSE1, "reassociation: no probe response or TX on hop"),
3588 IPW2100_ORD(STAT_ASSN_CAUSE2, "reassociation: poor tx/rx quality"),
3589 IPW2100_ORD(STAT_ASSN_CAUSE3, "reassociation: tx/rx quality (excessive AP load"),
3590 IPW2100_ORD(STAT_ASSN_CAUSE4, "reassociation: AP RSSI level"),
3591 IPW2100_ORD(STAT_ASSN_CAUSE5, "reassociations due to load leveling"),
3592 IPW2100_ORD(STAT_AUTH_FAIL, "times authentication failed"),
3593 IPW2100_ORD(STAT_AUTH_RESP_FAIL,"times authentication response failed"),
3594 IPW2100_ORD(STATION_TABLE_CNT, "entries in association table"),
3595 IPW2100_ORD(RSSI_AVG_CURR, "Current avg RSSI"),
3596 IPW2100_ORD(POWER_MGMT_MODE, "Power mode - 0=CAM, 1=PSP"),
3597 IPW2100_ORD(COUNTRY_CODE, "IEEE country code as recv'd from beacon"),
3598 IPW2100_ORD(COUNTRY_CHANNELS, "channels suported by country"),
3599 IPW2100_ORD(RESET_CNT, "adapter resets (warm)"),
3600 IPW2100_ORD(BEACON_INTERVAL, "Beacon interval"),
3601 IPW2100_ORD(ANTENNA_DIVERSITY, "TRUE if antenna diversity is disabled"),
3602 IPW2100_ORD(DTIM_PERIOD, "beacon intervals between DTIMs"),
3603 IPW2100_ORD(OUR_FREQ, "current radio freq lower digits - channel ID"),
3604 IPW2100_ORD(RTC_TIME, "current RTC time"),
3605 IPW2100_ORD(PORT_TYPE, "operating mode"),
3606 IPW2100_ORD(CURRENT_TX_RATE, "current tx rate"),
3607 IPW2100_ORD(SUPPORTED_RATES, "supported tx rates"),
3608 IPW2100_ORD(ATIM_WINDOW, "current ATIM Window"),
3609 IPW2100_ORD(BASIC_RATES, "basic tx rates"),
3610 IPW2100_ORD(NIC_HIGHEST_RATE, "NIC highest tx rate"),
3611 IPW2100_ORD(AP_HIGHEST_RATE, "AP highest tx rate"),
3612 IPW2100_ORD(CAPABILITIES, "Management frame capability field"),
3613 IPW2100_ORD(AUTH_TYPE, "Type of authentication"),
3614 IPW2100_ORD(RADIO_TYPE, "Adapter card platform type"),
3615 IPW2100_ORD(RTS_THRESHOLD, "Min packet length for RTS handshaking"),
3616 IPW2100_ORD(INT_MODE, "International mode"),
3617 IPW2100_ORD(FRAGMENTATION_THRESHOLD, "protocol frag threshold"),
3618 IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_START_ADDRESS, "EEPROM offset in SRAM"),
3619 IPW2100_ORD(EEPROM_SRAM_DB_BLOCK_SIZE, "EEPROM size in SRAM"),
3620 IPW2100_ORD(EEPROM_SKU_CAPABILITY, "EEPROM SKU Capability"),
3621 IPW2100_ORD(EEPROM_IBSS_11B_CHANNELS, "EEPROM IBSS 11b channel set"),
3622 IPW2100_ORD(MAC_VERSION, "MAC Version"),
3623 IPW2100_ORD(MAC_REVISION, "MAC Revision"),
3624 IPW2100_ORD(RADIO_VERSION, "Radio Version"),
3625 IPW2100_ORD(NIC_MANF_DATE_TIME, "MANF Date/Time STAMP"),
3626 IPW2100_ORD(UCODE_VERSION, "Ucode Version"),
3627};
3628
3629
edfc43f2
AM
3630static ssize_t show_registers(struct device *d, struct device_attribute *attr,
3631 char *buf)
2c86c275
JK
3632{
3633 int i;
3634 struct ipw2100_priv *priv = dev_get_drvdata(d);
3635 struct net_device *dev = priv->net_dev;
3636 char * out = buf;
3637 u32 val = 0;
3638
3639 out += sprintf(out, "%30s [Address ] : Hex\n", "Register");
3640
3641 for (i = 0; i < (sizeof(hw_data) / sizeof(*hw_data)); i++) {
3642 read_register(dev, hw_data[i].addr, &val);
3643 out += sprintf(out, "%30s [%08X] : %08X\n",
3644 hw_data[i].name, hw_data[i].addr, val);
3645 }
3646
3647 return out - buf;
3648}
3649static DEVICE_ATTR(registers, S_IRUGO, show_registers, NULL);
3650
3651
edfc43f2
AM
3652static ssize_t show_hardware(struct device *d, struct device_attribute *attr,
3653 char *buf)
2c86c275
JK
3654{
3655 struct ipw2100_priv *priv = dev_get_drvdata(d);
3656 struct net_device *dev = priv->net_dev;
3657 char * out = buf;
3658 int i;
3659
3660 out += sprintf(out, "%30s [Address ] : Hex\n", "NIC entry");
3661
3662 for (i = 0; i < (sizeof(nic_data) / sizeof(*nic_data)); i++) {
3663 u8 tmp8;
3664 u16 tmp16;
3665 u32 tmp32;
3666
3667 switch (nic_data[i].size) {
3668 case 1:
3669 read_nic_byte(dev, nic_data[i].addr, &tmp8);
3670 out += sprintf(out, "%30s [%08X] : %02X\n",
3671 nic_data[i].name, nic_data[i].addr,
3672 tmp8);
3673 break;
3674 case 2:
3675 read_nic_word(dev, nic_data[i].addr, &tmp16);
3676 out += sprintf(out, "%30s [%08X] : %04X\n",
3677 nic_data[i].name, nic_data[i].addr,
3678 tmp16);
3679 break;
3680 case 4:
3681 read_nic_dword(dev, nic_data[i].addr, &tmp32);
3682 out += sprintf(out, "%30s [%08X] : %08X\n",
3683 nic_data[i].name, nic_data[i].addr,
3684 tmp32);
3685 break;
3686 }
3687 }
3688 return out - buf;
3689}
3690static DEVICE_ATTR(hardware, S_IRUGO, show_hardware, NULL);
3691
3692
edfc43f2
AM
3693static ssize_t show_memory(struct device *d, struct device_attribute *attr,
3694 char *buf)
2c86c275
JK
3695{
3696 struct ipw2100_priv *priv = dev_get_drvdata(d);
3697 struct net_device *dev = priv->net_dev;
3698 static unsigned long loop = 0;
3699 int len = 0;
3700 u32 buffer[4];
3701 int i;
3702 char line[81];
3703
3704 if (loop >= 0x30000)
3705 loop = 0;
3706
3707 /* sysfs provides us PAGE_SIZE buffer */
3708 while (len < PAGE_SIZE - 128 && loop < 0x30000) {
3709
3710 if (priv->snapshot[0]) for (i = 0; i < 4; i++)
3711 buffer[i] = *(u32 *)SNAPSHOT_ADDR(loop + i * 4);
3712 else for (i = 0; i < 4; i++)
3713 read_nic_dword(dev, loop + i * 4, &buffer[i]);
3714
3715 if (priv->dump_raw)
3716 len += sprintf(buf + len,
3717 "%c%c%c%c"
3718 "%c%c%c%c"
3719 "%c%c%c%c"
3720 "%c%c%c%c",
3721 ((u8*)buffer)[0x0],
3722 ((u8*)buffer)[0x1],
3723 ((u8*)buffer)[0x2],
3724 ((u8*)buffer)[0x3],
3725 ((u8*)buffer)[0x4],
3726 ((u8*)buffer)[0x5],
3727 ((u8*)buffer)[0x6],
3728 ((u8*)buffer)[0x7],
3729 ((u8*)buffer)[0x8],
3730 ((u8*)buffer)[0x9],
3731 ((u8*)buffer)[0xa],
3732 ((u8*)buffer)[0xb],
3733 ((u8*)buffer)[0xc],
3734 ((u8*)buffer)[0xd],
3735 ((u8*)buffer)[0xe],
3736 ((u8*)buffer)[0xf]);
3737 else
3738 len += sprintf(buf + len, "%s\n",
3739 snprint_line(line, sizeof(line),
3740 (u8*)buffer, 16, loop));
3741 loop += 16;
3742 }
3743
3744 return len;
3745}
3746
edfc43f2
AM
3747static ssize_t store_memory(struct device *d, struct device_attribute *attr,
3748 const char *buf, size_t count)
2c86c275
JK
3749{
3750 struct ipw2100_priv *priv = dev_get_drvdata(d);
3751 struct net_device *dev = priv->net_dev;
3752 const char *p = buf;
3753
3754 if (count < 1)
3755 return count;
3756
3757 if (p[0] == '1' ||
3758 (count >= 2 && tolower(p[0]) == 'o' && tolower(p[1]) == 'n')) {
3759 IPW_DEBUG_INFO("%s: Setting memory dump to RAW mode.\n",
3760 dev->name);
3761 priv->dump_raw = 1;
3762
3763 } else if (p[0] == '0' || (count >= 2 && tolower(p[0]) == 'o' &&
3764 tolower(p[1]) == 'f')) {
3765 IPW_DEBUG_INFO("%s: Setting memory dump to HEX mode.\n",
3766 dev->name);
3767 priv->dump_raw = 0;
3768
3769 } else if (tolower(p[0]) == 'r') {
3770 IPW_DEBUG_INFO("%s: Resetting firmware snapshot.\n",
3771 dev->name);
3772 ipw2100_snapshot_free(priv);
3773
3774 } else
3775 IPW_DEBUG_INFO("%s: Usage: 0|on = HEX, 1|off = RAW, "
3776 "reset = clear memory snapshot\n",
3777 dev->name);
3778
3779 return count;
3780}
3781static DEVICE_ATTR(memory, S_IWUSR|S_IRUGO, show_memory, store_memory);
3782
3783
edfc43f2
AM
3784static ssize_t show_ordinals(struct device *d, struct device_attribute *attr,
3785 char *buf)
2c86c275
JK
3786{
3787 struct ipw2100_priv *priv = dev_get_drvdata(d);
3788 u32 val = 0;
3789 int len = 0;
3790 u32 val_len;
3791 static int loop = 0;
3792
3793 if (loop >= sizeof(ord_data) / sizeof(*ord_data))
3794 loop = 0;
3795
3796 /* sysfs provides us PAGE_SIZE buffer */
3797 while (len < PAGE_SIZE - 128 &&
3798 loop < (sizeof(ord_data) / sizeof(*ord_data))) {
3799
3800 val_len = sizeof(u32);
3801
3802 if (ipw2100_get_ordinal(priv, ord_data[loop].index, &val,
3803 &val_len))
3804 len += sprintf(buf + len, "[0x%02X] = ERROR %s\n",
3805 ord_data[loop].index,
3806 ord_data[loop].desc);
3807 else
3808 len += sprintf(buf + len, "[0x%02X] = 0x%08X %s\n",
3809 ord_data[loop].index, val,
3810 ord_data[loop].desc);
3811 loop++;
3812 }
3813
3814 return len;
3815}
3816static DEVICE_ATTR(ordinals, S_IRUGO, show_ordinals, NULL);
3817
3818
edfc43f2
AM
3819static ssize_t show_stats(struct device *d, struct device_attribute *attr,
3820 char *buf)
2c86c275
JK
3821{
3822 struct ipw2100_priv *priv = dev_get_drvdata(d);
3823 char * out = buf;
3824
3825 out += sprintf(out, "interrupts: %d {tx: %d, rx: %d, other: %d}\n",
3826 priv->interrupts, priv->tx_interrupts,
3827 priv->rx_interrupts, priv->inta_other);
3828 out += sprintf(out, "firmware resets: %d\n", priv->resets);
3829 out += sprintf(out, "firmware hangs: %d\n", priv->hangs);
3830#ifdef CONFIG_IPW_DEBUG
3831 out += sprintf(out, "packet mismatch image: %s\n",
3832 priv->snapshot[0] ? "YES" : "NO");
3833#endif
3834
3835 return out - buf;
3836}
3837static DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL);
3838
3839
c4aee8c2 3840static int ipw2100_switch_mode(struct ipw2100_priv *priv, u32 mode)
2c86c275
JK
3841{
3842 int err;
3843
3844 if (mode == priv->ieee->iw_mode)
3845 return 0;
3846
3847 err = ipw2100_disable_adapter(priv);
3848 if (err) {
797b4f76 3849 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n",
2c86c275
JK
3850 priv->net_dev->name, err);
3851 return err;
3852 }
3853
3854 switch (mode) {
3855 case IW_MODE_INFRA:
3856 priv->net_dev->type = ARPHRD_ETHER;
3857 break;
3858 case IW_MODE_ADHOC:
3859 priv->net_dev->type = ARPHRD_ETHER;
3860 break;
3861#ifdef CONFIG_IPW2100_MONITOR
3862 case IW_MODE_MONITOR:
3863 priv->last_mode = priv->ieee->iw_mode;
3864 priv->net_dev->type = ARPHRD_IEEE80211;
3865 break;
3866#endif /* CONFIG_IPW2100_MONITOR */
3867 }
3868
3869 priv->ieee->iw_mode = mode;
3870
3871#ifdef CONFIG_PM
3872 /* Indicate ipw2100_download_firmware download firmware
3873 * from disk instead of memory. */
3874 ipw2100_firmware.version = 0;
3875#endif
3876
3877 printk(KERN_INFO "%s: Reseting on mode change.\n",
3878 priv->net_dev->name);
3879 priv->reset_backoff = 0;
3880 schedule_reset(priv);
3881
3882 return 0;
3883}
3884
edfc43f2
AM
3885static ssize_t show_internals(struct device *d, struct device_attribute *attr,
3886 char *buf)
2c86c275
JK
3887{
3888 struct ipw2100_priv *priv = dev_get_drvdata(d);
3889 int len = 0;
3890
3891#define DUMP_VAR(x,y) len += sprintf(buf + len, # x ": %" # y "\n", priv-> x)
3892
3893 if (priv->status & STATUS_ASSOCIATED)
3894 len += sprintf(buf + len, "connected: %lu\n",
3895 get_seconds() - priv->connect_start);
3896 else
3897 len += sprintf(buf + len, "not connected\n");
3898
3899 DUMP_VAR(ieee->crypt[priv->ieee->tx_keyidx], p);
3900 DUMP_VAR(status, 08lx);
3901 DUMP_VAR(config, 08lx);
3902 DUMP_VAR(capability, 08lx);
3903
3904 len += sprintf(buf + len, "last_rtc: %lu\n", (unsigned long)priv->last_rtc);
3905
3906 DUMP_VAR(fatal_error, d);
3907 DUMP_VAR(stop_hang_check, d);
3908 DUMP_VAR(stop_rf_kill, d);
3909 DUMP_VAR(messages_sent, d);
3910
3911 DUMP_VAR(tx_pend_stat.value, d);
3912 DUMP_VAR(tx_pend_stat.hi, d);
3913
3914 DUMP_VAR(tx_free_stat.value, d);
3915 DUMP_VAR(tx_free_stat.lo, d);
3916
3917 DUMP_VAR(msg_free_stat.value, d);
3918 DUMP_VAR(msg_free_stat.lo, d);
3919
3920 DUMP_VAR(msg_pend_stat.value, d);
3921 DUMP_VAR(msg_pend_stat.hi, d);
3922
3923 DUMP_VAR(fw_pend_stat.value, d);
3924 DUMP_VAR(fw_pend_stat.hi, d);
3925
3926 DUMP_VAR(txq_stat.value, d);
3927 DUMP_VAR(txq_stat.lo, d);
3928
3929 DUMP_VAR(ieee->scans, d);
3930 DUMP_VAR(reset_backoff, d);
3931
3932 return len;
3933}
3934static DEVICE_ATTR(internals, S_IRUGO, show_internals, NULL);
3935
3936
edfc43f2
AM
3937static ssize_t show_bssinfo(struct device *d, struct device_attribute *attr,
3938 char *buf)
2c86c275
JK
3939{
3940 struct ipw2100_priv *priv = dev_get_drvdata(d);
3941 char essid[IW_ESSID_MAX_SIZE + 1];
3942 u8 bssid[ETH_ALEN];
3943 u32 chan = 0;
3944 char * out = buf;
3945 int length;
3946 int ret;
3947
3948 memset(essid, 0, sizeof(essid));
3949 memset(bssid, 0, sizeof(bssid));
3950
3951 length = IW_ESSID_MAX_SIZE;
3952 ret = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_SSID, essid, &length);
3953 if (ret)
3954 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
3955 __LINE__);
3956
3957 length = sizeof(bssid);
3958 ret = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID,
3959 bssid, &length);
3960 if (ret)
3961 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
3962 __LINE__);
3963
3964 length = sizeof(u32);
3965 ret = ipw2100_get_ordinal(priv, IPW_ORD_OUR_FREQ, &chan, &length);
3966 if (ret)
3967 IPW_DEBUG_INFO("failed querying ordinals at line %d\n",
3968 __LINE__);
3969
3970 out += sprintf(out, "ESSID: %s\n", essid);
3971 out += sprintf(out, "BSSID: %02x:%02x:%02x:%02x:%02x:%02x\n",
3972 bssid[0], bssid[1], bssid[2],
3973 bssid[3], bssid[4], bssid[5]);
3974 out += sprintf(out, "Channel: %d\n", chan);
3975
3976 return out - buf;
3977}
3978static DEVICE_ATTR(bssinfo, S_IRUGO, show_bssinfo, NULL);
3979
3980
2c86c275
JK
3981#ifdef CONFIG_IPW_DEBUG
3982static ssize_t show_debug_level(struct device_driver *d, char *buf)
3983{
3984 return sprintf(buf, "0x%08X\n", ipw2100_debug_level);
3985}
3986
3987static ssize_t store_debug_level(struct device_driver *d, const char *buf,
3988 size_t count)
3989{
3990 char *p = (char *)buf;
3991 u32 val;
3992
3993 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
3994 p++;
3995 if (p[0] == 'x' || p[0] == 'X')
3996 p++;
3997 val = simple_strtoul(p, &p, 16);
3998 } else
3999 val = simple_strtoul(p, &p, 10);
4000 if (p == buf)
4001 IPW_DEBUG_INFO(DRV_NAME
4002 ": %s is not in hex or decimal form.\n", buf);
4003 else
4004 ipw2100_debug_level = val;
4005
4006 return strnlen(buf, count);
4007}
4008static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO, show_debug_level,
4009 store_debug_level);
4010#endif /* CONFIG_IPW_DEBUG */
4011
4012
edfc43f2
AM
4013static ssize_t show_fatal_error(struct device *d,
4014 struct device_attribute *attr, char *buf)
2c86c275
JK
4015{
4016 struct ipw2100_priv *priv = dev_get_drvdata(d);
4017 char *out = buf;
4018 int i;
4019
4020 if (priv->fatal_error)
4021 out += sprintf(out, "0x%08X\n",
4022 priv->fatal_error);
4023 else
4024 out += sprintf(out, "0\n");
4025
4026 for (i = 1; i <= IPW2100_ERROR_QUEUE; i++) {
4027 if (!priv->fatal_errors[(priv->fatal_index - i) %
4028 IPW2100_ERROR_QUEUE])
4029 continue;
4030
4031 out += sprintf(out, "%d. 0x%08X\n", i,
4032 priv->fatal_errors[(priv->fatal_index - i) %
4033 IPW2100_ERROR_QUEUE]);
4034 }
4035
4036 return out - buf;
4037}
4038
edfc43f2
AM
4039static ssize_t store_fatal_error(struct device *d,
4040 struct device_attribute *attr, const char *buf, size_t count)
2c86c275
JK
4041{
4042 struct ipw2100_priv *priv = dev_get_drvdata(d);
4043 schedule_reset(priv);
4044 return count;
4045}
4046static DEVICE_ATTR(fatal_error, S_IWUSR|S_IRUGO, show_fatal_error, store_fatal_error);
4047
4048
edfc43f2
AM
4049static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
4050 char *buf)
2c86c275
JK
4051{
4052 struct ipw2100_priv *priv = dev_get_drvdata(d);
4053 return sprintf(buf, "%d\n", priv->ieee->scan_age);
4054}
4055
edfc43f2
AM
4056static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
4057 const char *buf, size_t count)
2c86c275
JK
4058{
4059 struct ipw2100_priv *priv = dev_get_drvdata(d);
4060 struct net_device *dev = priv->net_dev;
4061 char buffer[] = "00000000";
4062 unsigned long len =
4063 (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1;
4064 unsigned long val;
4065 char *p = buffer;
4066
4067 IPW_DEBUG_INFO("enter\n");
4068
4069 strncpy(buffer, buf, len);
4070 buffer[len] = 0;
4071
4072 if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
4073 p++;
4074 if (p[0] == 'x' || p[0] == 'X')
4075 p++;
4076 val = simple_strtoul(p, &p, 16);
4077 } else
4078 val = simple_strtoul(p, &p, 10);
4079 if (p == buffer) {
4080 IPW_DEBUG_INFO("%s: user supplied invalid value.\n",
4081 dev->name);
4082 } else {
4083 priv->ieee->scan_age = val;
4084 IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age);
4085 }
4086
4087 IPW_DEBUG_INFO("exit\n");
4088 return len;
4089}
4090static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
4091
4092
edfc43f2
AM
4093static ssize_t show_rf_kill(struct device *d, struct device_attribute *attr,
4094 char *buf)
2c86c275
JK
4095{
4096 /* 0 - RF kill not enabled
4097 1 - SW based RF kill active (sysfs)
4098 2 - HW based RF kill active
4099 3 - Both HW and SW baed RF kill active */
4100 struct ipw2100_priv *priv = (struct ipw2100_priv *)d->driver_data;
4101 int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) |
4102 (rf_kill_active(priv) ? 0x2 : 0x0);
4103 return sprintf(buf, "%i\n", val);
4104}
4105
4106static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
4107{
4108 if ((disable_radio ? 1 : 0) ==
4109 (priv->status & STATUS_RF_KILL_SW ? 1 : 0))
4110 return 0 ;
4111
4112 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n",
4113 disable_radio ? "OFF" : "ON");
4114
4115 down(&priv->action_sem);
4116
4117 if (disable_radio) {
4118 priv->status |= STATUS_RF_KILL_SW;
4119 ipw2100_down(priv);
4120 } else {
4121 priv->status &= ~STATUS_RF_KILL_SW;
4122 if (rf_kill_active(priv)) {
4123 IPW_DEBUG_RF_KILL("Can not turn radio back on - "
4124 "disabled by HW switch\n");
4125 /* Make sure the RF_KILL check timer is running */
4126 priv->stop_rf_kill = 0;
4127 cancel_delayed_work(&priv->rf_kill);
4128 queue_delayed_work(priv->workqueue, &priv->rf_kill,
4129 HZ);
4130 } else
4131 schedule_reset(priv);
4132 }
4133
4134 up(&priv->action_sem);
4135 return 1;
4136}
4137
edfc43f2
AM
4138static ssize_t store_rf_kill(struct device *d, struct device_attribute *attr,
4139 const char *buf, size_t count)
2c86c275
JK
4140{
4141 struct ipw2100_priv *priv = dev_get_drvdata(d);
4142 ipw_radio_kill_sw(priv, buf[0] == '1');
4143 return count;
4144}
4145static DEVICE_ATTR(rf_kill, S_IWUSR|S_IRUGO, show_rf_kill, store_rf_kill);
4146
4147
4148static struct attribute *ipw2100_sysfs_entries[] = {
4149 &dev_attr_hardware.attr,
4150 &dev_attr_registers.attr,
4151 &dev_attr_ordinals.attr,
4152 &dev_attr_pci.attr,
4153 &dev_attr_stats.attr,
4154 &dev_attr_internals.attr,
4155 &dev_attr_bssinfo.attr,
4156 &dev_attr_memory.attr,
4157 &dev_attr_scan_age.attr,
4158 &dev_attr_fatal_error.attr,
4159 &dev_attr_rf_kill.attr,
4160 &dev_attr_cfg.attr,
4161 &dev_attr_status.attr,
4162 &dev_attr_capability.attr,
4163 NULL,
4164};
4165
4166static struct attribute_group ipw2100_attribute_group = {
4167 .attrs = ipw2100_sysfs_entries,
4168};
4169
4170
4171static int status_queue_allocate(struct ipw2100_priv *priv, int entries)
4172{
4173 struct ipw2100_status_queue *q = &priv->status_queue;
4174
4175 IPW_DEBUG_INFO("enter\n");
4176
4177 q->size = entries * sizeof(struct ipw2100_status);
4178 q->drv = (struct ipw2100_status *)pci_alloc_consistent(
4179 priv->pci_dev, q->size, &q->nic);
4180 if (!q->drv) {
4181 IPW_DEBUG_WARNING(
4182 "Can not allocate status queue.\n");
4183 return -ENOMEM;
4184 }
4185
4186 memset(q->drv, 0, q->size);
4187
4188 IPW_DEBUG_INFO("exit\n");
4189
4190 return 0;
4191}
4192
4193static void status_queue_free(struct ipw2100_priv *priv)
4194{
4195 IPW_DEBUG_INFO("enter\n");
4196
4197 if (priv->status_queue.drv) {
4198 pci_free_consistent(
4199 priv->pci_dev, priv->status_queue.size,
4200 priv->status_queue.drv, priv->status_queue.nic);
4201 priv->status_queue.drv = NULL;
4202 }
4203
4204 IPW_DEBUG_INFO("exit\n");
4205}
4206
4207static int bd_queue_allocate(struct ipw2100_priv *priv,
4208 struct ipw2100_bd_queue *q, int entries)
4209{
4210 IPW_DEBUG_INFO("enter\n");
4211
4212 memset(q, 0, sizeof(struct ipw2100_bd_queue));
4213
4214 q->entries = entries;
4215 q->size = entries * sizeof(struct ipw2100_bd);
4216 q->drv = pci_alloc_consistent(priv->pci_dev, q->size, &q->nic);
4217 if (!q->drv) {
4218 IPW_DEBUG_INFO("can't allocate shared memory for buffer descriptors\n");
4219 return -ENOMEM;
4220 }
4221 memset(q->drv, 0, q->size);
4222
4223 IPW_DEBUG_INFO("exit\n");
4224
4225 return 0;
4226}
4227
4228static void bd_queue_free(struct ipw2100_priv *priv,
4229 struct ipw2100_bd_queue *q)
4230{
4231 IPW_DEBUG_INFO("enter\n");
4232
4233 if (!q)
4234 return;
4235
4236 if (q->drv) {
4237 pci_free_consistent(priv->pci_dev,
4238 q->size, q->drv, q->nic);
4239 q->drv = NULL;
4240 }
4241
4242 IPW_DEBUG_INFO("exit\n");
4243}
4244
4245static void bd_queue_initialize(
4246 struct ipw2100_priv *priv, struct ipw2100_bd_queue * q,
4247 u32 base, u32 size, u32 r, u32 w)
4248{
4249 IPW_DEBUG_INFO("enter\n");
4250
aaa4d308 4251 IPW_DEBUG_INFO("initializing bd queue at virt=%p, phys=%08x\n", q->drv, (u32)q->nic);
2c86c275
JK
4252
4253 write_register(priv->net_dev, base, q->nic);
4254 write_register(priv->net_dev, size, q->entries);
4255 write_register(priv->net_dev, r, q->oldest);
4256 write_register(priv->net_dev, w, q->next);
4257
4258 IPW_DEBUG_INFO("exit\n");
4259}
4260
4261static void ipw2100_kill_workqueue(struct ipw2100_priv *priv)
4262{
4263 if (priv->workqueue) {
4264 priv->stop_rf_kill = 1;
4265 priv->stop_hang_check = 1;
4266 cancel_delayed_work(&priv->reset_work);
4267 cancel_delayed_work(&priv->security_work);
4268 cancel_delayed_work(&priv->wx_event_work);
4269 cancel_delayed_work(&priv->hang_check);
4270 cancel_delayed_work(&priv->rf_kill);
4271 destroy_workqueue(priv->workqueue);
4272 priv->workqueue = NULL;
4273 }
4274}
4275
4276static int ipw2100_tx_allocate(struct ipw2100_priv *priv)
4277{
4278 int i, j, err = -EINVAL;
4279 void *v;
4280 dma_addr_t p;
4281
4282 IPW_DEBUG_INFO("enter\n");
4283
4284 err = bd_queue_allocate(priv, &priv->tx_queue, TX_QUEUE_LENGTH);
4285 if (err) {
4286 IPW_DEBUG_ERROR("%s: failed bd_queue_allocate\n",
4287 priv->net_dev->name);
4288 return err;
4289 }
4290
4291 priv->tx_buffers = (struct ipw2100_tx_packet *)kmalloc(
4292 TX_PENDED_QUEUE_LENGTH * sizeof(struct ipw2100_tx_packet),
4293 GFP_ATOMIC);
4294 if (!priv->tx_buffers) {
797b4f76 4295 printk(KERN_ERR DRV_NAME ": %s: alloc failed form tx buffers.\n",
2c86c275
JK
4296 priv->net_dev->name);
4297 bd_queue_free(priv, &priv->tx_queue);
4298 return -ENOMEM;
4299 }
4300
4301 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) {
4302 v = pci_alloc_consistent(
4303 priv->pci_dev, sizeof(struct ipw2100_data_header), &p);
4304 if (!v) {
797b4f76 4305 printk(KERN_ERR DRV_NAME ": %s: PCI alloc failed for tx "
2c86c275
JK
4306 "buffers.\n", priv->net_dev->name);
4307 err = -ENOMEM;
4308 break;
4309 }
4310
4311 priv->tx_buffers[i].type = DATA;
4312 priv->tx_buffers[i].info.d_struct.data = (struct ipw2100_data_header*)v;
4313 priv->tx_buffers[i].info.d_struct.data_phys = p;
4314 priv->tx_buffers[i].info.d_struct.txb = NULL;
4315 }
4316
4317 if (i == TX_PENDED_QUEUE_LENGTH)
4318 return 0;
4319
4320 for (j = 0; j < i; j++) {
4321 pci_free_consistent(
4322 priv->pci_dev,
4323 sizeof(struct ipw2100_data_header),
4324 priv->tx_buffers[j].info.d_struct.data,
4325 priv->tx_buffers[j].info.d_struct.data_phys);
4326 }
4327
4328 kfree(priv->tx_buffers);
4329 priv->tx_buffers = NULL;
4330
4331 return err;
4332}
4333
4334static void ipw2100_tx_initialize(struct ipw2100_priv *priv)
4335{
4336 int i;
4337
4338 IPW_DEBUG_INFO("enter\n");
4339
4340 /*
4341 * reinitialize packet info lists
4342 */
4343 INIT_LIST_HEAD(&priv->fw_pend_list);
4344 INIT_STAT(&priv->fw_pend_stat);
4345
4346 /*
4347 * reinitialize lists
4348 */
4349 INIT_LIST_HEAD(&priv->tx_pend_list);
4350 INIT_LIST_HEAD(&priv->tx_free_list);
4351 INIT_STAT(&priv->tx_pend_stat);
4352 INIT_STAT(&priv->tx_free_stat);
4353
4354 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) {
4355 /* We simply drop any SKBs that have been queued for
4356 * transmit */
4357 if (priv->tx_buffers[i].info.d_struct.txb) {
4358 ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.txb);
4359 priv->tx_buffers[i].info.d_struct.txb = NULL;
4360 }
4361
4362 list_add_tail(&priv->tx_buffers[i].list, &priv->tx_free_list);
4363 }
4364
4365 SET_STAT(&priv->tx_free_stat, i);
4366
4367 priv->tx_queue.oldest = 0;
4368 priv->tx_queue.available = priv->tx_queue.entries;
4369 priv->tx_queue.next = 0;
4370 INIT_STAT(&priv->txq_stat);
4371 SET_STAT(&priv->txq_stat, priv->tx_queue.available);
4372
4373 bd_queue_initialize(priv, &priv->tx_queue,
4374 IPW_MEM_HOST_SHARED_TX_QUEUE_BD_BASE,
4375 IPW_MEM_HOST_SHARED_TX_QUEUE_BD_SIZE,
4376 IPW_MEM_HOST_SHARED_TX_QUEUE_READ_INDEX,
4377 IPW_MEM_HOST_SHARED_TX_QUEUE_WRITE_INDEX);
4378
4379 IPW_DEBUG_INFO("exit\n");
4380
4381}
4382
4383static void ipw2100_tx_free(struct ipw2100_priv *priv)
4384{
4385 int i;
4386
4387 IPW_DEBUG_INFO("enter\n");
4388
4389 bd_queue_free(priv, &priv->tx_queue);
4390
4391 if (!priv->tx_buffers)
4392 return;
4393
4394 for (i = 0; i < TX_PENDED_QUEUE_LENGTH; i++) {
4395 if (priv->tx_buffers[i].info.d_struct.txb) {
4396 ieee80211_txb_free(priv->tx_buffers[i].info.d_struct.txb);
4397 priv->tx_buffers[i].info.d_struct.txb = NULL;
4398 }
4399 if (priv->tx_buffers[i].info.d_struct.data)
4400 pci_free_consistent(
4401 priv->pci_dev,
4402 sizeof(struct ipw2100_data_header),
4403 priv->tx_buffers[i].info.d_struct.data,
4404 priv->tx_buffers[i].info.d_struct.data_phys);
4405 }
4406
4407 kfree(priv->tx_buffers);
4408 priv->tx_buffers = NULL;
4409
4410 IPW_DEBUG_INFO("exit\n");
4411}
4412
4413
4414
4415static int ipw2100_rx_allocate(struct ipw2100_priv *priv)
4416{
4417 int i, j, err = -EINVAL;
4418
4419 IPW_DEBUG_INFO("enter\n");
4420
4421 err = bd_queue_allocate(priv, &priv->rx_queue, RX_QUEUE_LENGTH);
4422 if (err) {
4423 IPW_DEBUG_INFO("failed bd_queue_allocate\n");
4424 return err;
4425 }
4426
4427 err = status_queue_allocate(priv, RX_QUEUE_LENGTH);
4428 if (err) {
4429 IPW_DEBUG_INFO("failed status_queue_allocate\n");
4430 bd_queue_free(priv, &priv->rx_queue);
4431 return err;
4432 }
4433
4434 /*
4435 * allocate packets
4436 */
4437 priv->rx_buffers = (struct ipw2100_rx_packet *)
4438 kmalloc(RX_QUEUE_LENGTH * sizeof(struct ipw2100_rx_packet),
4439 GFP_KERNEL);
4440 if (!priv->rx_buffers) {
4441 IPW_DEBUG_INFO("can't allocate rx packet buffer table\n");
4442
4443 bd_queue_free(priv, &priv->rx_queue);
4444
4445 status_queue_free(priv);
4446
4447 return -ENOMEM;
4448 }
4449
4450 for (i = 0; i < RX_QUEUE_LENGTH; i++) {
4451 struct ipw2100_rx_packet *packet = &priv->rx_buffers[i];
4452
4453 err = ipw2100_alloc_skb(priv, packet);
4454 if (unlikely(err)) {
4455 err = -ENOMEM;
4456 break;
4457 }
4458
4459 /* The BD holds the cache aligned address */
4460 priv->rx_queue.drv[i].host_addr = packet->dma_addr;
4461 priv->rx_queue.drv[i].buf_length = IPW_RX_NIC_BUFFER_LENGTH;
4462 priv->status_queue.drv[i].status_fields = 0;
4463 }
4464
4465 if (i == RX_QUEUE_LENGTH)
4466 return 0;
4467
4468 for (j = 0; j < i; j++) {
4469 pci_unmap_single(priv->pci_dev, priv->rx_buffers[j].dma_addr,
4470 sizeof(struct ipw2100_rx_packet),
4471 PCI_DMA_FROMDEVICE);
4472 dev_kfree_skb(priv->rx_buffers[j].skb);
4473 }
4474
4475 kfree(priv->rx_buffers);
4476 priv->rx_buffers = NULL;
4477
4478 bd_queue_free(priv, &priv->rx_queue);
4479
4480 status_queue_free(priv);
4481
4482 return err;
4483}
4484
4485static void ipw2100_rx_initialize(struct ipw2100_priv *priv)
4486{
4487 IPW_DEBUG_INFO("enter\n");
4488
4489 priv->rx_queue.oldest = 0;
4490 priv->rx_queue.available = priv->rx_queue.entries - 1;
4491 priv->rx_queue.next = priv->rx_queue.entries - 1;
4492
4493 INIT_STAT(&priv->rxq_stat);
4494 SET_STAT(&priv->rxq_stat, priv->rx_queue.available);
4495
4496 bd_queue_initialize(priv, &priv->rx_queue,
4497 IPW_MEM_HOST_SHARED_RX_BD_BASE,
4498 IPW_MEM_HOST_SHARED_RX_BD_SIZE,
4499 IPW_MEM_HOST_SHARED_RX_READ_INDEX,
4500 IPW_MEM_HOST_SHARED_RX_WRITE_INDEX);
4501
4502 /* set up the status queue */
4503 write_register(priv->net_dev, IPW_MEM_HOST_SHARED_RX_STATUS_BASE,
4504 priv->status_queue.nic);
4505
4506 IPW_DEBUG_INFO("exit\n");
4507}
4508
4509static void ipw2100_rx_free(struct ipw2100_priv *priv)
4510{
4511 int i;
4512
4513 IPW_DEBUG_INFO("enter\n");
4514
4515 bd_queue_free(priv, &priv->rx_queue);
4516 status_queue_free(priv);
4517
4518 if (!priv->rx_buffers)
4519 return;
4520
4521 for (i = 0; i < RX_QUEUE_LENGTH; i++) {
4522 if (priv->rx_buffers[i].rxp) {
4523 pci_unmap_single(priv->pci_dev,
4524 priv->rx_buffers[i].dma_addr,
4525 sizeof(struct ipw2100_rx),
4526 PCI_DMA_FROMDEVICE);
4527 dev_kfree_skb(priv->rx_buffers[i].skb);
4528 }
4529 }
4530
4531 kfree(priv->rx_buffers);
4532 priv->rx_buffers = NULL;
4533
4534 IPW_DEBUG_INFO("exit\n");
4535}
4536
4537static int ipw2100_read_mac_address(struct ipw2100_priv *priv)
4538{
4539 u32 length = ETH_ALEN;
4540 u8 mac[ETH_ALEN];
4541
4542 int err;
4543
4544 err = ipw2100_get_ordinal(priv, IPW_ORD_STAT_ADAPTER_MAC,
4545 mac, &length);
4546 if (err) {
4547 IPW_DEBUG_INFO("MAC address read failed\n");
4548 return -EIO;
4549 }
4550 IPW_DEBUG_INFO("card MAC is %02X:%02X:%02X:%02X:%02X:%02X\n",
4551 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
4552
4553 memcpy(priv->net_dev->dev_addr, mac, ETH_ALEN);
4554
4555 return 0;
4556}
4557
4558/********************************************************************
4559 *
4560 * Firmware Commands
4561 *
4562 ********************************************************************/
4563
c4aee8c2 4564static int ipw2100_set_mac_address(struct ipw2100_priv *priv, int batch_mode)
2c86c275
JK
4565{
4566 struct host_command cmd = {
4567 .host_command = ADAPTER_ADDRESS,
4568 .host_command_sequence = 0,
4569 .host_command_length = ETH_ALEN
4570 };
4571 int err;
4572
4573 IPW_DEBUG_HC("SET_MAC_ADDRESS\n");
4574
4575 IPW_DEBUG_INFO("enter\n");
4576
4577 if (priv->config & CFG_CUSTOM_MAC) {
4578 memcpy(cmd.host_command_parameters, priv->mac_addr,
4579 ETH_ALEN);
4580 memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
4581 } else
4582 memcpy(cmd.host_command_parameters, priv->net_dev->dev_addr,
4583 ETH_ALEN);
4584
4585 err = ipw2100_hw_send_command(priv, &cmd);
4586
4587 IPW_DEBUG_INFO("exit\n");
4588 return err;
4589}
4590
c4aee8c2 4591static int ipw2100_set_port_type(struct ipw2100_priv *priv, u32 port_type,
2c86c275
JK
4592 int batch_mode)
4593{
4594 struct host_command cmd = {
4595 .host_command = PORT_TYPE,
4596 .host_command_sequence = 0,
4597 .host_command_length = sizeof(u32)
4598 };
4599 int err;
4600
4601 switch (port_type) {
4602 case IW_MODE_INFRA:
4603 cmd.host_command_parameters[0] = IPW_BSS;
4604 break;
4605 case IW_MODE_ADHOC:
4606 cmd.host_command_parameters[0] = IPW_IBSS;
4607 break;
4608 }
4609
4610 IPW_DEBUG_HC("PORT_TYPE: %s\n",
4611 port_type == IPW_IBSS ? "Ad-Hoc" : "Managed");
4612
4613 if (!batch_mode) {
4614 err = ipw2100_disable_adapter(priv);
4615 if (err) {
797b4f76 4616 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n",
2c86c275
JK
4617 priv->net_dev->name, err);
4618 return err;
4619 }
4620 }
4621
4622 /* send cmd to firmware */
4623 err = ipw2100_hw_send_command(priv, &cmd);
4624
4625 if (!batch_mode)
4626 ipw2100_enable_adapter(priv);
4627
4628 return err;
4629}
4630
4631
c4aee8c2
JB
4632static int ipw2100_set_channel(struct ipw2100_priv *priv, u32 channel,
4633 int batch_mode)
2c86c275
JK
4634{
4635 struct host_command cmd = {
4636 .host_command = CHANNEL,
4637 .host_command_sequence = 0,
4638 .host_command_length = sizeof(u32)
4639 };
4640 int err;
4641
4642 cmd.host_command_parameters[0] = channel;
4643
4644 IPW_DEBUG_HC("CHANNEL: %d\n", channel);
4645
4646 /* If BSS then we don't support channel selection */
4647 if (priv->ieee->iw_mode == IW_MODE_INFRA)
4648 return 0;
4649
4650 if ((channel != 0) &&
4651 ((channel < REG_MIN_CHANNEL) || (channel > REG_MAX_CHANNEL)))
4652 return -EINVAL;
4653
4654 if (!batch_mode) {
4655 err = ipw2100_disable_adapter(priv);
4656 if (err)
4657 return err;
4658 }
4659
4660 err = ipw2100_hw_send_command(priv, &cmd);
4661 if (err) {
4662 IPW_DEBUG_INFO("Failed to set channel to %d",
4663 channel);
4664 return err;
4665 }
4666
4667 if (channel)
4668 priv->config |= CFG_STATIC_CHANNEL;
4669 else
4670 priv->config &= ~CFG_STATIC_CHANNEL;
4671
4672 priv->channel = channel;
4673
4674 if (!batch_mode) {
4675 err = ipw2100_enable_adapter(priv);
4676 if (err)
4677 return err;
4678 }
4679
4680 return 0;
4681}
4682
c4aee8c2 4683static int ipw2100_system_config(struct ipw2100_priv *priv, int batch_mode)
2c86c275
JK
4684{
4685 struct host_command cmd = {
4686 .host_command = SYSTEM_CONFIG,
4687 .host_command_sequence = 0,
4688 .host_command_length = 12,
4689 };
4690 u32 ibss_mask, len = sizeof(u32);
4691 int err;
4692
4693 /* Set system configuration */
4694
4695 if (!batch_mode) {
4696 err = ipw2100_disable_adapter(priv);
4697 if (err)
4698 return err;
4699 }
4700
4701 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
4702 cmd.host_command_parameters[0] |= IPW_CFG_IBSS_AUTO_START;
4703
4704 cmd.host_command_parameters[0] |= IPW_CFG_IBSS_MASK |
4705 IPW_CFG_BSS_MASK |
4706 IPW_CFG_802_1x_ENABLE;
4707
4708 if (!(priv->config & CFG_LONG_PREAMBLE))
4709 cmd.host_command_parameters[0] |= IPW_CFG_PREAMBLE_AUTO;
4710
4711 err = ipw2100_get_ordinal(priv,
4712 IPW_ORD_EEPROM_IBSS_11B_CHANNELS,
4713 &ibss_mask, &len);
4714 if (err)
4715 ibss_mask = IPW_IBSS_11B_DEFAULT_MASK;
4716
4717 cmd.host_command_parameters[1] = REG_CHANNEL_MASK;
4718 cmd.host_command_parameters[2] = REG_CHANNEL_MASK & ibss_mask;
4719
4720 /* 11b only */
4721 /*cmd.host_command_parameters[0] |= DIVERSITY_ANTENNA_A;*/
4722
4723 err = ipw2100_hw_send_command(priv, &cmd);
4724 if (err)
4725 return err;
4726
4727/* If IPv6 is configured in the kernel then we don't want to filter out all
4728 * of the multicast packets as IPv6 needs some. */
4729#if !defined(CONFIG_IPV6) && !defined(CONFIG_IPV6_MODULE)
4730 cmd.host_command = ADD_MULTICAST;
4731 cmd.host_command_sequence = 0;
4732 cmd.host_command_length = 0;
4733
4734 ipw2100_hw_send_command(priv, &cmd);
4735#endif
4736 if (!batch_mode) {
4737 err = ipw2100_enable_adapter(priv);
4738 if (err)
4739 return err;
4740 }
4741
4742 return 0;
4743}
4744
c4aee8c2
JB
4745static int ipw2100_set_tx_rates(struct ipw2100_priv *priv, u32 rate,
4746 int batch_mode)
2c86c275
JK
4747{
4748 struct host_command cmd = {
4749 .host_command = BASIC_TX_RATES,
4750 .host_command_sequence = 0,
4751 .host_command_length = 4
4752 };
4753 int err;
4754
4755 cmd.host_command_parameters[0] = rate & TX_RATE_MASK;
4756
4757 if (!batch_mode) {
4758 err = ipw2100_disable_adapter(priv);
4759 if (err)
4760 return err;
4761 }
4762
4763 /* Set BASIC TX Rate first */
4764 ipw2100_hw_send_command(priv, &cmd);
4765
4766 /* Set TX Rate */
4767 cmd.host_command = TX_RATES;
4768 ipw2100_hw_send_command(priv, &cmd);
4769
4770 /* Set MSDU TX Rate */
4771 cmd.host_command = MSDU_TX_RATES;
4772 ipw2100_hw_send_command(priv, &cmd);
4773
4774 if (!batch_mode) {
4775 err = ipw2100_enable_adapter(priv);
4776 if (err)
4777 return err;
4778 }
4779
4780 priv->tx_rates = rate;
4781
4782 return 0;
4783}
4784
c4aee8c2
JB
4785static int ipw2100_set_power_mode(struct ipw2100_priv *priv,
4786 int power_level)
2c86c275
JK
4787{
4788 struct host_command cmd = {
4789 .host_command = POWER_MODE,
4790 .host_command_sequence = 0,
4791 .host_command_length = 4
4792 };
4793 int err;
4794
4795 cmd.host_command_parameters[0] = power_level;
4796
4797 err = ipw2100_hw_send_command(priv, &cmd);
4798 if (err)
4799 return err;
4800
4801 if (power_level == IPW_POWER_MODE_CAM)
4802 priv->power_mode = IPW_POWER_LEVEL(priv->power_mode);
4803 else
4804 priv->power_mode = IPW_POWER_ENABLED | power_level;
4805
4806#ifdef CONFIG_IPW2100_TX_POWER
4807 if (priv->port_type == IBSS &&
4808 priv->adhoc_power != DFTL_IBSS_TX_POWER) {
4809 /* Set beacon interval */
4810 cmd.host_command = TX_POWER_INDEX;
4811 cmd.host_command_parameters[0] = (u32)priv->adhoc_power;
4812
4813 err = ipw2100_hw_send_command(priv, &cmd);
4814 if (err)
4815 return err;
4816 }
4817#endif
4818
4819 return 0;
4820}
4821
4822
c4aee8c2 4823static int ipw2100_set_rts_threshold(struct ipw2100_priv *priv, u32 threshold)
2c86c275
JK
4824{
4825 struct host_command cmd = {
4826 .host_command = RTS_THRESHOLD,
4827 .host_command_sequence = 0,
4828 .host_command_length = 4
4829 };
4830 int err;
4831
4832 if (threshold & RTS_DISABLED)
4833 cmd.host_command_parameters[0] = MAX_RTS_THRESHOLD;
4834 else
4835 cmd.host_command_parameters[0] = threshold & ~RTS_DISABLED;
4836
4837 err = ipw2100_hw_send_command(priv, &cmd);
4838 if (err)
4839 return err;
4840
4841 priv->rts_threshold = threshold;
4842
4843 return 0;
4844}
4845
4846#if 0
4847int ipw2100_set_fragmentation_threshold(struct ipw2100_priv *priv,
4848 u32 threshold, int batch_mode)
4849{
4850 struct host_command cmd = {
4851 .host_command = FRAG_THRESHOLD,
4852 .host_command_sequence = 0,
4853 .host_command_length = 4,
4854 .host_command_parameters[0] = 0,
4855 };
4856 int err;
4857
4858 if (!batch_mode) {
4859 err = ipw2100_disable_adapter(priv);
4860 if (err)
4861 return err;
4862 }
4863
4864 if (threshold == 0)
4865 threshold = DEFAULT_FRAG_THRESHOLD;
4866 else {
4867 threshold = max(threshold, MIN_FRAG_THRESHOLD);
4868 threshold = min(threshold, MAX_FRAG_THRESHOLD);
4869 }
4870
4871 cmd.host_command_parameters[0] = threshold;
4872
4873 IPW_DEBUG_HC("FRAG_THRESHOLD: %u\n", threshold);
4874
4875 err = ipw2100_hw_send_command(priv, &cmd);
4876
4877 if (!batch_mode)
4878 ipw2100_enable_adapter(priv);
4879
4880 if (!err)
4881 priv->frag_threshold = threshold;
4882
4883 return err;
4884}
4885#endif
4886
c4aee8c2 4887static int ipw2100_set_short_retry(struct ipw2100_priv *priv, u32 retry)
2c86c275
JK
4888{
4889 struct host_command cmd = {
4890 .host_command = SHORT_RETRY_LIMIT,
4891 .host_command_sequence = 0,
4892 .host_command_length = 4
4893 };
4894 int err;
4895
4896 cmd.host_command_parameters[0] = retry;
4897
4898 err = ipw2100_hw_send_command(priv, &cmd);
4899 if (err)
4900 return err;
4901
4902 priv->short_retry_limit = retry;
4903
4904 return 0;
4905}
4906
c4aee8c2 4907static int ipw2100_set_long_retry(struct ipw2100_priv *priv, u32 retry)
2c86c275
JK
4908{
4909 struct host_command cmd = {
4910 .host_command = LONG_RETRY_LIMIT,
4911 .host_command_sequence = 0,
4912 .host_command_length = 4
4913 };
4914 int err;
4915
4916 cmd.host_command_parameters[0] = retry;
4917
4918 err = ipw2100_hw_send_command(priv, &cmd);
4919 if (err)
4920 return err;
4921
4922 priv->long_retry_limit = retry;
4923
4924 return 0;
4925}
4926
4927
c4aee8c2
JB
4928static int ipw2100_set_mandatory_bssid(struct ipw2100_priv *priv, u8 *bssid,
4929 int batch_mode)
2c86c275
JK
4930{
4931 struct host_command cmd = {
4932 .host_command = MANDATORY_BSSID,
4933 .host_command_sequence = 0,
4934 .host_command_length = (bssid == NULL) ? 0 : ETH_ALEN
4935 };
4936 int err;
4937
4938#ifdef CONFIG_IPW_DEBUG
4939 if (bssid != NULL)
4940 IPW_DEBUG_HC(
4941 "MANDATORY_BSSID: %02X:%02X:%02X:%02X:%02X:%02X\n",
4942 bssid[0], bssid[1], bssid[2], bssid[3], bssid[4],
4943 bssid[5]);
4944 else
4945 IPW_DEBUG_HC("MANDATORY_BSSID: <clear>\n");
4946#endif
4947 /* if BSSID is empty then we disable mandatory bssid mode */
4948 if (bssid != NULL)
4949 memcpy((u8 *)cmd.host_command_parameters, bssid, ETH_ALEN);
4950
4951 if (!batch_mode) {
4952 err = ipw2100_disable_adapter(priv);
4953 if (err)
4954 return err;
4955 }
4956
4957 err = ipw2100_hw_send_command(priv, &cmd);
4958
4959 if (!batch_mode)
4960 ipw2100_enable_adapter(priv);
4961
4962 return err;
4963}
4964
4965#ifdef CONFIG_IEEE80211_WPA
4966static int ipw2100_disassociate_bssid(struct ipw2100_priv *priv)
4967{
4968 struct host_command cmd = {
4969 .host_command = DISASSOCIATION_BSSID,
4970 .host_command_sequence = 0,
4971 .host_command_length = ETH_ALEN
4972 };
4973 int err;
4974 int len;
4975
4976 IPW_DEBUG_HC("DISASSOCIATION_BSSID\n");
4977
4978 len = ETH_ALEN;
4979 /* The Firmware currently ignores the BSSID and just disassociates from
4980 * the currently associated AP -- but in the off chance that a future
4981 * firmware does use the BSSID provided here, we go ahead and try and
4982 * set it to the currently associated AP's BSSID */
4983 memcpy(cmd.host_command_parameters, priv->bssid, ETH_ALEN);
4984
4985 err = ipw2100_hw_send_command(priv, &cmd);
4986
4987 return err;
4988}
4989#endif
4990
4991/*
4992 * Pseudo code for setting up wpa_frame:
4993 */
4994#if 0
4995void x(struct ieee80211_assoc_frame *wpa_assoc)
4996{
4997 struct ipw2100_wpa_assoc_frame frame;
4998 frame->fixed_ie_mask = IPW_WPA_CAPABILTIES |
4999 IPW_WPA_LISTENINTERVAL |
5000 IPW_WPA_AP_ADDRESS;
5001 frame->capab_info = wpa_assoc->capab_info;
5002 frame->lisen_interval = wpa_assoc->listent_interval;
5003 memcpy(frame->current_ap, wpa_assoc->current_ap, ETH_ALEN);
5004
5005 /* UNKNOWN -- I'm not postivive about this part; don't have any WPA
5006 * setup here to test it with.
5007 *
5008 * Walk the IEs in the wpa_assoc and figure out the total size of all
5009 * that data. Stick that into frame->var_ie_len. Then memcpy() all of
5010 * the IEs from wpa_frame into frame.
5011 */
5012 frame->var_ie_len = calculate_ie_len(wpa_assoc);
5013 memcpy(frame->var_ie, wpa_assoc->variable, frame->var_ie_len);
5014
5015 ipw2100_set_wpa_ie(priv, &frame, 0);
5016}
5017#endif
5018
5019
5020
5021
5022static int ipw2100_set_wpa_ie(struct ipw2100_priv *,
5023 struct ipw2100_wpa_assoc_frame *, int)
5024__attribute__ ((unused));
5025
5026static int ipw2100_set_wpa_ie(struct ipw2100_priv *priv,
5027 struct ipw2100_wpa_assoc_frame *wpa_frame,
5028 int batch_mode)
5029{
5030 struct host_command cmd = {
5031 .host_command = SET_WPA_IE,
5032 .host_command_sequence = 0,
5033 .host_command_length = sizeof(struct ipw2100_wpa_assoc_frame),
5034 };
5035 int err;
5036
5037 IPW_DEBUG_HC("SET_WPA_IE\n");
5038
5039 if (!batch_mode) {
5040 err = ipw2100_disable_adapter(priv);
5041 if (err)
5042 return err;
5043 }
5044
5045 memcpy(cmd.host_command_parameters, wpa_frame,
5046 sizeof(struct ipw2100_wpa_assoc_frame));
5047
5048 err = ipw2100_hw_send_command(priv, &cmd);
5049
5050 if (!batch_mode) {
5051 if (ipw2100_enable_adapter(priv))
5052 err = -EIO;
5053 }
5054
5055 return err;
5056}
5057
5058struct security_info_params {
5059 u32 allowed_ciphers;
5060 u16 version;
5061 u8 auth_mode;
5062 u8 replay_counters_number;
5063 u8 unicast_using_group;
5064} __attribute__ ((packed));
5065
c4aee8c2
JB
5066static int ipw2100_set_security_information(struct ipw2100_priv *priv,
5067 int auth_mode,
5068 int security_level,
5069 int unicast_using_group,
5070 int batch_mode)
2c86c275
JK
5071{
5072 struct host_command cmd = {
5073 .host_command = SET_SECURITY_INFORMATION,
5074 .host_command_sequence = 0,
5075 .host_command_length = sizeof(struct security_info_params)
5076 };
5077 struct security_info_params *security =
5078 (struct security_info_params *)&cmd.host_command_parameters;
5079 int err;
5080 memset(security, 0, sizeof(*security));
5081
5082 /* If shared key AP authentication is turned on, then we need to
5083 * configure the firmware to try and use it.
5084 *
5085 * Actual data encryption/decryption is handled by the host. */
5086 security->auth_mode = auth_mode;
5087 security->unicast_using_group = unicast_using_group;
5088
5089 switch (security_level) {
5090 default:
5091 case SEC_LEVEL_0:
5092 security->allowed_ciphers = IPW_NONE_CIPHER;
5093 break;
5094 case SEC_LEVEL_1:
5095 security->allowed_ciphers = IPW_WEP40_CIPHER |
5096 IPW_WEP104_CIPHER;
5097 break;
5098 case SEC_LEVEL_2:
5099 security->allowed_ciphers = IPW_WEP40_CIPHER |
5100 IPW_WEP104_CIPHER | IPW_TKIP_CIPHER;
5101 break;
5102 case SEC_LEVEL_2_CKIP:
5103 security->allowed_ciphers = IPW_WEP40_CIPHER |
5104 IPW_WEP104_CIPHER | IPW_CKIP_CIPHER;
5105 break;
5106 case SEC_LEVEL_3:
5107 security->allowed_ciphers = IPW_WEP40_CIPHER |
5108 IPW_WEP104_CIPHER | IPW_TKIP_CIPHER | IPW_CCMP_CIPHER;
5109 break;
5110 }
5111
5112 IPW_DEBUG_HC(
5113 "SET_SECURITY_INFORMATION: auth:%d cipher:0x%02X (level %d)\n",
5114 security->auth_mode, security->allowed_ciphers, security_level);
5115
5116 security->replay_counters_number = 0;
5117
5118 if (!batch_mode) {
5119 err = ipw2100_disable_adapter(priv);
5120 if (err)
5121 return err;
5122 }
5123
5124 err = ipw2100_hw_send_command(priv, &cmd);
5125
5126 if (!batch_mode)
5127 ipw2100_enable_adapter(priv);
5128
5129 return err;
5130}
5131
c4aee8c2
JB
5132static int ipw2100_set_tx_power(struct ipw2100_priv *priv,
5133 u32 tx_power)
2c86c275
JK
5134{
5135 struct host_command cmd = {
5136 .host_command = TX_POWER_INDEX,
5137 .host_command_sequence = 0,
5138 .host_command_length = 4
5139 };
5140 int err = 0;
5141
5142 cmd.host_command_parameters[0] = tx_power;
5143
5144 if (priv->ieee->iw_mode == IW_MODE_ADHOC)
5145 err = ipw2100_hw_send_command(priv, &cmd);
5146 if (!err)
5147 priv->tx_power = tx_power;
5148
5149 return 0;
5150}
5151
c4aee8c2
JB
5152static int ipw2100_set_ibss_beacon_interval(struct ipw2100_priv *priv,
5153 u32 interval, int batch_mode)
2c86c275
JK
5154{
5155 struct host_command cmd = {
5156 .host_command = BEACON_INTERVAL,
5157 .host_command_sequence = 0,
5158 .host_command_length = 4
5159 };
5160 int err;
5161
5162 cmd.host_command_parameters[0] = interval;
5163
5164 IPW_DEBUG_INFO("enter\n");
5165
5166 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
5167 if (!batch_mode) {
5168 err = ipw2100_disable_adapter(priv);
5169 if (err)
5170 return err;
5171 }
5172
5173 ipw2100_hw_send_command(priv, &cmd);
5174
5175 if (!batch_mode) {
5176 err = ipw2100_enable_adapter(priv);
5177 if (err)
5178 return err;
5179 }
5180 }
5181
5182 IPW_DEBUG_INFO("exit\n");
5183
5184 return 0;
5185}
5186
5187
5188void ipw2100_queues_initialize(struct ipw2100_priv *priv)
5189{
5190 ipw2100_tx_initialize(priv);
5191 ipw2100_rx_initialize(priv);
5192 ipw2100_msg_initialize(priv);
5193}
5194
5195void ipw2100_queues_free(struct ipw2100_priv *priv)
5196{
5197 ipw2100_tx_free(priv);
5198 ipw2100_rx_free(priv);
5199 ipw2100_msg_free(priv);
5200}
5201
5202int ipw2100_queues_allocate(struct ipw2100_priv *priv)
5203{
5204 if (ipw2100_tx_allocate(priv) ||
5205 ipw2100_rx_allocate(priv) ||
5206 ipw2100_msg_allocate(priv))
5207 goto fail;
5208
5209 return 0;
5210
5211 fail:
5212 ipw2100_tx_free(priv);
5213 ipw2100_rx_free(priv);
5214 ipw2100_msg_free(priv);
5215 return -ENOMEM;
5216}
5217
5218#define IPW_PRIVACY_CAPABLE 0x0008
5219
5220static int ipw2100_set_wep_flags(struct ipw2100_priv *priv, u32 flags,
5221 int batch_mode)
5222{
5223 struct host_command cmd = {
5224 .host_command = WEP_FLAGS,
5225 .host_command_sequence = 0,
5226 .host_command_length = 4
5227 };
5228 int err;
5229
5230 cmd.host_command_parameters[0] = flags;
5231
5232 IPW_DEBUG_HC("WEP_FLAGS: flags = 0x%08X\n", flags);
5233
5234 if (!batch_mode) {
5235 err = ipw2100_disable_adapter(priv);
5236 if (err) {
797b4f76 5237 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n",
2c86c275
JK
5238 priv->net_dev->name, err);
5239 return err;
5240 }
5241 }
5242
5243 /* send cmd to firmware */
5244 err = ipw2100_hw_send_command(priv, &cmd);
5245
5246 if (!batch_mode)
5247 ipw2100_enable_adapter(priv);
5248
5249 return err;
5250}
5251
5252struct ipw2100_wep_key {
5253 u8 idx;
5254 u8 len;
5255 u8 key[13];
5256};
5257
5258/* Macros to ease up priting WEP keys */
5259#define WEP_FMT_64 "%02X%02X%02X%02X-%02X"
5260#define WEP_FMT_128 "%02X%02X%02X%02X-%02X%02X%02X%02X-%02X%02X%02X"
5261#define WEP_STR_64(x) x[0],x[1],x[2],x[3],x[4]
5262#define WEP_STR_128(x) x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10]
5263
5264
5265/**
5266 * Set a the wep key
5267 *
5268 * @priv: struct to work on
5269 * @idx: index of the key we want to set
5270 * @key: ptr to the key data to set
5271 * @len: length of the buffer at @key
5272 * @batch_mode: FIXME perform the operation in batch mode, not
5273 * disabling the device.
5274 *
5275 * @returns 0 if OK, < 0 errno code on error.
5276 *
5277 * Fill out a command structure with the new wep key, length an
5278 * index and send it down the wire.
5279 */
5280static int ipw2100_set_key(struct ipw2100_priv *priv,
5281 int idx, char *key, int len, int batch_mode)
5282{
5283 int keylen = len ? (len <= 5 ? 5 : 13) : 0;
5284 struct host_command cmd = {
5285 .host_command = WEP_KEY_INFO,
5286 .host_command_sequence = 0,
5287 .host_command_length = sizeof(struct ipw2100_wep_key),
5288 };
5289 struct ipw2100_wep_key *wep_key = (void*)cmd.host_command_parameters;
5290 int err;
5291
5292 IPW_DEBUG_HC("WEP_KEY_INFO: index = %d, len = %d/%d\n",
5293 idx, keylen, len);
5294
5295 /* NOTE: We don't check cached values in case the firmware was reset
5296 * or some other problem is occuring. If the user is setting the key,
5297 * then we push the change */
5298
5299 wep_key->idx = idx;
5300 wep_key->len = keylen;
5301
5302 if (keylen) {
5303 memcpy(wep_key->key, key, len);
5304 memset(wep_key->key + len, 0, keylen - len);
5305 }
5306
5307 /* Will be optimized out on debug not being configured in */
5308 if (keylen == 0)
5309 IPW_DEBUG_WEP("%s: Clearing key %d\n",
5310 priv->net_dev->name, wep_key->idx);
5311 else if (keylen == 5)
5312 IPW_DEBUG_WEP("%s: idx: %d, len: %d key: " WEP_FMT_64 "\n",
5313 priv->net_dev->name, wep_key->idx, wep_key->len,
5314 WEP_STR_64(wep_key->key));
5315 else
5316 IPW_DEBUG_WEP("%s: idx: %d, len: %d key: " WEP_FMT_128
5317 "\n",
5318 priv->net_dev->name, wep_key->idx, wep_key->len,
5319 WEP_STR_128(wep_key->key));
5320
5321 if (!batch_mode) {
5322 err = ipw2100_disable_adapter(priv);
5323 /* FIXME: IPG: shouldn't this prink be in _disable_adapter()? */
5324 if (err) {
797b4f76 5325 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n",
2c86c275
JK
5326 priv->net_dev->name, err);
5327 return err;
5328 }
5329 }
5330
5331 /* send cmd to firmware */
5332 err = ipw2100_hw_send_command(priv, &cmd);
5333
5334 if (!batch_mode) {
5335 int err2 = ipw2100_enable_adapter(priv);
5336 if (err == 0)
5337 err = err2;
5338 }
5339 return err;
5340}
5341
5342static int ipw2100_set_key_index(struct ipw2100_priv *priv,
5343 int idx, int batch_mode)
5344{
5345 struct host_command cmd = {
5346 .host_command = WEP_KEY_INDEX,
5347 .host_command_sequence = 0,
5348 .host_command_length = 4,
011fe95a 5349 .host_command_parameters = { idx },
2c86c275
JK
5350 };
5351 int err;
5352
5353 IPW_DEBUG_HC("WEP_KEY_INDEX: index = %d\n", idx);
5354
5355 if (idx < 0 || idx > 3)
5356 return -EINVAL;
5357
5358 if (!batch_mode) {
5359 err = ipw2100_disable_adapter(priv);
5360 if (err) {
797b4f76 5361 printk(KERN_ERR DRV_NAME ": %s: Could not disable adapter %d\n",
2c86c275
JK
5362 priv->net_dev->name, err);
5363 return err;
5364 }
5365 }
5366
5367 /* send cmd to firmware */
5368 err = ipw2100_hw_send_command(priv, &cmd);
5369
5370 if (!batch_mode)
5371 ipw2100_enable_adapter(priv);
5372
5373 return err;
5374}
5375
5376
5377static int ipw2100_configure_security(struct ipw2100_priv *priv,
5378 int batch_mode)
5379{
5380 int i, err, auth_mode, sec_level, use_group;
5381
5382 if (!(priv->status & STATUS_RUNNING))
5383 return 0;
5384
5385 if (!batch_mode) {
5386 err = ipw2100_disable_adapter(priv);
5387 if (err)
5388 return err;
5389 }
5390
5391 if (!priv->sec.enabled) {
5392 err = ipw2100_set_security_information(
5393 priv, IPW_AUTH_OPEN, SEC_LEVEL_0, 0, 1);
5394 } else {
5395 auth_mode = IPW_AUTH_OPEN;
5396 if ((priv->sec.flags & SEC_AUTH_MODE) &&
5397 (priv->sec.auth_mode == WLAN_AUTH_SHARED_KEY))
5398 auth_mode = IPW_AUTH_SHARED;
5399
5400 sec_level = SEC_LEVEL_0;
5401 if (priv->sec.flags & SEC_LEVEL)
5402 sec_level = priv->sec.level;
5403
5404 use_group = 0;
5405 if (priv->sec.flags & SEC_UNICAST_GROUP)
5406 use_group = priv->sec.unicast_uses_group;
5407
5408 err = ipw2100_set_security_information(
5409 priv, auth_mode, sec_level, use_group, 1);
5410 }
5411
5412 if (err)
5413 goto exit;
5414
5415 if (priv->sec.enabled) {
5416 for (i = 0; i < 4; i++) {
5417 if (!(priv->sec.flags & (1 << i))) {
5418 memset(priv->sec.keys[i], 0, WEP_KEY_LEN);
5419 priv->sec.key_sizes[i] = 0;
5420 } else {
5421 err = ipw2100_set_key(priv, i,
5422 priv->sec.keys[i],
5423 priv->sec.key_sizes[i],
5424 1);
5425 if (err)
5426 goto exit;
5427 }
5428 }
5429
5430 ipw2100_set_key_index(priv, priv->ieee->tx_keyidx, 1);
5431 }
5432
5433 /* Always enable privacy so the Host can filter WEP packets if
5434 * encrypted data is sent up */
5435 err = ipw2100_set_wep_flags(
5436 priv, priv->sec.enabled ? IPW_PRIVACY_CAPABLE : 0, 1);
5437 if (err)
5438 goto exit;
5439
5440 priv->status &= ~STATUS_SECURITY_UPDATED;
5441
5442 exit:
5443 if (!batch_mode)
5444 ipw2100_enable_adapter(priv);
5445
5446 return err;
5447}
5448
5449static void ipw2100_security_work(struct ipw2100_priv *priv)
5450{
5451 /* If we happen to have reconnected before we get a chance to
5452 * process this, then update the security settings--which causes
5453 * a disassociation to occur */
5454 if (!(priv->status & STATUS_ASSOCIATED) &&
5455 priv->status & STATUS_SECURITY_UPDATED)
5456 ipw2100_configure_security(priv, 0);
5457}
5458
5459static void shim__set_security(struct net_device *dev,
5460 struct ieee80211_security *sec)
5461{
5462 struct ipw2100_priv *priv = ieee80211_priv(dev);
5463 int i, force_update = 0;
5464
5465 down(&priv->action_sem);
5466 if (!(priv->status & STATUS_INITIALIZED))
5467 goto done;
5468
5469 for (i = 0; i < 4; i++) {
5470 if (sec->flags & (1 << i)) {
5471 priv->sec.key_sizes[i] = sec->key_sizes[i];
5472 if (sec->key_sizes[i] == 0)
5473 priv->sec.flags &= ~(1 << i);
5474 else
5475 memcpy(priv->sec.keys[i], sec->keys[i],
5476 sec->key_sizes[i]);
5477 priv->sec.flags |= (1 << i);
5478 priv->status |= STATUS_SECURITY_UPDATED;
5479 }
5480 }
5481
5482 if ((sec->flags & SEC_ACTIVE_KEY) &&
5483 priv->sec.active_key != sec->active_key) {
5484 if (sec->active_key <= 3) {
5485 priv->sec.active_key = sec->active_key;
5486 priv->sec.flags |= SEC_ACTIVE_KEY;
5487 } else
5488 priv->sec.flags &= ~SEC_ACTIVE_KEY;
5489
5490 priv->status |= STATUS_SECURITY_UPDATED;
5491 }
5492
5493 if ((sec->flags & SEC_AUTH_MODE) &&
5494 (priv->sec.auth_mode != sec->auth_mode)) {
5495 priv->sec.auth_mode = sec->auth_mode;
5496 priv->sec.flags |= SEC_AUTH_MODE;
5497 priv->status |= STATUS_SECURITY_UPDATED;
5498 }
5499
5500 if (sec->flags & SEC_ENABLED &&
5501 priv->sec.enabled != sec->enabled) {
5502 priv->sec.flags |= SEC_ENABLED;
5503 priv->sec.enabled = sec->enabled;
5504 priv->status |= STATUS_SECURITY_UPDATED;
5505 force_update = 1;
5506 }
5507
5508 if (sec->flags & SEC_LEVEL &&
5509 priv->sec.level != sec->level) {
5510 priv->sec.level = sec->level;
5511 priv->sec.flags |= SEC_LEVEL;
5512 priv->status |= STATUS_SECURITY_UPDATED;
5513 }
5514
5515 IPW_DEBUG_WEP("Security flags: %c %c%c%c%c %c%c%c%c\n",
5516 priv->sec.flags & (1<<8) ? '1' : '0',
5517 priv->sec.flags & (1<<7) ? '1' : '0',
5518 priv->sec.flags & (1<<6) ? '1' : '0',
5519 priv->sec.flags & (1<<5) ? '1' : '0',
5520 priv->sec.flags & (1<<4) ? '1' : '0',
5521 priv->sec.flags & (1<<3) ? '1' : '0',
5522 priv->sec.flags & (1<<2) ? '1' : '0',
5523 priv->sec.flags & (1<<1) ? '1' : '0',
5524 priv->sec.flags & (1<<0) ? '1' : '0');
5525
5526/* As a temporary work around to enable WPA until we figure out why
5527 * wpa_supplicant toggles the security capability of the driver, which
5528 * forces a disassocation with force_update...
5529 *
5530 * if (force_update || !(priv->status & STATUS_ASSOCIATED))*/
5531 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
5532 ipw2100_configure_security(priv, 0);
5533done:
5534 up(&priv->action_sem);
5535}
5536
5537static int ipw2100_adapter_setup(struct ipw2100_priv *priv)
5538{
5539 int err;
5540 int batch_mode = 1;
5541 u8 *bssid;
5542
5543 IPW_DEBUG_INFO("enter\n");
5544
5545 err = ipw2100_disable_adapter(priv);
5546 if (err)
5547 return err;
5548#ifdef CONFIG_IPW2100_MONITOR
5549 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
5550 err = ipw2100_set_channel(priv, priv->channel, batch_mode);
5551 if (err)
5552 return err;
5553
5554 IPW_DEBUG_INFO("exit\n");
5555
5556 return 0;
5557 }
5558#endif /* CONFIG_IPW2100_MONITOR */
5559
5560 err = ipw2100_read_mac_address(priv);
5561 if (err)
5562 return -EIO;
5563
5564 err = ipw2100_set_mac_address(priv, batch_mode);
5565 if (err)
5566 return err;
5567
5568 err = ipw2100_set_port_type(priv, priv->ieee->iw_mode, batch_mode);
5569 if (err)
5570 return err;
5571
5572 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
5573 err = ipw2100_set_channel(priv, priv->channel, batch_mode);
5574 if (err)
5575 return err;
5576 }
5577
5578 err = ipw2100_system_config(priv, batch_mode);
5579 if (err)
5580 return err;
5581
5582 err = ipw2100_set_tx_rates(priv, priv->tx_rates, batch_mode);
5583 if (err)
5584 return err;
5585
5586 /* Default to power mode OFF */
5587 err = ipw2100_set_power_mode(priv, IPW_POWER_MODE_CAM);
5588 if (err)
5589 return err;
5590
5591 err = ipw2100_set_rts_threshold(priv, priv->rts_threshold);
5592 if (err)
5593 return err;
5594
5595 if (priv->config & CFG_STATIC_BSSID)
5596 bssid = priv->bssid;
5597 else
5598 bssid = NULL;
5599 err = ipw2100_set_mandatory_bssid(priv, bssid, batch_mode);
5600 if (err)
5601 return err;
5602
5603 if (priv->config & CFG_STATIC_ESSID)
5604 err = ipw2100_set_essid(priv, priv->essid, priv->essid_len,
5605 batch_mode);
5606 else
5607 err = ipw2100_set_essid(priv, NULL, 0, batch_mode);
5608 if (err)
5609 return err;
5610
5611 err = ipw2100_configure_security(priv, batch_mode);
5612 if (err)
5613 return err;
5614
5615 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
5616 err = ipw2100_set_ibss_beacon_interval(
5617 priv, priv->beacon_interval, batch_mode);
5618 if (err)
5619 return err;
5620
5621 err = ipw2100_set_tx_power(priv, priv->tx_power);
5622 if (err)
5623 return err;
5624 }
5625
5626 /*
5627 err = ipw2100_set_fragmentation_threshold(
5628 priv, priv->frag_threshold, batch_mode);
5629 if (err)
5630 return err;
5631 */
5632
5633 IPW_DEBUG_INFO("exit\n");
5634
5635 return 0;
5636}
5637
5638
5639/*************************************************************************
5640 *
5641 * EXTERNALLY CALLED METHODS
5642 *
5643 *************************************************************************/
5644
5645/* This method is called by the network layer -- not to be confused with
5646 * ipw2100_set_mac_address() declared above called by this driver (and this
5647 * method as well) to talk to the firmware */
5648static int ipw2100_set_address(struct net_device *dev, void *p)
5649{
5650 struct ipw2100_priv *priv = ieee80211_priv(dev);
5651 struct sockaddr *addr = p;
5652 int err = 0;
5653
5654 if (!is_valid_ether_addr(addr->sa_data))
5655 return -EADDRNOTAVAIL;
5656
5657 down(&priv->action_sem);
5658
5659 priv->config |= CFG_CUSTOM_MAC;
5660 memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
5661
5662 err = ipw2100_set_mac_address(priv, 0);
5663 if (err)
5664 goto done;
5665
5666 priv->reset_backoff = 0;
5667 up(&priv->action_sem);
5668 ipw2100_reset_adapter(priv);
5669 return 0;
5670
5671 done:
5672 up(&priv->action_sem);
5673 return err;
5674}
5675
5676static int ipw2100_open(struct net_device *dev)
5677{
5678 struct ipw2100_priv *priv = ieee80211_priv(dev);
5679 unsigned long flags;
5680 IPW_DEBUG_INFO("dev->open\n");
5681
5682 spin_lock_irqsave(&priv->low_lock, flags);
3ce329ce
JB
5683 if (priv->status & STATUS_ASSOCIATED) {
5684 netif_carrier_on(dev);
2c86c275 5685 netif_start_queue(dev);
3ce329ce 5686 }
2c86c275
JK
5687 spin_unlock_irqrestore(&priv->low_lock, flags);
5688
5689 return 0;
5690}
5691
5692static int ipw2100_close(struct net_device *dev)
5693{
5694 struct ipw2100_priv *priv = ieee80211_priv(dev);
5695 unsigned long flags;
5696 struct list_head *element;
5697 struct ipw2100_tx_packet *packet;
5698
5699 IPW_DEBUG_INFO("enter\n");
5700
5701 spin_lock_irqsave(&priv->low_lock, flags);
5702
5703 if (priv->status & STATUS_ASSOCIATED)
5704 netif_carrier_off(dev);
5705 netif_stop_queue(dev);
5706
5707 /* Flush the TX queue ... */
5708 while (!list_empty(&priv->tx_pend_list)) {
5709 element = priv->tx_pend_list.next;
5710 packet = list_entry(element, struct ipw2100_tx_packet, list);
5711
5712 list_del(element);
5713 DEC_STAT(&priv->tx_pend_stat);
5714
5715 ieee80211_txb_free(packet->info.d_struct.txb);
5716 packet->info.d_struct.txb = NULL;
5717
5718 list_add_tail(element, &priv->tx_free_list);
5719 INC_STAT(&priv->tx_free_stat);
5720 }
5721 spin_unlock_irqrestore(&priv->low_lock, flags);
5722
5723 IPW_DEBUG_INFO("exit\n");
5724
5725 return 0;
5726}
5727
5728
5729
5730/*
5731 * TODO: Fix this function... its just wrong
5732 */
5733static void ipw2100_tx_timeout(struct net_device *dev)
5734{
5735 struct ipw2100_priv *priv = ieee80211_priv(dev);
5736
5737 priv->ieee->stats.tx_errors++;
5738
5739#ifdef CONFIG_IPW2100_MONITOR
5740 if (priv->ieee->iw_mode == IW_MODE_MONITOR)
5741 return;
5742#endif
5743
5744 IPW_DEBUG_INFO("%s: TX timed out. Scheduling firmware restart.\n",
5745 dev->name);
5746 schedule_reset(priv);
5747}
5748
5749
5750/*
5751 * TODO: reimplement it so that it reads statistics
5752 * from the adapter using ordinal tables
5753 * instead of/in addition to collecting them
5754 * in the driver
5755 */
5756static struct net_device_stats *ipw2100_stats(struct net_device *dev)
5757{
5758 struct ipw2100_priv *priv = ieee80211_priv(dev);
5759
5760 return &priv->ieee->stats;
5761}
5762
5763/* Support for wpa_supplicant. Will be replaced with WEXT once
5764 * they get WPA support. */
5765#ifdef CONFIG_IEEE80211_WPA
5766
5767/* following definitions must match definitions in driver_ipw2100.c */
5768
5769#define IPW2100_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
5770
5771#define IPW2100_CMD_SET_WPA_PARAM 1
5772#define IPW2100_CMD_SET_WPA_IE 2
5773#define IPW2100_CMD_SET_ENCRYPTION 3
5774#define IPW2100_CMD_MLME 4
5775
5776#define IPW2100_PARAM_WPA_ENABLED 1
5777#define IPW2100_PARAM_TKIP_COUNTERMEASURES 2
5778#define IPW2100_PARAM_DROP_UNENCRYPTED 3
5779#define IPW2100_PARAM_PRIVACY_INVOKED 4
5780#define IPW2100_PARAM_AUTH_ALGS 5
5781#define IPW2100_PARAM_IEEE_802_1X 6
5782
5783#define IPW2100_MLME_STA_DEAUTH 1
5784#define IPW2100_MLME_STA_DISASSOC 2
5785
5786#define IPW2100_CRYPT_ERR_UNKNOWN_ALG 2
5787#define IPW2100_CRYPT_ERR_UNKNOWN_ADDR 3
5788#define IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED 4
5789#define IPW2100_CRYPT_ERR_KEY_SET_FAILED 5
5790#define IPW2100_CRYPT_ERR_TX_KEY_SET_FAILED 6
5791#define IPW2100_CRYPT_ERR_CARD_CONF_FAILED 7
5792
5793#define IPW2100_CRYPT_ALG_NAME_LEN 16
5794
5795struct ipw2100_param {
5796 u32 cmd;
5797 u8 sta_addr[ETH_ALEN];
5798 union {
5799 struct {
5800 u8 name;
5801 u32 value;
5802 } wpa_param;
5803 struct {
5804 u32 len;
5805 u8 *data;
5806 } wpa_ie;
5807 struct{
5808 int command;
5809 int reason_code;
5810 } mlme;
5811 struct {
5812 u8 alg[IPW2100_CRYPT_ALG_NAME_LEN];
5813 u8 set_tx;
5814 u32 err;
5815 u8 idx;
5816 u8 seq[8]; /* sequence counter (set: RX, get: TX) */
5817 u16 key_len;
5818 u8 key[0];
5819 } crypt;
5820
5821 } u;
5822};
5823
5824/* end of driver_ipw2100.c code */
5825
5826static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value){
5827
5828 struct ieee80211_device *ieee = priv->ieee;
5829 struct ieee80211_security sec = {
5830 .flags = SEC_LEVEL | SEC_ENABLED,
5831 };
5832 int ret = 0;
5833
5834 ieee->wpa_enabled = value;
5835
5836 if (value){
5837 sec.level = SEC_LEVEL_3;
5838 sec.enabled = 1;
5839 } else {
5840 sec.level = SEC_LEVEL_0;
5841 sec.enabled = 0;
5842 }
5843
5844 if (ieee->set_security)
5845 ieee->set_security(ieee->dev, &sec);
5846 else
5847 ret = -EOPNOTSUPP;
5848
5849 return ret;
5850}
5851
5852#define AUTH_ALG_OPEN_SYSTEM 0x1
5853#define AUTH_ALG_SHARED_KEY 0x2
5854
5855static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value){
5856
5857 struct ieee80211_device *ieee = priv->ieee;
5858 struct ieee80211_security sec = {
5859 .flags = SEC_AUTH_MODE,
5860 };
5861 int ret = 0;
5862
5863 if (value & AUTH_ALG_SHARED_KEY){
5864 sec.auth_mode = WLAN_AUTH_SHARED_KEY;
5865 ieee->open_wep = 0;
5866 } else {
5867 sec.auth_mode = WLAN_AUTH_OPEN;
5868 ieee->open_wep = 1;
5869 }
5870
5871 if (ieee->set_security)
5872 ieee->set_security(ieee->dev, &sec);
5873 else
5874 ret = -EOPNOTSUPP;
5875
5876 return ret;
5877}
5878
5879
5880static int ipw2100_wpa_set_param(struct net_device *dev, u8 name, u32 value){
5881
5882 struct ipw2100_priv *priv = ieee80211_priv(dev);
5883 int ret=0;
5884
5885 switch(name){
5886 case IPW2100_PARAM_WPA_ENABLED:
5887 ret = ipw2100_wpa_enable(priv, value);
5888 break;
5889
5890 case IPW2100_PARAM_TKIP_COUNTERMEASURES:
5891 priv->ieee->tkip_countermeasures=value;
5892 break;
5893
5894 case IPW2100_PARAM_DROP_UNENCRYPTED:
5895 priv->ieee->drop_unencrypted=value;
5896 break;
5897
5898 case IPW2100_PARAM_PRIVACY_INVOKED:
5899 priv->ieee->privacy_invoked=value;
5900 break;
5901
5902 case IPW2100_PARAM_AUTH_ALGS:
5903 ret = ipw2100_wpa_set_auth_algs(priv, value);
5904 break;
5905
5906 case IPW2100_PARAM_IEEE_802_1X:
5907 priv->ieee->ieee802_1x=value;
5908 break;
5909
5910 default:
797b4f76 5911 printk(KERN_ERR DRV_NAME ": %s: Unknown WPA param: %d\n",
2c86c275
JK
5912 dev->name, name);
5913 ret = -EOPNOTSUPP;
5914 }
5915
5916 return ret;
5917}
5918
5919static int ipw2100_wpa_mlme(struct net_device *dev, int command, int reason){
5920
5921 struct ipw2100_priv *priv = ieee80211_priv(dev);
5922 int ret=0;
5923
5924 switch(command){
5925 case IPW2100_MLME_STA_DEAUTH:
5926 // silently ignore
5927 break;
5928
5929 case IPW2100_MLME_STA_DISASSOC:
5930 ipw2100_disassociate_bssid(priv);
5931 break;
5932
5933 default:
797b4f76 5934 printk(KERN_ERR DRV_NAME ": %s: Unknown MLME request: %d\n",
2c86c275
JK
5935 dev->name, command);
5936 ret = -EOPNOTSUPP;
5937 }
5938
5939 return ret;
5940}
5941
5942
5943void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv,
5944 char *wpa_ie, int wpa_ie_len){
5945
5946 struct ipw2100_wpa_assoc_frame frame;
5947
5948 frame.fixed_ie_mask = 0;
5949
5950 /* copy WPA IE */
5951 memcpy(frame.var_ie, wpa_ie, wpa_ie_len);
5952 frame.var_ie_len = wpa_ie_len;
5953
5954 /* make sure WPA is enabled */
5955 ipw2100_wpa_enable(priv, 1);
5956 ipw2100_set_wpa_ie(priv, &frame, 0);
5957}
5958
5959
5960static int ipw2100_wpa_set_wpa_ie(struct net_device *dev,
5961 struct ipw2100_param *param, int plen){
5962
5963 struct ipw2100_priv *priv = ieee80211_priv(dev);
5964 struct ieee80211_device *ieee = priv->ieee;
5965 u8 *buf;
5966
5967 if (! ieee->wpa_enabled)
5968 return -EOPNOTSUPP;
5969
5970 if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
5971 (param->u.wpa_ie.len &&
5972 param->u.wpa_ie.data==NULL))
5973 return -EINVAL;
5974
5975 if (param->u.wpa_ie.len){
5976 buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
5977 if (buf == NULL)
5978 return -ENOMEM;
5979
5980 memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
5981
5982 kfree(ieee->wpa_ie);
5983 ieee->wpa_ie = buf;
5984 ieee->wpa_ie_len = param->u.wpa_ie.len;
5985
5986 } else {
5987 kfree(ieee->wpa_ie);
5988 ieee->wpa_ie = NULL;
5989 ieee->wpa_ie_len = 0;
5990 }
5991
5992 ipw2100_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
5993
5994 return 0;
5995}
5996
5997/* implementation borrowed from hostap driver */
5998
5999static int ipw2100_wpa_set_encryption(struct net_device *dev,
6000 struct ipw2100_param *param, int param_len){
6001
6002 int ret = 0;
6003 struct ipw2100_priv *priv = ieee80211_priv(dev);
6004 struct ieee80211_device *ieee = priv->ieee;
6005 struct ieee80211_crypto_ops *ops;
6006 struct ieee80211_crypt_data **crypt;
6007
6008 struct ieee80211_security sec = {
6009 .flags = 0,
6010 };
6011
6012 param->u.crypt.err = 0;
6013 param->u.crypt.alg[IPW2100_CRYPT_ALG_NAME_LEN - 1] = '\0';
6014
6015 if (param_len !=
6016 (int) ((char *) param->u.crypt.key - (char *) param) +
6017 param->u.crypt.key_len){
6018 IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len, param->u.crypt.key_len);
6019 return -EINVAL;
6020 }
6021 if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
6022 param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
6023 param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
6024 if (param->u.crypt.idx >= WEP_KEYS)
6025 return -EINVAL;
6026 crypt = &ieee->crypt[param->u.crypt.idx];
6027 } else {
6028 return -EINVAL;
6029 }
6030
6031 if (strcmp(param->u.crypt.alg, "none") == 0) {
6032 if (crypt){
6033 sec.enabled = 0;
6034 sec.level = SEC_LEVEL_0;
6035 sec.flags |= SEC_ENABLED | SEC_LEVEL;
6036 ieee80211_crypt_delayed_deinit(ieee, crypt);
6037 }
6038 goto done;
6039 }
6040 sec.enabled = 1;
6041 sec.flags |= SEC_ENABLED;
6042
6043 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
6044 if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
6045 request_module("ieee80211_crypt_wep");
6046 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
6047 } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
6048 request_module("ieee80211_crypt_tkip");
6049 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
6050 } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
6051 request_module("ieee80211_crypt_ccmp");
6052 ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
6053 }
6054 if (ops == NULL) {
6055 IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n",
6056 dev->name, param->u.crypt.alg);
6057 param->u.crypt.err = IPW2100_CRYPT_ERR_UNKNOWN_ALG;
6058 ret = -EINVAL;
6059 goto done;
6060 }
6061
6062 if (*crypt == NULL || (*crypt)->ops != ops) {
6063 struct ieee80211_crypt_data *new_crypt;
6064
6065 ieee80211_crypt_delayed_deinit(ieee, crypt);
6066
6067 new_crypt = (struct ieee80211_crypt_data *)
6068 kmalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL);
6069 if (new_crypt == NULL) {
6070 ret = -ENOMEM;
6071 goto done;
6072 }
6073 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
6074 new_crypt->ops = ops;
6075 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
6076 new_crypt->priv = new_crypt->ops->init(param->u.crypt.idx);
6077
6078 if (new_crypt->priv == NULL) {
6079 kfree(new_crypt);
6080 param->u.crypt.err =
6081 IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED;
6082 ret = -EINVAL;
6083 goto done;
6084 }
6085
6086 *crypt = new_crypt;
6087 }
6088
6089 if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
6090 (*crypt)->ops->set_key(param->u.crypt.key,
6091 param->u.crypt.key_len, param->u.crypt.seq,
6092 (*crypt)->priv) < 0) {
6093 IPW_DEBUG_INFO("%s: key setting failed\n",
6094 dev->name);
6095 param->u.crypt.err = IPW2100_CRYPT_ERR_KEY_SET_FAILED;
6096 ret = -EINVAL;
6097 goto done;
6098 }
6099
6100 if (param->u.crypt.set_tx){
6101 ieee->tx_keyidx = param->u.crypt.idx;
6102 sec.active_key = param->u.crypt.idx;
6103 sec.flags |= SEC_ACTIVE_KEY;
6104 }
6105
6106 if (ops->name != NULL){
6107
6108 if (strcmp(ops->name, "WEP") == 0) {
6109 memcpy(sec.keys[param->u.crypt.idx], param->u.crypt.key, param->u.crypt.key_len);
6110 sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
6111 sec.flags |= (1 << param->u.crypt.idx);
6112 sec.flags |= SEC_LEVEL;
6113 sec.level = SEC_LEVEL_1;
6114 } else if (strcmp(ops->name, "TKIP") == 0) {
6115 sec.flags |= SEC_LEVEL;
6116 sec.level = SEC_LEVEL_2;
6117 } else if (strcmp(ops->name, "CCMP") == 0) {
6118 sec.flags |= SEC_LEVEL;
6119 sec.level = SEC_LEVEL_3;
6120 }
6121 }
6122 done:
6123 if (ieee->set_security)
6124 ieee->set_security(ieee->dev, &sec);
6125
6126 /* Do not reset port if card is in Managed mode since resetting will
6127 * generate new IEEE 802.11 authentication which may end up in looping
6128 * with IEEE 802.1X. If your hardware requires a reset after WEP
6129 * configuration (for example... Prism2), implement the reset_port in
6130 * the callbacks structures used to initialize the 802.11 stack. */
6131 if (ieee->reset_on_keychange &&
6132 ieee->iw_mode != IW_MODE_INFRA &&
6133 ieee->reset_port &&
6134 ieee->reset_port(dev)) {
6135 IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name);
6136 param->u.crypt.err = IPW2100_CRYPT_ERR_CARD_CONF_FAILED;
6137 return -EINVAL;
6138 }
6139
6140 return ret;
6141}
6142
6143
6144static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p){
6145
6146 struct ipw2100_param *param;
6147 int ret=0;
6148
6149 IPW_DEBUG_IOCTL("wpa_supplicant: len=%d\n", p->length);
6150
6151 if (p->length < sizeof(struct ipw2100_param) || !p->pointer)
6152 return -EINVAL;
6153
6154 param = (struct ipw2100_param *)kmalloc(p->length, GFP_KERNEL);
6155 if (param == NULL)
6156 return -ENOMEM;
6157
6158 if (copy_from_user(param, p->pointer, p->length)){
6159 kfree(param);
6160 return -EFAULT;
6161 }
6162
6163 switch (param->cmd){
6164
6165 case IPW2100_CMD_SET_WPA_PARAM:
6166 ret = ipw2100_wpa_set_param(dev, param->u.wpa_param.name,
6167 param->u.wpa_param.value);
6168 break;
6169
6170 case IPW2100_CMD_SET_WPA_IE:
6171 ret = ipw2100_wpa_set_wpa_ie(dev, param, p->length);
6172 break;
6173
6174 case IPW2100_CMD_SET_ENCRYPTION:
6175 ret = ipw2100_wpa_set_encryption(dev, param, p->length);
6176 break;
6177
6178 case IPW2100_CMD_MLME:
6179 ret = ipw2100_wpa_mlme(dev, param->u.mlme.command,
6180 param->u.mlme.reason_code);
6181 break;
6182
6183 default:
797b4f76 6184 printk(KERN_ERR DRV_NAME ": %s: Unknown WPA supplicant request: %d\n",
2c86c275
JK
6185 dev->name, param->cmd);
6186 ret = -EOPNOTSUPP;
6187
6188 }
6189
6190 if (ret == 0 && copy_to_user(p->pointer, param, p->length))
6191 ret = -EFAULT;
6192
6193 kfree(param);
6194 return ret;
6195}
6196#endif /* CONFIG_IEEE80211_WPA */
6197
6198static int ipw2100_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
6199{
6200#ifdef CONFIG_IEEE80211_WPA
6201 struct iwreq *wrq = (struct iwreq *) rq;
6202 int ret=-1;
6203 switch (cmd){
6204 case IPW2100_IOCTL_WPA_SUPPLICANT:
6205 ret = ipw2100_wpa_supplicant(dev, &wrq->u.data);
6206 return ret;
6207
6208 default:
6209 return -EOPNOTSUPP;
6210 }
6211
6212#endif /* CONFIG_IEEE80211_WPA */
6213
6214 return -EOPNOTSUPP;
6215}
6216
6217
6218static void ipw_ethtool_get_drvinfo(struct net_device *dev,
6219 struct ethtool_drvinfo *info)
6220{
6221 struct ipw2100_priv *priv = ieee80211_priv(dev);
6222 char fw_ver[64], ucode_ver[64];
6223
6224 strcpy(info->driver, DRV_NAME);
6225 strcpy(info->version, DRV_VERSION);
6226
6227 ipw2100_get_fwversion(priv, fw_ver, sizeof(fw_ver));
6228 ipw2100_get_ucodeversion(priv, ucode_ver, sizeof(ucode_ver));
6229
6230 snprintf(info->fw_version, sizeof(info->fw_version), "%s:%d:%s",
6231 fw_ver, priv->eeprom_version, ucode_ver);
6232
6233 strcpy(info->bus_info, pci_name(priv->pci_dev));
6234}
6235
6236static u32 ipw2100_ethtool_get_link(struct net_device *dev)
6237{
6238 struct ipw2100_priv *priv = ieee80211_priv(dev);
6239 return (priv->status & STATUS_ASSOCIATED) ? 1 : 0;
6240}
6241
6242
6243static struct ethtool_ops ipw2100_ethtool_ops = {
6244 .get_link = ipw2100_ethtool_get_link,
6245 .get_drvinfo = ipw_ethtool_get_drvinfo,
6246};
6247
6248static void ipw2100_hang_check(void *adapter)
6249{
6250 struct ipw2100_priv *priv = adapter;
6251 unsigned long flags;
6252 u32 rtc = 0xa5a5a5a5;
6253 u32 len = sizeof(rtc);
6254 int restart = 0;
6255
6256 spin_lock_irqsave(&priv->low_lock, flags);
6257
6258 if (priv->fatal_error != 0) {
6259 /* If fatal_error is set then we need to restart */
6260 IPW_DEBUG_INFO("%s: Hardware fatal error detected.\n",
6261 priv->net_dev->name);
6262
6263 restart = 1;
6264 } else if (ipw2100_get_ordinal(priv, IPW_ORD_RTC_TIME, &rtc, &len) ||
6265 (rtc == priv->last_rtc)) {
6266 /* Check if firmware is hung */
6267 IPW_DEBUG_INFO("%s: Firmware RTC stalled.\n",
6268 priv->net_dev->name);
6269
6270 restart = 1;
6271 }
6272
6273 if (restart) {
6274 /* Kill timer */
6275 priv->stop_hang_check = 1;
6276 priv->hangs++;
6277
6278 /* Restart the NIC */
6279 schedule_reset(priv);
6280 }
6281
6282 priv->last_rtc = rtc;
6283
6284 if (!priv->stop_hang_check)
6285 queue_delayed_work(priv->workqueue, &priv->hang_check, HZ / 2);
6286
6287 spin_unlock_irqrestore(&priv->low_lock, flags);
6288}
6289
6290
6291static void ipw2100_rf_kill(void *adapter)
6292{
6293 struct ipw2100_priv *priv = adapter;
6294 unsigned long flags;
6295
6296 spin_lock_irqsave(&priv->low_lock, flags);
6297
6298 if (rf_kill_active(priv)) {
6299 IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n");
6300 if (!priv->stop_rf_kill)
6301 queue_delayed_work(priv->workqueue, &priv->rf_kill, HZ);
6302 goto exit_unlock;
6303 }
6304
6305 /* RF Kill is now disabled, so bring the device back up */
6306
6307 if (!(priv->status & STATUS_RF_KILL_MASK)) {
6308 IPW_DEBUG_RF_KILL("HW RF Kill no longer active, restarting "
6309 "device\n");
6310 schedule_reset(priv);
6311 } else
6312 IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still "
6313 "enabled\n");
6314
6315 exit_unlock:
6316 spin_unlock_irqrestore(&priv->low_lock, flags);
6317}
6318
6319static void ipw2100_irq_tasklet(struct ipw2100_priv *priv);
6320
6321/* Look into using netdev destructor to shutdown ieee80211? */
6322
6323static struct net_device *ipw2100_alloc_device(
6324 struct pci_dev *pci_dev,
2be041a7 6325 void __iomem *base_addr,
2c86c275
JK
6326 unsigned long mem_start,
6327 unsigned long mem_len)
6328{
6329 struct ipw2100_priv *priv;
6330 struct net_device *dev;
6331
6332 dev = alloc_ieee80211(sizeof(struct ipw2100_priv));
6333 if (!dev)
6334 return NULL;
6335 priv = ieee80211_priv(dev);
6336 priv->ieee = netdev_priv(dev);
6337 priv->pci_dev = pci_dev;
6338 priv->net_dev = dev;
6339
6340 priv->ieee->hard_start_xmit = ipw2100_tx;
6341 priv->ieee->set_security = shim__set_security;
6342
6343 dev->open = ipw2100_open;
6344 dev->stop = ipw2100_close;
6345 dev->init = ipw2100_net_init;
6346 dev->do_ioctl = ipw2100_ioctl;
6347 dev->get_stats = ipw2100_stats;
6348 dev->ethtool_ops = &ipw2100_ethtool_ops;
6349 dev->tx_timeout = ipw2100_tx_timeout;
6350 dev->wireless_handlers = &ipw2100_wx_handler_def;
6351 dev->get_wireless_stats = ipw2100_wx_wireless_stats;
6352 dev->set_mac_address = ipw2100_set_address;
6353 dev->watchdog_timeo = 3*HZ;
6354 dev->irq = 0;
6355
6356 dev->base_addr = (unsigned long)base_addr;
6357 dev->mem_start = mem_start;
6358 dev->mem_end = dev->mem_start + mem_len - 1;
6359
6360 /* NOTE: We don't use the wireless_handlers hook
6361 * in dev as the system will start throwing WX requests
6362 * to us before we're actually initialized and it just
6363 * ends up causing problems. So, we just handle
6364 * the WX extensions through the ipw2100_ioctl interface */
6365
6366
6367 /* memset() puts everything to 0, so we only have explicitely set
6368 * those values that need to be something else */
6369
6370 /* If power management is turned on, default to AUTO mode */
6371 priv->power_mode = IPW_POWER_AUTO;
6372
6373
6374
6375#ifdef CONFIG_IEEE80211_WPA
6376 priv->ieee->wpa_enabled = 0;
6377 priv->ieee->tkip_countermeasures = 0;
6378 priv->ieee->drop_unencrypted = 0;
6379 priv->ieee->privacy_invoked = 0;
6380 priv->ieee->ieee802_1x = 1;
6381#endif /* CONFIG_IEEE80211_WPA */
6382
6383 /* Set module parameters */
6384 switch (mode) {
6385 case 1:
6386 priv->ieee->iw_mode = IW_MODE_ADHOC;
6387 break;
6388#ifdef CONFIG_IPW2100_MONITOR
6389 case 2:
6390 priv->ieee->iw_mode = IW_MODE_MONITOR;
6391 break;
6392#endif
6393 default:
6394 case 0:
6395 priv->ieee->iw_mode = IW_MODE_INFRA;
6396 break;
6397 }
6398
6399 if (disable == 1)
6400 priv->status |= STATUS_RF_KILL_SW;
6401
6402 if (channel != 0 &&
6403 ((channel >= REG_MIN_CHANNEL) &&
6404 (channel <= REG_MAX_CHANNEL))) {
6405 priv->config |= CFG_STATIC_CHANNEL;
6406 priv->channel = channel;
6407 }
6408
6409 if (associate)
6410 priv->config |= CFG_ASSOCIATE;
6411
6412 priv->beacon_interval = DEFAULT_BEACON_INTERVAL;
6413 priv->short_retry_limit = DEFAULT_SHORT_RETRY_LIMIT;
6414 priv->long_retry_limit = DEFAULT_LONG_RETRY_LIMIT;
6415 priv->rts_threshold = DEFAULT_RTS_THRESHOLD | RTS_DISABLED;
6416 priv->frag_threshold = DEFAULT_FTS | FRAG_DISABLED;
6417 priv->tx_power = IPW_TX_POWER_DEFAULT;
6418 priv->tx_rates = DEFAULT_TX_RATES;
6419
6420 strcpy(priv->nick, "ipw2100");
6421
6422 spin_lock_init(&priv->low_lock);
6423 sema_init(&priv->action_sem, 1);
6424 sema_init(&priv->adapter_sem, 1);
6425
6426 init_waitqueue_head(&priv->wait_command_queue);
6427
6428 netif_carrier_off(dev);
6429
6430 INIT_LIST_HEAD(&priv->msg_free_list);
6431 INIT_LIST_HEAD(&priv->msg_pend_list);
6432 INIT_STAT(&priv->msg_free_stat);
6433 INIT_STAT(&priv->msg_pend_stat);
6434
6435 INIT_LIST_HEAD(&priv->tx_free_list);
6436 INIT_LIST_HEAD(&priv->tx_pend_list);
6437 INIT_STAT(&priv->tx_free_stat);
6438 INIT_STAT(&priv->tx_pend_stat);
6439
6440 INIT_LIST_HEAD(&priv->fw_pend_list);
6441 INIT_STAT(&priv->fw_pend_stat);
6442
6443
6444#ifdef CONFIG_SOFTWARE_SUSPEND2
6445 priv->workqueue = create_workqueue(DRV_NAME, 0);
6446#else
6447 priv->workqueue = create_workqueue(DRV_NAME);
6448#endif
6449 INIT_WORK(&priv->reset_work,
6450 (void (*)(void *))ipw2100_reset_adapter, priv);
6451 INIT_WORK(&priv->security_work,
6452 (void (*)(void *))ipw2100_security_work, priv);
6453 INIT_WORK(&priv->wx_event_work,
6454 (void (*)(void *))ipw2100_wx_event_work, priv);
6455 INIT_WORK(&priv->hang_check, ipw2100_hang_check, priv);
6456 INIT_WORK(&priv->rf_kill, ipw2100_rf_kill, priv);
6457
6458 tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
6459 ipw2100_irq_tasklet, (unsigned long)priv);
6460
6461 /* NOTE: We do not start the deferred work for status checks yet */
6462 priv->stop_rf_kill = 1;
6463 priv->stop_hang_check = 1;
6464
6465 return dev;
6466}
6467
2c86c275
JK
6468static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6469 const struct pci_device_id *ent)
6470{
6471 unsigned long mem_start, mem_len, mem_flags;
2be041a7 6472 void __iomem *base_addr = NULL;
2c86c275
JK
6473 struct net_device *dev = NULL;
6474 struct ipw2100_priv *priv = NULL;
6475 int err = 0;
6476 int registered = 0;
6477 u32 val;
6478
6479 IPW_DEBUG_INFO("enter\n");
6480
6481 mem_start = pci_resource_start(pci_dev, 0);
6482 mem_len = pci_resource_len(pci_dev, 0);
6483 mem_flags = pci_resource_flags(pci_dev, 0);
6484
6485 if ((mem_flags & IORESOURCE_MEM) != IORESOURCE_MEM) {
6486 IPW_DEBUG_INFO("weird - resource type is not memory\n");
6487 err = -ENODEV;
6488 goto fail;
6489 }
6490
6491 base_addr = ioremap_nocache(mem_start, mem_len);
6492 if (!base_addr) {
6493 printk(KERN_WARNING DRV_NAME
6494 "Error calling ioremap_nocache.\n");
6495 err = -EIO;
6496 goto fail;
6497 }
6498
6499 /* allocate and initialize our net_device */
6500 dev = ipw2100_alloc_device(pci_dev, base_addr, mem_start, mem_len);
6501 if (!dev) {
6502 printk(KERN_WARNING DRV_NAME
6503 "Error calling ipw2100_alloc_device.\n");
6504 err = -ENOMEM;
6505 goto fail;
6506 }
6507
6508 /* set up PCI mappings for device */
6509 err = pci_enable_device(pci_dev);
6510 if (err) {
6511 printk(KERN_WARNING DRV_NAME
6512 "Error calling pci_enable_device.\n");
6513 return err;
6514 }
6515
6516 priv = ieee80211_priv(dev);
6517
6518 pci_set_master(pci_dev);
6519 pci_set_drvdata(pci_dev, priv);
6520
05743d16 6521 err = pci_set_dma_mask(pci_dev, DMA_32BIT_MASK);
2c86c275
JK
6522 if (err) {
6523 printk(KERN_WARNING DRV_NAME
6524 "Error calling pci_set_dma_mask.\n");
6525 pci_disable_device(pci_dev);
6526 return err;
6527 }
6528
6529 err = pci_request_regions(pci_dev, DRV_NAME);
6530 if (err) {
6531 printk(KERN_WARNING DRV_NAME
6532 "Error calling pci_request_regions.\n");
6533 pci_disable_device(pci_dev);
6534 return err;
6535 }
6536
6537 /* We disable the RETRY_TIMEOUT register (0x41) to keep
6538 * PCI Tx retries from interfering with C3 CPU state */
6539 pci_read_config_dword(pci_dev, 0x40, &val);
6540 if ((val & 0x0000ff00) != 0)
6541 pci_write_config_dword(pci_dev, 0x40, val & 0xffff00ff);
6542
8724a118 6543 pci_set_power_state(pci_dev, PCI_D0);
2c86c275
JK
6544
6545 if (!ipw2100_hw_is_adapter_in_system(dev)) {
6546 printk(KERN_WARNING DRV_NAME
6547 "Device not found via register read.\n");
6548 err = -ENODEV;
6549 goto fail;
6550 }
6551
6552 SET_NETDEV_DEV(dev, &pci_dev->dev);
6553
6554 /* Force interrupts to be shut off on the device */
6555 priv->status |= STATUS_INT_ENABLED;
6556 ipw2100_disable_interrupts(priv);
6557
6558 /* Allocate and initialize the Tx/Rx queues and lists */
6559 if (ipw2100_queues_allocate(priv)) {
6560 printk(KERN_WARNING DRV_NAME
6561 "Error calilng ipw2100_queues_allocate.\n");
6562 err = -ENOMEM;
6563 goto fail;
6564 }
6565 ipw2100_queues_initialize(priv);
6566
6567 err = request_irq(pci_dev->irq,
6568 ipw2100_interrupt, SA_SHIRQ,
6569 dev->name, priv);
6570 if (err) {
6571 printk(KERN_WARNING DRV_NAME
6572 "Error calling request_irq: %d.\n",
6573 pci_dev->irq);
6574 goto fail;
6575 }
6576 dev->irq = pci_dev->irq;
6577
6578 IPW_DEBUG_INFO("Attempting to register device...\n");
6579
6580 SET_MODULE_OWNER(dev);
6581
6582 printk(KERN_INFO DRV_NAME
6583 ": Detected Intel PRO/Wireless 2100 Network Connection\n");
6584
6585 /* Bring up the interface. Pre 0.46, after we registered the
6586 * network device we would call ipw2100_up. This introduced a race
6587 * condition with newer hotplug configurations (network was coming
6588 * up and making calls before the device was initialized).
6589 *
6590 * If we called ipw2100_up before we registered the device, then the
6591 * device name wasn't registered. So, we instead use the net_dev->init
6592 * member to call a function that then just turns and calls ipw2100_up.
6593 * net_dev->init is called after name allocation but before the
6594 * notifier chain is called */
6595 down(&priv->action_sem);
6596 err = register_netdev(dev);
6597 if (err) {
6598 printk(KERN_WARNING DRV_NAME
6599 "Error calling register_netdev.\n");
6600 goto fail_unlock;
6601 }
6602 registered = 1;
6603
6604 IPW_DEBUG_INFO("%s: Bound to %s\n", dev->name, pci_name(pci_dev));
6605
6606 /* perform this after register_netdev so that dev->name is set */
6607 sysfs_create_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
6608 netif_carrier_off(dev);
6609
6610 /* If the RF Kill switch is disabled, go ahead and complete the
6611 * startup sequence */
6612 if (!(priv->status & STATUS_RF_KILL_MASK)) {
6613 /* Enable the adapter - sends HOST_COMPLETE */
6614 if (ipw2100_enable_adapter(priv)) {
6615 printk(KERN_WARNING DRV_NAME
6616 ": %s: failed in call to enable adapter.\n",
6617 priv->net_dev->name);
6618 ipw2100_hw_stop_adapter(priv);
6619 err = -EIO;
6620 goto fail_unlock;
6621 }
6622
6623 /* Start a scan . . . */
6624 ipw2100_set_scan_options(priv);
6625 ipw2100_start_scan(priv);
6626 }
6627
6628 IPW_DEBUG_INFO("exit\n");
6629
6630 priv->status |= STATUS_INITIALIZED;
6631
6632 up(&priv->action_sem);
6633
6634 return 0;
6635
6636 fail_unlock:
6637 up(&priv->action_sem);
6638
6639 fail:
6640 if (dev) {
6641 if (registered)
6642 unregister_netdev(dev);
6643
6644 ipw2100_hw_stop_adapter(priv);
6645
6646 ipw2100_disable_interrupts(priv);
6647
6648 if (dev->irq)
6649 free_irq(dev->irq, priv);
6650
6651 ipw2100_kill_workqueue(priv);
6652
6653 /* These are safe to call even if they weren't allocated */
6654 ipw2100_queues_free(priv);
6655 sysfs_remove_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
6656
6657 free_ieee80211(dev);
6658 pci_set_drvdata(pci_dev, NULL);
6659 }
6660
6661 if (base_addr)
2be041a7 6662 iounmap(base_addr);
2c86c275
JK
6663
6664 pci_release_regions(pci_dev);
6665 pci_disable_device(pci_dev);
6666
6667 return err;
6668}
6669
6670static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
6671{
6672 struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
6673 struct net_device *dev;
6674
6675 if (priv) {
6676 down(&priv->action_sem);
6677
6678 priv->status &= ~STATUS_INITIALIZED;
6679
6680 dev = priv->net_dev;
6681 sysfs_remove_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
6682
6683#ifdef CONFIG_PM
6684 if (ipw2100_firmware.version)
6685 ipw2100_release_firmware(priv, &ipw2100_firmware);
6686#endif
6687 /* Take down the hardware */
6688 ipw2100_down(priv);
6689
6690 /* Release the semaphore so that the network subsystem can
6691 * complete any needed calls into the driver... */
6692 up(&priv->action_sem);
6693
6694 /* Unregister the device first - this results in close()
6695 * being called if the device is open. If we free storage
6696 * first, then close() will crash. */
6697 unregister_netdev(dev);
6698
6699 /* ipw2100_down will ensure that there is no more pending work
6700 * in the workqueue's, so we can safely remove them now. */
6701 ipw2100_kill_workqueue(priv);
6702
6703 ipw2100_queues_free(priv);
6704
6705 /* Free potential debugging firmware snapshot */
6706 ipw2100_snapshot_free(priv);
6707
6708 if (dev->irq)
6709 free_irq(dev->irq, priv);
6710
6711 if (dev->base_addr)
2be041a7 6712 iounmap((void __iomem *)dev->base_addr);
2c86c275
JK
6713
6714 free_ieee80211(dev);
6715 }
6716
6717 pci_release_regions(pci_dev);
6718 pci_disable_device(pci_dev);
6719
6720 IPW_DEBUG_INFO("exit\n");
6721}
6722
6723
6724#ifdef CONFIG_PM
6725#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
6726static int ipw2100_suspend(struct pci_dev *pci_dev, u32 state)
6727#else
6728static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
6729#endif
6730{
6731 struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
6732 struct net_device *dev = priv->net_dev;
6733
6734 IPW_DEBUG_INFO("%s: Going into suspend...\n",
6735 dev->name);
6736
6737 down(&priv->action_sem);
6738 if (priv->status & STATUS_INITIALIZED) {
6739 /* Take down the device; powers it off, etc. */
6740 ipw2100_down(priv);
6741 }
6742
6743 /* Remove the PRESENT state of the device */
6744 netif_device_detach(dev);
6745
2c86c275 6746 pci_save_state(pci_dev);
2c86c275 6747 pci_disable_device (pci_dev);
2c86c275 6748 pci_set_power_state(pci_dev, PCI_D3hot);
2c86c275
JK
6749
6750 up(&priv->action_sem);
6751
6752 return 0;
6753}
6754
6755static int ipw2100_resume(struct pci_dev *pci_dev)
6756{
6757 struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
6758 struct net_device *dev = priv->net_dev;
6759 u32 val;
6760
6761 if (IPW2100_PM_DISABLED)
6762 return 0;
6763
6764 down(&priv->action_sem);
6765
6766 IPW_DEBUG_INFO("%s: Coming out of suspend...\n",
6767 dev->name);
6768
2c86c275 6769 pci_set_power_state(pci_dev, PCI_D0);
2c86c275 6770 pci_enable_device(pci_dev);
2c86c275 6771 pci_restore_state(pci_dev);
2c86c275
JK
6772
6773 /*
6774 * Suspend/Resume resets the PCI configuration space, so we have to
6775 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
6776 * from interfering with C3 CPU state. pci_restore_state won't help
6777 * here since it only restores the first 64 bytes pci config header.
6778 */
6779 pci_read_config_dword(pci_dev, 0x40, &val);
6780 if ((val & 0x0000ff00) != 0)
6781 pci_write_config_dword(pci_dev, 0x40, val & 0xffff00ff);
6782
6783 /* Set the device back into the PRESENT state; this will also wake
6784 * the queue of needed */
6785 netif_device_attach(dev);
6786
6787 /* Bring the device back up */
6788 if (!(priv->status & STATUS_RF_KILL_SW))
6789 ipw2100_up(priv, 0);
6790
6791 up(&priv->action_sem);
6792
6793 return 0;
6794}
6795#endif
6796
6797
6798#define IPW2100_DEV_ID(x) { PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, x }
6799
6800static struct pci_device_id ipw2100_pci_id_table[] __devinitdata = {
6801 IPW2100_DEV_ID(0x2520), /* IN 2100A mPCI 3A */
6802 IPW2100_DEV_ID(0x2521), /* IN 2100A mPCI 3B */
6803 IPW2100_DEV_ID(0x2524), /* IN 2100A mPCI 3B */
6804 IPW2100_DEV_ID(0x2525), /* IN 2100A mPCI 3B */
6805 IPW2100_DEV_ID(0x2526), /* IN 2100A mPCI Gen A3 */
6806 IPW2100_DEV_ID(0x2522), /* IN 2100 mPCI 3B */
6807 IPW2100_DEV_ID(0x2523), /* IN 2100 mPCI 3A */
6808 IPW2100_DEV_ID(0x2527), /* IN 2100 mPCI 3B */
6809 IPW2100_DEV_ID(0x2528), /* IN 2100 mPCI 3B */
6810 IPW2100_DEV_ID(0x2529), /* IN 2100 mPCI 3B */
6811 IPW2100_DEV_ID(0x252B), /* IN 2100 mPCI 3A */
6812 IPW2100_DEV_ID(0x252C), /* IN 2100 mPCI 3A */
6813 IPW2100_DEV_ID(0x252D), /* IN 2100 mPCI 3A */
6814
6815 IPW2100_DEV_ID(0x2550), /* IB 2100A mPCI 3B */
6816 IPW2100_DEV_ID(0x2551), /* IB 2100 mPCI 3B */
6817 IPW2100_DEV_ID(0x2553), /* IB 2100 mPCI 3B */
6818 IPW2100_DEV_ID(0x2554), /* IB 2100 mPCI 3B */
6819 IPW2100_DEV_ID(0x2555), /* IB 2100 mPCI 3B */
6820
6821 IPW2100_DEV_ID(0x2560), /* DE 2100A mPCI 3A */
6822 IPW2100_DEV_ID(0x2562), /* DE 2100A mPCI 3A */
6823 IPW2100_DEV_ID(0x2563), /* DE 2100A mPCI 3A */
6824 IPW2100_DEV_ID(0x2561), /* DE 2100 mPCI 3A */
6825 IPW2100_DEV_ID(0x2565), /* DE 2100 mPCI 3A */
6826 IPW2100_DEV_ID(0x2566), /* DE 2100 mPCI 3A */
6827 IPW2100_DEV_ID(0x2567), /* DE 2100 mPCI 3A */
6828
6829 IPW2100_DEV_ID(0x2570), /* GA 2100 mPCI 3B */
6830
6831 IPW2100_DEV_ID(0x2580), /* TO 2100A mPCI 3B */
6832 IPW2100_DEV_ID(0x2582), /* TO 2100A mPCI 3B */
6833 IPW2100_DEV_ID(0x2583), /* TO 2100A mPCI 3B */
6834 IPW2100_DEV_ID(0x2581), /* TO 2100 mPCI 3B */
6835 IPW2100_DEV_ID(0x2585), /* TO 2100 mPCI 3B */
6836 IPW2100_DEV_ID(0x2586), /* TO 2100 mPCI 3B */
6837 IPW2100_DEV_ID(0x2587), /* TO 2100 mPCI 3B */
6838
6839 IPW2100_DEV_ID(0x2590), /* SO 2100A mPCI 3B */
6840 IPW2100_DEV_ID(0x2592), /* SO 2100A mPCI 3B */
6841 IPW2100_DEV_ID(0x2591), /* SO 2100 mPCI 3B */
6842 IPW2100_DEV_ID(0x2593), /* SO 2100 mPCI 3B */
6843 IPW2100_DEV_ID(0x2596), /* SO 2100 mPCI 3B */
6844 IPW2100_DEV_ID(0x2598), /* SO 2100 mPCI 3B */
6845
6846 IPW2100_DEV_ID(0x25A0), /* HP 2100 mPCI 3B */
6847 {0,},
6848};
6849
6850MODULE_DEVICE_TABLE(pci, ipw2100_pci_id_table);
6851
6852static struct pci_driver ipw2100_pci_driver = {
6853 .name = DRV_NAME,
6854 .id_table = ipw2100_pci_id_table,
6855 .probe = ipw2100_pci_init_one,
6856 .remove = __devexit_p(ipw2100_pci_remove_one),
6857#ifdef CONFIG_PM
6858 .suspend = ipw2100_suspend,
6859 .resume = ipw2100_resume,
6860#endif
6861};
6862
6863
6864/**
6865 * Initialize the ipw2100 driver/module
6866 *
6867 * @returns 0 if ok, < 0 errno node con error.
6868 *
6869 * Note: we cannot init the /proc stuff until the PCI driver is there,
6870 * or we risk an unlikely race condition on someone accessing
6871 * uninitialized data in the PCI dev struct through /proc.
6872 */
6873static int __init ipw2100_init(void)
6874{
6875 int ret;
6876
6877 printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
6878 printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT);
6879
6880#ifdef CONFIG_IEEE80211_NOWEP
6881 IPW_DEBUG_INFO(DRV_NAME ": Compiled with WEP disabled.\n");
6882#endif
6883
6884 ret = pci_module_init(&ipw2100_pci_driver);
6885
6886#ifdef CONFIG_IPW_DEBUG
6887 ipw2100_debug_level = debug;
6888 driver_create_file(&ipw2100_pci_driver.driver,
6889 &driver_attr_debug_level);
6890#endif
6891
6892 return ret;
6893}
6894
6895
6896/**
6897 * Cleanup ipw2100 driver registration
6898 */
6899static void __exit ipw2100_exit(void)
6900{
6901 /* FIXME: IPG: check that we have no instances of the devices open */
6902#ifdef CONFIG_IPW_DEBUG
6903 driver_remove_file(&ipw2100_pci_driver.driver,
6904 &driver_attr_debug_level);
6905#endif
6906 pci_unregister_driver(&ipw2100_pci_driver);
6907}
6908
6909module_init(ipw2100_init);
6910module_exit(ipw2100_exit);
6911
6912#define WEXT_USECHANNELS 1
6913
c4aee8c2 6914static const long ipw2100_frequencies[] = {
2c86c275
JK
6915 2412, 2417, 2422, 2427,
6916 2432, 2437, 2442, 2447,
6917 2452, 2457, 2462, 2467,
6918 2472, 2484
6919};
6920
6921#define FREQ_COUNT (sizeof(ipw2100_frequencies) / \
6922 sizeof(ipw2100_frequencies[0]))
6923
c4aee8c2 6924static const long ipw2100_rates_11b[] = {
2c86c275
JK
6925 1000000,
6926 2000000,
6927 5500000,
6928 11000000
6929};
6930
6931#define RATE_COUNT (sizeof(ipw2100_rates_11b) / sizeof(ipw2100_rates_11b[0]))
6932
6933static int ipw2100_wx_get_name(struct net_device *dev,
6934 struct iw_request_info *info,
6935 union iwreq_data *wrqu, char *extra)
6936{
6937 /*
6938 * This can be called at any time. No action lock required
6939 */
6940
6941 struct ipw2100_priv *priv = ieee80211_priv(dev);
6942 if (!(priv->status & STATUS_ASSOCIATED))
6943 strcpy(wrqu->name, "unassociated");
6944 else
6945 snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");
6946
6947 IPW_DEBUG_WX("Name: %s\n", wrqu->name);
6948 return 0;
6949}
6950
6951
6952static int ipw2100_wx_set_freq(struct net_device *dev,
6953 struct iw_request_info *info,
6954 union iwreq_data *wrqu, char *extra)
6955{
6956 struct ipw2100_priv *priv = ieee80211_priv(dev);
6957 struct iw_freq *fwrq = &wrqu->freq;
6958 int err = 0;
6959
6960 if (priv->ieee->iw_mode == IW_MODE_INFRA)
6961 return -EOPNOTSUPP;
6962
6963 down(&priv->action_sem);
6964 if (!(priv->status & STATUS_INITIALIZED)) {
6965 err = -EIO;
6966 goto done;
6967 }
6968
6969 /* if setting by freq convert to channel */
6970 if (fwrq->e == 1) {
6971 if ((fwrq->m >= (int) 2.412e8 &&
6972 fwrq->m <= (int) 2.487e8)) {
6973 int f = fwrq->m / 100000;
6974 int c = 0;
6975
6976 while ((c < REG_MAX_CHANNEL) &&
6977 (f != ipw2100_frequencies[c]))
6978 c++;
6979
6980 /* hack to fall through */
6981 fwrq->e = 0;
6982 fwrq->m = c + 1;
6983 }
6984 }
6985
6986 if (fwrq->e > 0 || fwrq->m > 1000)
6987 return -EOPNOTSUPP;
6988 else { /* Set the channel */
6989 IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
6990 err = ipw2100_set_channel(priv, fwrq->m, 0);
6991 }
6992
6993 done:
6994 up(&priv->action_sem);
6995 return err;
6996}
6997
6998
6999static int ipw2100_wx_get_freq(struct net_device *dev,
7000 struct iw_request_info *info,
7001 union iwreq_data *wrqu, char *extra)
7002{
7003 /*
7004 * This can be called at any time. No action lock required
7005 */
7006
7007 struct ipw2100_priv *priv = ieee80211_priv(dev);
7008
7009 wrqu->freq.e = 0;
7010
7011 /* If we are associated, trying to associate, or have a statically
7012 * configured CHANNEL then return that; otherwise return ANY */
7013 if (priv->config & CFG_STATIC_CHANNEL ||
7014 priv->status & STATUS_ASSOCIATED)
7015 wrqu->freq.m = priv->channel;
7016 else
7017 wrqu->freq.m = 0;
7018
7019 IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel);
7020 return 0;
7021
7022}
7023
7024static int ipw2100_wx_set_mode(struct net_device *dev,
7025 struct iw_request_info *info,
7026 union iwreq_data *wrqu, char *extra)
7027{
7028 struct ipw2100_priv *priv = ieee80211_priv(dev);
7029 int err = 0;
7030
7031 IPW_DEBUG_WX("SET Mode -> %d \n", wrqu->mode);
7032
7033 if (wrqu->mode == priv->ieee->iw_mode)
7034 return 0;
7035
7036 down(&priv->action_sem);
7037 if (!(priv->status & STATUS_INITIALIZED)) {
7038 err = -EIO;
7039 goto done;
7040 }
7041
7042 switch (wrqu->mode) {
7043#ifdef CONFIG_IPW2100_MONITOR
7044 case IW_MODE_MONITOR:
7045 err = ipw2100_switch_mode(priv, IW_MODE_MONITOR);
7046 break;
7047#endif /* CONFIG_IPW2100_MONITOR */
7048 case IW_MODE_ADHOC:
7049 err = ipw2100_switch_mode(priv, IW_MODE_ADHOC);
7050 break;
7051 case IW_MODE_INFRA:
7052 case IW_MODE_AUTO:
7053 default:
7054 err = ipw2100_switch_mode(priv, IW_MODE_INFRA);
7055 break;
7056 }
7057
7058done:
7059 up(&priv->action_sem);
7060 return err;
7061}
7062
7063static int ipw2100_wx_get_mode(struct net_device *dev,
7064 struct iw_request_info *info,
7065 union iwreq_data *wrqu, char *extra)
7066{
7067 /*
7068 * This can be called at any time. No action lock required
7069 */
7070
7071 struct ipw2100_priv *priv = ieee80211_priv(dev);
7072
7073 wrqu->mode = priv->ieee->iw_mode;
7074 IPW_DEBUG_WX("GET Mode -> %d\n", wrqu->mode);
7075
7076 return 0;
7077}
7078
7079
7080#define POWER_MODES 5
7081
7082/* Values are in microsecond */
c4aee8c2 7083static const s32 timeout_duration[POWER_MODES] = {
2c86c275
JK
7084 350000,
7085 250000,
7086 75000,
7087 37000,
7088 25000,
7089};
7090
c4aee8c2 7091static const s32 period_duration[POWER_MODES] = {
2c86c275
JK
7092 400000,
7093 700000,
7094 1000000,
7095 1000000,
7096 1000000
7097};
7098
7099static int ipw2100_wx_get_range(struct net_device *dev,
7100 struct iw_request_info *info,
7101 union iwreq_data *wrqu, char *extra)
7102{
7103 /*
7104 * This can be called at any time. No action lock required
7105 */
7106
7107 struct ipw2100_priv *priv = ieee80211_priv(dev);
7108 struct iw_range *range = (struct iw_range *)extra;
7109 u16 val;
7110 int i, level;
7111
7112 wrqu->data.length = sizeof(*range);
7113 memset(range, 0, sizeof(*range));
7114
7115 /* Let's try to keep this struct in the same order as in
7116 * linux/include/wireless.h
7117 */
7118
7119 /* TODO: See what values we can set, and remove the ones we can't
7120 * set, or fill them with some default data.
7121 */
7122
7123 /* ~5 Mb/s real (802.11b) */
7124 range->throughput = 5 * 1000 * 1000;
7125
7126// range->sensitivity; /* signal level threshold range */
7127
7128 range->max_qual.qual = 100;
7129 /* TODO: Find real max RSSI and stick here */
7130 range->max_qual.level = 0;
7131 range->max_qual.noise = 0;
7132 range->max_qual.updated = 7; /* Updated all three */
7133
7134 range->avg_qual.qual = 70; /* > 8% missed beacons is 'bad' */
7135 /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
7136 range->avg_qual.level = 20 + IPW2100_RSSI_TO_DBM;
7137 range->avg_qual.noise = 0;
7138 range->avg_qual.updated = 7; /* Updated all three */
7139
7140 range->num_bitrates = RATE_COUNT;
7141
7142 for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
7143 range->bitrate[i] = ipw2100_rates_11b[i];
7144 }
7145
7146 range->min_rts = MIN_RTS_THRESHOLD;
7147 range->max_rts = MAX_RTS_THRESHOLD;
7148 range->min_frag = MIN_FRAG_THRESHOLD;
7149 range->max_frag = MAX_FRAG_THRESHOLD;
7150
7151 range->min_pmp = period_duration[0]; /* Minimal PM period */
7152 range->max_pmp = period_duration[POWER_MODES-1];/* Maximal PM period */
7153 range->min_pmt = timeout_duration[POWER_MODES-1]; /* Minimal PM timeout */
7154 range->max_pmt = timeout_duration[0];/* Maximal PM timeout */
7155
7156 /* How to decode max/min PM period */
7157 range->pmp_flags = IW_POWER_PERIOD;
7158 /* How to decode max/min PM period */
7159 range->pmt_flags = IW_POWER_TIMEOUT;
7160 /* What PM options are supported */
7161 range->pm_capa = IW_POWER_TIMEOUT | IW_POWER_PERIOD;
7162
7163 range->encoding_size[0] = 5;
7164 range->encoding_size[1] = 13; /* Different token sizes */
7165 range->num_encoding_sizes = 2; /* Number of entry in the list */
7166 range->max_encoding_tokens = WEP_KEYS; /* Max number of tokens */
7167// range->encoding_login_index; /* token index for login token */
7168
7169 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
7170 range->txpower_capa = IW_TXPOW_DBM;
7171 range->num_txpower = IW_MAX_TXPOWER;
7172 for (i = 0, level = (IPW_TX_POWER_MAX_DBM * 16); i < IW_MAX_TXPOWER;
7173 i++, level -= ((IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM) * 16) /
7174 (IW_MAX_TXPOWER - 1))
7175 range->txpower[i] = level / 16;
7176 } else {
7177 range->txpower_capa = 0;
7178 range->num_txpower = 0;
7179 }
7180
7181
7182 /* Set the Wireless Extension versions */
7183 range->we_version_compiled = WIRELESS_EXT;
7184 range->we_version_source = 16;
7185
7186// range->retry_capa; /* What retry options are supported */
7187// range->retry_flags; /* How to decode max/min retry limit */
7188// range->r_time_flags; /* How to decode max/min retry life */
7189// range->min_retry; /* Minimal number of retries */
7190// range->max_retry; /* Maximal number of retries */
7191// range->min_r_time; /* Minimal retry lifetime */
7192// range->max_r_time; /* Maximal retry lifetime */
7193
7194 range->num_channels = FREQ_COUNT;
7195
7196 val = 0;
7197 for (i = 0; i < FREQ_COUNT; i++) {
7198 // TODO: Include only legal frequencies for some countries
7199// if (local->channel_mask & (1 << i)) {
7200 range->freq[val].i = i + 1;
7201 range->freq[val].m = ipw2100_frequencies[i] * 100000;
7202 range->freq[val].e = 1;
7203 val++;
7204// }
7205 if (val == IW_MAX_FREQUENCIES)
7206 break;
7207 }
7208 range->num_frequency = val;
7209
7210 IPW_DEBUG_WX("GET Range\n");
7211
7212 return 0;
7213}
7214
7215static int ipw2100_wx_set_wap(struct net_device *dev,
7216 struct iw_request_info *info,
7217 union iwreq_data *wrqu, char *extra)
7218{
7219 struct ipw2100_priv *priv = ieee80211_priv(dev);
7220 int err = 0;
7221
7222 static const unsigned char any[] = {
7223 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
7224 };
7225 static const unsigned char off[] = {
7226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
7227 };
7228
7229 // sanity checks
7230 if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
7231 return -EINVAL;
7232
7233 down(&priv->action_sem);
7234 if (!(priv->status & STATUS_INITIALIZED)) {
7235 err = -EIO;
7236 goto done;
7237 }
7238
7239 if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) ||
7240 !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) {
7241 /* we disable mandatory BSSID association */
7242 IPW_DEBUG_WX("exit - disable mandatory BSSID\n");
7243 priv->config &= ~CFG_STATIC_BSSID;
7244 err = ipw2100_set_mandatory_bssid(priv, NULL, 0);
7245 goto done;
7246 }
7247
7248 priv->config |= CFG_STATIC_BSSID;
7249 memcpy(priv->mandatory_bssid_mac, wrqu->ap_addr.sa_data, ETH_ALEN);
7250
7251 err = ipw2100_set_mandatory_bssid(priv, wrqu->ap_addr.sa_data, 0);
7252
7253 IPW_DEBUG_WX("SET BSSID -> %02X:%02X:%02X:%02X:%02X:%02X\n",
7254 wrqu->ap_addr.sa_data[0] & 0xff,
7255 wrqu->ap_addr.sa_data[1] & 0xff,
7256 wrqu->ap_addr.sa_data[2] & 0xff,
7257 wrqu->ap_addr.sa_data[3] & 0xff,
7258 wrqu->ap_addr.sa_data[4] & 0xff,
7259 wrqu->ap_addr.sa_data[5] & 0xff);
7260
7261 done:
7262 up(&priv->action_sem);
7263 return err;
7264}
7265
7266static int ipw2100_wx_get_wap(struct net_device *dev,
7267 struct iw_request_info *info,
7268 union iwreq_data *wrqu, char *extra)
7269{
7270 /*
7271 * This can be called at any time. No action lock required
7272 */
7273
7274 struct ipw2100_priv *priv = ieee80211_priv(dev);
7275
7276 /* If we are associated, trying to associate, or have a statically
7277 * configured BSSID then return that; otherwise return ANY */
7278 if (priv->config & CFG_STATIC_BSSID ||
7279 priv->status & STATUS_ASSOCIATED) {
7280 wrqu->ap_addr.sa_family = ARPHRD_ETHER;
7281 memcpy(wrqu->ap_addr.sa_data, &priv->bssid, ETH_ALEN);
7282 } else
7283 memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
7284
7285 IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n",
7286 MAC_ARG(wrqu->ap_addr.sa_data));
7287 return 0;
7288}
7289
7290static int ipw2100_wx_set_essid(struct net_device *dev,
7291 struct iw_request_info *info,
7292 union iwreq_data *wrqu, char *extra)
7293{
7294 struct ipw2100_priv *priv = ieee80211_priv(dev);
7295 char *essid = ""; /* ANY */
7296 int length = 0;
7297 int err = 0;
7298
7299 down(&priv->action_sem);
7300 if (!(priv->status & STATUS_INITIALIZED)) {
7301 err = -EIO;
7302 goto done;
7303 }
7304
7305 if (wrqu->essid.flags && wrqu->essid.length) {
7306 length = wrqu->essid.length - 1;
7307 essid = extra;
7308 }
7309
7310 if (length == 0) {
7311 IPW_DEBUG_WX("Setting ESSID to ANY\n");
7312 priv->config &= ~CFG_STATIC_ESSID;
7313 err = ipw2100_set_essid(priv, NULL, 0, 0);
7314 goto done;
7315 }
7316
7317 length = min(length, IW_ESSID_MAX_SIZE);
7318
7319 priv->config |= CFG_STATIC_ESSID;
7320
7321 if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) {
7322 IPW_DEBUG_WX("ESSID set to current ESSID.\n");
7323 err = 0;
7324 goto done;
7325 }
7326
7327 IPW_DEBUG_WX("Setting ESSID: '%s' (%d)\n", escape_essid(essid, length),
7328 length);
7329
7330 priv->essid_len = length;
7331 memcpy(priv->essid, essid, priv->essid_len);
7332
7333 err = ipw2100_set_essid(priv, essid, length, 0);
7334
7335 done:
7336 up(&priv->action_sem);
7337 return err;
7338}
7339
7340static int ipw2100_wx_get_essid(struct net_device *dev,
7341 struct iw_request_info *info,
7342 union iwreq_data *wrqu, char *extra)
7343{
7344 /*
7345 * This can be called at any time. No action lock required
7346 */
7347
7348 struct ipw2100_priv *priv = ieee80211_priv(dev);
7349
7350 /* If we are associated, trying to associate, or have a statically
7351 * configured ESSID then return that; otherwise return ANY */
7352 if (priv->config & CFG_STATIC_ESSID ||
7353 priv->status & STATUS_ASSOCIATED) {
7354 IPW_DEBUG_WX("Getting essid: '%s'\n",
7355 escape_essid(priv->essid, priv->essid_len));
7356 memcpy(extra, priv->essid, priv->essid_len);
7357 wrqu->essid.length = priv->essid_len;
7358 wrqu->essid.flags = 1; /* active */
7359 } else {
7360 IPW_DEBUG_WX("Getting essid: ANY\n");
7361 wrqu->essid.length = 0;
7362 wrqu->essid.flags = 0; /* active */
7363 }
7364
7365 return 0;
7366}
7367
7368static int ipw2100_wx_set_nick(struct net_device *dev,
7369 struct iw_request_info *info,
7370 union iwreq_data *wrqu, char *extra)
7371{
7372 /*
7373 * This can be called at any time. No action lock required
7374 */
7375
7376 struct ipw2100_priv *priv = ieee80211_priv(dev);
7377
7378 if (wrqu->data.length > IW_ESSID_MAX_SIZE)
7379 return -E2BIG;
7380
7381 wrqu->data.length = min((size_t)wrqu->data.length, sizeof(priv->nick));
7382 memset(priv->nick, 0, sizeof(priv->nick));
7383 memcpy(priv->nick, extra, wrqu->data.length);
7384
7385 IPW_DEBUG_WX("SET Nickname -> %s \n", priv->nick);
7386
7387 return 0;
7388}
7389
7390static int ipw2100_wx_get_nick(struct net_device *dev,
7391 struct iw_request_info *info,
7392 union iwreq_data *wrqu, char *extra)
7393{
7394 /*
7395 * This can be called at any time. No action lock required
7396 */
7397
7398 struct ipw2100_priv *priv = ieee80211_priv(dev);
7399
7400 wrqu->data.length = strlen(priv->nick) + 1;
7401 memcpy(extra, priv->nick, wrqu->data.length);
7402 wrqu->data.flags = 1; /* active */
7403
7404 IPW_DEBUG_WX("GET Nickname -> %s \n", extra);
7405
7406 return 0;
7407}
7408
7409static int ipw2100_wx_set_rate(struct net_device *dev,
7410 struct iw_request_info *info,
7411 union iwreq_data *wrqu, char *extra)
7412{
7413 struct ipw2100_priv *priv = ieee80211_priv(dev);
7414 u32 target_rate = wrqu->bitrate.value;
7415 u32 rate;
7416 int err = 0;
7417
7418 down(&priv->action_sem);
7419 if (!(priv->status & STATUS_INITIALIZED)) {
7420 err = -EIO;
7421 goto done;
7422 }
7423
7424 rate = 0;
7425
7426 if (target_rate == 1000000 ||
7427 (!wrqu->bitrate.fixed && target_rate > 1000000))
7428 rate |= TX_RATE_1_MBIT;
7429 if (target_rate == 2000000 ||
7430 (!wrqu->bitrate.fixed && target_rate > 2000000))
7431 rate |= TX_RATE_2_MBIT;
7432 if (target_rate == 5500000 ||
7433 (!wrqu->bitrate.fixed && target_rate > 5500000))
7434 rate |= TX_RATE_5_5_MBIT;
7435 if (target_rate == 11000000 ||
7436 (!wrqu->bitrate.fixed && target_rate > 11000000))
7437 rate |= TX_RATE_11_MBIT;
7438 if (rate == 0)
7439 rate = DEFAULT_TX_RATES;
7440
7441 err = ipw2100_set_tx_rates(priv, rate, 0);
7442
7443 IPW_DEBUG_WX("SET Rate -> %04X \n", rate);
7444 done:
7445 up(&priv->action_sem);
7446 return err;
7447}
7448
7449
7450static int ipw2100_wx_get_rate(struct net_device *dev,
7451 struct iw_request_info *info,
7452 union iwreq_data *wrqu, char *extra)
7453{
7454 struct ipw2100_priv *priv = ieee80211_priv(dev);
7455 int val;
7456 int len = sizeof(val);
7457 int err = 0;
7458
7459 if (!(priv->status & STATUS_ENABLED) ||
7460 priv->status & STATUS_RF_KILL_MASK ||
7461 !(priv->status & STATUS_ASSOCIATED)) {
7462 wrqu->bitrate.value = 0;
7463 return 0;
7464 }
7465
7466 down(&priv->action_sem);
7467 if (!(priv->status & STATUS_INITIALIZED)) {
7468 err = -EIO;
7469 goto done;
7470 }
7471
7472 err = ipw2100_get_ordinal(priv, IPW_ORD_CURRENT_TX_RATE, &val, &len);
7473 if (err) {
7474 IPW_DEBUG_WX("failed querying ordinals.\n");
7475 return err;
7476 }
7477
7478 switch (val & TX_RATE_MASK) {
7479 case TX_RATE_1_MBIT:
7480 wrqu->bitrate.value = 1000000;
7481 break;
7482 case TX_RATE_2_MBIT:
7483 wrqu->bitrate.value = 2000000;
7484 break;
7485 case TX_RATE_5_5_MBIT:
7486 wrqu->bitrate.value = 5500000;
7487 break;
7488 case TX_RATE_11_MBIT:
7489 wrqu->bitrate.value = 11000000;
7490 break;
7491 default:
7492 wrqu->bitrate.value = 0;
7493 }
7494
7495 IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
7496
7497 done:
7498 up(&priv->action_sem);
7499 return err;
7500}
7501
7502static int ipw2100_wx_set_rts(struct net_device *dev,
7503 struct iw_request_info *info,
7504 union iwreq_data *wrqu, char *extra)
7505{
7506 struct ipw2100_priv *priv = ieee80211_priv(dev);
7507 int value, err;
7508
7509 /* Auto RTS not yet supported */
7510 if (wrqu->rts.fixed == 0)
7511 return -EINVAL;
7512
7513 down(&priv->action_sem);
7514 if (!(priv->status & STATUS_INITIALIZED)) {
7515 err = -EIO;
7516 goto done;
7517 }
7518
7519 if (wrqu->rts.disabled)
7520 value = priv->rts_threshold | RTS_DISABLED;
7521 else {
7522 if (wrqu->rts.value < 1 ||
7523 wrqu->rts.value > 2304) {
7524 err = -EINVAL;
7525 goto done;
7526 }
7527 value = wrqu->rts.value;
7528 }
7529
7530 err = ipw2100_set_rts_threshold(priv, value);
7531
7532 IPW_DEBUG_WX("SET RTS Threshold -> 0x%08X \n", value);
7533 done:
7534 up(&priv->action_sem);
7535 return err;
7536}
7537
7538static int ipw2100_wx_get_rts(struct net_device *dev,
7539 struct iw_request_info *info,
7540 union iwreq_data *wrqu, char *extra)
7541{
7542 /*
7543 * This can be called at any time. No action lock required
7544 */
7545
7546 struct ipw2100_priv *priv = ieee80211_priv(dev);
7547
7548 wrqu->rts.value = priv->rts_threshold & ~RTS_DISABLED;
7549 wrqu->rts.fixed = 1; /* no auto select */
7550
7551 /* If RTS is set to the default value, then it is disabled */
7552 wrqu->rts.disabled = (priv->rts_threshold & RTS_DISABLED) ? 1 : 0;
7553
7554 IPW_DEBUG_WX("GET RTS Threshold -> 0x%08X \n", wrqu->rts.value);
7555
7556 return 0;
7557}
7558
7559static int ipw2100_wx_set_txpow(struct net_device *dev,
7560 struct iw_request_info *info,
7561 union iwreq_data *wrqu, char *extra)
7562{
7563 struct ipw2100_priv *priv = ieee80211_priv(dev);
7564 int err = 0, value;
7565
7566 if (priv->ieee->iw_mode != IW_MODE_ADHOC)
7567 return -EINVAL;
7568
7569 if (wrqu->txpower.disabled == 1 || wrqu->txpower.fixed == 0)
7570 value = IPW_TX_POWER_DEFAULT;
7571 else {
7572 if (wrqu->txpower.value < IPW_TX_POWER_MIN_DBM ||
7573 wrqu->txpower.value > IPW_TX_POWER_MAX_DBM)
7574 return -EINVAL;
7575
7576 value = (wrqu->txpower.value - IPW_TX_POWER_MIN_DBM) * 16 /
7577 (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM);
7578 }
7579
7580 down(&priv->action_sem);
7581 if (!(priv->status & STATUS_INITIALIZED)) {
7582 err = -EIO;
7583 goto done;
7584 }
7585
7586 err = ipw2100_set_tx_power(priv, value);
7587
7588 IPW_DEBUG_WX("SET TX Power -> %d \n", value);
7589
7590 done:
7591 up(&priv->action_sem);
7592 return err;
7593}
7594
7595static int ipw2100_wx_get_txpow(struct net_device *dev,
7596 struct iw_request_info *info,
7597 union iwreq_data *wrqu, char *extra)
7598{
7599 /*
7600 * This can be called at any time. No action lock required
7601 */
7602
7603 struct ipw2100_priv *priv = ieee80211_priv(dev);
7604
7605 if (priv->ieee->iw_mode != IW_MODE_ADHOC) {
7606 wrqu->power.disabled = 1;
7607 return 0;
7608 }
7609
7610 if (priv->tx_power == IPW_TX_POWER_DEFAULT) {
7611 wrqu->power.fixed = 0;
7612 wrqu->power.value = IPW_TX_POWER_MAX_DBM;
7613 wrqu->power.disabled = 1;
7614 } else {
7615 wrqu->power.disabled = 0;
7616 wrqu->power.fixed = 1;
7617 wrqu->power.value =
7618 (priv->tx_power *
7619 (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM)) /
7620 (IPW_TX_POWER_MAX - IPW_TX_POWER_MIN) +
7621 IPW_TX_POWER_MIN_DBM;
7622 }
7623
7624 wrqu->power.flags = IW_TXPOW_DBM;
7625
7626 IPW_DEBUG_WX("GET TX Power -> %d \n", wrqu->power.value);
7627
7628 return 0;
7629}
7630
7631static int ipw2100_wx_set_frag(struct net_device *dev,
7632 struct iw_request_info *info,
7633 union iwreq_data *wrqu, char *extra)
7634{
7635 /*
7636 * This can be called at any time. No action lock required
7637 */
7638
7639 struct ipw2100_priv *priv = ieee80211_priv(dev);
7640
7641 if (!wrqu->frag.fixed)
7642 return -EINVAL;
7643
7644 if (wrqu->frag.disabled) {
7645 priv->frag_threshold |= FRAG_DISABLED;
7646 priv->ieee->fts = DEFAULT_FTS;
7647 } else {
7648 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
7649 wrqu->frag.value > MAX_FRAG_THRESHOLD)
7650 return -EINVAL;
7651
7652 priv->ieee->fts = wrqu->frag.value & ~0x1;
7653 priv->frag_threshold = priv->ieee->fts;
7654 }
7655
7656 IPW_DEBUG_WX("SET Frag Threshold -> %d \n", priv->ieee->fts);
7657
7658 return 0;
7659}
7660
7661static int ipw2100_wx_get_frag(struct net_device *dev,
7662 struct iw_request_info *info,
7663 union iwreq_data *wrqu, char *extra)
7664{
7665 /*
7666 * This can be called at any time. No action lock required
7667 */
7668
7669 struct ipw2100_priv *priv = ieee80211_priv(dev);
7670 wrqu->frag.value = priv->frag_threshold & ~FRAG_DISABLED;
7671 wrqu->frag.fixed = 0; /* no auto select */
7672 wrqu->frag.disabled = (priv->frag_threshold & FRAG_DISABLED) ? 1 : 0;
7673
7674 IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value);
7675
7676 return 0;
7677}
7678
7679static int ipw2100_wx_set_retry(struct net_device *dev,
7680 struct iw_request_info *info,
7681 union iwreq_data *wrqu, char *extra)
7682{
7683 struct ipw2100_priv *priv = ieee80211_priv(dev);
7684 int err = 0;
7685
7686 if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
7687 wrqu->retry.disabled)
7688 return -EINVAL;
7689
7690 if (!(wrqu->retry.flags & IW_RETRY_LIMIT))
7691 return 0;
7692
7693 down(&priv->action_sem);
7694 if (!(priv->status & STATUS_INITIALIZED)) {
7695 err = -EIO;
7696 goto done;
7697 }
7698
7699 if (wrqu->retry.flags & IW_RETRY_MIN) {
7700 err = ipw2100_set_short_retry(priv, wrqu->retry.value);
7701 IPW_DEBUG_WX("SET Short Retry Limit -> %d \n",
7702 wrqu->retry.value);
7703 goto done;
7704 }
7705
7706 if (wrqu->retry.flags & IW_RETRY_MAX) {
7707 err = ipw2100_set_long_retry(priv, wrqu->retry.value);
7708 IPW_DEBUG_WX("SET Long Retry Limit -> %d \n",
7709 wrqu->retry.value);
7710 goto done;
7711 }
7712
7713 err = ipw2100_set_short_retry(priv, wrqu->retry.value);
7714 if (!err)
7715 err = ipw2100_set_long_retry(priv, wrqu->retry.value);
7716
7717 IPW_DEBUG_WX("SET Both Retry Limits -> %d \n", wrqu->retry.value);
7718
7719 done:
7720 up(&priv->action_sem);
7721 return err;
7722}
7723
7724static int ipw2100_wx_get_retry(struct net_device *dev,
7725 struct iw_request_info *info,
7726 union iwreq_data *wrqu, char *extra)
7727{
7728 /*
7729 * This can be called at any time. No action lock required
7730 */
7731
7732 struct ipw2100_priv *priv = ieee80211_priv(dev);
7733
7734 wrqu->retry.disabled = 0; /* can't be disabled */
7735
7736 if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
7737 IW_RETRY_LIFETIME)
7738 return -EINVAL;
7739
7740 if (wrqu->retry.flags & IW_RETRY_MAX) {
7741 wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
7742 wrqu->retry.value = priv->long_retry_limit;
7743 } else {
7744 wrqu->retry.flags =
7745 (priv->short_retry_limit !=
7746 priv->long_retry_limit) ?
7747 IW_RETRY_LIMIT & IW_RETRY_MIN : IW_RETRY_LIMIT;
7748
7749 wrqu->retry.value = priv->short_retry_limit;
7750 }
7751
7752 IPW_DEBUG_WX("GET Retry -> %d \n", wrqu->retry.value);
7753
7754 return 0;
7755}
7756
7757static int ipw2100_wx_set_scan(struct net_device *dev,
7758 struct iw_request_info *info,
7759 union iwreq_data *wrqu, char *extra)
7760{
7761 struct ipw2100_priv *priv = ieee80211_priv(dev);
7762 int err = 0;
7763
7764 down(&priv->action_sem);
7765 if (!(priv->status & STATUS_INITIALIZED)) {
7766 err = -EIO;
7767 goto done;
7768 }
7769
7770 IPW_DEBUG_WX("Initiating scan...\n");
7771 if (ipw2100_set_scan_options(priv) ||
7772 ipw2100_start_scan(priv)) {
7773 IPW_DEBUG_WX("Start scan failed.\n");
7774
7775 /* TODO: Mark a scan as pending so when hardware initialized
7776 * a scan starts */
7777 }
7778
7779 done:
7780 up(&priv->action_sem);
7781 return err;
7782}
7783
7784static int ipw2100_wx_get_scan(struct net_device *dev,
7785 struct iw_request_info *info,
7786 union iwreq_data *wrqu, char *extra)
7787{
7788 /*
7789 * This can be called at any time. No action lock required
7790 */
7791
7792 struct ipw2100_priv *priv = ieee80211_priv(dev);
7793 return ieee80211_wx_get_scan(priv->ieee, info, wrqu, extra);
7794}
7795
7796
7797/*
7798 * Implementation based on code in hostap-driver v0.1.3 hostap_ioctl.c
7799 */
7800static int ipw2100_wx_set_encode(struct net_device *dev,
7801 struct iw_request_info *info,
7802 union iwreq_data *wrqu, char *key)
7803{
7804 /*
7805 * No check of STATUS_INITIALIZED required
7806 */
7807
7808 struct ipw2100_priv *priv = ieee80211_priv(dev);
7809 return ieee80211_wx_set_encode(priv->ieee, info, wrqu, key);
7810}
7811
7812static int ipw2100_wx_get_encode(struct net_device *dev,
7813 struct iw_request_info *info,
7814 union iwreq_data *wrqu, char *key)
7815{
7816 /*
7817 * This can be called at any time. No action lock required
7818 */
7819
7820 struct ipw2100_priv *priv = ieee80211_priv(dev);
7821 return ieee80211_wx_get_encode(priv->ieee, info, wrqu, key);
7822}
7823
7824static int ipw2100_wx_set_power(struct net_device *dev,
7825 struct iw_request_info *info,
7826 union iwreq_data *wrqu, char *extra)
7827{
7828 struct ipw2100_priv *priv = ieee80211_priv(dev);
7829 int err = 0;
7830
7831 down(&priv->action_sem);
7832 if (!(priv->status & STATUS_INITIALIZED)) {
7833 err = -EIO;
7834 goto done;
7835 }
7836
7837 if (wrqu->power.disabled) {
7838 priv->power_mode = IPW_POWER_LEVEL(priv->power_mode);
7839 err = ipw2100_set_power_mode(priv, IPW_POWER_MODE_CAM);
7840 IPW_DEBUG_WX("SET Power Management Mode -> off\n");
7841 goto done;
7842 }
7843
7844 switch (wrqu->power.flags & IW_POWER_MODE) {
7845 case IW_POWER_ON: /* If not specified */
7846 case IW_POWER_MODE: /* If set all mask */
7847 case IW_POWER_ALL_R: /* If explicitely state all */
7848 break;
7849 default: /* Otherwise we don't support it */
7850 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
7851 wrqu->power.flags);
7852 err = -EOPNOTSUPP;
7853 goto done;
7854 }
7855
7856 /* If the user hasn't specified a power management mode yet, default
7857 * to BATTERY */
7858 priv->power_mode = IPW_POWER_ENABLED | priv->power_mode;
7859 err = ipw2100_set_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
7860
7861 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n",
7862 priv->power_mode);
7863
7864 done:
7865 up(&priv->action_sem);
7866 return err;
7867
7868}
7869
7870static int ipw2100_wx_get_power(struct net_device *dev,
7871 struct iw_request_info *info,
7872 union iwreq_data *wrqu, char *extra)
7873{
7874 /*
7875 * This can be called at any time. No action lock required
7876 */
7877
7878 struct ipw2100_priv *priv = ieee80211_priv(dev);
7879
7880 if (!(priv->power_mode & IPW_POWER_ENABLED)) {
7881 wrqu->power.disabled = 1;
7882 } else {
7883 wrqu->power.disabled = 0;
7884 wrqu->power.flags = 0;
7885 }
7886
7887 IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode);
7888
7889 return 0;
7890}
7891
7892
7893/*
7894 *
7895 * IWPRIV handlers
7896 *
7897 */
7898#ifdef CONFIG_IPW2100_MONITOR
7899static int ipw2100_wx_set_promisc(struct net_device *dev,
7900 struct iw_request_info *info,
7901 union iwreq_data *wrqu, char *extra)
7902{
7903 struct ipw2100_priv *priv = ieee80211_priv(dev);
7904 int *parms = (int *)extra;
7905 int enable = (parms[0] > 0);
7906 int err = 0;
7907
7908 down(&priv->action_sem);
7909 if (!(priv->status & STATUS_INITIALIZED)) {
7910 err = -EIO;
7911 goto done;
7912 }
7913
7914 if (enable) {
7915 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
7916 err = ipw2100_set_channel(priv, parms[1], 0);
7917 goto done;
7918 }
7919 priv->channel = parms[1];
7920 err = ipw2100_switch_mode(priv, IW_MODE_MONITOR);
7921 } else {
7922 if (priv->ieee->iw_mode == IW_MODE_MONITOR)
7923 err = ipw2100_switch_mode(priv, priv->last_mode);
7924 }
7925 done:
7926 up(&priv->action_sem);
7927 return err;
7928}
7929
7930static int ipw2100_wx_reset(struct net_device *dev,
7931 struct iw_request_info *info,
7932 union iwreq_data *wrqu, char *extra)
7933{
7934 struct ipw2100_priv *priv = ieee80211_priv(dev);
7935 if (priv->status & STATUS_INITIALIZED)
7936 schedule_reset(priv);
7937 return 0;
7938}
7939
7940#endif
7941
7942static int ipw2100_wx_set_powermode(struct net_device *dev,
7943 struct iw_request_info *info,
7944 union iwreq_data *wrqu, char *extra)
7945{
7946 struct ipw2100_priv *priv = ieee80211_priv(dev);
7947 int err = 0, mode = *(int *)extra;
7948
7949 down(&priv->action_sem);
7950 if (!(priv->status & STATUS_INITIALIZED)) {
7951 err = -EIO;
7952 goto done;
7953 }
7954
7955 if ((mode < 1) || (mode > POWER_MODES))
7956 mode = IPW_POWER_AUTO;
7957
7958 if (priv->power_mode != mode)
7959 err = ipw2100_set_power_mode(priv, mode);
7960 done:
7961 up(&priv->action_sem);
7962 return err;
7963}
7964
7965#define MAX_POWER_STRING 80
7966static int ipw2100_wx_get_powermode(struct net_device *dev,
7967 struct iw_request_info *info,
7968 union iwreq_data *wrqu, char *extra)
7969{
7970 /*
7971 * This can be called at any time. No action lock required
7972 */
7973
7974 struct ipw2100_priv *priv = ieee80211_priv(dev);
7975 int level = IPW_POWER_LEVEL(priv->power_mode);
7976 s32 timeout, period;
7977
7978 if (!(priv->power_mode & IPW_POWER_ENABLED)) {
7979 snprintf(extra, MAX_POWER_STRING,
7980 "Power save level: %d (Off)", level);
7981 } else {
7982 switch (level) {
7983 case IPW_POWER_MODE_CAM:
7984 snprintf(extra, MAX_POWER_STRING,
7985 "Power save level: %d (None)", level);
7986 break;
7987 case IPW_POWER_AUTO:
7988 snprintf(extra, MAX_POWER_STRING,
7989 "Power save level: %d (Auto)", 0);
7990 break;
7991 default:
7992 timeout = timeout_duration[level - 1] / 1000;
7993 period = period_duration[level - 1] / 1000;
7994 snprintf(extra, MAX_POWER_STRING,
7995 "Power save level: %d "
7996 "(Timeout %dms, Period %dms)",
7997 level, timeout, period);
7998 }
7999 }
8000
8001 wrqu->data.length = strlen(extra) + 1;
8002
8003 return 0;
8004}
8005
8006
8007static int ipw2100_wx_set_preamble(struct net_device *dev,
8008 struct iw_request_info *info,
8009 union iwreq_data *wrqu, char *extra)
8010{
8011 struct ipw2100_priv *priv = ieee80211_priv(dev);
8012 int err, mode = *(int *)extra;
8013
8014 down(&priv->action_sem);
8015 if (!(priv->status & STATUS_INITIALIZED)) {
8016 err = -EIO;
8017 goto done;
8018 }
8019
8020 if (mode == 1)
8021 priv->config |= CFG_LONG_PREAMBLE;
8022 else if (mode == 0)
8023 priv->config &= ~CFG_LONG_PREAMBLE;
8024 else {
8025 err = -EINVAL;
8026 goto done;
8027 }
8028
8029 err = ipw2100_system_config(priv, 0);
8030
8031done:
8032 up(&priv->action_sem);
8033 return err;
8034}
8035
8036static int ipw2100_wx_get_preamble(struct net_device *dev,
8037 struct iw_request_info *info,
8038 union iwreq_data *wrqu, char *extra)
8039{
8040 /*
8041 * This can be called at any time. No action lock required
8042 */
8043
8044 struct ipw2100_priv *priv = ieee80211_priv(dev);
8045
8046 if (priv->config & CFG_LONG_PREAMBLE)
8047 snprintf(wrqu->name, IFNAMSIZ, "long (1)");
8048 else
8049 snprintf(wrqu->name, IFNAMSIZ, "auto (0)");
8050
8051 return 0;
8052}
8053
8054static iw_handler ipw2100_wx_handlers[] =
8055{
8056 NULL, /* SIOCSIWCOMMIT */
8057 ipw2100_wx_get_name, /* SIOCGIWNAME */
8058 NULL, /* SIOCSIWNWID */
8059 NULL, /* SIOCGIWNWID */
8060 ipw2100_wx_set_freq, /* SIOCSIWFREQ */
8061 ipw2100_wx_get_freq, /* SIOCGIWFREQ */
8062 ipw2100_wx_set_mode, /* SIOCSIWMODE */
8063 ipw2100_wx_get_mode, /* SIOCGIWMODE */
8064 NULL, /* SIOCSIWSENS */
8065 NULL, /* SIOCGIWSENS */
8066 NULL, /* SIOCSIWRANGE */
8067 ipw2100_wx_get_range, /* SIOCGIWRANGE */
8068 NULL, /* SIOCSIWPRIV */
8069 NULL, /* SIOCGIWPRIV */
8070 NULL, /* SIOCSIWSTATS */
8071 NULL, /* SIOCGIWSTATS */
8072 NULL, /* SIOCSIWSPY */
8073 NULL, /* SIOCGIWSPY */
8074 NULL, /* SIOCGIWTHRSPY */
8075 NULL, /* SIOCWIWTHRSPY */
8076 ipw2100_wx_set_wap, /* SIOCSIWAP */
8077 ipw2100_wx_get_wap, /* SIOCGIWAP */
8078 NULL, /* -- hole -- */
8724a118 8079 NULL, /* SIOCGIWAPLIST -- deprecated */
2c86c275
JK
8080 ipw2100_wx_set_scan, /* SIOCSIWSCAN */
8081 ipw2100_wx_get_scan, /* SIOCGIWSCAN */
8082 ipw2100_wx_set_essid, /* SIOCSIWESSID */
8083 ipw2100_wx_get_essid, /* SIOCGIWESSID */
8084 ipw2100_wx_set_nick, /* SIOCSIWNICKN */
8085 ipw2100_wx_get_nick, /* SIOCGIWNICKN */
8086 NULL, /* -- hole -- */
8087 NULL, /* -- hole -- */
8088 ipw2100_wx_set_rate, /* SIOCSIWRATE */
8089 ipw2100_wx_get_rate, /* SIOCGIWRATE */
8090 ipw2100_wx_set_rts, /* SIOCSIWRTS */
8091 ipw2100_wx_get_rts, /* SIOCGIWRTS */
8092 ipw2100_wx_set_frag, /* SIOCSIWFRAG */
8093 ipw2100_wx_get_frag, /* SIOCGIWFRAG */
8094 ipw2100_wx_set_txpow, /* SIOCSIWTXPOW */
8095 ipw2100_wx_get_txpow, /* SIOCGIWTXPOW */
8096 ipw2100_wx_set_retry, /* SIOCSIWRETRY */
8097 ipw2100_wx_get_retry, /* SIOCGIWRETRY */
8098 ipw2100_wx_set_encode, /* SIOCSIWENCODE */
8099 ipw2100_wx_get_encode, /* SIOCGIWENCODE */
8100 ipw2100_wx_set_power, /* SIOCSIWPOWER */
8101 ipw2100_wx_get_power, /* SIOCGIWPOWER */
8102};
8103
8104#define IPW2100_PRIV_SET_MONITOR SIOCIWFIRSTPRIV
8105#define IPW2100_PRIV_RESET SIOCIWFIRSTPRIV+1
8106#define IPW2100_PRIV_SET_POWER SIOCIWFIRSTPRIV+2
8107#define IPW2100_PRIV_GET_POWER SIOCIWFIRSTPRIV+3
8108#define IPW2100_PRIV_SET_LONGPREAMBLE SIOCIWFIRSTPRIV+4
8109#define IPW2100_PRIV_GET_LONGPREAMBLE SIOCIWFIRSTPRIV+5
8110
8111static const struct iw_priv_args ipw2100_private_args[] = {
8112
8113#ifdef CONFIG_IPW2100_MONITOR
8114 {
8115 IPW2100_PRIV_SET_MONITOR,
8116 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"
8117 },
8118 {
8119 IPW2100_PRIV_RESET,
8120 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"
8121 },
8122#endif /* CONFIG_IPW2100_MONITOR */
8123
8124 {
8125 IPW2100_PRIV_SET_POWER,
8126 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_power"
8127 },
8128 {
8129 IPW2100_PRIV_GET_POWER,
8130 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_POWER_STRING, "get_power"
8131 },
8132 {
8133 IPW2100_PRIV_SET_LONGPREAMBLE,
8134 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble"
8135 },
8136 {
8137 IPW2100_PRIV_GET_LONGPREAMBLE,
8138 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "get_preamble"
8139 },
8140};
8141
8142static iw_handler ipw2100_private_handler[] = {
8143#ifdef CONFIG_IPW2100_MONITOR
8144 ipw2100_wx_set_promisc,
8145 ipw2100_wx_reset,
8146#else /* CONFIG_IPW2100_MONITOR */
8147 NULL,
8148 NULL,
8149#endif /* CONFIG_IPW2100_MONITOR */
8150 ipw2100_wx_set_powermode,
8151 ipw2100_wx_get_powermode,
8152 ipw2100_wx_set_preamble,
8153 ipw2100_wx_get_preamble,
8154};
8155
c4aee8c2 8156static struct iw_handler_def ipw2100_wx_handler_def =
2c86c275
JK
8157{
8158 .standard = ipw2100_wx_handlers,
8159 .num_standard = sizeof(ipw2100_wx_handlers) / sizeof(iw_handler),
8160 .num_private = sizeof(ipw2100_private_handler) / sizeof(iw_handler),
8161 .num_private_args = sizeof(ipw2100_private_args) /
8162 sizeof(struct iw_priv_args),
8163 .private = (iw_handler *)ipw2100_private_handler,
8164 .private_args = (struct iw_priv_args *)ipw2100_private_args,
8165};
8166
8167/*
8168 * Get wireless statistics.
8169 * Called by /proc/net/wireless
8170 * Also called by SIOCGIWSTATS
8171 */
c4aee8c2 8172static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev)
2c86c275
JK
8173{
8174 enum {
8175 POOR = 30,
8176 FAIR = 60,
8177 GOOD = 80,
8178 VERY_GOOD = 90,
8179 EXCELLENT = 95,
8180 PERFECT = 100
8181 };
8182 int rssi_qual;
8183 int tx_qual;
8184 int beacon_qual;
8185
8186 struct ipw2100_priv *priv = ieee80211_priv(dev);
8187 struct iw_statistics *wstats;
8188 u32 rssi, quality, tx_retries, missed_beacons, tx_failures;
8189 u32 ord_len = sizeof(u32);
8190
8191 if (!priv)
8192 return (struct iw_statistics *) NULL;
8193
8194 wstats = &priv->wstats;
8195
8196 /* if hw is disabled, then ipw2100_get_ordinal() can't be called.
8197 * ipw2100_wx_wireless_stats seems to be called before fw is
8198 * initialized. STATUS_ASSOCIATED will only be set if the hw is up
8199 * and associated; if not associcated, the values are all meaningless
8200 * anyway, so set them all to NULL and INVALID */
8201 if (!(priv->status & STATUS_ASSOCIATED)) {
8202 wstats->miss.beacon = 0;
8203 wstats->discard.retries = 0;
8204 wstats->qual.qual = 0;
8205 wstats->qual.level = 0;
8206 wstats->qual.noise = 0;
8207 wstats->qual.updated = 7;
8208 wstats->qual.updated |= IW_QUAL_NOISE_INVALID |
8209 IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;
8210 return wstats;
8211 }
8212
8213 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_PERCENT_MISSED_BCNS,
8214 &missed_beacons, &ord_len))
8215 goto fail_get_ordinal;
8216
8217 /* If we don't have a connection the quality and level is 0*/
8218 if (!(priv->status & STATUS_ASSOCIATED)) {
8219 wstats->qual.qual = 0;
8220 wstats->qual.level = 0;
8221 } else {
8222 if (ipw2100_get_ordinal(priv, IPW_ORD_RSSI_AVG_CURR,
8223 &rssi, &ord_len))
8224 goto fail_get_ordinal;
8225 wstats->qual.level = rssi + IPW2100_RSSI_TO_DBM;
8226 if (rssi < 10)
8227 rssi_qual = rssi * POOR / 10;
8228 else if (rssi < 15)
8229 rssi_qual = (rssi - 10) * (FAIR - POOR) / 5 + POOR;
8230 else if (rssi < 20)
8231 rssi_qual = (rssi - 15) * (GOOD - FAIR) / 5 + FAIR;
8232 else if (rssi < 30)
8233 rssi_qual = (rssi - 20) * (VERY_GOOD - GOOD) /
8234 10 + GOOD;
8235 else
8236 rssi_qual = (rssi - 30) * (PERFECT - VERY_GOOD) /
8237 10 + VERY_GOOD;
8238
8239 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_PERCENT_RETRIES,
8240 &tx_retries, &ord_len))
8241 goto fail_get_ordinal;
8242
8243 if (tx_retries > 75)
8244 tx_qual = (90 - tx_retries) * POOR / 15;
8245 else if (tx_retries > 70)
8246 tx_qual = (75 - tx_retries) * (FAIR - POOR) / 5 + POOR;
8247 else if (tx_retries > 65)
8248 tx_qual = (70 - tx_retries) * (GOOD - FAIR) / 5 + FAIR;
8249 else if (tx_retries > 50)
8250 tx_qual = (65 - tx_retries) * (VERY_GOOD - GOOD) /
8251 15 + GOOD;
8252 else
8253 tx_qual = (50 - tx_retries) *
8254 (PERFECT - VERY_GOOD) / 50 + VERY_GOOD;
8255
8256 if (missed_beacons > 50)
8257 beacon_qual = (60 - missed_beacons) * POOR / 10;
8258 else if (missed_beacons > 40)
8259 beacon_qual = (50 - missed_beacons) * (FAIR - POOR) /
8260 10 + POOR;
8261 else if (missed_beacons > 32)
8262 beacon_qual = (40 - missed_beacons) * (GOOD - FAIR) /
8263 18 + FAIR;
8264 else if (missed_beacons > 20)
8265 beacon_qual = (32 - missed_beacons) *
8266 (VERY_GOOD - GOOD) / 20 + GOOD;
8267 else
8268 beacon_qual = (20 - missed_beacons) *
8269 (PERFECT - VERY_GOOD) / 20 + VERY_GOOD;
8270
8271 quality = min(beacon_qual, min(tx_qual, rssi_qual));
8272
8273#ifdef CONFIG_IPW_DEBUG
8274 if (beacon_qual == quality)
8275 IPW_DEBUG_WX("Quality clamped by Missed Beacons\n");
8276 else if (tx_qual == quality)
8277 IPW_DEBUG_WX("Quality clamped by Tx Retries\n");
8278 else if (quality != 100)
8279 IPW_DEBUG_WX("Quality clamped by Signal Strength\n");
8280 else
8281 IPW_DEBUG_WX("Quality not clamped.\n");
8282#endif
8283
8284 wstats->qual.qual = quality;
8285 wstats->qual.level = rssi + IPW2100_RSSI_TO_DBM;
8286 }
8287
8288 wstats->qual.noise = 0;
8289 wstats->qual.updated = 7;
8290 wstats->qual.updated |= IW_QUAL_NOISE_INVALID;
8291
8292 /* FIXME: this is percent and not a # */
8293 wstats->miss.beacon = missed_beacons;
8294
8295 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURES,
8296 &tx_failures, &ord_len))
8297 goto fail_get_ordinal;
8298 wstats->discard.retries = tx_failures;
8299
8300 return wstats;
8301
8302 fail_get_ordinal:
8303 IPW_DEBUG_WX("failed querying ordinals.\n");
8304
8305 return (struct iw_statistics *) NULL;
8306}
8307
c4aee8c2 8308static void ipw2100_wx_event_work(struct ipw2100_priv *priv)
2c86c275
JK
8309{
8310 union iwreq_data wrqu;
8311 int len = ETH_ALEN;
8312
8313 if (priv->status & STATUS_STOPPING)
8314 return;
8315
8316 down(&priv->action_sem);
8317
8318 IPW_DEBUG_WX("enter\n");
8319
8320 up(&priv->action_sem);
8321
8322 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
8323
8324 /* Fetch BSSID from the hardware */
8325 if (!(priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) ||
8326 priv->status & STATUS_RF_KILL_MASK ||
8327 ipw2100_get_ordinal(priv, IPW_ORD_STAT_ASSN_AP_BSSID,
8328 &priv->bssid, &len)) {
8329 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
8330 } else {
8331 /* We now have the BSSID, so can finish setting to the full
8332 * associated state */
8333 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
8334 memcpy(&priv->ieee->bssid, priv->bssid, ETH_ALEN);
8335 priv->status &= ~STATUS_ASSOCIATING;
8336 priv->status |= STATUS_ASSOCIATED;
8337 netif_carrier_on(priv->net_dev);
8338 if (netif_queue_stopped(priv->net_dev)) {
8339 IPW_DEBUG_INFO("Waking net queue.\n");
8340 netif_wake_queue(priv->net_dev);
8341 } else {
8342 IPW_DEBUG_INFO("Starting net queue.\n");
8343 netif_start_queue(priv->net_dev);
8344 }
8345 }
8346
8347 if (!(priv->status & STATUS_ASSOCIATED)) {
8348 IPW_DEBUG_WX("Configuring ESSID\n");
8349 down(&priv->action_sem);
8350 /* This is a disassociation event, so kick the firmware to
8351 * look for another AP */
8352 if (priv->config & CFG_STATIC_ESSID)
8353 ipw2100_set_essid(priv, priv->essid, priv->essid_len, 0);
8354 else
8355 ipw2100_set_essid(priv, NULL, 0, 0);
8356 up(&priv->action_sem);
8357 }
8358
8359 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
8360}
8361
8362#define IPW2100_FW_MAJOR_VERSION 1
8363#define IPW2100_FW_MINOR_VERSION 3
8364
8365#define IPW2100_FW_MINOR(x) ((x & 0xff) >> 8)
8366#define IPW2100_FW_MAJOR(x) (x & 0xff)
8367
8368#define IPW2100_FW_VERSION ((IPW2100_FW_MINOR_VERSION << 8) | \
8369 IPW2100_FW_MAJOR_VERSION)
8370
8371#define IPW2100_FW_PREFIX "ipw2100-" __stringify(IPW2100_FW_MAJOR_VERSION) \
8372"." __stringify(IPW2100_FW_MINOR_VERSION)
8373
8374#define IPW2100_FW_NAME(x) IPW2100_FW_PREFIX "" x ".fw"
8375
8376
8377/*
8378
8379BINARY FIRMWARE HEADER FORMAT
8380
8381offset length desc
83820 2 version
83832 2 mode == 0:BSS,1:IBSS,2:MONITOR
83844 4 fw_len
83858 4 uc_len
8386C fw_len firmware data
838712 + fw_len uc_len microcode data
8388
8389*/
8390
8391struct ipw2100_fw_header {
8392 short version;
8393 short mode;
8394 unsigned int fw_size;
8395 unsigned int uc_size;
8396} __attribute__ ((packed));
8397
8398
8399
8400static int ipw2100_mod_firmware_load(struct ipw2100_fw *fw)
8401{
8402 struct ipw2100_fw_header *h =
8403 (struct ipw2100_fw_header *)fw->fw_entry->data;
8404
8405 if (IPW2100_FW_MAJOR(h->version) != IPW2100_FW_MAJOR_VERSION) {
797b4f76 8406 printk(KERN_WARNING DRV_NAME ": Firmware image not compatible "
2c86c275
JK
8407 "(detected version id of %u). "
8408 "See Documentation/networking/README.ipw2100\n",
8409 h->version);
8410 return 1;
8411 }
8412
8413 fw->version = h->version;
8414 fw->fw.data = fw->fw_entry->data + sizeof(struct ipw2100_fw_header);
8415 fw->fw.size = h->fw_size;
8416 fw->uc.data = fw->fw.data + h->fw_size;
8417 fw->uc.size = h->uc_size;
8418
8419 return 0;
8420}
8421
8422
c4aee8c2
JB
8423static int ipw2100_get_firmware(struct ipw2100_priv *priv,
8424 struct ipw2100_fw *fw)
2c86c275
JK
8425{
8426 char *fw_name;
8427 int rc;
8428
8429 IPW_DEBUG_INFO("%s: Using hotplug firmware load.\n",
8430 priv->net_dev->name);
8431
8432 switch (priv->ieee->iw_mode) {
8433 case IW_MODE_ADHOC:
8434 fw_name = IPW2100_FW_NAME("-i");
8435 break;
8436#ifdef CONFIG_IPW2100_MONITOR
8437 case IW_MODE_MONITOR:
8438 fw_name = IPW2100_FW_NAME("-p");
8439 break;
8440#endif
8441 case IW_MODE_INFRA:
8442 default:
8443 fw_name = IPW2100_FW_NAME("");
8444 break;
8445 }
8446
8447 rc = request_firmware(&fw->fw_entry, fw_name, &priv->pci_dev->dev);
8448
8449 if (rc < 0) {
797b4f76 8450 printk(KERN_ERR DRV_NAME ": "
2c86c275
JK
8451 "%s: Firmware '%s' not available or load failed.\n",
8452 priv->net_dev->name, fw_name);
8453 return rc;
8454 }
aaa4d308 8455 IPW_DEBUG_INFO("firmware data %p size %zd\n", fw->fw_entry->data,
2c86c275
JK
8456 fw->fw_entry->size);
8457
8458 ipw2100_mod_firmware_load(fw);
8459
8460 return 0;
8461}
8462
c4aee8c2
JB
8463static void ipw2100_release_firmware(struct ipw2100_priv *priv,
8464 struct ipw2100_fw *fw)
2c86c275
JK
8465{
8466 fw->version = 0;
8467 if (fw->fw_entry)
8468 release_firmware(fw->fw_entry);
8469 fw->fw_entry = NULL;
8470}
8471
8472
c4aee8c2
JB
8473static int ipw2100_get_fwversion(struct ipw2100_priv *priv, char *buf,
8474 size_t max)
2c86c275
JK
8475{
8476 char ver[MAX_FW_VERSION_LEN];
8477 u32 len = MAX_FW_VERSION_LEN;
8478 u32 tmp;
8479 int i;
8480 /* firmware version is an ascii string (max len of 14) */
8481 if (ipw2100_get_ordinal(priv, IPW_ORD_STAT_FW_VER_NUM,
8482 ver, &len))
8483 return -EIO;
8484 tmp = max;
8485 if (len >= max)
8486 len = max - 1;
8487 for (i = 0; i < len; i++)
8488 buf[i] = ver[i];
8489 buf[i] = '\0';
8490 return tmp;
8491}
8492
c4aee8c2
JB
8493static int ipw2100_get_ucodeversion(struct ipw2100_priv *priv, char *buf,
8494 size_t max)
2c86c275
JK
8495{
8496 u32 ver;
8497 u32 len = sizeof(ver);
8498 /* microcode version is a 32 bit integer */
8499 if (ipw2100_get_ordinal(priv, IPW_ORD_UCODE_VERSION,
8500 &ver, &len))
8501 return -EIO;
8502 return snprintf(buf, max, "%08X", ver);
8503}
8504
8505/*
8506 * On exit, the firmware will have been freed from the fw list
8507 */
c4aee8c2
JB
8508static int ipw2100_fw_download(struct ipw2100_priv *priv,
8509 struct ipw2100_fw *fw)
2c86c275
JK
8510{
8511 /* firmware is constructed of N contiguous entries, each entry is
8512 * structured as:
8513 *
8514 * offset sie desc
8515 * 0 4 address to write to
8516 * 4 2 length of data run
8517 * 6 length data
8518 */
8519 unsigned int addr;
8520 unsigned short len;
8521
8522 const unsigned char *firmware_data = fw->fw.data;
8523 unsigned int firmware_data_left = fw->fw.size;
8524
8525 while (firmware_data_left > 0) {
8526 addr = *(u32 *)(firmware_data);
8527 firmware_data += 4;
8528 firmware_data_left -= 4;
8529
8530 len = *(u16 *)(firmware_data);
8531 firmware_data += 2;
8532 firmware_data_left -= 2;
8533
8534 if (len > 32) {
797b4f76 8535 printk(KERN_ERR DRV_NAME ": "
2c86c275
JK
8536 "Invalid firmware run-length of %d bytes\n",
8537 len);
8538 return -EINVAL;
8539 }
8540
8541 write_nic_memory(priv->net_dev, addr, len, firmware_data);
8542 firmware_data += len;
8543 firmware_data_left -= len;
8544 }
8545
8546 return 0;
8547}
8548
8549struct symbol_alive_response {
8550 u8 cmd_id;
8551 u8 seq_num;
8552 u8 ucode_rev;
8553 u8 eeprom_valid;
8554 u16 valid_flags;
8555 u8 IEEE_addr[6];
8556 u16 flags;
8557 u16 pcb_rev;
8558 u16 clock_settle_time; // 1us LSB
8559 u16 powerup_settle_time; // 1us LSB
8560 u16 hop_settle_time; // 1us LSB
8561 u8 date[3]; // month, day, year
8562 u8 time[2]; // hours, minutes
8563 u8 ucode_valid;
8564};
8565
c4aee8c2
JB
8566static int ipw2100_ucode_download(struct ipw2100_priv *priv,
8567 struct ipw2100_fw *fw)
2c86c275
JK
8568{
8569 struct net_device *dev = priv->net_dev;
8570 const unsigned char *microcode_data = fw->uc.data;
8571 unsigned int microcode_data_left = fw->uc.size;
2be041a7 8572 void __iomem *reg = (void __iomem *)dev->base_addr;
2c86c275
JK
8573
8574 struct symbol_alive_response response;
8575 int i, j;
8576 u8 data;
8577
8578 /* Symbol control */
8579 write_nic_word(dev, IPW2100_CONTROL_REG, 0x703);
2be041a7 8580 readl(reg);
2c86c275 8581 write_nic_word(dev, IPW2100_CONTROL_REG, 0x707);
2be041a7 8582 readl(reg);
2c86c275
JK
8583
8584 /* HW config */
8585 write_nic_byte(dev, 0x210014, 0x72); /* fifo width =16 */
2be041a7 8586 readl(reg);
2c86c275 8587 write_nic_byte(dev, 0x210014, 0x72); /* fifo width =16 */
2be041a7 8588 readl(reg);
2c86c275
JK
8589
8590 /* EN_CS_ACCESS bit to reset control store pointer */
8591 write_nic_byte(dev, 0x210000, 0x40);
2be041a7 8592 readl(reg);
2c86c275 8593 write_nic_byte(dev, 0x210000, 0x0);
2be041a7 8594 readl(reg);
2c86c275 8595 write_nic_byte(dev, 0x210000, 0x40);
2be041a7 8596 readl(reg);
2c86c275
JK
8597
8598 /* copy microcode from buffer into Symbol */
8599
8600 while (microcode_data_left > 0) {
8601 write_nic_byte(dev, 0x210010, *microcode_data++);
8602 write_nic_byte(dev, 0x210010, *microcode_data++);
8603 microcode_data_left -= 2;
8604 }
8605
8606 /* EN_CS_ACCESS bit to reset the control store pointer */
8607 write_nic_byte(dev, 0x210000, 0x0);
2be041a7 8608 readl(reg);
2c86c275
JK
8609
8610 /* Enable System (Reg 0)
8611 * first enable causes garbage in RX FIFO */
8612 write_nic_byte(dev, 0x210000, 0x0);
2be041a7 8613 readl(reg);
2c86c275 8614 write_nic_byte(dev, 0x210000, 0x80);
2be041a7 8615 readl(reg);
2c86c275
JK
8616
8617 /* Reset External Baseband Reg */
8618 write_nic_word(dev, IPW2100_CONTROL_REG, 0x703);
2be041a7 8619 readl(reg);
2c86c275 8620 write_nic_word(dev, IPW2100_CONTROL_REG, 0x707);
2be041a7 8621 readl(reg);
2c86c275
JK
8622
8623 /* HW Config (Reg 5) */
8624 write_nic_byte(dev, 0x210014, 0x72); // fifo width =16
2be041a7 8625 readl(reg);
2c86c275 8626 write_nic_byte(dev, 0x210014, 0x72); // fifo width =16
2be041a7 8627 readl(reg);
2c86c275
JK
8628
8629 /* Enable System (Reg 0)
8630 * second enable should be OK */
8631 write_nic_byte(dev, 0x210000, 0x00); // clear enable system
2be041a7 8632 readl(reg);
2c86c275
JK
8633 write_nic_byte(dev, 0x210000, 0x80); // set enable system
8634
8635 /* check Symbol is enabled - upped this from 5 as it wasn't always
8636 * catching the update */
8637 for (i = 0; i < 10; i++) {
8638 udelay(10);
8639
8640 /* check Dino is enabled bit */
8641 read_nic_byte(dev, 0x210000, &data);
8642 if (data & 0x1)
8643 break;
8644 }
8645
8646 if (i == 10) {
797b4f76 8647 printk(KERN_ERR DRV_NAME ": %s: Error initializing Symbol\n",
2c86c275
JK
8648 dev->name);
8649 return -EIO;
8650 }
8651
8652 /* Get Symbol alive response */
8653 for (i = 0; i < 30; i++) {
8654 /* Read alive response structure */
8655 for (j = 0;
8656 j < (sizeof(struct symbol_alive_response) >> 1);
8657 j++)
8658 read_nic_word(dev, 0x210004,
8659 ((u16 *)&response) + j);
8660
8661 if ((response.cmd_id == 1) &&
8662 (response.ucode_valid == 0x1))
8663 break;
8664 udelay(10);
8665 }
8666
8667 if (i == 30) {
797b4f76 8668 printk(KERN_ERR DRV_NAME ": %s: No response from Symbol - hw not alive\n",
2c86c275
JK
8669 dev->name);
8670 printk_buf(IPW_DL_ERROR, (u8*)&response, sizeof(response));
8671 return -EIO;
8672 }
8673
8674 return 0;
8675}