11961 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/******************************************************************************3 4 Copyright(c) 2003 - 2006 Intel Corporation. All rights reserved.5 6 802.11 status code portion of this file from ethereal-0.10.6:7 Copyright 2000, Axis Communications AB8 Ethereal - Network traffic analyzer9 By Gerald Combs <gerald@ethereal.com>10 Copyright 1998 Gerald Combs11 12 13 Contact Information:14 Intel Linux Wireless <ilw@linux.intel.com>15 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-649716 17******************************************************************************/18 19#include <linux/sched.h>20#include <linux/slab.h>21#include <net/cfg80211-wext.h>22#include "ipw2200.h"23#include "ipw.h"24 25 26#ifndef KBUILD_EXTMOD27#define VK "k"28#else29#define VK30#endif31 32#ifdef CONFIG_IPW2200_DEBUG33#define VD "d"34#else35#define VD36#endif37 38#ifdef CONFIG_IPW2200_MONITOR39#define VM "m"40#else41#define VM42#endif43 44#ifdef CONFIG_IPW2200_PROMISCUOUS45#define VP "p"46#else47#define VP48#endif49 50#ifdef CONFIG_IPW2200_RADIOTAP51#define VR "r"52#else53#define VR54#endif55 56#ifdef CONFIG_IPW2200_QOS57#define VQ "q"58#else59#define VQ60#endif61 62#define IPW2200_VERSION "1.2.2" VK VD VM VP VR VQ63#define DRV_DESCRIPTION "Intel(R) PRO/Wireless 2200/2915 Network Driver"64#define DRV_COPYRIGHT "Copyright(c) 2003-2006 Intel Corporation"65#define DRV_VERSION IPW2200_VERSION66 67#define ETH_P_80211_STATS (ETH_P_80211_RAW + 1)68 69MODULE_DESCRIPTION(DRV_DESCRIPTION);70MODULE_VERSION(DRV_VERSION);71MODULE_AUTHOR(DRV_COPYRIGHT);72MODULE_LICENSE("GPL");73MODULE_FIRMWARE("ipw2200-ibss.fw");74#ifdef CONFIG_IPW2200_MONITOR75MODULE_FIRMWARE("ipw2200-sniffer.fw");76#endif77MODULE_FIRMWARE("ipw2200-bss.fw");78 79static int cmdlog = 0;80static int debug = 0;81static int default_channel = 0;82static int network_mode = 0;83 84static u32 ipw_debug_level;85static int associate;86static int auto_create = 1;87static int led_support = 1;88static int disable = 0;89static int bt_coexist = 0;90static int hwcrypto = 0;91static int roaming = 1;92static const char ipw_modes[] = {93 'a', 'b', 'g', '?'94};95static int antenna = CFG_SYS_ANTENNA_BOTH;96 97#ifdef CONFIG_IPW2200_PROMISCUOUS98static int rtap_iface = 0; /* def: 0 -- do not create rtap interface */99#endif100 101static struct ieee80211_rate ipw2200_rates[] = {102 { .bitrate = 10 },103 { .bitrate = 20, .flags = IEEE80211_RATE_SHORT_PREAMBLE },104 { .bitrate = 55, .flags = IEEE80211_RATE_SHORT_PREAMBLE },105 { .bitrate = 110, .flags = IEEE80211_RATE_SHORT_PREAMBLE },106 { .bitrate = 60 },107 { .bitrate = 90 },108 { .bitrate = 120 },109 { .bitrate = 180 },110 { .bitrate = 240 },111 { .bitrate = 360 },112 { .bitrate = 480 },113 { .bitrate = 540 }114};115 116#define ipw2200_a_rates (ipw2200_rates + 4)117#define ipw2200_num_a_rates 8118#define ipw2200_bg_rates (ipw2200_rates + 0)119#define ipw2200_num_bg_rates 12120 121/* Ugly macro to convert literal channel numbers into their mhz equivalents122 * There are certianly some conditions that will break this (like feeding it '30')123 * but they shouldn't arise since nothing talks on channel 30. */124#define ieee80211chan2mhz(x) \125 (((x) <= 14) ? \126 (((x) == 14) ? 2484 : ((x) * 5) + 2407) : \127 ((x) + 1000) * 5)128 129#ifdef CONFIG_IPW2200_QOS130static int qos_enable = 0;131static int qos_burst_enable = 0;132static int qos_no_ack_mask = 0;133static int burst_duration_CCK = 0;134static int burst_duration_OFDM = 0;135 136static struct libipw_qos_parameters def_qos_parameters_OFDM = {137 {QOS_TX0_CW_MIN_OFDM, QOS_TX1_CW_MIN_OFDM, QOS_TX2_CW_MIN_OFDM,138 QOS_TX3_CW_MIN_OFDM},139 {QOS_TX0_CW_MAX_OFDM, QOS_TX1_CW_MAX_OFDM, QOS_TX2_CW_MAX_OFDM,140 QOS_TX3_CW_MAX_OFDM},141 {QOS_TX0_AIFS, QOS_TX1_AIFS, QOS_TX2_AIFS, QOS_TX3_AIFS},142 {QOS_TX0_ACM, QOS_TX1_ACM, QOS_TX2_ACM, QOS_TX3_ACM},143 {QOS_TX0_TXOP_LIMIT_OFDM, QOS_TX1_TXOP_LIMIT_OFDM,144 QOS_TX2_TXOP_LIMIT_OFDM, QOS_TX3_TXOP_LIMIT_OFDM}145};146 147static struct libipw_qos_parameters def_qos_parameters_CCK = {148 {QOS_TX0_CW_MIN_CCK, QOS_TX1_CW_MIN_CCK, QOS_TX2_CW_MIN_CCK,149 QOS_TX3_CW_MIN_CCK},150 {QOS_TX0_CW_MAX_CCK, QOS_TX1_CW_MAX_CCK, QOS_TX2_CW_MAX_CCK,151 QOS_TX3_CW_MAX_CCK},152 {QOS_TX0_AIFS, QOS_TX1_AIFS, QOS_TX2_AIFS, QOS_TX3_AIFS},153 {QOS_TX0_ACM, QOS_TX1_ACM, QOS_TX2_ACM, QOS_TX3_ACM},154 {QOS_TX0_TXOP_LIMIT_CCK, QOS_TX1_TXOP_LIMIT_CCK, QOS_TX2_TXOP_LIMIT_CCK,155 QOS_TX3_TXOP_LIMIT_CCK}156};157 158static struct libipw_qos_parameters def_parameters_OFDM = {159 {DEF_TX0_CW_MIN_OFDM, DEF_TX1_CW_MIN_OFDM, DEF_TX2_CW_MIN_OFDM,160 DEF_TX3_CW_MIN_OFDM},161 {DEF_TX0_CW_MAX_OFDM, DEF_TX1_CW_MAX_OFDM, DEF_TX2_CW_MAX_OFDM,162 DEF_TX3_CW_MAX_OFDM},163 {DEF_TX0_AIFS, DEF_TX1_AIFS, DEF_TX2_AIFS, DEF_TX3_AIFS},164 {DEF_TX0_ACM, DEF_TX1_ACM, DEF_TX2_ACM, DEF_TX3_ACM},165 {DEF_TX0_TXOP_LIMIT_OFDM, DEF_TX1_TXOP_LIMIT_OFDM,166 DEF_TX2_TXOP_LIMIT_OFDM, DEF_TX3_TXOP_LIMIT_OFDM}167};168 169static struct libipw_qos_parameters def_parameters_CCK = {170 {DEF_TX0_CW_MIN_CCK, DEF_TX1_CW_MIN_CCK, DEF_TX2_CW_MIN_CCK,171 DEF_TX3_CW_MIN_CCK},172 {DEF_TX0_CW_MAX_CCK, DEF_TX1_CW_MAX_CCK, DEF_TX2_CW_MAX_CCK,173 DEF_TX3_CW_MAX_CCK},174 {DEF_TX0_AIFS, DEF_TX1_AIFS, DEF_TX2_AIFS, DEF_TX3_AIFS},175 {DEF_TX0_ACM, DEF_TX1_ACM, DEF_TX2_ACM, DEF_TX3_ACM},176 {DEF_TX0_TXOP_LIMIT_CCK, DEF_TX1_TXOP_LIMIT_CCK, DEF_TX2_TXOP_LIMIT_CCK,177 DEF_TX3_TXOP_LIMIT_CCK}178};179 180static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };181 182static int from_priority_to_tx_queue[] = {183 IPW_TX_QUEUE_1, IPW_TX_QUEUE_2, IPW_TX_QUEUE_2, IPW_TX_QUEUE_1,184 IPW_TX_QUEUE_3, IPW_TX_QUEUE_3, IPW_TX_QUEUE_4, IPW_TX_QUEUE_4185};186 187static u32 ipw_qos_get_burst_duration(struct ipw_priv *priv);188 189static int ipw_send_qos_params_command(struct ipw_priv *priv, struct libipw_qos_parameters190 *qos_param);191static int ipw_send_qos_info_command(struct ipw_priv *priv, struct libipw_qos_information_element192 *qos_param);193#endif /* CONFIG_IPW2200_QOS */194 195static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev);196static void ipw_remove_current_network(struct ipw_priv *priv);197static void ipw_rx(struct ipw_priv *priv);198static int ipw_queue_tx_reclaim(struct ipw_priv *priv,199 struct clx2_tx_queue *txq, int qindex);200static int ipw_queue_reset(struct ipw_priv *priv);201 202static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, const void *buf,203 int len, int sync);204 205static void ipw_tx_queue_free(struct ipw_priv *);206 207static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *);208static void ipw_rx_queue_free(struct ipw_priv *, struct ipw_rx_queue *);209static void ipw_rx_queue_replenish(void *);210static int ipw_up(struct ipw_priv *);211static void ipw_bg_up(struct work_struct *work);212static void ipw_down(struct ipw_priv *);213static void ipw_bg_down(struct work_struct *work);214static int ipw_config(struct ipw_priv *);215static int init_supported_rates(struct ipw_priv *priv,216 struct ipw_supported_rates *prates);217static void ipw_set_hwcrypto_keys(struct ipw_priv *);218static void ipw_send_wep_keys(struct ipw_priv *, int);219 220static int snprint_line(char *buf, size_t count,221 const u8 * data, u32 len, u32 ofs)222{223 int out, i, j, l;224 char c;225 226 out = scnprintf(buf, count, "%08X", ofs);227 228 for (l = 0, i = 0; i < 2; i++) {229 out += scnprintf(buf + out, count - out, " ");230 for (j = 0; j < 8 && l < len; j++, l++)231 out += scnprintf(buf + out, count - out, "%02X ",232 data[(i * 8 + j)]);233 for (; j < 8; j++)234 out += scnprintf(buf + out, count - out, " ");235 }236 237 out += scnprintf(buf + out, count - out, " ");238 for (l = 0, i = 0; i < 2; i++) {239 out += scnprintf(buf + out, count - out, " ");240 for (j = 0; j < 8 && l < len; j++, l++) {241 c = data[(i * 8 + j)];242 if (!isascii(c) || !isprint(c))243 c = '.';244 245 out += scnprintf(buf + out, count - out, "%c", c);246 }247 248 for (; j < 8; j++)249 out += scnprintf(buf + out, count - out, " ");250 }251 252 return out;253}254 255static void printk_buf(int level, const u8 * data, u32 len)256{257 char line[81];258 u32 ofs = 0;259 if (!(ipw_debug_level & level))260 return;261 262 while (len) {263 snprint_line(line, sizeof(line), &data[ofs],264 min(len, 16U), ofs);265 printk(KERN_DEBUG "%s\n", line);266 ofs += 16;267 len -= min(len, 16U);268 }269}270 271static int snprintk_buf(u8 * output, size_t size, const u8 * data, size_t len)272{273 size_t out = size;274 u32 ofs = 0;275 int total = 0;276 277 while (size && len) {278 out = snprint_line(output, size, &data[ofs],279 min_t(size_t, len, 16U), ofs);280 281 ofs += 16;282 output += out;283 size -= out;284 len -= min_t(size_t, len, 16U);285 total += out;286 }287 return total;288}289 290/* alias for 32-bit indirect read (for SRAM/reg above 4K), with debug wrapper */291static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg);292#define ipw_read_reg32(a, b) _ipw_read_reg32(a, b)293 294/* alias for 8-bit indirect read (for SRAM/reg above 4K), with debug wrapper */295static u8 _ipw_read_reg8(struct ipw_priv *ipw, u32 reg);296#define ipw_read_reg8(a, b) _ipw_read_reg8(a, b)297 298/* 8-bit indirect write (for SRAM/reg above 4K), with debug wrapper */299static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value);300static inline void ipw_write_reg8(struct ipw_priv *a, u32 b, u8 c)301{302 IPW_DEBUG_IO("%s %d: write_indirect8(0x%08X, 0x%08X)\n", __FILE__,303 __LINE__, (u32) (b), (u32) (c));304 _ipw_write_reg8(a, b, c);305}306 307/* 16-bit indirect write (for SRAM/reg above 4K), with debug wrapper */308static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value);309static inline void ipw_write_reg16(struct ipw_priv *a, u32 b, u16 c)310{311 IPW_DEBUG_IO("%s %d: write_indirect16(0x%08X, 0x%08X)\n", __FILE__,312 __LINE__, (u32) (b), (u32) (c));313 _ipw_write_reg16(a, b, c);314}315 316/* 32-bit indirect write (for SRAM/reg above 4K), with debug wrapper */317static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value);318static inline void ipw_write_reg32(struct ipw_priv *a, u32 b, u32 c)319{320 IPW_DEBUG_IO("%s %d: write_indirect32(0x%08X, 0x%08X)\n", __FILE__,321 __LINE__, (u32) (b), (u32) (c));322 _ipw_write_reg32(a, b, c);323}324 325/* 8-bit direct write (low 4K) */326static inline void _ipw_write8(struct ipw_priv *ipw, unsigned long ofs,327 u8 val)328{329 writeb(val, ipw->hw_base + ofs);330}331 332/* 8-bit direct write (for low 4K of SRAM/regs), with debug wrapper */333#define ipw_write8(ipw, ofs, val) do { \334 IPW_DEBUG_IO("%s %d: write_direct8(0x%08X, 0x%08X)\n", __FILE__, \335 __LINE__, (u32)(ofs), (u32)(val)); \336 _ipw_write8(ipw, ofs, val); \337} while (0)338 339/* 16-bit direct write (low 4K) */340static inline void _ipw_write16(struct ipw_priv *ipw, unsigned long ofs,341 u16 val)342{343 writew(val, ipw->hw_base + ofs);344}345 346/* 16-bit direct write (for low 4K of SRAM/regs), with debug wrapper */347#define ipw_write16(ipw, ofs, val) do { \348 IPW_DEBUG_IO("%s %d: write_direct16(0x%08X, 0x%08X)\n", __FILE__, \349 __LINE__, (u32)(ofs), (u32)(val)); \350 _ipw_write16(ipw, ofs, val); \351} while (0)352 353/* 32-bit direct write (low 4K) */354static inline void _ipw_write32(struct ipw_priv *ipw, unsigned long ofs,355 u32 val)356{357 writel(val, ipw->hw_base + ofs);358}359 360/* 32-bit direct write (for low 4K of SRAM/regs), with debug wrapper */361#define ipw_write32(ipw, ofs, val) do { \362 IPW_DEBUG_IO("%s %d: write_direct32(0x%08X, 0x%08X)\n", __FILE__, \363 __LINE__, (u32)(ofs), (u32)(val)); \364 _ipw_write32(ipw, ofs, val); \365} while (0)366 367/* 8-bit direct read (low 4K) */368static inline u8 _ipw_read8(struct ipw_priv *ipw, unsigned long ofs)369{370 return readb(ipw->hw_base + ofs);371}372 373/* alias to 8-bit direct read (low 4K of SRAM/regs), with debug wrapper */374#define ipw_read8(ipw, ofs) ({ \375 IPW_DEBUG_IO("%s %d: read_direct8(0x%08X)\n", __FILE__, __LINE__, \376 (u32)(ofs)); \377 _ipw_read8(ipw, ofs); \378})379 380/* 32-bit direct read (low 4K) */381static inline u32 _ipw_read32(struct ipw_priv *ipw, unsigned long ofs)382{383 return readl(ipw->hw_base + ofs);384}385 386/* alias to 32-bit direct read (low 4K of SRAM/regs), with debug wrapper */387#define ipw_read32(ipw, ofs) ({ \388 IPW_DEBUG_IO("%s %d: read_direct32(0x%08X)\n", __FILE__, __LINE__, \389 (u32)(ofs)); \390 _ipw_read32(ipw, ofs); \391})392 393static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int);394/* alias to multi-byte read (SRAM/regs above 4K), with debug wrapper */395#define ipw_read_indirect(a, b, c, d) ({ \396 IPW_DEBUG_IO("%s %d: read_indirect(0x%08X) %u bytes\n", __FILE__, \397 __LINE__, (u32)(b), (u32)(d)); \398 _ipw_read_indirect(a, b, c, d); \399})400 401/* alias to multi-byte read (SRAM/regs above 4K), with debug wrapper */402static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data,403 int num);404#define ipw_write_indirect(a, b, c, d) do { \405 IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %u bytes\n", __FILE__, \406 __LINE__, (u32)(b), (u32)(d)); \407 _ipw_write_indirect(a, b, c, d); \408} while (0)409 410/* 32-bit indirect write (above 4K) */411static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value)412{413 IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value);414 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg);415 _ipw_write32(priv, IPW_INDIRECT_DATA, value);416}417 418/* 8-bit indirect write (above 4K) */419static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value)420{421 u32 aligned_addr = reg & IPW_INDIRECT_ADDR_MASK; /* dword align */422 u32 dif_len = reg - aligned_addr;423 424 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);425 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);426 _ipw_write8(priv, IPW_INDIRECT_DATA + dif_len, value);427}428 429/* 16-bit indirect write (above 4K) */430static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value)431{432 u32 aligned_addr = reg & IPW_INDIRECT_ADDR_MASK; /* dword align */433 u32 dif_len = (reg - aligned_addr) & (~0x1ul);434 435 IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);436 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);437 _ipw_write16(priv, IPW_INDIRECT_DATA + dif_len, value);438}439 440/* 8-bit indirect read (above 4K) */441static u8 _ipw_read_reg8(struct ipw_priv *priv, u32 reg)442{443 u32 word;444 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);445 IPW_DEBUG_IO(" reg = 0x%8X :\n", reg);446 word = _ipw_read32(priv, IPW_INDIRECT_DATA);447 return (word >> ((reg & 0x3) * 8)) & 0xff;448}449 450/* 32-bit indirect read (above 4K) */451static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg)452{453 u32 value;454 455 IPW_DEBUG_IO("%p : reg = 0x%08x\n", priv, reg);456 457 _ipw_write32(priv, IPW_INDIRECT_ADDR, reg);458 value = _ipw_read32(priv, IPW_INDIRECT_DATA);459 IPW_DEBUG_IO(" reg = 0x%4X : value = 0x%4x\n", reg, value);460 return value;461}462 463/* General purpose, no alignment requirement, iterative (multi-byte) read, */464/* for area above 1st 4K of SRAM/reg space */465static void _ipw_read_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,466 int num)467{468 u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK; /* dword align */469 u32 dif_len = addr - aligned_addr;470 u32 i;471 472 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);473 474 if (num <= 0) {475 return;476 }477 478 /* Read the first dword (or portion) byte by byte */479 if (unlikely(dif_len)) {480 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);481 /* Start reading at aligned_addr + dif_len */482 for (i = dif_len; ((i < 4) && (num > 0)); i++, num--)483 *buf++ = _ipw_read8(priv, IPW_INDIRECT_DATA + i);484 aligned_addr += 4;485 }486 487 /* Read all of the middle dwords as dwords, with auto-increment */488 _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);489 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)490 *(u32 *) buf = _ipw_read32(priv, IPW_AUTOINC_DATA);491 492 /* Read the last dword (or portion) byte by byte */493 if (unlikely(num)) {494 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);495 for (i = 0; num > 0; i++, num--)496 *buf++ = ipw_read8(priv, IPW_INDIRECT_DATA + i);497 }498}499 500/* General purpose, no alignment requirement, iterative (multi-byte) write, */501/* for area above 1st 4K of SRAM/reg space */502static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,503 int num)504{505 u32 aligned_addr = addr & IPW_INDIRECT_ADDR_MASK; /* dword align */506 u32 dif_len = addr - aligned_addr;507 u32 i;508 509 IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);510 511 if (num <= 0) {512 return;513 }514 515 /* Write the first dword (or portion) byte by byte */516 if (unlikely(dif_len)) {517 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);518 /* Start writing at aligned_addr + dif_len */519 for (i = dif_len; ((i < 4) && (num > 0)); i++, num--, buf++)520 _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);521 aligned_addr += 4;522 }523 524 /* Write all of the middle dwords as dwords, with auto-increment */525 _ipw_write32(priv, IPW_AUTOINC_ADDR, aligned_addr);526 for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)527 _ipw_write32(priv, IPW_AUTOINC_DATA, *(u32 *) buf);528 529 /* Write the last dword (or portion) byte by byte */530 if (unlikely(num)) {531 _ipw_write32(priv, IPW_INDIRECT_ADDR, aligned_addr);532 for (i = 0; num > 0; i++, num--, buf++)533 _ipw_write8(priv, IPW_INDIRECT_DATA + i, *buf);534 }535}536 537/* General purpose, no alignment requirement, iterative (multi-byte) write, */538/* for 1st 4K of SRAM/regs space */539static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf,540 int num)541{542 memcpy_toio((priv->hw_base + addr), buf, num);543}544 545/* Set bit(s) in low 4K of SRAM/regs */546static inline void ipw_set_bit(struct ipw_priv *priv, u32 reg, u32 mask)547{548 ipw_write32(priv, reg, ipw_read32(priv, reg) | mask);549}550 551/* Clear bit(s) in low 4K of SRAM/regs */552static inline void ipw_clear_bit(struct ipw_priv *priv, u32 reg, u32 mask)553{554 ipw_write32(priv, reg, ipw_read32(priv, reg) & ~mask);555}556 557static inline void __ipw_enable_interrupts(struct ipw_priv *priv)558{559 if (priv->status & STATUS_INT_ENABLED)560 return;561 priv->status |= STATUS_INT_ENABLED;562 ipw_write32(priv, IPW_INTA_MASK_R, IPW_INTA_MASK_ALL);563}564 565static inline void __ipw_disable_interrupts(struct ipw_priv *priv)566{567 if (!(priv->status & STATUS_INT_ENABLED))568 return;569 priv->status &= ~STATUS_INT_ENABLED;570 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);571}572 573static inline void ipw_enable_interrupts(struct ipw_priv *priv)574{575 unsigned long flags;576 577 spin_lock_irqsave(&priv->irq_lock, flags);578 __ipw_enable_interrupts(priv);579 spin_unlock_irqrestore(&priv->irq_lock, flags);580}581 582static inline void ipw_disable_interrupts(struct ipw_priv *priv)583{584 unsigned long flags;585 586 spin_lock_irqsave(&priv->irq_lock, flags);587 __ipw_disable_interrupts(priv);588 spin_unlock_irqrestore(&priv->irq_lock, flags);589}590 591static char *ipw_error_desc(u32 val)592{593 switch (val) {594 case IPW_FW_ERROR_OK:595 return "ERROR_OK";596 case IPW_FW_ERROR_FAIL:597 return "ERROR_FAIL";598 case IPW_FW_ERROR_MEMORY_UNDERFLOW:599 return "MEMORY_UNDERFLOW";600 case IPW_FW_ERROR_MEMORY_OVERFLOW:601 return "MEMORY_OVERFLOW";602 case IPW_FW_ERROR_BAD_PARAM:603 return "BAD_PARAM";604 case IPW_FW_ERROR_BAD_CHECKSUM:605 return "BAD_CHECKSUM";606 case IPW_FW_ERROR_NMI_INTERRUPT:607 return "NMI_INTERRUPT";608 case IPW_FW_ERROR_BAD_DATABASE:609 return "BAD_DATABASE";610 case IPW_FW_ERROR_ALLOC_FAIL:611 return "ALLOC_FAIL";612 case IPW_FW_ERROR_DMA_UNDERRUN:613 return "DMA_UNDERRUN";614 case IPW_FW_ERROR_DMA_STATUS:615 return "DMA_STATUS";616 case IPW_FW_ERROR_DINO_ERROR:617 return "DINO_ERROR";618 case IPW_FW_ERROR_EEPROM_ERROR:619 return "EEPROM_ERROR";620 case IPW_FW_ERROR_SYSASSERT:621 return "SYSASSERT";622 case IPW_FW_ERROR_FATAL_ERROR:623 return "FATAL_ERROR";624 default:625 return "UNKNOWN_ERROR";626 }627}628 629static void ipw_dump_error_log(struct ipw_priv *priv,630 struct ipw_fw_error *error)631{632 u32 i;633 634 if (!error) {635 IPW_ERROR("Error allocating and capturing error log. "636 "Nothing to dump.\n");637 return;638 }639 640 IPW_ERROR("Start IPW Error Log Dump:\n");641 IPW_ERROR("Status: 0x%08X, Config: %08X\n",642 error->status, error->config);643 644 for (i = 0; i < error->elem_len; i++)645 IPW_ERROR("%s %i 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",646 ipw_error_desc(error->elem[i].desc),647 error->elem[i].time,648 error->elem[i].blink1,649 error->elem[i].blink2,650 error->elem[i].link1,651 error->elem[i].link2, error->elem[i].data);652 for (i = 0; i < error->log_len; i++)653 IPW_ERROR("%i\t0x%08x\t%i\n",654 error->log[i].time,655 error->log[i].data, error->log[i].event);656}657 658static inline int ipw_is_init(struct ipw_priv *priv)659{660 return (priv->status & STATUS_INIT) ? 1 : 0;661}662 663static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, u32 * len)664{665 u32 addr, field_info, field_len, field_count, total_len;666 667 IPW_DEBUG_ORD("ordinal = %i\n", ord);668 669 if (!priv || !val || !len) {670 IPW_DEBUG_ORD("Invalid argument\n");671 return -EINVAL;672 }673 674 /* verify device ordinal tables have been initialized */675 if (!priv->table0_addr || !priv->table1_addr || !priv->table2_addr) {676 IPW_DEBUG_ORD("Access ordinals before initialization\n");677 return -EINVAL;678 }679 680 switch (IPW_ORD_TABLE_ID_MASK & ord) {681 case IPW_ORD_TABLE_0_MASK:682 /*683 * TABLE 0: Direct access to a table of 32 bit values684 *685 * This is a very simple table with the data directly686 * read from the table687 */688 689 /* remove the table id from the ordinal */690 ord &= IPW_ORD_TABLE_VALUE_MASK;691 692 /* boundary check */693 if (ord > priv->table0_len) {694 IPW_DEBUG_ORD("ordinal value (%i) longer then "695 "max (%i)\n", ord, priv->table0_len);696 return -EINVAL;697 }698 699 /* verify we have enough room to store the value */700 if (*len < sizeof(u32)) {701 IPW_DEBUG_ORD("ordinal buffer length too small, "702 "need %zd\n", sizeof(u32));703 return -EINVAL;704 }705 706 IPW_DEBUG_ORD("Reading TABLE0[%i] from offset 0x%08x\n",707 ord, priv->table0_addr + (ord << 2));708 709 *len = sizeof(u32);710 ord <<= 2;711 *((u32 *) val) = ipw_read32(priv, priv->table0_addr + ord);712 break;713 714 case IPW_ORD_TABLE_1_MASK:715 /*716 * TABLE 1: Indirect access to a table of 32 bit values717 *718 * This is a fairly large table of u32 values each719 * representing starting addr for the data (which is720 * also a u32)721 */722 723 /* remove the table id from the ordinal */724 ord &= IPW_ORD_TABLE_VALUE_MASK;725 726 /* boundary check */727 if (ord > priv->table1_len) {728 IPW_DEBUG_ORD("ordinal value too long\n");729 return -EINVAL;730 }731 732 /* verify we have enough room to store the value */733 if (*len < sizeof(u32)) {734 IPW_DEBUG_ORD("ordinal buffer length too small, "735 "need %zd\n", sizeof(u32));736 return -EINVAL;737 }738 739 *((u32 *) val) =740 ipw_read_reg32(priv, (priv->table1_addr + (ord << 2)));741 *len = sizeof(u32);742 break;743 744 case IPW_ORD_TABLE_2_MASK:745 /*746 * TABLE 2: Indirect access to a table of variable sized values747 *748 * This table consist of six values, each containing749 * - dword containing the starting offset of the data750 * - dword containing the lengh in the first 16bits751 * and the count in the second 16bits752 */753 754 /* remove the table id from the ordinal */755 ord &= IPW_ORD_TABLE_VALUE_MASK;756 757 /* boundary check */758 if (ord > priv->table2_len) {759 IPW_DEBUG_ORD("ordinal value too long\n");760 return -EINVAL;761 }762 763 /* get the address of statistic */764 addr = ipw_read_reg32(priv, priv->table2_addr + (ord << 3));765 766 /* get the second DW of statistics ;767 * two 16-bit words - first is length, second is count */768 field_info =769 ipw_read_reg32(priv,770 priv->table2_addr + (ord << 3) +771 sizeof(u32));772 773 /* get each entry length */774 field_len = *((u16 *) & field_info);775 776 /* get number of entries */777 field_count = *(((u16 *) & field_info) + 1);778 779 /* abort if not enough memory */780 total_len = field_len * field_count;781 if (total_len > *len) {782 *len = total_len;783 return -EINVAL;784 }785 786 *len = total_len;787 if (!total_len)788 return 0;789 790 IPW_DEBUG_ORD("addr = 0x%08x, total_len = %i, "791 "field_info = 0x%08x\n",792 addr, total_len, field_info);793 ipw_read_indirect(priv, addr, val, total_len);794 break;795 796 default:797 IPW_DEBUG_ORD("Invalid ordinal!\n");798 return -EINVAL;799 800 }801 802 return 0;803}804 805static void ipw_init_ordinals(struct ipw_priv *priv)806{807 priv->table0_addr = IPW_ORDINALS_TABLE_LOWER;808 priv->table0_len = ipw_read32(priv, priv->table0_addr);809 810 IPW_DEBUG_ORD("table 0 offset at 0x%08x, len = %i\n",811 priv->table0_addr, priv->table0_len);812 813 priv->table1_addr = ipw_read32(priv, IPW_ORDINALS_TABLE_1);814 priv->table1_len = ipw_read_reg32(priv, priv->table1_addr);815 816 IPW_DEBUG_ORD("table 1 offset at 0x%08x, len = %i\n",817 priv->table1_addr, priv->table1_len);818 819 priv->table2_addr = ipw_read32(priv, IPW_ORDINALS_TABLE_2);820 priv->table2_len = ipw_read_reg32(priv, priv->table2_addr);821 priv->table2_len &= 0x0000ffff; /* use first two bytes */822 823 IPW_DEBUG_ORD("table 2 offset at 0x%08x, len = %i\n",824 priv->table2_addr, priv->table2_len);825 826}827 828static u32 ipw_register_toggle(u32 reg)829{830 reg &= ~IPW_START_STANDBY;831 if (reg & IPW_GATE_ODMA)832 reg &= ~IPW_GATE_ODMA;833 if (reg & IPW_GATE_IDMA)834 reg &= ~IPW_GATE_IDMA;835 if (reg & IPW_GATE_ADMA)836 reg &= ~IPW_GATE_ADMA;837 return reg;838}839 840/*841 * LED behavior:842 * - On radio ON, turn on any LEDs that require to be on during start843 * - On initialization, start unassociated blink844 * - On association, disable unassociated blink845 * - On disassociation, start unassociated blink846 * - On radio OFF, turn off any LEDs started during radio on847 *848 */849#define LD_TIME_LINK_ON msecs_to_jiffies(300)850#define LD_TIME_LINK_OFF msecs_to_jiffies(2700)851#define LD_TIME_ACT_ON msecs_to_jiffies(250)852 853static void ipw_led_link_on(struct ipw_priv *priv)854{855 unsigned long flags;856 u32 led;857 858 /* If configured to not use LEDs, or nic_type is 1,859 * then we don't toggle a LINK led */860 if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)861 return;862 863 spin_lock_irqsave(&priv->lock, flags);864 865 if (!(priv->status & STATUS_RF_KILL_MASK) &&866 !(priv->status & STATUS_LED_LINK_ON)) {867 IPW_DEBUG_LED("Link LED On\n");868 led = ipw_read_reg32(priv, IPW_EVENT_REG);869 led |= priv->led_association_on;870 871 led = ipw_register_toggle(led);872 873 IPW_DEBUG_LED("Reg: 0x%08X\n", led);874 ipw_write_reg32(priv, IPW_EVENT_REG, led);875 876 priv->status |= STATUS_LED_LINK_ON;877 878 /* If we aren't associated, schedule turning the LED off */879 if (!(priv->status & STATUS_ASSOCIATED))880 schedule_delayed_work(&priv->led_link_off,881 LD_TIME_LINK_ON);882 }883 884 spin_unlock_irqrestore(&priv->lock, flags);885}886 887static void ipw_bg_led_link_on(struct work_struct *work)888{889 struct ipw_priv *priv =890 container_of(work, struct ipw_priv, led_link_on.work);891 mutex_lock(&priv->mutex);892 ipw_led_link_on(priv);893 mutex_unlock(&priv->mutex);894}895 896static void ipw_led_link_off(struct ipw_priv *priv)897{898 unsigned long flags;899 u32 led;900 901 /* If configured not to use LEDs, or nic type is 1,902 * then we don't goggle the LINK led. */903 if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)904 return;905 906 spin_lock_irqsave(&priv->lock, flags);907 908 if (priv->status & STATUS_LED_LINK_ON) {909 led = ipw_read_reg32(priv, IPW_EVENT_REG);910 led &= priv->led_association_off;911 led = ipw_register_toggle(led);912 913 IPW_DEBUG_LED("Reg: 0x%08X\n", led);914 ipw_write_reg32(priv, IPW_EVENT_REG, led);915 916 IPW_DEBUG_LED("Link LED Off\n");917 918 priv->status &= ~STATUS_LED_LINK_ON;919 920 /* If we aren't associated and the radio is on, schedule921 * turning the LED on (blink while unassociated) */922 if (!(priv->status & STATUS_RF_KILL_MASK) &&923 !(priv->status & STATUS_ASSOCIATED))924 schedule_delayed_work(&priv->led_link_on,925 LD_TIME_LINK_OFF);926 927 }928 929 spin_unlock_irqrestore(&priv->lock, flags);930}931 932static void ipw_bg_led_link_off(struct work_struct *work)933{934 struct ipw_priv *priv =935 container_of(work, struct ipw_priv, led_link_off.work);936 mutex_lock(&priv->mutex);937 ipw_led_link_off(priv);938 mutex_unlock(&priv->mutex);939}940 941static void __ipw_led_activity_on(struct ipw_priv *priv)942{943 u32 led;944 945 if (priv->config & CFG_NO_LED)946 return;947 948 if (priv->status & STATUS_RF_KILL_MASK)949 return;950 951 if (!(priv->status & STATUS_LED_ACT_ON)) {952 led = ipw_read_reg32(priv, IPW_EVENT_REG);953 led |= priv->led_activity_on;954 955 led = ipw_register_toggle(led);956 957 IPW_DEBUG_LED("Reg: 0x%08X\n", led);958 ipw_write_reg32(priv, IPW_EVENT_REG, led);959 960 IPW_DEBUG_LED("Activity LED On\n");961 962 priv->status |= STATUS_LED_ACT_ON;963 964 cancel_delayed_work(&priv->led_act_off);965 schedule_delayed_work(&priv->led_act_off, LD_TIME_ACT_ON);966 } else {967 /* Reschedule LED off for full time period */968 cancel_delayed_work(&priv->led_act_off);969 schedule_delayed_work(&priv->led_act_off, LD_TIME_ACT_ON);970 }971}972 973#if 0974void ipw_led_activity_on(struct ipw_priv *priv)975{976 unsigned long flags;977 spin_lock_irqsave(&priv->lock, flags);978 __ipw_led_activity_on(priv);979 spin_unlock_irqrestore(&priv->lock, flags);980}981#endif /* 0 */982 983static void ipw_led_activity_off(struct ipw_priv *priv)984{985 unsigned long flags;986 u32 led;987 988 if (priv->config & CFG_NO_LED)989 return;990 991 spin_lock_irqsave(&priv->lock, flags);992 993 if (priv->status & STATUS_LED_ACT_ON) {994 led = ipw_read_reg32(priv, IPW_EVENT_REG);995 led &= priv->led_activity_off;996 997 led = ipw_register_toggle(led);998 999 IPW_DEBUG_LED("Reg: 0x%08X\n", led);1000 ipw_write_reg32(priv, IPW_EVENT_REG, led);1001 1002 IPW_DEBUG_LED("Activity LED Off\n");1003 1004 priv->status &= ~STATUS_LED_ACT_ON;1005 }1006 1007 spin_unlock_irqrestore(&priv->lock, flags);1008}1009 1010static void ipw_bg_led_activity_off(struct work_struct *work)1011{1012 struct ipw_priv *priv =1013 container_of(work, struct ipw_priv, led_act_off.work);1014 mutex_lock(&priv->mutex);1015 ipw_led_activity_off(priv);1016 mutex_unlock(&priv->mutex);1017}1018 1019static void ipw_led_band_on(struct ipw_priv *priv)1020{1021 unsigned long flags;1022 u32 led;1023 1024 /* Only nic type 1 supports mode LEDs */1025 if (priv->config & CFG_NO_LED ||1026 priv->nic_type != EEPROM_NIC_TYPE_1 || !priv->assoc_network)1027 return;1028 1029 spin_lock_irqsave(&priv->lock, flags);1030 1031 led = ipw_read_reg32(priv, IPW_EVENT_REG);1032 if (priv->assoc_network->mode == IEEE_A) {1033 led |= priv->led_ofdm_on;1034 led &= priv->led_association_off;1035 IPW_DEBUG_LED("Mode LED On: 802.11a\n");1036 } else if (priv->assoc_network->mode == IEEE_G) {1037 led |= priv->led_ofdm_on;1038 led |= priv->led_association_on;1039 IPW_DEBUG_LED("Mode LED On: 802.11g\n");1040 } else {1041 led &= priv->led_ofdm_off;1042 led |= priv->led_association_on;1043 IPW_DEBUG_LED("Mode LED On: 802.11b\n");1044 }1045 1046 led = ipw_register_toggle(led);1047 1048 IPW_DEBUG_LED("Reg: 0x%08X\n", led);1049 ipw_write_reg32(priv, IPW_EVENT_REG, led);1050 1051 spin_unlock_irqrestore(&priv->lock, flags);1052}1053 1054static void ipw_led_band_off(struct ipw_priv *priv)1055{1056 unsigned long flags;1057 u32 led;1058 1059 /* Only nic type 1 supports mode LEDs */1060 if (priv->config & CFG_NO_LED || priv->nic_type != EEPROM_NIC_TYPE_1)1061 return;1062 1063 spin_lock_irqsave(&priv->lock, flags);1064 1065 led = ipw_read_reg32(priv, IPW_EVENT_REG);1066 led &= priv->led_ofdm_off;1067 led &= priv->led_association_off;1068 1069 led = ipw_register_toggle(led);1070 1071 IPW_DEBUG_LED("Reg: 0x%08X\n", led);1072 ipw_write_reg32(priv, IPW_EVENT_REG, led);1073 1074 spin_unlock_irqrestore(&priv->lock, flags);1075}1076 1077static void ipw_led_radio_on(struct ipw_priv *priv)1078{1079 ipw_led_link_on(priv);1080}1081 1082static void ipw_led_radio_off(struct ipw_priv *priv)1083{1084 ipw_led_activity_off(priv);1085 ipw_led_link_off(priv);1086}1087 1088static void ipw_led_link_up(struct ipw_priv *priv)1089{1090 /* Set the Link Led on for all nic types */1091 ipw_led_link_on(priv);1092}1093 1094static void ipw_led_link_down(struct ipw_priv *priv)1095{1096 ipw_led_activity_off(priv);1097 ipw_led_link_off(priv);1098 1099 if (priv->status & STATUS_RF_KILL_MASK)1100 ipw_led_radio_off(priv);1101}1102 1103static void ipw_led_init(struct ipw_priv *priv)1104{1105 priv->nic_type = priv->eeprom[EEPROM_NIC_TYPE];1106 1107 /* Set the default PINs for the link and activity leds */1108 priv->led_activity_on = IPW_ACTIVITY_LED;1109 priv->led_activity_off = ~(IPW_ACTIVITY_LED);1110 1111 priv->led_association_on = IPW_ASSOCIATED_LED;1112 priv->led_association_off = ~(IPW_ASSOCIATED_LED);1113 1114 /* Set the default PINs for the OFDM leds */1115 priv->led_ofdm_on = IPW_OFDM_LED;1116 priv->led_ofdm_off = ~(IPW_OFDM_LED);1117 1118 switch (priv->nic_type) {1119 case EEPROM_NIC_TYPE_1:1120 /* In this NIC type, the LEDs are reversed.... */1121 priv->led_activity_on = IPW_ASSOCIATED_LED;1122 priv->led_activity_off = ~(IPW_ASSOCIATED_LED);1123 priv->led_association_on = IPW_ACTIVITY_LED;1124 priv->led_association_off = ~(IPW_ACTIVITY_LED);1125 1126 if (!(priv->config & CFG_NO_LED))1127 ipw_led_band_on(priv);1128 1129 /* And we don't blink link LEDs for this nic, so1130 * just return here */1131 return;1132 1133 case EEPROM_NIC_TYPE_3:1134 case EEPROM_NIC_TYPE_2:1135 case EEPROM_NIC_TYPE_4:1136 case EEPROM_NIC_TYPE_0:1137 break;1138 1139 default:1140 IPW_DEBUG_INFO("Unknown NIC type from EEPROM: %d\n",1141 priv->nic_type);1142 priv->nic_type = EEPROM_NIC_TYPE_0;1143 break;1144 }1145 1146 if (!(priv->config & CFG_NO_LED)) {1147 if (priv->status & STATUS_ASSOCIATED)1148 ipw_led_link_on(priv);1149 else1150 ipw_led_link_off(priv);1151 }1152}1153 1154static void ipw_led_shutdown(struct ipw_priv *priv)1155{1156 ipw_led_activity_off(priv);1157 ipw_led_link_off(priv);1158 ipw_led_band_off(priv);1159 cancel_delayed_work(&priv->led_link_on);1160 cancel_delayed_work(&priv->led_link_off);1161 cancel_delayed_work(&priv->led_act_off);1162}1163 1164/*1165 * The following adds a new attribute to the sysfs representation1166 * of this device driver (i.e. a new file in /sys/bus/pci/drivers/ipw/)1167 * used for controlling the debug level.1168 *1169 * See the level definitions in ipw for details.1170 */1171static ssize_t debug_level_show(struct device_driver *d, char *buf)1172{1173 return sprintf(buf, "0x%08X\n", ipw_debug_level);1174}1175 1176static ssize_t debug_level_store(struct device_driver *d, const char *buf,1177 size_t count)1178{1179 unsigned long val;1180 1181 int result = kstrtoul(buf, 0, &val);1182 1183 if (result == -EINVAL)1184 printk(KERN_INFO DRV_NAME1185 ": %s is not in hex or decimal form.\n", buf);1186 else if (result == -ERANGE)1187 printk(KERN_INFO DRV_NAME1188 ": %s has overflowed.\n", buf);1189 else1190 ipw_debug_level = val;1191 1192 return count;1193}1194static DRIVER_ATTR_RW(debug_level);1195 1196static inline u32 ipw_get_event_log_len(struct ipw_priv *priv)1197{1198 /* length = 1st dword in log */1199 return ipw_read_reg32(priv, ipw_read32(priv, IPW_EVENT_LOG));1200}1201 1202static void ipw_capture_event_log(struct ipw_priv *priv,1203 u32 log_len, struct ipw_event *log)1204{1205 u32 base;1206 1207 if (log_len) {1208 base = ipw_read32(priv, IPW_EVENT_LOG);1209 ipw_read_indirect(priv, base + sizeof(base) + sizeof(u32),1210 (u8 *) log, sizeof(*log) * log_len);1211 }1212}1213 1214static struct ipw_fw_error *ipw_alloc_error_log(struct ipw_priv *priv)1215{1216 struct ipw_fw_error *error;1217 u32 log_len = ipw_get_event_log_len(priv);1218 u32 base = ipw_read32(priv, IPW_ERROR_LOG);1219 u32 elem_len = ipw_read_reg32(priv, base);1220 1221 error = kmalloc(size_add(struct_size(error, elem, elem_len),1222 array_size(sizeof(*error->log), log_len)),1223 GFP_ATOMIC);1224 if (!error) {1225 IPW_ERROR("Memory allocation for firmware error log "1226 "failed.\n");1227 return NULL;1228 }1229 error->jiffies = jiffies;1230 error->status = priv->status;1231 error->config = priv->config;1232 error->elem_len = elem_len;1233 error->log_len = log_len;1234 error->log = (struct ipw_event *)(error->elem + elem_len);1235 1236 ipw_capture_event_log(priv, log_len, error->log);1237 1238 if (elem_len)1239 ipw_read_indirect(priv, base + sizeof(base), (u8 *) error->elem,1240 sizeof(*error->elem) * elem_len);1241 1242 return error;1243}1244 1245static ssize_t event_log_show(struct device *d,1246 struct device_attribute *attr, char *buf)1247{1248 struct ipw_priv *priv = dev_get_drvdata(d);1249 u32 log_len = ipw_get_event_log_len(priv);1250 u32 log_size;1251 struct ipw_event *log;1252 u32 len = 0, i;1253 1254 /* not using min() because of its strict type checking */1255 log_size = PAGE_SIZE / sizeof(*log) > log_len ?1256 sizeof(*log) * log_len : PAGE_SIZE;1257 log = kzalloc(log_size, GFP_KERNEL);1258 if (!log) {1259 IPW_ERROR("Unable to allocate memory for log\n");1260 return 0;1261 }1262 log_len = log_size / sizeof(*log);1263 ipw_capture_event_log(priv, log_len, log);1264 1265 len += scnprintf(buf + len, PAGE_SIZE - len, "%08X", log_len);1266 for (i = 0; i < log_len; i++)1267 len += scnprintf(buf + len, PAGE_SIZE - len,1268 "\n%08X%08X%08X",1269 log[i].time, log[i].event, log[i].data);1270 len += scnprintf(buf + len, PAGE_SIZE - len, "\n");1271 kfree(log);1272 return len;1273}1274 1275static DEVICE_ATTR_RO(event_log);1276 1277static ssize_t error_show(struct device *d,1278 struct device_attribute *attr, char *buf)1279{1280 struct ipw_priv *priv = dev_get_drvdata(d);1281 u32 len = 0, i;1282 if (!priv->error)1283 return 0;1284 len += scnprintf(buf + len, PAGE_SIZE - len,1285 "%08lX%08X%08X%08X",1286 priv->error->jiffies,1287 priv->error->status,1288 priv->error->config, priv->error->elem_len);1289 for (i = 0; i < priv->error->elem_len; i++)1290 len += scnprintf(buf + len, PAGE_SIZE - len,1291 "\n%08X%08X%08X%08X%08X%08X%08X",1292 priv->error->elem[i].time,1293 priv->error->elem[i].desc,1294 priv->error->elem[i].blink1,1295 priv->error->elem[i].blink2,1296 priv->error->elem[i].link1,1297 priv->error->elem[i].link2,1298 priv->error->elem[i].data);1299 1300 len += scnprintf(buf + len, PAGE_SIZE - len,1301 "\n%08X", priv->error->log_len);1302 for (i = 0; i < priv->error->log_len; i++)1303 len += scnprintf(buf + len, PAGE_SIZE - len,1304 "\n%08X%08X%08X",1305 priv->error->log[i].time,1306 priv->error->log[i].event,1307 priv->error->log[i].data);1308 len += scnprintf(buf + len, PAGE_SIZE - len, "\n");1309 return len;1310}1311 1312static ssize_t error_store(struct device *d,1313 struct device_attribute *attr,1314 const char *buf, size_t count)1315{1316 struct ipw_priv *priv = dev_get_drvdata(d);1317 1318 kfree(priv->error);1319 priv->error = NULL;1320 return count;1321}1322 1323static DEVICE_ATTR_RW(error);1324 1325static ssize_t cmd_log_show(struct device *d,1326 struct device_attribute *attr, char *buf)1327{1328 struct ipw_priv *priv = dev_get_drvdata(d);1329 u32 len = 0, i;1330 if (!priv->cmdlog)1331 return 0;1332 for (i = (priv->cmdlog_pos + 1) % priv->cmdlog_len;1333 (i != priv->cmdlog_pos) && (len < PAGE_SIZE);1334 i = (i + 1) % priv->cmdlog_len) {1335 len +=1336 scnprintf(buf + len, PAGE_SIZE - len,1337 "\n%08lX%08X%08X%08X\n", priv->cmdlog[i].jiffies,1338 priv->cmdlog[i].retcode, priv->cmdlog[i].cmd.cmd,1339 priv->cmdlog[i].cmd.len);1340 len +=1341 snprintk_buf(buf + len, PAGE_SIZE - len,1342 (u8 *) priv->cmdlog[i].cmd.param,1343 priv->cmdlog[i].cmd.len);1344 len += scnprintf(buf + len, PAGE_SIZE - len, "\n");1345 }1346 len += scnprintf(buf + len, PAGE_SIZE - len, "\n");1347 return len;1348}1349 1350static DEVICE_ATTR_RO(cmd_log);1351 1352#ifdef CONFIG_IPW2200_PROMISCUOUS1353static void ipw_prom_free(struct ipw_priv *priv);1354static int ipw_prom_alloc(struct ipw_priv *priv);1355static ssize_t rtap_iface_store(struct device *d,1356 struct device_attribute *attr,1357 const char *buf, size_t count)1358{1359 struct ipw_priv *priv = dev_get_drvdata(d);1360 int rc = 0;1361 1362 if (count < 1)1363 return -EINVAL;1364 1365 switch (buf[0]) {1366 case '0':1367 if (!rtap_iface)1368 return count;1369 1370 if (netif_running(priv->prom_net_dev)) {1371 IPW_WARNING("Interface is up. Cannot unregister.\n");1372 return count;1373 }1374 1375 ipw_prom_free(priv);1376 rtap_iface = 0;1377 break;1378 1379 case '1':1380 if (rtap_iface)1381 return count;1382 1383 rc = ipw_prom_alloc(priv);1384 if (!rc)1385 rtap_iface = 1;1386 break;1387 1388 default:1389 return -EINVAL;1390 }1391 1392 if (rc) {1393 IPW_ERROR("Failed to register promiscuous network "1394 "device (error %d).\n", rc);1395 }1396 1397 return count;1398}1399 1400static ssize_t rtap_iface_show(struct device *d,1401 struct device_attribute *attr,1402 char *buf)1403{1404 struct ipw_priv *priv = dev_get_drvdata(d);1405 if (rtap_iface)1406 return sprintf(buf, "%s", priv->prom_net_dev->name);1407 else {1408 buf[0] = '-';1409 buf[1] = '1';1410 buf[2] = '\0';1411 return 3;1412 }1413}1414 1415static DEVICE_ATTR_ADMIN_RW(rtap_iface);1416 1417static ssize_t rtap_filter_store(struct device *d,1418 struct device_attribute *attr,1419 const char *buf, size_t count)1420{1421 struct ipw_priv *priv = dev_get_drvdata(d);1422 1423 if (!priv->prom_priv) {1424 IPW_ERROR("Attempting to set filter without "1425 "rtap_iface enabled.\n");1426 return -EPERM;1427 }1428 1429 priv->prom_priv->filter = simple_strtol(buf, NULL, 0);1430 1431 IPW_DEBUG_INFO("Setting rtap filter to " BIT_FMT16 "\n",1432 BIT_ARG16(priv->prom_priv->filter));1433 1434 return count;1435}1436 1437static ssize_t rtap_filter_show(struct device *d,1438 struct device_attribute *attr,1439 char *buf)1440{1441 struct ipw_priv *priv = dev_get_drvdata(d);1442 return sprintf(buf, "0x%04X",1443 priv->prom_priv ? priv->prom_priv->filter : 0);1444}1445 1446static DEVICE_ATTR_ADMIN_RW(rtap_filter);1447#endif1448 1449static ssize_t scan_age_show(struct device *d, struct device_attribute *attr,1450 char *buf)1451{1452 struct ipw_priv *priv = dev_get_drvdata(d);1453 return sprintf(buf, "%d\n", priv->ieee->scan_age);1454}1455 1456static ssize_t scan_age_store(struct device *d, struct device_attribute *attr,1457 const char *buf, size_t count)1458{1459 struct ipw_priv *priv = dev_get_drvdata(d);1460 struct net_device *dev = priv->net_dev;1461 1462 IPW_DEBUG_INFO("enter\n");1463 1464 unsigned long val;1465 int result = kstrtoul(buf, 0, &val);1466 1467 if (result == -EINVAL || result == -ERANGE) {1468 IPW_DEBUG_INFO("%s: user supplied invalid value.\n", dev->name);1469 } else {1470 priv->ieee->scan_age = val;1471 IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age);1472 }1473 1474 IPW_DEBUG_INFO("exit\n");1475 return count;1476}1477 1478static DEVICE_ATTR_RW(scan_age);1479 1480static ssize_t led_show(struct device *d, struct device_attribute *attr,1481 char *buf)1482{1483 struct ipw_priv *priv = dev_get_drvdata(d);1484 return sprintf(buf, "%d\n", (priv->config & CFG_NO_LED) ? 0 : 1);1485}1486 1487static ssize_t led_store(struct device *d, struct device_attribute *attr,1488 const char *buf, size_t count)1489{1490 struct ipw_priv *priv = dev_get_drvdata(d);1491 1492 IPW_DEBUG_INFO("enter\n");1493 1494 if (count == 0)1495 return 0;1496 1497 if (*buf == 0) {1498 IPW_DEBUG_LED("Disabling LED control.\n");1499 priv->config |= CFG_NO_LED;1500 ipw_led_shutdown(priv);1501 } else {1502 IPW_DEBUG_LED("Enabling LED control.\n");1503 priv->config &= ~CFG_NO_LED;1504 ipw_led_init(priv);1505 }1506 1507 IPW_DEBUG_INFO("exit\n");1508 return count;1509}1510 1511static DEVICE_ATTR_RW(led);1512 1513static ssize_t status_show(struct device *d,1514 struct device_attribute *attr, char *buf)1515{1516 struct ipw_priv *p = dev_get_drvdata(d);1517 return sprintf(buf, "0x%08x\n", (int)p->status);1518}1519 1520static DEVICE_ATTR_RO(status);1521 1522static ssize_t cfg_show(struct device *d, struct device_attribute *attr,1523 char *buf)1524{1525 struct ipw_priv *p = dev_get_drvdata(d);1526 return sprintf(buf, "0x%08x\n", (int)p->config);1527}1528 1529static DEVICE_ATTR_RO(cfg);1530 1531static ssize_t nic_type_show(struct device *d,1532 struct device_attribute *attr, char *buf)1533{1534 struct ipw_priv *priv = dev_get_drvdata(d);1535 return sprintf(buf, "TYPE: %d\n", priv->nic_type);1536}1537 1538static DEVICE_ATTR_RO(nic_type);1539 1540static ssize_t ucode_version_show(struct device *d,1541 struct device_attribute *attr, char *buf)1542{1543 u32 len = sizeof(u32), tmp = 0;1544 struct ipw_priv *p = dev_get_drvdata(d);1545 1546 if (ipw_get_ordinal(p, IPW_ORD_STAT_UCODE_VERSION, &tmp, &len))1547 return 0;1548 1549 return sprintf(buf, "0x%08x\n", tmp);1550}1551 1552static DEVICE_ATTR_RO(ucode_version);1553 1554static ssize_t rtc_show(struct device *d, struct device_attribute *attr,1555 char *buf)1556{1557 u32 len = sizeof(u32), tmp = 0;1558 struct ipw_priv *p = dev_get_drvdata(d);1559 1560 if (ipw_get_ordinal(p, IPW_ORD_STAT_RTC, &tmp, &len))1561 return 0;1562 1563 return sprintf(buf, "0x%08x\n", tmp);1564}1565 1566static DEVICE_ATTR_RO(rtc);1567 1568/*1569 * Add a device attribute to view/control the delay between eeprom1570 * operations.1571 */1572static ssize_t eeprom_delay_show(struct device *d,1573 struct device_attribute *attr, char *buf)1574{1575 struct ipw_priv *p = dev_get_drvdata(d);1576 int n = p->eeprom_delay;1577 return sprintf(buf, "%i\n", n);1578}1579static ssize_t eeprom_delay_store(struct device *d,1580 struct device_attribute *attr,1581 const char *buf, size_t count)1582{1583 struct ipw_priv *p = dev_get_drvdata(d);1584 sscanf(buf, "%i", &p->eeprom_delay);1585 return strnlen(buf, count);1586}1587 1588static DEVICE_ATTR_RW(eeprom_delay);1589 1590static ssize_t command_event_reg_show(struct device *d,1591 struct device_attribute *attr, char *buf)1592{1593 u32 reg = 0;1594 struct ipw_priv *p = dev_get_drvdata(d);1595 1596 reg = ipw_read_reg32(p, IPW_INTERNAL_CMD_EVENT);1597 return sprintf(buf, "0x%08x\n", reg);1598}1599static ssize_t command_event_reg_store(struct device *d,1600 struct device_attribute *attr,1601 const char *buf, size_t count)1602{1603 u32 reg;1604 struct ipw_priv *p = dev_get_drvdata(d);1605 1606 sscanf(buf, "%x", ®);1607 ipw_write_reg32(p, IPW_INTERNAL_CMD_EVENT, reg);1608 return strnlen(buf, count);1609}1610 1611static DEVICE_ATTR_RW(command_event_reg);1612 1613static ssize_t mem_gpio_reg_show(struct device *d,1614 struct device_attribute *attr, char *buf)1615{1616 u32 reg = 0;1617 struct ipw_priv *p = dev_get_drvdata(d);1618 1619 reg = ipw_read_reg32(p, 0x301100);1620 return sprintf(buf, "0x%08x\n", reg);1621}1622static ssize_t mem_gpio_reg_store(struct device *d,1623 struct device_attribute *attr,1624 const char *buf, size_t count)1625{1626 u32 reg;1627 struct ipw_priv *p = dev_get_drvdata(d);1628 1629 sscanf(buf, "%x", ®);1630 ipw_write_reg32(p, 0x301100, reg);1631 return strnlen(buf, count);1632}1633 1634static DEVICE_ATTR_RW(mem_gpio_reg);1635 1636static ssize_t indirect_dword_show(struct device *d,1637 struct device_attribute *attr, char *buf)1638{1639 u32 reg = 0;1640 struct ipw_priv *priv = dev_get_drvdata(d);1641 1642 if (priv->status & STATUS_INDIRECT_DWORD)1643 reg = ipw_read_reg32(priv, priv->indirect_dword);1644 else1645 reg = 0;1646 1647 return sprintf(buf, "0x%08x\n", reg);1648}1649static ssize_t indirect_dword_store(struct device *d,1650 struct device_attribute *attr,1651 const char *buf, size_t count)1652{1653 struct ipw_priv *priv = dev_get_drvdata(d);1654 1655 sscanf(buf, "%x", &priv->indirect_dword);1656 priv->status |= STATUS_INDIRECT_DWORD;1657 return strnlen(buf, count);1658}1659 1660static DEVICE_ATTR_RW(indirect_dword);1661 1662static ssize_t indirect_byte_show(struct device *d,1663 struct device_attribute *attr, char *buf)1664{1665 u8 reg = 0;1666 struct ipw_priv *priv = dev_get_drvdata(d);1667 1668 if (priv->status & STATUS_INDIRECT_BYTE)1669 reg = ipw_read_reg8(priv, priv->indirect_byte);1670 else1671 reg = 0;1672 1673 return sprintf(buf, "0x%02x\n", reg);1674}1675static ssize_t indirect_byte_store(struct device *d,1676 struct device_attribute *attr,1677 const char *buf, size_t count)1678{1679 struct ipw_priv *priv = dev_get_drvdata(d);1680 1681 sscanf(buf, "%x", &priv->indirect_byte);1682 priv->status |= STATUS_INDIRECT_BYTE;1683 return strnlen(buf, count);1684}1685 1686static DEVICE_ATTR_RW(indirect_byte);1687 1688static ssize_t direct_dword_show(struct device *d,1689 struct device_attribute *attr, char *buf)1690{1691 u32 reg = 0;1692 struct ipw_priv *priv = dev_get_drvdata(d);1693 1694 if (priv->status & STATUS_DIRECT_DWORD)1695 reg = ipw_read32(priv, priv->direct_dword);1696 else1697 reg = 0;1698 1699 return sprintf(buf, "0x%08x\n", reg);1700}1701static ssize_t direct_dword_store(struct device *d,1702 struct device_attribute *attr,1703 const char *buf, size_t count)1704{1705 struct ipw_priv *priv = dev_get_drvdata(d);1706 1707 sscanf(buf, "%x", &priv->direct_dword);1708 priv->status |= STATUS_DIRECT_DWORD;1709 return strnlen(buf, count);1710}1711 1712static DEVICE_ATTR_RW(direct_dword);1713 1714static int rf_kill_active(struct ipw_priv *priv)1715{1716 if (0 == (ipw_read32(priv, 0x30) & 0x10000)) {1717 priv->status |= STATUS_RF_KILL_HW;1718 wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, true);1719 } else {1720 priv->status &= ~STATUS_RF_KILL_HW;1721 wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, false);1722 }1723 1724 return (priv->status & STATUS_RF_KILL_HW) ? 1 : 0;1725}1726 1727static ssize_t rf_kill_show(struct device *d, struct device_attribute *attr,1728 char *buf)1729{1730 /* 0 - RF kill not enabled1731 1 - SW based RF kill active (sysfs)1732 2 - HW based RF kill active1733 3 - Both HW and SW baed RF kill active */1734 struct ipw_priv *priv = dev_get_drvdata(d);1735 int val = ((priv->status & STATUS_RF_KILL_SW) ? 0x1 : 0x0) |1736 (rf_kill_active(priv) ? 0x2 : 0x0);1737 return sprintf(buf, "%i\n", val);1738}1739 1740static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)1741{1742 if ((disable_radio ? 1 : 0) ==1743 ((priv->status & STATUS_RF_KILL_SW) ? 1 : 0))1744 return 0;1745 1746 IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO %s\n",1747 disable_radio ? "OFF" : "ON");1748 1749 if (disable_radio) {1750 priv->status |= STATUS_RF_KILL_SW;1751 1752 cancel_delayed_work(&priv->request_scan);1753 cancel_delayed_work(&priv->request_direct_scan);1754 cancel_delayed_work(&priv->request_passive_scan);1755 cancel_delayed_work(&priv->scan_event);1756 schedule_work(&priv->down);1757 } else {1758 priv->status &= ~STATUS_RF_KILL_SW;1759 if (rf_kill_active(priv)) {1760 IPW_DEBUG_RF_KILL("Can not turn radio back on - "1761 "disabled by HW switch\n");1762 /* Make sure the RF_KILL check timer is running */1763 cancel_delayed_work(&priv->rf_kill);1764 schedule_delayed_work(&priv->rf_kill,1765 round_jiffies_relative(2 * HZ));1766 } else1767 schedule_work(&priv->up);1768 }1769 1770 return 1;1771}1772 1773static ssize_t rf_kill_store(struct device *d, struct device_attribute *attr,1774 const char *buf, size_t count)1775{1776 struct ipw_priv *priv = dev_get_drvdata(d);1777 1778 ipw_radio_kill_sw(priv, buf[0] == '1');1779 1780 return count;1781}1782 1783static DEVICE_ATTR_RW(rf_kill);1784 1785static ssize_t speed_scan_show(struct device *d, struct device_attribute *attr,1786 char *buf)1787{1788 struct ipw_priv *priv = dev_get_drvdata(d);1789 int pos = 0, len = 0;1790 if (priv->config & CFG_SPEED_SCAN) {1791 while (priv->speed_scan[pos] != 0)1792 len += sprintf(&buf[len], "%d ",1793 priv->speed_scan[pos++]);1794 return len + sprintf(&buf[len], "\n");1795 }1796 1797 return sprintf(buf, "0\n");1798}1799 1800static ssize_t speed_scan_store(struct device *d, struct device_attribute *attr,1801 const char *buf, size_t count)1802{1803 struct ipw_priv *priv = dev_get_drvdata(d);1804 int channel, pos = 0;1805 const char *p = buf;1806 1807 /* list of space separated channels to scan, optionally ending with 0 */1808 while ((channel = simple_strtol(p, NULL, 0))) {1809 if (pos == MAX_SPEED_SCAN - 1) {1810 priv->speed_scan[pos] = 0;1811 break;1812 }1813 1814 if (libipw_is_valid_channel(priv->ieee, channel))1815 priv->speed_scan[pos++] = channel;1816 else1817 IPW_WARNING("Skipping invalid channel request: %d\n",1818 channel);1819 p = strchr(p, ' ');1820 if (!p)1821 break;1822 while (*p == ' ' || *p == '\t')1823 p++;1824 }1825 1826 if (pos == 0)1827 priv->config &= ~CFG_SPEED_SCAN;1828 else {1829 priv->speed_scan_pos = 0;1830 priv->config |= CFG_SPEED_SCAN;1831 }1832 1833 return count;1834}1835 1836static DEVICE_ATTR_RW(speed_scan);1837 1838static ssize_t net_stats_show(struct device *d, struct device_attribute *attr,1839 char *buf)1840{1841 struct ipw_priv *priv = dev_get_drvdata(d);1842 return sprintf(buf, "%c\n", (priv->config & CFG_NET_STATS) ? '1' : '0');1843}1844 1845static ssize_t net_stats_store(struct device *d, struct device_attribute *attr,1846 const char *buf, size_t count)1847{1848 struct ipw_priv *priv = dev_get_drvdata(d);1849 if (buf[0] == '1')1850 priv->config |= CFG_NET_STATS;1851 else1852 priv->config &= ~CFG_NET_STATS;1853 1854 return count;1855}1856 1857static DEVICE_ATTR_RW(net_stats);1858 1859static ssize_t channels_show(struct device *d,1860 struct device_attribute *attr,1861 char *buf)1862{1863 struct ipw_priv *priv = dev_get_drvdata(d);1864 const struct libipw_geo *geo = libipw_get_geo(priv->ieee);1865 int len = 0, i;1866 1867 len = sprintf(&buf[len],1868 "Displaying %d channels in 2.4Ghz band "1869 "(802.11bg):\n", geo->bg_channels);1870 1871 for (i = 0; i < geo->bg_channels; i++) {1872 len += sprintf(&buf[len], "%d: BSS%s%s, %s, Band %s.\n",1873 geo->bg[i].channel,1874 geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT ?1875 " (radar spectrum)" : "",1876 ((geo->bg[i].flags & LIBIPW_CH_NO_IBSS) ||1877 (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT))1878 ? "" : ", IBSS",1879 geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY ?1880 "passive only" : "active/passive",1881 geo->bg[i].flags & LIBIPW_CH_B_ONLY ?1882 "B" : "B/G");1883 }1884 1885 len += sprintf(&buf[len],1886 "Displaying %d channels in 5.2Ghz band "1887 "(802.11a):\n", geo->a_channels);1888 for (i = 0; i < geo->a_channels; i++) {1889 len += sprintf(&buf[len], "%d: BSS%s%s, %s.\n",1890 geo->a[i].channel,1891 geo->a[i].flags & LIBIPW_CH_RADAR_DETECT ?1892 " (radar spectrum)" : "",1893 ((geo->a[i].flags & LIBIPW_CH_NO_IBSS) ||1894 (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT))1895 ? "" : ", IBSS",1896 geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY ?1897 "passive only" : "active/passive");1898 }1899 1900 return len;1901}1902 1903static DEVICE_ATTR_ADMIN_RO(channels);1904 1905static void notify_wx_assoc_event(struct ipw_priv *priv)1906{1907 union iwreq_data wrqu;1908 wrqu.ap_addr.sa_family = ARPHRD_ETHER;1909 if (priv->status & STATUS_ASSOCIATED)1910 memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);1911 else1912 eth_zero_addr(wrqu.ap_addr.sa_data);1913 wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);1914}1915 1916static void ipw_irq_tasklet(struct tasklet_struct *t)1917{1918 struct ipw_priv *priv = from_tasklet(priv, t, irq_tasklet);1919 u32 inta, inta_mask, handled = 0;1920 unsigned long flags;1921 1922 spin_lock_irqsave(&priv->irq_lock, flags);1923 1924 inta = ipw_read32(priv, IPW_INTA_RW);1925 inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);1926 1927 if (inta == 0xFFFFFFFF) {1928 /* Hardware disappeared */1929 IPW_WARNING("TASKLET INTA == 0xFFFFFFFF\n");1930 /* Only handle the cached INTA values */1931 inta = 0;1932 }1933 inta &= (IPW_INTA_MASK_ALL & inta_mask);1934 1935 /* Add any cached INTA values that need to be handled */1936 inta |= priv->isr_inta;1937 1938 spin_unlock_irqrestore(&priv->irq_lock, flags);1939 1940 spin_lock_irqsave(&priv->lock, flags);1941 1942 /* handle all the justifications for the interrupt */1943 if (inta & IPW_INTA_BIT_RX_TRANSFER) {1944 ipw_rx(priv);1945 handled |= IPW_INTA_BIT_RX_TRANSFER;1946 }1947 1948 if (inta & IPW_INTA_BIT_TX_CMD_QUEUE) {1949 IPW_DEBUG_HC("Command completed.\n");1950 ipw_queue_tx_reclaim(priv, &priv->txq_cmd, -1);1951 priv->status &= ~STATUS_HCMD_ACTIVE;1952 wake_up_interruptible(&priv->wait_command_queue);1953 handled |= IPW_INTA_BIT_TX_CMD_QUEUE;1954 }1955 1956 if (inta & IPW_INTA_BIT_TX_QUEUE_1) {1957 IPW_DEBUG_TX("TX_QUEUE_1\n");1958 ipw_queue_tx_reclaim(priv, &priv->txq[0], 0);1959 handled |= IPW_INTA_BIT_TX_QUEUE_1;1960 }1961 1962 if (inta & IPW_INTA_BIT_TX_QUEUE_2) {1963 IPW_DEBUG_TX("TX_QUEUE_2\n");1964 ipw_queue_tx_reclaim(priv, &priv->txq[1], 1);1965 handled |= IPW_INTA_BIT_TX_QUEUE_2;1966 }1967 1968 if (inta & IPW_INTA_BIT_TX_QUEUE_3) {1969 IPW_DEBUG_TX("TX_QUEUE_3\n");1970 ipw_queue_tx_reclaim(priv, &priv->txq[2], 2);1971 handled |= IPW_INTA_BIT_TX_QUEUE_3;1972 }1973 1974 if (inta & IPW_INTA_BIT_TX_QUEUE_4) {1975 IPW_DEBUG_TX("TX_QUEUE_4\n");1976 ipw_queue_tx_reclaim(priv, &priv->txq[3], 3);1977 handled |= IPW_INTA_BIT_TX_QUEUE_4;1978 }1979 1980 if (inta & IPW_INTA_BIT_STATUS_CHANGE) {1981 IPW_WARNING("STATUS_CHANGE\n");1982 handled |= IPW_INTA_BIT_STATUS_CHANGE;1983 }1984 1985 if (inta & IPW_INTA_BIT_BEACON_PERIOD_EXPIRED) {1986 IPW_WARNING("TX_PERIOD_EXPIRED\n");1987 handled |= IPW_INTA_BIT_BEACON_PERIOD_EXPIRED;1988 }1989 1990 if (inta & IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE) {1991 IPW_WARNING("HOST_CMD_DONE\n");1992 handled |= IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE;1993 }1994 1995 if (inta & IPW_INTA_BIT_FW_INITIALIZATION_DONE) {1996 IPW_WARNING("FW_INITIALIZATION_DONE\n");1997 handled |= IPW_INTA_BIT_FW_INITIALIZATION_DONE;1998 }1999 2000 if (inta & IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE) {2001 IPW_WARNING("PHY_OFF_DONE\n");2002 handled |= IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE;2003 }2004 2005 if (inta & IPW_INTA_BIT_RF_KILL_DONE) {2006 IPW_DEBUG_RF_KILL("RF_KILL_DONE\n");2007 priv->status |= STATUS_RF_KILL_HW;2008 wiphy_rfkill_set_hw_state(priv->ieee->wdev.wiphy, true);2009 wake_up_interruptible(&priv->wait_command_queue);2010 priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);2011 cancel_delayed_work(&priv->request_scan);2012 cancel_delayed_work(&priv->request_direct_scan);2013 cancel_delayed_work(&priv->request_passive_scan);2014 cancel_delayed_work(&priv->scan_event);2015 schedule_work(&priv->link_down);2016 schedule_delayed_work(&priv->rf_kill, 2 * HZ);2017 handled |= IPW_INTA_BIT_RF_KILL_DONE;2018 }2019 2020 if (inta & IPW_INTA_BIT_FATAL_ERROR) {2021 IPW_WARNING("Firmware error detected. Restarting.\n");2022 if (priv->error) {2023 IPW_DEBUG_FW("Sysfs 'error' log already exists.\n");2024 if (ipw_debug_level & IPW_DL_FW_ERRORS) {2025 struct ipw_fw_error *error =2026 ipw_alloc_error_log(priv);2027 ipw_dump_error_log(priv, error);2028 kfree(error);2029 }2030 } else {2031 priv->error = ipw_alloc_error_log(priv);2032 if (priv->error)2033 IPW_DEBUG_FW("Sysfs 'error' log captured.\n");2034 else2035 IPW_DEBUG_FW("Error allocating sysfs 'error' "2036 "log.\n");2037 if (ipw_debug_level & IPW_DL_FW_ERRORS)2038 ipw_dump_error_log(priv, priv->error);2039 }2040 2041 /* XXX: If hardware encryption is for WPA/WPA2,2042 * we have to notify the supplicant. */2043 if (priv->ieee->sec.encrypt) {2044 priv->status &= ~STATUS_ASSOCIATED;2045 notify_wx_assoc_event(priv);2046 }2047 2048 /* Keep the restart process from trying to send host2049 * commands by clearing the INIT status bit */2050 priv->status &= ~STATUS_INIT;2051 2052 /* Cancel currently queued command. */2053 priv->status &= ~STATUS_HCMD_ACTIVE;2054 wake_up_interruptible(&priv->wait_command_queue);2055 2056 schedule_work(&priv->adapter_restart);2057 handled |= IPW_INTA_BIT_FATAL_ERROR;2058 }2059 2060 if (inta & IPW_INTA_BIT_PARITY_ERROR) {2061 IPW_ERROR("Parity error\n");2062 handled |= IPW_INTA_BIT_PARITY_ERROR;2063 }2064 2065 if (handled != inta) {2066 IPW_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled);2067 }2068 2069 spin_unlock_irqrestore(&priv->lock, flags);2070 2071 /* enable all interrupts */2072 ipw_enable_interrupts(priv);2073}2074 2075#define IPW_CMD(x) case IPW_CMD_ ## x : return #x2076static char *get_cmd_string(u8 cmd)2077{2078 switch (cmd) {2079 IPW_CMD(HOST_COMPLETE);2080 IPW_CMD(POWER_DOWN);2081 IPW_CMD(SYSTEM_CONFIG);2082 IPW_CMD(MULTICAST_ADDRESS);2083 IPW_CMD(SSID);2084 IPW_CMD(ADAPTER_ADDRESS);2085 IPW_CMD(PORT_TYPE);2086 IPW_CMD(RTS_THRESHOLD);2087 IPW_CMD(FRAG_THRESHOLD);2088 IPW_CMD(POWER_MODE);2089 IPW_CMD(WEP_KEY);2090 IPW_CMD(TGI_TX_KEY);2091 IPW_CMD(SCAN_REQUEST);2092 IPW_CMD(SCAN_REQUEST_EXT);2093 IPW_CMD(ASSOCIATE);2094 IPW_CMD(SUPPORTED_RATES);2095 IPW_CMD(SCAN_ABORT);2096 IPW_CMD(TX_FLUSH);2097 IPW_CMD(QOS_PARAMETERS);2098 IPW_CMD(DINO_CONFIG);2099 IPW_CMD(RSN_CAPABILITIES);2100 IPW_CMD(RX_KEY);2101 IPW_CMD(CARD_DISABLE);2102 IPW_CMD(SEED_NUMBER);2103 IPW_CMD(TX_POWER);2104 IPW_CMD(COUNTRY_INFO);2105 IPW_CMD(AIRONET_INFO);2106 IPW_CMD(AP_TX_POWER);2107 IPW_CMD(CCKM_INFO);2108 IPW_CMD(CCX_VER_INFO);2109 IPW_CMD(SET_CALIBRATION);2110 IPW_CMD(SENSITIVITY_CALIB);2111 IPW_CMD(RETRY_LIMIT);2112 IPW_CMD(IPW_PRE_POWER_DOWN);2113 IPW_CMD(VAP_BEACON_TEMPLATE);2114 IPW_CMD(VAP_DTIM_PERIOD);2115 IPW_CMD(EXT_SUPPORTED_RATES);2116 IPW_CMD(VAP_LOCAL_TX_PWR_CONSTRAINT);2117 IPW_CMD(VAP_QUIET_INTERVALS);2118 IPW_CMD(VAP_CHANNEL_SWITCH);2119 IPW_CMD(VAP_MANDATORY_CHANNELS);2120 IPW_CMD(VAP_CELL_PWR_LIMIT);2121 IPW_CMD(VAP_CF_PARAM_SET);2122 IPW_CMD(VAP_SET_BEACONING_STATE);2123 IPW_CMD(MEASUREMENT);2124 IPW_CMD(POWER_CAPABILITY);2125 IPW_CMD(SUPPORTED_CHANNELS);2126 IPW_CMD(TPC_REPORT);2127 IPW_CMD(WME_INFO);2128 IPW_CMD(PRODUCTION_COMMAND);2129 default:2130 return "UNKNOWN";2131 }2132}2133 2134#define HOST_COMPLETE_TIMEOUT HZ2135 2136static int __ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)2137{2138 int rc = 0;2139 unsigned long flags;2140 unsigned long now, end;2141 2142 spin_lock_irqsave(&priv->lock, flags);2143 if (priv->status & STATUS_HCMD_ACTIVE) {2144 IPW_ERROR("Failed to send %s: Already sending a command.\n",2145 get_cmd_string(cmd->cmd));2146 spin_unlock_irqrestore(&priv->lock, flags);2147 return -EAGAIN;2148 }2149 2150 priv->status |= STATUS_HCMD_ACTIVE;2151 2152 if (priv->cmdlog) {2153 priv->cmdlog[priv->cmdlog_pos].jiffies = jiffies;2154 priv->cmdlog[priv->cmdlog_pos].cmd.cmd = cmd->cmd;2155 priv->cmdlog[priv->cmdlog_pos].cmd.len = cmd->len;2156 memcpy(priv->cmdlog[priv->cmdlog_pos].cmd.param, cmd->param,2157 cmd->len);2158 priv->cmdlog[priv->cmdlog_pos].retcode = -1;2159 }2160 2161 IPW_DEBUG_HC("%s command (#%d) %d bytes: 0x%08X\n",2162 get_cmd_string(cmd->cmd), cmd->cmd, cmd->len,2163 priv->status);2164 2165#ifndef DEBUG_CMD_WEP_KEY2166 if (cmd->cmd == IPW_CMD_WEP_KEY)2167 IPW_DEBUG_HC("WEP_KEY command masked out for secure.\n");2168 else2169#endif2170 printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len);2171 2172 rc = ipw_queue_tx_hcmd(priv, cmd->cmd, cmd->param, cmd->len, 0);2173 if (rc) {2174 priv->status &= ~STATUS_HCMD_ACTIVE;2175 IPW_ERROR("Failed to send %s: Reason %d\n",2176 get_cmd_string(cmd->cmd), rc);2177 spin_unlock_irqrestore(&priv->lock, flags);2178 goto exit;2179 }2180 spin_unlock_irqrestore(&priv->lock, flags);2181 2182 now = jiffies;2183 end = now + HOST_COMPLETE_TIMEOUT;2184again:2185 rc = wait_event_interruptible_timeout(priv->wait_command_queue,2186 !(priv->2187 status & STATUS_HCMD_ACTIVE),2188 end - now);2189 if (rc < 0) {2190 now = jiffies;2191 if (time_before(now, end))2192 goto again;2193 rc = 0;2194 }2195 2196 if (rc == 0) {2197 spin_lock_irqsave(&priv->lock, flags);2198 if (priv->status & STATUS_HCMD_ACTIVE) {2199 IPW_ERROR("Failed to send %s: Command timed out.\n",2200 get_cmd_string(cmd->cmd));2201 priv->status &= ~STATUS_HCMD_ACTIVE;2202 spin_unlock_irqrestore(&priv->lock, flags);2203 rc = -EIO;2204 goto exit;2205 }2206 spin_unlock_irqrestore(&priv->lock, flags);2207 } else2208 rc = 0;2209 2210 if (priv->status & STATUS_RF_KILL_HW) {2211 IPW_ERROR("Failed to send %s: Aborted due to RF kill switch.\n",2212 get_cmd_string(cmd->cmd));2213 rc = -EIO;2214 goto exit;2215 }2216 2217 exit:2218 if (priv->cmdlog) {2219 priv->cmdlog[priv->cmdlog_pos++].retcode = rc;2220 priv->cmdlog_pos %= priv->cmdlog_len;2221 }2222 return rc;2223}2224 2225static int ipw_send_cmd_simple(struct ipw_priv *priv, u8 command)2226{2227 struct host_cmd cmd = {2228 .cmd = command,2229 };2230 2231 return __ipw_send_cmd(priv, &cmd);2232}2233 2234static int ipw_send_cmd_pdu(struct ipw_priv *priv, u8 command, u8 len,2235 const void *data)2236{2237 struct host_cmd cmd = {2238 .cmd = command,2239 .len = len,2240 .param = data,2241 };2242 2243 return __ipw_send_cmd(priv, &cmd);2244}2245 2246static int ipw_send_host_complete(struct ipw_priv *priv)2247{2248 if (!priv) {2249 IPW_ERROR("Invalid args\n");2250 return -1;2251 }2252 2253 return ipw_send_cmd_simple(priv, IPW_CMD_HOST_COMPLETE);2254}2255 2256static int ipw_send_system_config(struct ipw_priv *priv)2257{2258 return ipw_send_cmd_pdu(priv, IPW_CMD_SYSTEM_CONFIG,2259 sizeof(priv->sys_config),2260 &priv->sys_config);2261}2262 2263static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len)2264{2265 if (!priv || !ssid) {2266 IPW_ERROR("Invalid args\n");2267 return -1;2268 }2269 2270 return ipw_send_cmd_pdu(priv, IPW_CMD_SSID, min(len, IW_ESSID_MAX_SIZE),2271 ssid);2272}2273 2274static int ipw_send_adapter_address(struct ipw_priv *priv, const u8 * mac)2275{2276 if (!priv || !mac) {2277 IPW_ERROR("Invalid args\n");2278 return -1;2279 }2280 2281 IPW_DEBUG_INFO("%s: Setting MAC to %pM\n",2282 priv->net_dev->name, mac);2283 2284 return ipw_send_cmd_pdu(priv, IPW_CMD_ADAPTER_ADDRESS, ETH_ALEN, mac);2285}2286 2287static void ipw_adapter_restart(void *adapter)2288{2289 struct ipw_priv *priv = adapter;2290 2291 if (priv->status & STATUS_RF_KILL_MASK)2292 return;2293 2294 ipw_down(priv);2295 2296 if (priv->assoc_network &&2297 (priv->assoc_network->capability & WLAN_CAPABILITY_IBSS))2298 ipw_remove_current_network(priv);2299 2300 if (ipw_up(priv)) {2301 IPW_ERROR("Failed to up device\n");2302 return;2303 }2304}2305 2306static void ipw_bg_adapter_restart(struct work_struct *work)2307{2308 struct ipw_priv *priv =2309 container_of(work, struct ipw_priv, adapter_restart);2310 mutex_lock(&priv->mutex);2311 ipw_adapter_restart(priv);2312 mutex_unlock(&priv->mutex);2313}2314 2315static void ipw_abort_scan(struct ipw_priv *priv);2316 2317#define IPW_SCAN_CHECK_WATCHDOG (5 * HZ)2318 2319static void ipw_scan_check(void *data)2320{2321 struct ipw_priv *priv = data;2322 2323 if (priv->status & STATUS_SCAN_ABORTING) {2324 IPW_DEBUG_SCAN("Scan completion watchdog resetting "2325 "adapter after (%dms).\n",2326 jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG));2327 schedule_work(&priv->adapter_restart);2328 } else if (priv->status & STATUS_SCANNING) {2329 IPW_DEBUG_SCAN("Scan completion watchdog aborting scan "2330 "after (%dms).\n",2331 jiffies_to_msecs(IPW_SCAN_CHECK_WATCHDOG));2332 ipw_abort_scan(priv);2333 schedule_delayed_work(&priv->scan_check, HZ);2334 }2335}2336 2337static void ipw_bg_scan_check(struct work_struct *work)2338{2339 struct ipw_priv *priv =2340 container_of(work, struct ipw_priv, scan_check.work);2341 mutex_lock(&priv->mutex);2342 ipw_scan_check(priv);2343 mutex_unlock(&priv->mutex);2344}2345 2346static int ipw_send_scan_request_ext(struct ipw_priv *priv,2347 struct ipw_scan_request_ext *request)2348{2349 return ipw_send_cmd_pdu(priv, IPW_CMD_SCAN_REQUEST_EXT,2350 sizeof(*request), request);2351}2352 2353static int ipw_send_scan_abort(struct ipw_priv *priv)2354{2355 if (!priv) {2356 IPW_ERROR("Invalid args\n");2357 return -1;2358 }2359 2360 return ipw_send_cmd_simple(priv, IPW_CMD_SCAN_ABORT);2361}2362 2363static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens)2364{2365 struct ipw_sensitivity_calib calib = {2366 .beacon_rssi_raw = cpu_to_le16(sens),2367 };2368 2369 return ipw_send_cmd_pdu(priv, IPW_CMD_SENSITIVITY_CALIB, sizeof(calib),2370 &calib);2371}2372 2373static int ipw_send_associate(struct ipw_priv *priv,2374 struct ipw_associate *associate)2375{2376 if (!priv || !associate) {2377 IPW_ERROR("Invalid args\n");2378 return -1;2379 }2380 2381 return ipw_send_cmd_pdu(priv, IPW_CMD_ASSOCIATE, sizeof(*associate),2382 associate);2383}2384 2385static int ipw_send_supported_rates(struct ipw_priv *priv,2386 struct ipw_supported_rates *rates)2387{2388 if (!priv || !rates) {2389 IPW_ERROR("Invalid args\n");2390 return -1;2391 }2392 2393 return ipw_send_cmd_pdu(priv, IPW_CMD_SUPPORTED_RATES, sizeof(*rates),2394 rates);2395}2396 2397static int ipw_set_random_seed(struct ipw_priv *priv)2398{2399 u32 val;2400 2401 if (!priv) {2402 IPW_ERROR("Invalid args\n");2403 return -1;2404 }2405 2406 get_random_bytes(&val, sizeof(val));2407 2408 return ipw_send_cmd_pdu(priv, IPW_CMD_SEED_NUMBER, sizeof(val), &val);2409}2410 2411static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off)2412{2413 __le32 v = cpu_to_le32(phy_off);2414 if (!priv) {2415 IPW_ERROR("Invalid args\n");2416 return -1;2417 }2418 2419 return ipw_send_cmd_pdu(priv, IPW_CMD_CARD_DISABLE, sizeof(v), &v);2420}2421 2422static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)2423{2424 if (!priv || !power) {2425 IPW_ERROR("Invalid args\n");2426 return -1;2427 }2428 2429 return ipw_send_cmd_pdu(priv, IPW_CMD_TX_POWER, sizeof(*power), power);2430}2431 2432static int ipw_set_tx_power(struct ipw_priv *priv)2433{2434 const struct libipw_geo *geo = libipw_get_geo(priv->ieee);2435 struct ipw_tx_power tx_power;2436 s8 max_power;2437 int i;2438 2439 memset(&tx_power, 0, sizeof(tx_power));2440 2441 /* configure device for 'G' band */2442 tx_power.ieee_mode = IPW_G_MODE;2443 tx_power.num_channels = geo->bg_channels;2444 for (i = 0; i < geo->bg_channels; i++) {2445 max_power = geo->bg[i].max_power;2446 tx_power.channels_tx_power[i].channel_number =2447 geo->bg[i].channel;2448 tx_power.channels_tx_power[i].tx_power = max_power ?2449 min(max_power, priv->tx_power) : priv->tx_power;2450 }2451 if (ipw_send_tx_power(priv, &tx_power))2452 return -EIO;2453 2454 /* configure device to also handle 'B' band */2455 tx_power.ieee_mode = IPW_B_MODE;2456 if (ipw_send_tx_power(priv, &tx_power))2457 return -EIO;2458 2459 /* configure device to also handle 'A' band */2460 if (priv->ieee->abg_true) {2461 tx_power.ieee_mode = IPW_A_MODE;2462 tx_power.num_channels = geo->a_channels;2463 for (i = 0; i < tx_power.num_channels; i++) {2464 max_power = geo->a[i].max_power;2465 tx_power.channels_tx_power[i].channel_number =2466 geo->a[i].channel;2467 tx_power.channels_tx_power[i].tx_power = max_power ?2468 min(max_power, priv->tx_power) : priv->tx_power;2469 }2470 if (ipw_send_tx_power(priv, &tx_power))2471 return -EIO;2472 }2473 return 0;2474}2475 2476static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts)2477{2478 struct ipw_rts_threshold rts_threshold = {2479 .rts_threshold = cpu_to_le16(rts),2480 };2481 2482 if (!priv) {2483 IPW_ERROR("Invalid args\n");2484 return -1;2485 }2486 2487 return ipw_send_cmd_pdu(priv, IPW_CMD_RTS_THRESHOLD,2488 sizeof(rts_threshold), &rts_threshold);2489}2490 2491static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)2492{2493 struct ipw_frag_threshold frag_threshold = {2494 .frag_threshold = cpu_to_le16(frag),2495 };2496 2497 if (!priv) {2498 IPW_ERROR("Invalid args\n");2499 return -1;2500 }2501 2502 return ipw_send_cmd_pdu(priv, IPW_CMD_FRAG_THRESHOLD,2503 sizeof(frag_threshold), &frag_threshold);2504}2505 2506static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)2507{2508 __le32 param;2509 2510 if (!priv) {2511 IPW_ERROR("Invalid args\n");2512 return -1;2513 }2514 2515 /* If on battery, set to 3, if AC set to CAM, else user2516 * level */2517 switch (mode) {2518 case IPW_POWER_BATTERY:2519 param = cpu_to_le32(IPW_POWER_INDEX_3);2520 break;2521 case IPW_POWER_AC:2522 param = cpu_to_le32(IPW_POWER_MODE_CAM);2523 break;2524 default:2525 param = cpu_to_le32(mode);2526 break;2527 }2528 2529 return ipw_send_cmd_pdu(priv, IPW_CMD_POWER_MODE, sizeof(param),2530 ¶m);2531}2532 2533static int ipw_send_retry_limit(struct ipw_priv *priv, u8 slimit, u8 llimit)2534{2535 struct ipw_retry_limit retry_limit = {2536 .short_retry_limit = slimit,2537 .long_retry_limit = llimit2538 };2539 2540 if (!priv) {2541 IPW_ERROR("Invalid args\n");2542 return -1;2543 }2544 2545 return ipw_send_cmd_pdu(priv, IPW_CMD_RETRY_LIMIT, sizeof(retry_limit),2546 &retry_limit);2547}2548 2549/*2550 * The IPW device contains a Microwire compatible EEPROM that stores2551 * various data like the MAC address. Usually the firmware has exclusive2552 * access to the eeprom, but during device initialization (before the2553 * device driver has sent the HostComplete command to the firmware) the2554 * device driver has read access to the EEPROM by way of indirect addressing2555 * through a couple of memory mapped registers.2556 *2557 * The following is a simplified implementation for pulling data out of the2558 * eeprom, along with some helper functions to find information in2559 * the per device private data's copy of the eeprom.2560 *2561 * NOTE: To better understand how these functions work (i.e what is a chip2562 * select and why do have to keep driving the eeprom clock?), read2563 * just about any data sheet for a Microwire compatible EEPROM.2564 */2565 2566/* write a 32 bit value into the indirect accessor register */2567static inline void eeprom_write_reg(struct ipw_priv *p, u32 data)2568{2569 ipw_write_reg32(p, FW_MEM_REG_EEPROM_ACCESS, data);2570 2571 /* the eeprom requires some time to complete the operation */2572 udelay(p->eeprom_delay);2573}2574 2575/* perform a chip select operation */2576static void eeprom_cs(struct ipw_priv *priv)2577{2578 eeprom_write_reg(priv, 0);2579 eeprom_write_reg(priv, EEPROM_BIT_CS);2580 eeprom_write_reg(priv, EEPROM_BIT_CS | EEPROM_BIT_SK);2581 eeprom_write_reg(priv, EEPROM_BIT_CS);2582}2583 2584/* perform a chip select operation */2585static void eeprom_disable_cs(struct ipw_priv *priv)2586{2587 eeprom_write_reg(priv, EEPROM_BIT_CS);2588 eeprom_write_reg(priv, 0);2589 eeprom_write_reg(priv, EEPROM_BIT_SK);2590}2591 2592/* push a single bit down to the eeprom */2593static inline void eeprom_write_bit(struct ipw_priv *p, u8 bit)2594{2595 int d = (bit ? EEPROM_BIT_DI : 0);2596 eeprom_write_reg(p, EEPROM_BIT_CS | d);2597 eeprom_write_reg(p, EEPROM_BIT_CS | d | EEPROM_BIT_SK);2598}2599 2600/* push an opcode followed by an address down to the eeprom */2601static void eeprom_op(struct ipw_priv *priv, u8 op, u8 addr)2602{2603 int i;2604 2605 eeprom_cs(priv);2606 eeprom_write_bit(priv, 1);2607 eeprom_write_bit(priv, op & 2);2608 eeprom_write_bit(priv, op & 1);2609 for (i = 7; i >= 0; i--) {2610 eeprom_write_bit(priv, addr & (1 << i));2611 }2612}2613 2614/* pull 16 bits off the eeprom, one bit at a time */2615static u16 eeprom_read_u16(struct ipw_priv *priv, u8 addr)2616{2617 int i;2618 u16 r = 0;2619 2620 /* Send READ Opcode */2621 eeprom_op(priv, EEPROM_CMD_READ, addr);2622 2623 /* Send dummy bit */2624 eeprom_write_reg(priv, EEPROM_BIT_CS);2625 2626 /* Read the byte off the eeprom one bit at a time */2627 for (i = 0; i < 16; i++) {2628 u32 data = 0;2629 eeprom_write_reg(priv, EEPROM_BIT_CS | EEPROM_BIT_SK);2630 eeprom_write_reg(priv, EEPROM_BIT_CS);2631 data = ipw_read_reg32(priv, FW_MEM_REG_EEPROM_ACCESS);2632 r = (r << 1) | ((data & EEPROM_BIT_DO) ? 1 : 0);2633 }2634 2635 /* Send another dummy bit */2636 eeprom_write_reg(priv, 0);2637 eeprom_disable_cs(priv);2638 2639 return r;2640}2641 2642/* helper function for pulling the mac address out of the private */2643/* data's copy of the eeprom data */2644static void eeprom_parse_mac(struct ipw_priv *priv, u8 * mac)2645{2646 memcpy(mac, &priv->eeprom[EEPROM_MAC_ADDRESS], ETH_ALEN);2647}2648 2649static void ipw_read_eeprom(struct ipw_priv *priv)2650{2651 int i;2652 __le16 *eeprom = (__le16 *) priv->eeprom;2653 2654 IPW_DEBUG_TRACE(">>\n");2655 2656 /* read entire contents of eeprom into private buffer */2657 for (i = 0; i < 128; i++)2658 eeprom[i] = cpu_to_le16(eeprom_read_u16(priv, (u8) i));2659 2660 IPW_DEBUG_TRACE("<<\n");2661}2662 2663/*2664 * Either the device driver (i.e. the host) or the firmware can2665 * load eeprom data into the designated region in SRAM. If neither2666 * happens then the FW will shutdown with a fatal error.2667 *2668 * In order to signal the FW to load the EEPROM, the EEPROM_LOAD_DISABLE2669 * bit needs region of shared SRAM needs to be non-zero.2670 */2671static void ipw_eeprom_init_sram(struct ipw_priv *priv)2672{2673 int i;2674 2675 IPW_DEBUG_TRACE(">>\n");2676 2677 /*2678 If the data looks correct, then copy it to our private2679 copy. Otherwise let the firmware know to perform the operation2680 on its own.2681 */2682 if (priv->eeprom[EEPROM_VERSION] != 0) {2683 IPW_DEBUG_INFO("Writing EEPROM data into SRAM\n");2684 2685 /* write the eeprom data to sram */2686 for (i = 0; i < IPW_EEPROM_IMAGE_SIZE; i++)2687 ipw_write8(priv, IPW_EEPROM_DATA + i, priv->eeprom[i]);2688 2689 /* Do not load eeprom data on fatal error or suspend */2690 ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0);2691 } else {2692 IPW_DEBUG_INFO("Enabling FW initialization of SRAM\n");2693 2694 /* Load eeprom data on fatal error or suspend */2695 ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 1);2696 }2697 2698 IPW_DEBUG_TRACE("<<\n");2699}2700 2701static void ipw_zero_memory(struct ipw_priv *priv, u32 start, u32 count)2702{2703 count >>= 2;2704 if (!count)2705 return;2706 _ipw_write32(priv, IPW_AUTOINC_ADDR, start);2707 while (count--)2708 _ipw_write32(priv, IPW_AUTOINC_DATA, 0);2709}2710 2711static inline void ipw_fw_dma_reset_command_blocks(struct ipw_priv *priv)2712{2713 ipw_zero_memory(priv, IPW_SHARED_SRAM_DMA_CONTROL,2714 CB_NUMBER_OF_ELEMENTS_SMALL *2715 sizeof(struct command_block));2716}2717 2718static int ipw_fw_dma_enable(struct ipw_priv *priv)2719{ /* start dma engine but no transfers yet */2720 2721 IPW_DEBUG_FW(">> :\n");2722 2723 /* Start the dma */2724 ipw_fw_dma_reset_command_blocks(priv);2725 2726 /* Write CB base address */2727 ipw_write_reg32(priv, IPW_DMA_I_CB_BASE, IPW_SHARED_SRAM_DMA_CONTROL);2728 2729 IPW_DEBUG_FW("<< :\n");2730 return 0;2731}2732 2733static void ipw_fw_dma_abort(struct ipw_priv *priv)2734{2735 u32 control = 0;2736 2737 IPW_DEBUG_FW(">> :\n");2738 2739 /* set the Stop and Abort bit */2740 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_STOP_AND_ABORT;2741 ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);2742 priv->sram_desc.last_cb_index = 0;2743 2744 IPW_DEBUG_FW("<<\n");2745}2746 2747static int ipw_fw_dma_write_command_block(struct ipw_priv *priv, int index,2748 struct command_block *cb)2749{2750 u32 address =2751 IPW_SHARED_SRAM_DMA_CONTROL +2752 (sizeof(struct command_block) * index);2753 IPW_DEBUG_FW(">> :\n");2754 2755 ipw_write_indirect(priv, address, (u8 *) cb,2756 (int)sizeof(struct command_block));2757 2758 IPW_DEBUG_FW("<< :\n");2759 return 0;2760 2761}2762 2763static int ipw_fw_dma_kick(struct ipw_priv *priv)2764{2765 u32 control = 0;2766 u32 index = 0;2767 2768 IPW_DEBUG_FW(">> :\n");2769 2770 for (index = 0; index < priv->sram_desc.last_cb_index; index++)2771 ipw_fw_dma_write_command_block(priv, index,2772 &priv->sram_desc.cb_list[index]);2773 2774 /* Enable the DMA in the CSR register */2775 ipw_clear_bit(priv, IPW_RESET_REG,2776 IPW_RESET_REG_MASTER_DISABLED |2777 IPW_RESET_REG_STOP_MASTER);2778 2779 /* Set the Start bit. */2780 control = DMA_CONTROL_SMALL_CB_CONST_VALUE | DMA_CB_START;2781 ipw_write_reg32(priv, IPW_DMA_I_DMA_CONTROL, control);2782 2783 IPW_DEBUG_FW("<< :\n");2784 return 0;2785}2786 2787static void ipw_fw_dma_dump_command_block(struct ipw_priv *priv)2788{2789 u32 address;2790 u32 register_value = 0;2791 u32 cb_fields_address = 0;2792 2793 IPW_DEBUG_FW(">> :\n");2794 address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB);2795 IPW_DEBUG_FW_INFO("Current CB is 0x%x\n", address);2796 2797 /* Read the DMA Controlor register */2798 register_value = ipw_read_reg32(priv, IPW_DMA_I_DMA_CONTROL);2799 IPW_DEBUG_FW_INFO("IPW_DMA_I_DMA_CONTROL is 0x%x\n", register_value);2800 2801 /* Print the CB values */2802 cb_fields_address = address;2803 register_value = ipw_read_reg32(priv, cb_fields_address);2804 IPW_DEBUG_FW_INFO("Current CB Control Field is 0x%x\n", register_value);2805 2806 cb_fields_address += sizeof(u32);2807 register_value = ipw_read_reg32(priv, cb_fields_address);2808 IPW_DEBUG_FW_INFO("Current CB Source Field is 0x%x\n", register_value);2809 2810 cb_fields_address += sizeof(u32);2811 register_value = ipw_read_reg32(priv, cb_fields_address);2812 IPW_DEBUG_FW_INFO("Current CB Destination Field is 0x%x\n",2813 register_value);2814 2815 cb_fields_address += sizeof(u32);2816 register_value = ipw_read_reg32(priv, cb_fields_address);2817 IPW_DEBUG_FW_INFO("Current CB Status Field is 0x%x\n", register_value);2818 2819 IPW_DEBUG_FW(">> :\n");2820}2821 2822static int ipw_fw_dma_command_block_index(struct ipw_priv *priv)2823{2824 u32 current_cb_address = 0;2825 u32 current_cb_index = 0;2826 2827 IPW_DEBUG_FW("<< :\n");2828 current_cb_address = ipw_read_reg32(priv, IPW_DMA_I_CURRENT_CB);2829 2830 current_cb_index = (current_cb_address - IPW_SHARED_SRAM_DMA_CONTROL) /2831 sizeof(struct command_block);2832 2833 IPW_DEBUG_FW_INFO("Current CB index 0x%x address = 0x%X\n",2834 current_cb_index, current_cb_address);2835 2836 IPW_DEBUG_FW(">> :\n");2837 return current_cb_index;2838 2839}2840 2841static int ipw_fw_dma_add_command_block(struct ipw_priv *priv,2842 u32 src_address,2843 u32 dest_address,2844 u32 length,2845 int interrupt_enabled, int is_last)2846{2847 2848 u32 control = CB_VALID | CB_SRC_LE | CB_DEST_LE | CB_SRC_AUTOINC |2849 CB_SRC_IO_GATED | CB_DEST_AUTOINC | CB_SRC_SIZE_LONG |2850 CB_DEST_SIZE_LONG;2851 struct command_block *cb;2852 u32 last_cb_element = 0;2853 2854 IPW_DEBUG_FW_INFO("src_address=0x%x dest_address=0x%x length=0x%x\n",2855 src_address, dest_address, length);2856 2857 if (priv->sram_desc.last_cb_index >= CB_NUMBER_OF_ELEMENTS_SMALL)2858 return -1;2859 2860 last_cb_element = priv->sram_desc.last_cb_index;2861 cb = &priv->sram_desc.cb_list[last_cb_element];2862 priv->sram_desc.last_cb_index++;2863 2864 /* Calculate the new CB control word */2865 if (interrupt_enabled)2866 control |= CB_INT_ENABLED;2867 2868 if (is_last)2869 control |= CB_LAST_VALID;2870 2871 control |= length;2872 2873 /* Calculate the CB Element's checksum value */2874 cb->status = control ^ src_address ^ dest_address;2875 2876 /* Copy the Source and Destination addresses */2877 cb->dest_addr = dest_address;2878 cb->source_addr = src_address;2879 2880 /* Copy the Control Word last */2881 cb->control = control;2882 2883 return 0;2884}2885 2886static int ipw_fw_dma_add_buffer(struct ipw_priv *priv, dma_addr_t *src_address,2887 int nr, u32 dest_address, u32 len)2888{2889 int ret, i;2890 u32 size;2891 2892 IPW_DEBUG_FW(">>\n");2893 IPW_DEBUG_FW_INFO("nr=%d dest_address=0x%x len=0x%x\n",2894 nr, dest_address, len);2895 2896 for (i = 0; i < nr; i++) {2897 size = min_t(u32, len - i * CB_MAX_LENGTH, CB_MAX_LENGTH);2898 ret = ipw_fw_dma_add_command_block(priv, src_address[i],2899 dest_address +2900 i * CB_MAX_LENGTH, size,2901 0, 0);2902 if (ret) {2903 IPW_DEBUG_FW_INFO(": Failed\n");2904 return -1;2905 } else2906 IPW_DEBUG_FW_INFO(": Added new cb\n");2907 }2908 2909 IPW_DEBUG_FW("<<\n");2910 return 0;2911}2912 2913static int ipw_fw_dma_wait(struct ipw_priv *priv)2914{2915 u32 current_index = 0, previous_index;2916 u32 watchdog = 0;2917 2918 IPW_DEBUG_FW(">> :\n");2919 2920 current_index = ipw_fw_dma_command_block_index(priv);2921 IPW_DEBUG_FW_INFO("sram_desc.last_cb_index:0x%08X\n",2922 (int)priv->sram_desc.last_cb_index);2923 2924 while (current_index < priv->sram_desc.last_cb_index) {2925 udelay(50);2926 previous_index = current_index;2927 current_index = ipw_fw_dma_command_block_index(priv);2928 2929 if (previous_index < current_index) {2930 watchdog = 0;2931 continue;2932 }2933 if (++watchdog > 400) {2934 IPW_DEBUG_FW_INFO("Timeout\n");2935 ipw_fw_dma_dump_command_block(priv);2936 ipw_fw_dma_abort(priv);2937 return -1;2938 }2939 }2940 2941 ipw_fw_dma_abort(priv);2942 2943 /*Disable the DMA in the CSR register */2944 ipw_set_bit(priv, IPW_RESET_REG,2945 IPW_RESET_REG_MASTER_DISABLED | IPW_RESET_REG_STOP_MASTER);2946 2947 IPW_DEBUG_FW("<< dmaWaitSync\n");2948 return 0;2949}2950 2951static void ipw_remove_current_network(struct ipw_priv *priv)2952{2953 struct list_head *element, *safe;2954 struct libipw_network *network = NULL;2955 unsigned long flags;2956 2957 spin_lock_irqsave(&priv->ieee->lock, flags);2958 list_for_each_safe(element, safe, &priv->ieee->network_list) {2959 network = list_entry(element, struct libipw_network, list);2960 if (ether_addr_equal(network->bssid, priv->bssid)) {2961 list_del(element);2962 list_add_tail(&network->list,2963 &priv->ieee->network_free_list);2964 }2965 }2966 spin_unlock_irqrestore(&priv->ieee->lock, flags);2967}2968 2969/* timeout in msec, attempted in 10-msec quanta */2970static int ipw_poll_bit(struct ipw_priv *priv, u32 addr, u32 mask,2971 int timeout)2972{2973 int i = 0;2974 2975 do {2976 if ((ipw_read32(priv, addr) & mask) == mask)2977 return i;2978 mdelay(10);2979 i += 10;2980 } while (i < timeout);2981 2982 return -ETIME;2983}2984 2985/* These functions load the firmware and micro code for the operation of2986 * the ipw hardware. It assumes the buffer has all the bits for the2987 * image and the caller is handling the memory allocation and clean up.2988 */2989 2990static int ipw_stop_master(struct ipw_priv *priv)2991{2992 int rc;2993 2994 IPW_DEBUG_TRACE(">>\n");2995 /* stop master. typical delay - 0 */2996 ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);2997 2998 /* timeout is in msec, polled in 10-msec quanta */2999 rc = ipw_poll_bit(priv, IPW_RESET_REG,3000 IPW_RESET_REG_MASTER_DISABLED, 100);3001 if (rc < 0) {3002 IPW_ERROR("wait for stop master failed after 100ms\n");3003 return -1;3004 }3005 3006 IPW_DEBUG_INFO("stop master %dms\n", rc);3007 3008 return rc;3009}3010 3011static void ipw_arc_release(struct ipw_priv *priv)3012{3013 IPW_DEBUG_TRACE(">>\n");3014 mdelay(5);3015 3016 ipw_clear_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);3017 3018 /* no one knows timing, for safety add some delay */3019 mdelay(5);3020}3021 3022struct fw_chunk {3023 __le32 address;3024 __le32 length;3025};3026 3027static int ipw_load_ucode(struct ipw_priv *priv, u8 * data, size_t len)3028{3029 int rc = 0, i, addr;3030 u8 cr = 0;3031 __le16 *image;3032 3033 image = (__le16 *) data;3034 3035 IPW_DEBUG_TRACE(">>\n");3036 3037 rc = ipw_stop_master(priv);3038 3039 if (rc < 0)3040 return rc;3041 3042 for (addr = IPW_SHARED_LOWER_BOUND;3043 addr < IPW_REGISTER_DOMAIN1_END; addr += 4) {3044 ipw_write32(priv, addr, 0);3045 }3046 3047 /* no ucode (yet) */3048 memset(&priv->dino_alive, 0, sizeof(priv->dino_alive));3049 /* destroy DMA queues */3050 /* reset sequence */3051 3052 ipw_write_reg32(priv, IPW_MEM_HALT_AND_RESET, IPW_BIT_HALT_RESET_ON);3053 ipw_arc_release(priv);3054 ipw_write_reg32(priv, IPW_MEM_HALT_AND_RESET, IPW_BIT_HALT_RESET_OFF);3055 mdelay(1);3056 3057 /* reset PHY */3058 ipw_write_reg32(priv, IPW_INTERNAL_CMD_EVENT, IPW_BASEBAND_POWER_DOWN);3059 mdelay(1);3060 3061 ipw_write_reg32(priv, IPW_INTERNAL_CMD_EVENT, 0);3062 mdelay(1);3063 3064 /* enable ucode store */3065 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0x0);3066 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, DINO_ENABLE_CS);3067 mdelay(1);3068 3069 /* write ucode */3070 /*3071 * @bug3072 * Do NOT set indirect address register once and then3073 * store data to indirect data register in the loop.3074 * It seems very reasonable, but in this case DINO do not3075 * accept ucode. It is essential to set address each time.3076 */3077 /* load new ipw uCode */3078 for (i = 0; i < len / 2; i++)3079 ipw_write_reg16(priv, IPW_BASEBAND_CONTROL_STORE,3080 le16_to_cpu(image[i]));3081 3082 /* enable DINO */3083 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0);3084 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, DINO_ENABLE_SYSTEM);3085 3086 /* this is where the igx / win driver deveates from the VAP driver. */3087 3088 /* wait for alive response */3089 for (i = 0; i < 100; i++) {3090 /* poll for incoming data */3091 cr = ipw_read_reg8(priv, IPW_BASEBAND_CONTROL_STATUS);3092 if (cr & DINO_RXFIFO_DATA)3093 break;3094 mdelay(1);3095 }3096 3097 if (cr & DINO_RXFIFO_DATA) {3098 /* alive_command_responce size is NOT multiple of 4 */3099 __le32 response_buffer[(sizeof(priv->dino_alive) + 3) / 4];3100 3101 for (i = 0; i < ARRAY_SIZE(response_buffer); i++)3102 response_buffer[i] =3103 cpu_to_le32(ipw_read_reg32(priv,3104 IPW_BASEBAND_RX_FIFO_READ));3105 memcpy(&priv->dino_alive, response_buffer,3106 sizeof(priv->dino_alive));3107 if (priv->dino_alive.alive_command == 13108 && priv->dino_alive.ucode_valid == 1) {3109 rc = 0;3110 IPW_DEBUG_INFO3111 ("Microcode OK, rev. %d (0x%x) dev. %d (0x%x) "3112 "of %02d/%02d/%02d %02d:%02d\n",3113 priv->dino_alive.software_revision,3114 priv->dino_alive.software_revision,3115 priv->dino_alive.device_identifier,3116 priv->dino_alive.device_identifier,3117 priv->dino_alive.time_stamp[0],3118 priv->dino_alive.time_stamp[1],3119 priv->dino_alive.time_stamp[2],3120 priv->dino_alive.time_stamp[3],3121 priv->dino_alive.time_stamp[4]);3122 } else {3123 IPW_DEBUG_INFO("Microcode is not alive\n");3124 rc = -EINVAL;3125 }3126 } else {3127 IPW_DEBUG_INFO("No alive response from DINO\n");3128 rc = -ETIME;3129 }3130 3131 /* disable DINO, otherwise for some reason3132 firmware have problem getting alive resp. */3133 ipw_write_reg8(priv, IPW_BASEBAND_CONTROL_STATUS, 0);3134 3135 return rc;3136}3137 3138static int ipw_load_firmware(struct ipw_priv *priv, u8 * data, size_t len)3139{3140 int ret = -1;3141 int offset = 0;3142 struct fw_chunk *chunk;3143 int total_nr = 0;3144 int i;3145 struct dma_pool *pool;3146 void **virts;3147 dma_addr_t *phys;3148 3149 IPW_DEBUG_TRACE("<< :\n");3150 3151 virts = kmalloc_array(CB_NUMBER_OF_ELEMENTS_SMALL, sizeof(void *),3152 GFP_KERNEL);3153 if (!virts)3154 return -ENOMEM;3155 3156 phys = kmalloc_array(CB_NUMBER_OF_ELEMENTS_SMALL, sizeof(dma_addr_t),3157 GFP_KERNEL);3158 if (!phys) {3159 kfree(virts);3160 return -ENOMEM;3161 }3162 pool = dma_pool_create("ipw2200", &priv->pci_dev->dev, CB_MAX_LENGTH, 0,3163 0);3164 if (!pool) {3165 IPW_ERROR("dma_pool_create failed\n");3166 kfree(phys);3167 kfree(virts);3168 return -ENOMEM;3169 }3170 3171 /* Start the Dma */3172 ret = ipw_fw_dma_enable(priv);3173 3174 /* the DMA is already ready this would be a bug. */3175 BUG_ON(priv->sram_desc.last_cb_index > 0);3176 3177 do {3178 u32 chunk_len;3179 u8 *start;3180 int size;3181 int nr = 0;3182 3183 chunk = (struct fw_chunk *)(data + offset);3184 offset += sizeof(struct fw_chunk);3185 chunk_len = le32_to_cpu(chunk->length);3186 start = data + offset;3187 3188 nr = (chunk_len + CB_MAX_LENGTH - 1) / CB_MAX_LENGTH;3189 for (i = 0; i < nr; i++) {3190 virts[total_nr] = dma_pool_alloc(pool, GFP_KERNEL,3191 &phys[total_nr]);3192 if (!virts[total_nr]) {3193 ret = -ENOMEM;3194 goto out;3195 }3196 size = min_t(u32, chunk_len - i * CB_MAX_LENGTH,3197 CB_MAX_LENGTH);3198 memcpy(virts[total_nr], start, size);3199 start += size;3200 total_nr++;3201 /* We don't support fw chunk larger than 64*8K */3202 BUG_ON(total_nr > CB_NUMBER_OF_ELEMENTS_SMALL);3203 }3204 3205 /* build DMA packet and queue up for sending */3206 /* dma to chunk->address, the chunk->length bytes from data +3207 * offeset*/3208 /* Dma loading */3209 ret = ipw_fw_dma_add_buffer(priv, &phys[total_nr - nr],3210 nr, le32_to_cpu(chunk->address),3211 chunk_len);3212 if (ret) {3213 IPW_DEBUG_INFO("dmaAddBuffer Failed\n");3214 goto out;3215 }3216 3217 offset += chunk_len;3218 } while (offset < len);3219 3220 /* Run the DMA and wait for the answer */3221 ret = ipw_fw_dma_kick(priv);3222 if (ret) {3223 IPW_ERROR("dmaKick Failed\n");3224 goto out;3225 }3226 3227 ret = ipw_fw_dma_wait(priv);3228 if (ret) {3229 IPW_ERROR("dmaWaitSync Failed\n");3230 goto out;3231 }3232 out:3233 for (i = 0; i < total_nr; i++)3234 dma_pool_free(pool, virts[i], phys[i]);3235 3236 dma_pool_destroy(pool);3237 kfree(phys);3238 kfree(virts);3239 3240 return ret;3241}3242 3243/* stop nic */3244static int ipw_stop_nic(struct ipw_priv *priv)3245{3246 int rc = 0;3247 3248 /* stop */3249 ipw_write32(priv, IPW_RESET_REG, IPW_RESET_REG_STOP_MASTER);3250 3251 rc = ipw_poll_bit(priv, IPW_RESET_REG,3252 IPW_RESET_REG_MASTER_DISABLED, 500);3253 if (rc < 0) {3254 IPW_ERROR("wait for reg master disabled failed after 500ms\n");3255 return rc;3256 }3257 3258 ipw_set_bit(priv, IPW_RESET_REG, CBD_RESET_REG_PRINCETON_RESET);3259 3260 return rc;3261}3262 3263static void ipw_start_nic(struct ipw_priv *priv)3264{3265 IPW_DEBUG_TRACE(">>\n");3266 3267 /* prvHwStartNic release ARC */3268 ipw_clear_bit(priv, IPW_RESET_REG,3269 IPW_RESET_REG_MASTER_DISABLED |3270 IPW_RESET_REG_STOP_MASTER |3271 CBD_RESET_REG_PRINCETON_RESET);3272 3273 /* enable power management */3274 ipw_set_bit(priv, IPW_GP_CNTRL_RW,3275 IPW_GP_CNTRL_BIT_HOST_ALLOWS_STANDBY);3276 3277 IPW_DEBUG_TRACE("<<\n");3278}3279 3280static int ipw_init_nic(struct ipw_priv *priv)3281{3282 int rc;3283 3284 IPW_DEBUG_TRACE(">>\n");3285 /* reset */3286 /*prvHwInitNic */3287 /* set "initialization complete" bit to move adapter to D0 state */3288 ipw_set_bit(priv, IPW_GP_CNTRL_RW, IPW_GP_CNTRL_BIT_INIT_DONE);3289 3290 /* low-level PLL activation */3291 ipw_write32(priv, IPW_READ_INT_REGISTER,3292 IPW_BIT_INT_HOST_SRAM_READ_INT_REGISTER);3293 3294 /* wait for clock stabilization */3295 rc = ipw_poll_bit(priv, IPW_GP_CNTRL_RW,3296 IPW_GP_CNTRL_BIT_CLOCK_READY, 250);3297 if (rc < 0)3298 IPW_DEBUG_INFO("FAILED wait for clock stablization\n");3299 3300 /* assert SW reset */3301 ipw_set_bit(priv, IPW_RESET_REG, IPW_RESET_REG_SW_RESET);3302 3303 udelay(10);3304 3305 /* set "initialization complete" bit to move adapter to D0 state */3306 ipw_set_bit(priv, IPW_GP_CNTRL_RW, IPW_GP_CNTRL_BIT_INIT_DONE);3307 3308 IPW_DEBUG_TRACE(">>\n");3309 return 0;3310}3311 3312/* Call this function from process context, it will sleep in request_firmware.3313 * Probe is an ok place to call this from.3314 */3315static int ipw_reset_nic(struct ipw_priv *priv)3316{3317 int rc = 0;3318 unsigned long flags;3319 3320 IPW_DEBUG_TRACE(">>\n");3321 3322 rc = ipw_init_nic(priv);3323 3324 spin_lock_irqsave(&priv->lock, flags);3325 /* Clear the 'host command active' bit... */3326 priv->status &= ~STATUS_HCMD_ACTIVE;3327 wake_up_interruptible(&priv->wait_command_queue);3328 priv->status &= ~(STATUS_SCANNING | STATUS_SCAN_ABORTING);3329 wake_up_interruptible(&priv->wait_state);3330 spin_unlock_irqrestore(&priv->lock, flags);3331 3332 IPW_DEBUG_TRACE("<<\n");3333 return rc;3334}3335 3336 3337struct ipw_fw {3338 __le32 ver;3339 __le32 boot_size;3340 __le32 ucode_size;3341 __le32 fw_size;3342 u8 data[];3343};3344 3345static int ipw_get_fw(struct ipw_priv *priv,3346 const struct firmware **raw, const char *name)3347{3348 struct ipw_fw *fw;3349 int rc;3350 3351 /* ask firmware_class module to get the boot firmware off disk */3352 rc = request_firmware(raw, name, &priv->pci_dev->dev);3353 if (rc < 0) {3354 IPW_ERROR("%s request_firmware failed: Reason %d\n", name, rc);3355 return rc;3356 }3357 3358 if ((*raw)->size < sizeof(*fw)) {3359 IPW_ERROR("%s is too small (%zd)\n", name, (*raw)->size);3360 return -EINVAL;3361 }3362 3363 fw = (void *)(*raw)->data;3364 3365 if ((*raw)->size < sizeof(*fw) + le32_to_cpu(fw->boot_size) +3366 le32_to_cpu(fw->ucode_size) + le32_to_cpu(fw->fw_size)) {3367 IPW_ERROR("%s is too small or corrupt (%zd)\n",3368 name, (*raw)->size);3369 return -EINVAL;3370 }3371 3372 IPW_DEBUG_INFO("Read firmware '%s' image v%d.%d (%zd bytes)\n",3373 name,3374 le32_to_cpu(fw->ver) >> 16,3375 le32_to_cpu(fw->ver) & 0xff,3376 (*raw)->size - sizeof(*fw));3377 return 0;3378}3379 3380#define IPW_RX_BUF_SIZE (3000)3381 3382static void ipw_rx_queue_reset(struct ipw_priv *priv,3383 struct ipw_rx_queue *rxq)3384{3385 unsigned long flags;3386 int i;3387 3388 spin_lock_irqsave(&rxq->lock, flags);3389 3390 INIT_LIST_HEAD(&rxq->rx_free);3391 INIT_LIST_HEAD(&rxq->rx_used);3392 3393 /* Fill the rx_used queue with _all_ of the Rx buffers */3394 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {3395 /* In the reset function, these buffers may have been allocated3396 * to an SKB, so we need to unmap and free potential storage */3397 if (rxq->pool[i].skb != NULL) {3398 dma_unmap_single(&priv->pci_dev->dev,3399 rxq->pool[i].dma_addr,3400 IPW_RX_BUF_SIZE, DMA_FROM_DEVICE);3401 dev_kfree_skb_irq(rxq->pool[i].skb);3402 rxq->pool[i].skb = NULL;3403 }3404 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);3405 }3406 3407 /* Set us so that we have processed and used all buffers, but have3408 * not restocked the Rx queue with fresh buffers */3409 rxq->read = rxq->write = 0;3410 rxq->free_count = 0;3411 spin_unlock_irqrestore(&rxq->lock, flags);3412}3413 3414#ifdef CONFIG_PM3415static int fw_loaded = 0;3416static const struct firmware *raw = NULL;3417 3418static void free_firmware(void)3419{3420 if (fw_loaded) {3421 release_firmware(raw);3422 raw = NULL;3423 fw_loaded = 0;3424 }3425}3426#else3427#define free_firmware() do {} while (0)3428#endif3429 3430static int ipw_load(struct ipw_priv *priv)3431{3432#ifndef CONFIG_PM3433 const struct firmware *raw = NULL;3434#endif3435 struct ipw_fw *fw;3436 u8 *boot_img, *ucode_img, *fw_img;3437 u8 *name = NULL;3438 int rc = 0, retries = 3;3439 3440 switch (priv->ieee->iw_mode) {3441 case IW_MODE_ADHOC:3442 name = "ipw2200-ibss.fw";3443 break;3444#ifdef CONFIG_IPW2200_MONITOR3445 case IW_MODE_MONITOR:3446 name = "ipw2200-sniffer.fw";3447 break;3448#endif3449 case IW_MODE_INFRA:3450 name = "ipw2200-bss.fw";3451 break;3452 }3453 3454 if (!name) {3455 rc = -EINVAL;3456 goto error;3457 }3458 3459#ifdef CONFIG_PM3460 if (!fw_loaded) {3461#endif3462 rc = ipw_get_fw(priv, &raw, name);3463 if (rc < 0)3464 goto error;3465#ifdef CONFIG_PM3466 }3467#endif3468 3469 fw = (void *)raw->data;3470 boot_img = &fw->data[0];3471 ucode_img = &fw->data[le32_to_cpu(fw->boot_size)];3472 fw_img = &fw->data[le32_to_cpu(fw->boot_size) +3473 le32_to_cpu(fw->ucode_size)];3474 3475 if (!priv->rxq)3476 priv->rxq = ipw_rx_queue_alloc(priv);3477 else3478 ipw_rx_queue_reset(priv, priv->rxq);3479 if (!priv->rxq) {3480 IPW_ERROR("Unable to initialize Rx queue\n");3481 rc = -ENOMEM;3482 goto error;3483 }3484 3485 retry:3486 /* Ensure interrupts are disabled */3487 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);3488 priv->status &= ~STATUS_INT_ENABLED;3489 3490 /* ack pending interrupts */3491 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);3492 3493 ipw_stop_nic(priv);3494 3495 rc = ipw_reset_nic(priv);3496 if (rc < 0) {3497 IPW_ERROR("Unable to reset NIC\n");3498 goto error;3499 }3500 3501 ipw_zero_memory(priv, IPW_NIC_SRAM_LOWER_BOUND,3502 IPW_NIC_SRAM_UPPER_BOUND - IPW_NIC_SRAM_LOWER_BOUND);3503 3504 /* DMA the initial boot firmware into the device */3505 rc = ipw_load_firmware(priv, boot_img, le32_to_cpu(fw->boot_size));3506 if (rc < 0) {3507 IPW_ERROR("Unable to load boot firmware: %d\n", rc);3508 goto error;3509 }3510 3511 /* kick start the device */3512 ipw_start_nic(priv);3513 3514 /* wait for the device to finish its initial startup sequence */3515 rc = ipw_poll_bit(priv, IPW_INTA_RW,3516 IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);3517 if (rc < 0) {3518 IPW_ERROR("device failed to boot initial fw image\n");3519 goto error;3520 }3521 IPW_DEBUG_INFO("initial device response after %dms\n", rc);3522 3523 /* ack fw init done interrupt */3524 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);3525 3526 /* DMA the ucode into the device */3527 rc = ipw_load_ucode(priv, ucode_img, le32_to_cpu(fw->ucode_size));3528 if (rc < 0) {3529 IPW_ERROR("Unable to load ucode: %d\n", rc);3530 goto error;3531 }3532 3533 /* stop nic */3534 ipw_stop_nic(priv);3535 3536 /* DMA bss firmware into the device */3537 rc = ipw_load_firmware(priv, fw_img, le32_to_cpu(fw->fw_size));3538 if (rc < 0) {3539 IPW_ERROR("Unable to load firmware: %d\n", rc);3540 goto error;3541 }3542#ifdef CONFIG_PM3543 fw_loaded = 1;3544#endif3545 3546 ipw_write32(priv, IPW_EEPROM_LOAD_DISABLE, 0);3547 3548 rc = ipw_queue_reset(priv);3549 if (rc < 0) {3550 IPW_ERROR("Unable to initialize queues\n");3551 goto error;3552 }3553 3554 /* Ensure interrupts are disabled */3555 ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);3556 /* ack pending interrupts */3557 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);3558 3559 /* kick start the device */3560 ipw_start_nic(priv);3561 3562 if (ipw_read32(priv, IPW_INTA_RW) & IPW_INTA_BIT_PARITY_ERROR) {3563 if (retries > 0) {3564 IPW_WARNING("Parity error. Retrying init.\n");3565 retries--;3566 goto retry;3567 }3568 3569 IPW_ERROR("TODO: Handle parity error -- schedule restart?\n");3570 rc = -EIO;3571 goto error;3572 }3573 3574 /* wait for the device */3575 rc = ipw_poll_bit(priv, IPW_INTA_RW,3576 IPW_INTA_BIT_FW_INITIALIZATION_DONE, 500);3577 if (rc < 0) {3578 IPW_ERROR("device failed to start within 500ms\n");3579 goto error;3580 }3581 IPW_DEBUG_INFO("device response after %dms\n", rc);3582 3583 /* ack fw init done interrupt */3584 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_BIT_FW_INITIALIZATION_DONE);3585 3586 /* read eeprom data */3587 priv->eeprom_delay = 1;3588 ipw_read_eeprom(priv);3589 /* initialize the eeprom region of sram */3590 ipw_eeprom_init_sram(priv);3591 3592 /* enable interrupts */3593 ipw_enable_interrupts(priv);3594 3595 /* Ensure our queue has valid packets */3596 ipw_rx_queue_replenish(priv);3597 3598 ipw_write32(priv, IPW_RX_READ_INDEX, priv->rxq->read);3599 3600 /* ack pending interrupts */3601 ipw_write32(priv, IPW_INTA_RW, IPW_INTA_MASK_ALL);3602 3603#ifndef CONFIG_PM3604 release_firmware(raw);3605#endif3606 return 0;3607 3608 error:3609 if (priv->rxq) {3610 ipw_rx_queue_free(priv, priv->rxq);3611 priv->rxq = NULL;3612 }3613 ipw_tx_queue_free(priv);3614 release_firmware(raw);3615#ifdef CONFIG_PM3616 fw_loaded = 0;3617 raw = NULL;3618#endif3619 3620 return rc;3621}3622 3623/*3624 * DMA services3625 *3626 * Theory of operation3627 *3628 * A queue is a circular buffers with 'Read' and 'Write' pointers.3629 * 2 empty entries always kept in the buffer to protect from overflow.3630 *3631 * For Tx queue, there are low mark and high mark limits. If, after queuing3632 * the packet for Tx, free space become < low mark, Tx queue stopped. When3633 * reclaiming packets (on 'tx done IRQ), if free space become > high mark,3634 * Tx queue resumed.3635 *3636 * The IPW operates with six queues, one receive queue in the device's3637 * sram, one transmit queue for sending commands to the device firmware,3638 * and four transmit queues for data.3639 *3640 * The four transmit queues allow for performing quality of service (qos)3641 * transmissions as per the 802.11 protocol. Currently Linux does not3642 * provide a mechanism to the user for utilizing prioritized queues, so3643 * we only utilize the first data transmit queue (queue1).3644 */3645 3646/*3647 * Driver allocates buffers of this size for Rx3648 */3649 3650/*3651 * ipw_rx_queue_space - Return number of free slots available in queue.3652 */3653static int ipw_rx_queue_space(const struct ipw_rx_queue *q)3654{3655 int s = q->read - q->write;3656 if (s <= 0)3657 s += RX_QUEUE_SIZE;3658 /* keep some buffer to not confuse full and empty queue */3659 s -= 2;3660 if (s < 0)3661 s = 0;3662 return s;3663}3664 3665static inline int ipw_tx_queue_space(const struct clx2_queue *q)3666{3667 int s = q->last_used - q->first_empty;3668 if (s <= 0)3669 s += q->n_bd;3670 s -= 2; /* keep some reserve to not confuse empty and full situations */3671 if (s < 0)3672 s = 0;3673 return s;3674}3675 3676static inline int ipw_queue_inc_wrap(int index, int n_bd)3677{3678 return (++index == n_bd) ? 0 : index;3679}3680 3681/*3682 * Initialize common DMA queue structure3683 *3684 * @param q queue to init3685 * @param count Number of BD's to allocate. Should be power of 23686 * @param read_register Address for 'read' register3687 * (not offset within BAR, full address)3688 * @param write_register Address for 'write' register3689 * (not offset within BAR, full address)3690 * @param base_register Address for 'base' register3691 * (not offset within BAR, full address)3692 * @param size Address for 'size' register3693 * (not offset within BAR, full address)3694 */3695static void ipw_queue_init(struct ipw_priv *priv, struct clx2_queue *q,3696 int count, u32 read, u32 write, u32 base, u32 size)3697{3698 q->n_bd = count;3699 3700 q->low_mark = q->n_bd / 4;3701 if (q->low_mark < 4)3702 q->low_mark = 4;3703 3704 q->high_mark = q->n_bd / 8;3705 if (q->high_mark < 2)3706 q->high_mark = 2;3707 3708 q->first_empty = q->last_used = 0;3709 q->reg_r = read;3710 q->reg_w = write;3711 3712 ipw_write32(priv, base, q->dma_addr);3713 ipw_write32(priv, size, count);3714 ipw_write32(priv, read, 0);3715 ipw_write32(priv, write, 0);3716 3717 _ipw_read32(priv, 0x90);3718}3719 3720static int ipw_queue_tx_init(struct ipw_priv *priv,3721 struct clx2_tx_queue *q,3722 int count, u32 read, u32 write, u32 base, u32 size)3723{3724 struct pci_dev *dev = priv->pci_dev;3725 3726 q->txb = kmalloc_array(count, sizeof(q->txb[0]), GFP_KERNEL);3727 if (!q->txb)3728 return -ENOMEM;3729 3730 q->bd =3731 dma_alloc_coherent(&dev->dev, sizeof(q->bd[0]) * count,3732 &q->q.dma_addr, GFP_KERNEL);3733 if (!q->bd) {3734 IPW_ERROR("dma_alloc_coherent(%zd) failed\n",3735 sizeof(q->bd[0]) * count);3736 kfree(q->txb);3737 q->txb = NULL;3738 return -ENOMEM;3739 }3740 3741 ipw_queue_init(priv, &q->q, count, read, write, base, size);3742 return 0;3743}3744 3745/*3746 * Free one TFD, those at index [txq->q.last_used].3747 * Do NOT advance any indexes3748 *3749 * @param dev3750 * @param txq3751 */3752static void ipw_queue_tx_free_tfd(struct ipw_priv *priv,3753 struct clx2_tx_queue *txq)3754{3755 struct tfd_frame *bd = &txq->bd[txq->q.last_used];3756 struct pci_dev *dev = priv->pci_dev;3757 int i;3758 3759 /* classify bd */3760 if (bd->control_flags.message_type == TX_HOST_COMMAND_TYPE)3761 /* nothing to cleanup after for host commands */3762 return;3763 3764 /* sanity check */3765 if (le32_to_cpu(bd->u.data.num_chunks) > NUM_TFD_CHUNKS) {3766 IPW_ERROR("Too many chunks: %i\n",3767 le32_to_cpu(bd->u.data.num_chunks));3768 /* @todo issue fatal error, it is quite serious situation */3769 return;3770 }3771 3772 /* unmap chunks if any */3773 for (i = 0; i < le32_to_cpu(bd->u.data.num_chunks); i++) {3774 dma_unmap_single(&dev->dev,3775 le32_to_cpu(bd->u.data.chunk_ptr[i]),3776 le16_to_cpu(bd->u.data.chunk_len[i]),3777 DMA_TO_DEVICE);3778 if (txq->txb[txq->q.last_used]) {3779 libipw_txb_free(txq->txb[txq->q.last_used]);3780 txq->txb[txq->q.last_used] = NULL;3781 }3782 }3783}3784 3785/*3786 * Deallocate DMA queue.3787 *3788 * Empty queue by removing and destroying all BD's.3789 * Free all buffers.3790 *3791 * @param dev3792 * @param q3793 */3794static void ipw_queue_tx_free(struct ipw_priv *priv, struct clx2_tx_queue *txq)3795{3796 struct clx2_queue *q = &txq->q;3797 struct pci_dev *dev = priv->pci_dev;3798 3799 if (q->n_bd == 0)3800 return;3801 3802 /* first, empty all BD's */3803 for (; q->first_empty != q->last_used;3804 q->last_used = ipw_queue_inc_wrap(q->last_used, q->n_bd)) {3805 ipw_queue_tx_free_tfd(priv, txq);3806 }3807 3808 /* free buffers belonging to queue itself */3809 dma_free_coherent(&dev->dev, sizeof(txq->bd[0]) * q->n_bd, txq->bd,3810 q->dma_addr);3811 kfree(txq->txb);3812 3813 /* 0 fill whole structure */3814 memset(txq, 0, sizeof(*txq));3815}3816 3817/*3818 * Destroy all DMA queues and structures3819 *3820 * @param priv3821 */3822static void ipw_tx_queue_free(struct ipw_priv *priv)3823{3824 /* Tx CMD queue */3825 ipw_queue_tx_free(priv, &priv->txq_cmd);3826 3827 /* Tx queues */3828 ipw_queue_tx_free(priv, &priv->txq[0]);3829 ipw_queue_tx_free(priv, &priv->txq[1]);3830 ipw_queue_tx_free(priv, &priv->txq[2]);3831 ipw_queue_tx_free(priv, &priv->txq[3]);3832}3833 3834static void ipw_create_bssid(struct ipw_priv *priv, u8 * bssid)3835{3836 /* First 3 bytes are manufacturer */3837 bssid[0] = priv->mac_addr[0];3838 bssid[1] = priv->mac_addr[1];3839 bssid[2] = priv->mac_addr[2];3840 3841 /* Last bytes are random */3842 get_random_bytes(&bssid[3], ETH_ALEN - 3);3843 3844 bssid[0] &= 0xfe; /* clear multicast bit */3845 bssid[0] |= 0x02; /* set local assignment bit (IEEE802) */3846}3847 3848static u8 ipw_add_station(struct ipw_priv *priv, u8 * bssid)3849{3850 struct ipw_station_entry entry;3851 int i;3852 3853 for (i = 0; i < priv->num_stations; i++) {3854 if (ether_addr_equal(priv->stations[i], bssid)) {3855 /* Another node is active in network */3856 priv->missed_adhoc_beacons = 0;3857 if (!(priv->config & CFG_STATIC_CHANNEL))3858 /* when other nodes drop out, we drop out */3859 priv->config &= ~CFG_ADHOC_PERSIST;3860 3861 return i;3862 }3863 }3864 3865 if (i == MAX_STATIONS)3866 return IPW_INVALID_STATION;3867 3868 IPW_DEBUG_SCAN("Adding AdHoc station: %pM\n", bssid);3869 3870 entry.reserved = 0;3871 entry.support_mode = 0;3872 memcpy(entry.mac_addr, bssid, ETH_ALEN);3873 memcpy(priv->stations[i], bssid, ETH_ALEN);3874 ipw_write_direct(priv, IPW_STATION_TABLE_LOWER + i * sizeof(entry),3875 &entry, sizeof(entry));3876 priv->num_stations++;3877 3878 return i;3879}3880 3881static u8 ipw_find_station(struct ipw_priv *priv, u8 * bssid)3882{3883 int i;3884 3885 for (i = 0; i < priv->num_stations; i++)3886 if (ether_addr_equal(priv->stations[i], bssid))3887 return i;3888 3889 return IPW_INVALID_STATION;3890}3891 3892static void ipw_send_disassociate(struct ipw_priv *priv, int quiet)3893{3894 int err;3895 3896 if (priv->status & STATUS_ASSOCIATING) {3897 IPW_DEBUG_ASSOC("Disassociating while associating.\n");3898 schedule_work(&priv->disassociate);3899 return;3900 }3901 3902 if (!(priv->status & STATUS_ASSOCIATED)) {3903 IPW_DEBUG_ASSOC("Disassociating while not associated.\n");3904 return;3905 }3906 3907 IPW_DEBUG_ASSOC("Disassociation attempt from %pM "3908 "on channel %d.\n",3909 priv->assoc_request.bssid,3910 priv->assoc_request.channel);3911 3912 priv->status &= ~(STATUS_ASSOCIATING | STATUS_ASSOCIATED);3913 priv->status |= STATUS_DISASSOCIATING;3914 3915 if (quiet)3916 priv->assoc_request.assoc_type = HC_DISASSOC_QUIET;3917 else3918 priv->assoc_request.assoc_type = HC_DISASSOCIATE;3919 3920 err = ipw_send_associate(priv, &priv->assoc_request);3921 if (err) {3922 IPW_DEBUG_HC("Attempt to send [dis]associate command "3923 "failed.\n");3924 return;3925 }3926 3927}3928 3929static int ipw_disassociate(void *data)3930{3931 struct ipw_priv *priv = data;3932 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))3933 return 0;3934 ipw_send_disassociate(data, 0);3935 netif_carrier_off(priv->net_dev);3936 return 1;3937}3938 3939static void ipw_bg_disassociate(struct work_struct *work)3940{3941 struct ipw_priv *priv =3942 container_of(work, struct ipw_priv, disassociate);3943 mutex_lock(&priv->mutex);3944 ipw_disassociate(priv);3945 mutex_unlock(&priv->mutex);3946}3947 3948static void ipw_system_config(struct work_struct *work)3949{3950 struct ipw_priv *priv =3951 container_of(work, struct ipw_priv, system_config);3952 3953#ifdef CONFIG_IPW2200_PROMISCUOUS3954 if (priv->prom_net_dev && netif_running(priv->prom_net_dev)) {3955 priv->sys_config.accept_all_data_frames = 1;3956 priv->sys_config.accept_non_directed_frames = 1;3957 priv->sys_config.accept_all_mgmt_bcpr = 1;3958 priv->sys_config.accept_all_mgmt_frames = 1;3959 }3960#endif3961 3962 ipw_send_system_config(priv);3963}3964 3965struct ipw_status_code {3966 u16 status;3967 const char *reason;3968};3969 3970static const struct ipw_status_code ipw_status_codes[] = {3971 {0x00, "Successful"},3972 {0x01, "Unspecified failure"},3973 {0x0A, "Cannot support all requested capabilities in the "3974 "Capability information field"},3975 {0x0B, "Reassociation denied due to inability to confirm that "3976 "association exists"},3977 {0x0C, "Association denied due to reason outside the scope of this "3978 "standard"},3979 {0x0D,3980 "Responding station does not support the specified authentication "3981 "algorithm"},3982 {0x0E,3983 "Received an Authentication frame with authentication sequence "3984 "transaction sequence number out of expected sequence"},3985 {0x0F, "Authentication rejected because of challenge failure"},3986 {0x10, "Authentication rejected due to timeout waiting for next "3987 "frame in sequence"},3988 {0x11, "Association denied because AP is unable to handle additional "3989 "associated stations"},3990 {0x12,3991 "Association denied due to requesting station not supporting all "3992 "of the datarates in the BSSBasicServiceSet Parameter"},3993 {0x13,3994 "Association denied due to requesting station not supporting "3995 "short preamble operation"},3996 {0x14,3997 "Association denied due to requesting station not supporting "3998 "PBCC encoding"},3999 {0x15,4000 "Association denied due to requesting station not supporting "4001 "channel agility"},4002 {0x19,4003 "Association denied due to requesting station not supporting "4004 "short slot operation"},4005 {0x1A,4006 "Association denied due to requesting station not supporting "4007 "DSSS-OFDM operation"},4008 {0x28, "Invalid Information Element"},4009 {0x29, "Group Cipher is not valid"},4010 {0x2A, "Pairwise Cipher is not valid"},4011 {0x2B, "AKMP is not valid"},4012 {0x2C, "Unsupported RSN IE version"},4013 {0x2D, "Invalid RSN IE Capabilities"},4014 {0x2E, "Cipher suite is rejected per security policy"},4015};4016 4017static const char *ipw_get_status_code(u16 status)4018{4019 int i;4020 for (i = 0; i < ARRAY_SIZE(ipw_status_codes); i++)4021 if (ipw_status_codes[i].status == (status & 0xff))4022 return ipw_status_codes[i].reason;4023 return "Unknown status value.";4024}4025 4026static inline void average_init(struct average *avg)4027{4028 memset(avg, 0, sizeof(*avg));4029}4030 4031#define DEPTH_RSSI 84032#define DEPTH_NOISE 164033static s16 exponential_average(s16 prev_avg, s16 val, u8 depth)4034{4035 return ((depth-1)*prev_avg + val)/depth;4036}4037 4038static void average_add(struct average *avg, s16 val)4039{4040 avg->sum -= avg->entries[avg->pos];4041 avg->sum += val;4042 avg->entries[avg->pos++] = val;4043 if (unlikely(avg->pos == AVG_ENTRIES)) {4044 avg->init = 1;4045 avg->pos = 0;4046 }4047}4048 4049static s16 average_value(struct average *avg)4050{4051 if (!unlikely(avg->init)) {4052 if (avg->pos)4053 return avg->sum / avg->pos;4054 return 0;4055 }4056 4057 return avg->sum / AVG_ENTRIES;4058}4059 4060static void ipw_reset_stats(struct ipw_priv *priv)4061{4062 u32 len = sizeof(u32);4063 4064 priv->quality = 0;4065 4066 average_init(&priv->average_missed_beacons);4067 priv->exp_avg_rssi = -60;4068 priv->exp_avg_noise = -85 + 0x100;4069 4070 priv->last_rate = 0;4071 priv->last_missed_beacons = 0;4072 priv->last_rx_packets = 0;4073 priv->last_tx_packets = 0;4074 priv->last_tx_failures = 0;4075 4076 /* Firmware managed, reset only when NIC is restarted, so we have to4077 * normalize on the current value */4078 ipw_get_ordinal(priv, IPW_ORD_STAT_RX_ERR_CRC,4079 &priv->last_rx_err, &len);4080 ipw_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURE,4081 &priv->last_tx_failures, &len);4082 4083 /* Driver managed, reset with each association */4084 priv->missed_adhoc_beacons = 0;4085 priv->missed_beacons = 0;4086 priv->tx_packets = 0;4087 priv->rx_packets = 0;4088 4089}4090 4091static u32 ipw_get_max_rate(struct ipw_priv *priv)4092{4093 u32 i = 0x80000000;4094 u32 mask = priv->rates_mask;4095 /* If currently associated in B mode, restrict the maximum4096 * rate match to B rates */4097 if (priv->assoc_request.ieee_mode == IPW_B_MODE)4098 mask &= LIBIPW_CCK_RATES_MASK;4099 4100 /* TODO: Verify that the rate is supported by the current rates4101 * list. */4102 4103 while (i && !(mask & i))4104 i >>= 1;4105 switch (i) {4106 case LIBIPW_CCK_RATE_1MB_MASK:4107 return 1000000;4108 case LIBIPW_CCK_RATE_2MB_MASK:4109 return 2000000;4110 case LIBIPW_CCK_RATE_5MB_MASK:4111 return 5500000;4112 case LIBIPW_OFDM_RATE_6MB_MASK:4113 return 6000000;4114 case LIBIPW_OFDM_RATE_9MB_MASK:4115 return 9000000;4116 case LIBIPW_CCK_RATE_11MB_MASK:4117 return 11000000;4118 case LIBIPW_OFDM_RATE_12MB_MASK:4119 return 12000000;4120 case LIBIPW_OFDM_RATE_18MB_MASK:4121 return 18000000;4122 case LIBIPW_OFDM_RATE_24MB_MASK:4123 return 24000000;4124 case LIBIPW_OFDM_RATE_36MB_MASK:4125 return 36000000;4126 case LIBIPW_OFDM_RATE_48MB_MASK:4127 return 48000000;4128 case LIBIPW_OFDM_RATE_54MB_MASK:4129 return 54000000;4130 }4131 4132 if (priv->ieee->mode == IEEE_B)4133 return 11000000;4134 else4135 return 54000000;4136}4137 4138static u32 ipw_get_current_rate(struct ipw_priv *priv)4139{4140 u32 rate, len = sizeof(rate);4141 int err;4142 4143 if (!(priv->status & STATUS_ASSOCIATED))4144 return 0;4145 4146 if (priv->tx_packets > IPW_REAL_RATE_RX_PACKET_THRESHOLD) {4147 err = ipw_get_ordinal(priv, IPW_ORD_STAT_TX_CURR_RATE, &rate,4148 &len);4149 if (err) {4150 IPW_DEBUG_INFO("failed querying ordinals.\n");4151 return 0;4152 }4153 } else4154 return ipw_get_max_rate(priv);4155 4156 switch (rate) {4157 case IPW_TX_RATE_1MB:4158 return 1000000;4159 case IPW_TX_RATE_2MB:4160 return 2000000;4161 case IPW_TX_RATE_5MB:4162 return 5500000;4163 case IPW_TX_RATE_6MB:4164 return 6000000;4165 case IPW_TX_RATE_9MB:4166 return 9000000;4167 case IPW_TX_RATE_11MB:4168 return 11000000;4169 case IPW_TX_RATE_12MB:4170 return 12000000;4171 case IPW_TX_RATE_18MB:4172 return 18000000;4173 case IPW_TX_RATE_24MB:4174 return 24000000;4175 case IPW_TX_RATE_36MB:4176 return 36000000;4177 case IPW_TX_RATE_48MB:4178 return 48000000;4179 case IPW_TX_RATE_54MB:4180 return 54000000;4181 }4182 4183 return 0;4184}4185 4186#define IPW_STATS_INTERVAL (2 * HZ)4187static void ipw_gather_stats(struct ipw_priv *priv)4188{4189 u32 rx_err, rx_err_delta, rx_packets_delta;4190 u32 tx_failures, tx_failures_delta, tx_packets_delta;4191 u32 missed_beacons_percent, missed_beacons_delta;4192 u32 quality = 0;4193 u32 len = sizeof(u32);4194 s16 rssi;4195 u32 beacon_quality, signal_quality, tx_quality, rx_quality,4196 rate_quality;4197 u32 max_rate;4198 4199 if (!(priv->status & STATUS_ASSOCIATED)) {4200 priv->quality = 0;4201 return;4202 }4203 4204 /* Update the statistics */4205 ipw_get_ordinal(priv, IPW_ORD_STAT_MISSED_BEACONS,4206 &priv->missed_beacons, &len);4207 missed_beacons_delta = priv->missed_beacons - priv->last_missed_beacons;4208 priv->last_missed_beacons = priv->missed_beacons;4209 if (priv->assoc_request.beacon_interval) {4210 missed_beacons_percent = missed_beacons_delta *4211 (HZ * le16_to_cpu(priv->assoc_request.beacon_interval)) /4212 (IPW_STATS_INTERVAL * 10);4213 } else {4214 missed_beacons_percent = 0;4215 }4216 average_add(&priv->average_missed_beacons, missed_beacons_percent);4217 4218 ipw_get_ordinal(priv, IPW_ORD_STAT_RX_ERR_CRC, &rx_err, &len);4219 rx_err_delta = rx_err - priv->last_rx_err;4220 priv->last_rx_err = rx_err;4221 4222 ipw_get_ordinal(priv, IPW_ORD_STAT_TX_FAILURE, &tx_failures, &len);4223 tx_failures_delta = tx_failures - priv->last_tx_failures;4224 priv->last_tx_failures = tx_failures;4225 4226 rx_packets_delta = priv->rx_packets - priv->last_rx_packets;4227 priv->last_rx_packets = priv->rx_packets;4228 4229 tx_packets_delta = priv->tx_packets - priv->last_tx_packets;4230 priv->last_tx_packets = priv->tx_packets;4231 4232 /* Calculate quality based on the following:4233 *4234 * Missed beacon: 100% = 0, 0% = 70% missed4235 * Rate: 60% = 1Mbs, 100% = Max4236 * Rx and Tx errors represent a straight % of total Rx/Tx4237 * RSSI: 100% = > -50, 0% = < -804238 * Rx errors: 100% = 0, 0% = 50% missed4239 *4240 * The lowest computed quality is used.4241 *4242 */4243#define BEACON_THRESHOLD 54244 beacon_quality = 100 - missed_beacons_percent;4245 if (beacon_quality < BEACON_THRESHOLD)4246 beacon_quality = 0;4247 else4248 beacon_quality = (beacon_quality - BEACON_THRESHOLD) * 100 /4249 (100 - BEACON_THRESHOLD);4250 IPW_DEBUG_STATS("Missed beacon: %3d%% (%d%%)\n",4251 beacon_quality, missed_beacons_percent);4252 4253 priv->last_rate = ipw_get_current_rate(priv);4254 max_rate = ipw_get_max_rate(priv);4255 rate_quality = priv->last_rate * 40 / max_rate + 60;4256 IPW_DEBUG_STATS("Rate quality : %3d%% (%dMbs)\n",4257 rate_quality, priv->last_rate / 1000000);4258 4259 if (rx_packets_delta > 100 && rx_packets_delta + rx_err_delta)4260 rx_quality = 100 - (rx_err_delta * 100) /4261 (rx_packets_delta + rx_err_delta);4262 else4263 rx_quality = 100;4264 IPW_DEBUG_STATS("Rx quality : %3d%% (%u errors, %u packets)\n",4265 rx_quality, rx_err_delta, rx_packets_delta);4266 4267 if (tx_packets_delta > 100 && tx_packets_delta + tx_failures_delta)4268 tx_quality = 100 - (tx_failures_delta * 100) /4269 (tx_packets_delta + tx_failures_delta);4270 else4271 tx_quality = 100;4272 IPW_DEBUG_STATS("Tx quality : %3d%% (%u errors, %u packets)\n",4273 tx_quality, tx_failures_delta, tx_packets_delta);4274 4275 rssi = priv->exp_avg_rssi;4276 signal_quality =4277 (100 *4278 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *4279 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) -4280 (priv->ieee->perfect_rssi - rssi) *4281 (15 * (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) +4282 62 * (priv->ieee->perfect_rssi - rssi))) /4283 ((priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *4284 (priv->ieee->perfect_rssi - priv->ieee->worst_rssi));4285 if (signal_quality > 100)4286 signal_quality = 100;4287 else if (signal_quality < 1)4288 signal_quality = 0;4289 4290 IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n",4291 signal_quality, rssi);4292 4293 quality = min(rx_quality, signal_quality);4294 quality = min(tx_quality, quality);4295 quality = min(rate_quality, quality);4296 quality = min(beacon_quality, quality);4297 if (quality == beacon_quality)4298 IPW_DEBUG_STATS("Quality (%d%%): Clamped to missed beacons.\n",4299 quality);4300 if (quality == rate_quality)4301 IPW_DEBUG_STATS("Quality (%d%%): Clamped to rate quality.\n",4302 quality);4303 if (quality == tx_quality)4304 IPW_DEBUG_STATS("Quality (%d%%): Clamped to Tx quality.\n",4305 quality);4306 if (quality == rx_quality)4307 IPW_DEBUG_STATS("Quality (%d%%): Clamped to Rx quality.\n",4308 quality);4309 if (quality == signal_quality)4310 IPW_DEBUG_STATS("Quality (%d%%): Clamped to signal quality.\n",4311 quality);4312 4313 priv->quality = quality;4314 4315 schedule_delayed_work(&priv->gather_stats, IPW_STATS_INTERVAL);4316}4317 4318static void ipw_bg_gather_stats(struct work_struct *work)4319{4320 struct ipw_priv *priv =4321 container_of(work, struct ipw_priv, gather_stats.work);4322 mutex_lock(&priv->mutex);4323 ipw_gather_stats(priv);4324 mutex_unlock(&priv->mutex);4325}4326 4327/* Missed beacon behavior:4328 * 1st missed -> roaming_threshold, just wait, don't do any scan/roam.4329 * roaming_threshold -> disassociate_threshold, scan and roam for better signal.4330 * Above disassociate threshold, give up and stop scanning.4331 * Roaming is disabled if disassociate_threshold <= roaming_threshold */4332static void ipw_handle_missed_beacon(struct ipw_priv *priv,4333 int missed_count)4334{4335 priv->notif_missed_beacons = missed_count;4336 4337 if (missed_count > priv->disassociate_threshold &&4338 priv->status & STATUS_ASSOCIATED) {4339 /* If associated and we've hit the missed4340 * beacon threshold, disassociate, turn4341 * off roaming, and abort any active scans */4342 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |4343 IPW_DL_STATE | IPW_DL_ASSOC,4344 "Missed beacon: %d - disassociate\n", missed_count);4345 priv->status &= ~STATUS_ROAMING;4346 if (priv->status & STATUS_SCANNING) {4347 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |4348 IPW_DL_STATE,4349 "Aborting scan with missed beacon.\n");4350 schedule_work(&priv->abort_scan);4351 }4352 4353 schedule_work(&priv->disassociate);4354 return;4355 }4356 4357 if (priv->status & STATUS_ROAMING) {4358 /* If we are currently roaming, then just4359 * print a debug statement... */4360 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,4361 "Missed beacon: %d - roam in progress\n",4362 missed_count);4363 return;4364 }4365 4366 if (roaming &&4367 (missed_count > priv->roaming_threshold &&4368 missed_count <= priv->disassociate_threshold)) {4369 /* If we are not already roaming, set the ROAM4370 * bit in the status and kick off a scan.4371 * This can happen several times before we reach4372 * disassociate_threshold. */4373 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,4374 "Missed beacon: %d - initiate "4375 "roaming\n", missed_count);4376 if (!(priv->status & STATUS_ROAMING)) {4377 priv->status |= STATUS_ROAMING;4378 if (!(priv->status & STATUS_SCANNING))4379 schedule_delayed_work(&priv->request_scan, 0);4380 }4381 return;4382 }4383 4384 if (priv->status & STATUS_SCANNING &&4385 missed_count > IPW_MB_SCAN_CANCEL_THRESHOLD) {4386 /* Stop scan to keep fw from getting4387 * stuck (only if we aren't roaming --4388 * otherwise we'll never scan more than 2 or 34389 * channels..) */4390 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF | IPW_DL_STATE,4391 "Aborting scan with missed beacon.\n");4392 schedule_work(&priv->abort_scan);4393 }4394 4395 IPW_DEBUG_NOTIF("Missed beacon: %d\n", missed_count);4396}4397 4398static void ipw_scan_event(struct work_struct *work)4399{4400 union iwreq_data wrqu;4401 4402 struct ipw_priv *priv =4403 container_of(work, struct ipw_priv, scan_event.work);4404 4405 wrqu.data.length = 0;4406 wrqu.data.flags = 0;4407 wireless_send_event(priv->net_dev, SIOCGIWSCAN, &wrqu, NULL);4408}4409 4410static void handle_scan_event(struct ipw_priv *priv)4411{4412 /* Only userspace-requested scan completion events go out immediately */4413 if (!priv->user_requested_scan) {4414 schedule_delayed_work(&priv->scan_event,4415 round_jiffies_relative(msecs_to_jiffies(4000)));4416 } else {4417 priv->user_requested_scan = 0;4418 mod_delayed_work(system_wq, &priv->scan_event, 0);4419 }4420}4421 4422/*4423 * Handle host notification packet.4424 * Called from interrupt routine4425 */4426static void ipw_rx_notification(struct ipw_priv *priv,4427 struct ipw_rx_notification *notif)4428{4429 u16 size = le16_to_cpu(notif->size);4430 4431 IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, size);4432 4433 switch (notif->subtype) {4434 case HOST_NOTIFICATION_STATUS_ASSOCIATED:{4435 struct notif_association *assoc = ¬if->u.assoc;4436 4437 switch (assoc->state) {4438 case CMAS_ASSOCIATED:{4439 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |4440 IPW_DL_ASSOC,4441 "associated: '%*pE' %pM\n",4442 priv->essid_len, priv->essid,4443 priv->bssid);4444 4445 switch (priv->ieee->iw_mode) {4446 case IW_MODE_INFRA:4447 memcpy(priv->ieee->bssid,4448 priv->bssid, ETH_ALEN);4449 break;4450 4451 case IW_MODE_ADHOC:4452 memcpy(priv->ieee->bssid,4453 priv->bssid, ETH_ALEN);4454 4455 /* clear out the station table */4456 priv->num_stations = 0;4457 4458 IPW_DEBUG_ASSOC4459 ("queueing adhoc check\n");4460 schedule_delayed_work(4461 &priv->adhoc_check,4462 le16_to_cpu(priv->4463 assoc_request.4464 beacon_interval));4465 break;4466 }4467 4468 priv->status &= ~STATUS_ASSOCIATING;4469 priv->status |= STATUS_ASSOCIATED;4470 schedule_work(&priv->system_config);4471 4472#ifdef CONFIG_IPW2200_QOS4473#define IPW_GET_PACKET_STYPE(x) WLAN_FC_GET_STYPE( \4474 le16_to_cpu(((struct ieee80211_hdr *)(x))->frame_control))4475 if ((priv->status & STATUS_AUTH) &&4476 (IPW_GET_PACKET_STYPE(¬if->u.raw)4477 == IEEE80211_STYPE_ASSOC_RESP)) {4478 if ((sizeof4479 (struct4480 libipw_assoc_response)4481 <= size)4482 && (size <= 2314)) {4483 struct4484 libipw_rx_stats4485 stats = {4486 .len = size - 1,4487 };4488 4489 IPW_DEBUG_QOS4490 ("QoS Associate "4491 "size %d\n", size);4492 libipw_rx_mgt(priv->4493 ieee,4494 (struct4495 libipw_hdr_4addr4496 *)4497 ¬if->u.raw, &stats);4498 }4499 }4500#endif4501 4502 schedule_work(&priv->link_up);4503 4504 break;4505 }4506 4507 case CMAS_AUTHENTICATED:{4508 if (priv->4509 status & (STATUS_ASSOCIATED |4510 STATUS_AUTH)) {4511 struct notif_authenticate *auth4512 = ¬if->u.auth;4513 IPW_DEBUG(IPW_DL_NOTIF |4514 IPW_DL_STATE |4515 IPW_DL_ASSOC,4516 "deauthenticated: '%*pE' %pM: (0x%04X) - %s\n",4517 priv->essid_len,4518 priv->essid,4519 priv->bssid,4520 le16_to_cpu(auth->status),4521 ipw_get_status_code4522 (le16_to_cpu4523 (auth->status)));4524 4525 priv->status &=4526 ~(STATUS_ASSOCIATING |4527 STATUS_AUTH |4528 STATUS_ASSOCIATED);4529 4530 schedule_work(&priv->link_down);4531 break;4532 }4533 4534 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |4535 IPW_DL_ASSOC,4536 "authenticated: '%*pE' %pM\n",4537 priv->essid_len, priv->essid,4538 priv->bssid);4539 break;4540 }4541 4542 case CMAS_INIT:{4543 if (priv->status & STATUS_AUTH) {4544 struct4545 libipw_assoc_response4546 *resp;4547 resp =4548 (struct4549 libipw_assoc_response4550 *)¬if->u.raw;4551 IPW_DEBUG(IPW_DL_NOTIF |4552 IPW_DL_STATE |4553 IPW_DL_ASSOC,4554 "association failed (0x%04X): %s\n",4555 le16_to_cpu(resp->status),4556 ipw_get_status_code4557 (le16_to_cpu4558 (resp->status)));4559 }4560 4561 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |4562 IPW_DL_ASSOC,4563 "disassociated: '%*pE' %pM\n",4564 priv->essid_len, priv->essid,4565 priv->bssid);4566 4567 priv->status &=4568 ~(STATUS_DISASSOCIATING |4569 STATUS_ASSOCIATING |4570 STATUS_ASSOCIATED | STATUS_AUTH);4571 if (priv->assoc_network4572 && (priv->assoc_network->4573 capability &4574 WLAN_CAPABILITY_IBSS))4575 ipw_remove_current_network4576 (priv);4577 4578 schedule_work(&priv->link_down);4579 4580 break;4581 }4582 4583 case CMAS_RX_ASSOC_RESP:4584 break;4585 4586 default:4587 IPW_ERROR("assoc: unknown (%d)\n",4588 assoc->state);4589 break;4590 }4591 4592 break;4593 }4594 4595 case HOST_NOTIFICATION_STATUS_AUTHENTICATE:{4596 struct notif_authenticate *auth = ¬if->u.auth;4597 switch (auth->state) {4598 case CMAS_AUTHENTICATED:4599 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,4600 "authenticated: '%*pE' %pM\n",4601 priv->essid_len, priv->essid,4602 priv->bssid);4603 priv->status |= STATUS_AUTH;4604 break;4605 4606 case CMAS_INIT:4607 if (priv->status & STATUS_AUTH) {4608 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |4609 IPW_DL_ASSOC,4610 "authentication failed (0x%04X): %s\n",4611 le16_to_cpu(auth->status),4612 ipw_get_status_code(le16_to_cpu4613 (auth->4614 status)));4615 }4616 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |4617 IPW_DL_ASSOC,4618 "deauthenticated: '%*pE' %pM\n",4619 priv->essid_len, priv->essid,4620 priv->bssid);4621 4622 priv->status &= ~(STATUS_ASSOCIATING |4623 STATUS_AUTH |4624 STATUS_ASSOCIATED);4625 4626 schedule_work(&priv->link_down);4627 break;4628 4629 case CMAS_TX_AUTH_SEQ_1:4630 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |4631 IPW_DL_ASSOC, "AUTH_SEQ_1\n");4632 break;4633 case CMAS_RX_AUTH_SEQ_2:4634 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |4635 IPW_DL_ASSOC, "AUTH_SEQ_2\n");4636 break;4637 case CMAS_AUTH_SEQ_1_PASS:4638 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |4639 IPW_DL_ASSOC, "AUTH_SEQ_1_PASS\n");4640 break;4641 case CMAS_AUTH_SEQ_1_FAIL:4642 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |4643 IPW_DL_ASSOC, "AUTH_SEQ_1_FAIL\n");4644 break;4645 case CMAS_TX_AUTH_SEQ_3:4646 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |4647 IPW_DL_ASSOC, "AUTH_SEQ_3\n");4648 break;4649 case CMAS_RX_AUTH_SEQ_4:4650 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |4651 IPW_DL_ASSOC, "RX_AUTH_SEQ_4\n");4652 break;4653 case CMAS_AUTH_SEQ_2_PASS:4654 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |4655 IPW_DL_ASSOC, "AUTH_SEQ_2_PASS\n");4656 break;4657 case CMAS_AUTH_SEQ_2_FAIL:4658 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |4659 IPW_DL_ASSOC, "AUT_SEQ_2_FAIL\n");4660 break;4661 case CMAS_TX_ASSOC:4662 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |4663 IPW_DL_ASSOC, "TX_ASSOC\n");4664 break;4665 case CMAS_RX_ASSOC_RESP:4666 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |4667 IPW_DL_ASSOC, "RX_ASSOC_RESP\n");4668 4669 break;4670 case CMAS_ASSOCIATED:4671 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE |4672 IPW_DL_ASSOC, "ASSOCIATED\n");4673 break;4674 default:4675 IPW_DEBUG_NOTIF("auth: failure - %d\n",4676 auth->state);4677 break;4678 }4679 break;4680 }4681 4682 case HOST_NOTIFICATION_STATUS_SCAN_CHANNEL_RESULT:{4683 struct notif_channel_result *x =4684 ¬if->u.channel_result;4685 4686 if (size == sizeof(*x)) {4687 IPW_DEBUG_SCAN("Scan result for channel %d\n",4688 x->channel_num);4689 } else {4690 IPW_DEBUG_SCAN("Scan result of wrong size %d "4691 "(should be %zd)\n",4692 size, sizeof(*x));4693 }4694 break;4695 }4696 4697 case HOST_NOTIFICATION_STATUS_SCAN_COMPLETED:{4698 struct notif_scan_complete *x = ¬if->u.scan_complete;4699 if (size == sizeof(*x)) {4700 IPW_DEBUG_SCAN4701 ("Scan completed: type %d, %d channels, "4702 "%d status\n", x->scan_type,4703 x->num_channels, x->status);4704 } else {4705 IPW_ERROR("Scan completed of wrong size %d "4706 "(should be %zd)\n",4707 size, sizeof(*x));4708 }4709 4710 priv->status &=4711 ~(STATUS_SCANNING | STATUS_SCAN_ABORTING);4712 4713 wake_up_interruptible(&priv->wait_state);4714 cancel_delayed_work(&priv->scan_check);4715 4716 if (priv->status & STATUS_EXIT_PENDING)4717 break;4718 4719 priv->ieee->scans++;4720 4721#ifdef CONFIG_IPW2200_MONITOR4722 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {4723 priv->status |= STATUS_SCAN_FORCED;4724 schedule_delayed_work(&priv->request_scan, 0);4725 break;4726 }4727 priv->status &= ~STATUS_SCAN_FORCED;4728#endif /* CONFIG_IPW2200_MONITOR */4729 4730 /* Do queued direct scans first */4731 if (priv->status & STATUS_DIRECT_SCAN_PENDING)4732 schedule_delayed_work(&priv->request_direct_scan, 0);4733 4734 if (!(priv->status & (STATUS_ASSOCIATED |4735 STATUS_ASSOCIATING |4736 STATUS_ROAMING |4737 STATUS_DISASSOCIATING)))4738 schedule_work(&priv->associate);4739 else if (priv->status & STATUS_ROAMING) {4740 if (x->status == SCAN_COMPLETED_STATUS_COMPLETE)4741 /* If a scan completed and we are in roam mode, then4742 * the scan that completed was the one requested as a4743 * result of entering roam... so, schedule the4744 * roam work */4745 schedule_work(&priv->roam);4746 else4747 /* Don't schedule if we aborted the scan */4748 priv->status &= ~STATUS_ROAMING;4749 } else if (priv->status & STATUS_SCAN_PENDING)4750 schedule_delayed_work(&priv->request_scan, 0);4751 else if (priv->config & CFG_BACKGROUND_SCAN4752 && priv->status & STATUS_ASSOCIATED)4753 schedule_delayed_work(&priv->request_scan,4754 round_jiffies_relative(HZ));4755 4756 /* Send an empty event to user space.4757 * We don't send the received data on the event because4758 * it would require us to do complex transcoding, and4759 * we want to minimise the work done in the irq handler4760 * Use a request to extract the data.4761 * Also, we generate this even for any scan, regardless4762 * on how the scan was initiated. User space can just4763 * sync on periodic scan to get fresh data...4764 * Jean II */4765 if (x->status == SCAN_COMPLETED_STATUS_COMPLETE)4766 handle_scan_event(priv);4767 break;4768 }4769 4770 case HOST_NOTIFICATION_STATUS_FRAG_LENGTH:{4771 struct notif_frag_length *x = ¬if->u.frag_len;4772 4773 if (size == sizeof(*x))4774 IPW_ERROR("Frag length: %d\n",4775 le16_to_cpu(x->frag_length));4776 else4777 IPW_ERROR("Frag length of wrong size %d "4778 "(should be %zd)\n",4779 size, sizeof(*x));4780 break;4781 }4782 4783 case HOST_NOTIFICATION_STATUS_LINK_DETERIORATION:{4784 struct notif_link_deterioration *x =4785 ¬if->u.link_deterioration;4786 4787 if (size == sizeof(*x)) {4788 IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,4789 "link deterioration: type %d, cnt %d\n",4790 x->silence_notification_type,4791 x->silence_count);4792 memcpy(&priv->last_link_deterioration, x,4793 sizeof(*x));4794 } else {4795 IPW_ERROR("Link Deterioration of wrong size %d "4796 "(should be %zd)\n",4797 size, sizeof(*x));4798 }4799 break;4800 }4801 4802 case HOST_NOTIFICATION_DINO_CONFIG_RESPONSE:{4803 IPW_ERROR("Dino config\n");4804 if (priv->hcmd4805 && priv->hcmd->cmd != HOST_CMD_DINO_CONFIG)4806 IPW_ERROR("Unexpected DINO_CONFIG_RESPONSE\n");4807 4808 break;4809 }4810 4811 case HOST_NOTIFICATION_STATUS_BEACON_STATE:{4812 struct notif_beacon_state *x = ¬if->u.beacon_state;4813 if (size != sizeof(*x)) {4814 IPW_ERROR4815 ("Beacon state of wrong size %d (should "4816 "be %zd)\n", size, sizeof(*x));4817 break;4818 }4819 4820 if (le32_to_cpu(x->state) ==4821 HOST_NOTIFICATION_STATUS_BEACON_MISSING)4822 ipw_handle_missed_beacon(priv,4823 le32_to_cpu(x->4824 number));4825 4826 break;4827 }4828 4829 case HOST_NOTIFICATION_STATUS_TGI_TX_KEY:{4830 struct notif_tgi_tx_key *x = ¬if->u.tgi_tx_key;4831 if (size == sizeof(*x)) {4832 IPW_ERROR("TGi Tx Key: state 0x%02x sec type "4833 "0x%02x station %d\n",4834 x->key_state, x->security_type,4835 x->station_index);4836 break;4837 }4838 4839 IPW_ERROR4840 ("TGi Tx Key of wrong size %d (should be %zd)\n",4841 size, sizeof(*x));4842 break;4843 }4844 4845 case HOST_NOTIFICATION_CALIB_KEEP_RESULTS:{4846 struct notif_calibration *x = ¬if->u.calibration;4847 4848 if (size == sizeof(*x)) {4849 memcpy(&priv->calib, x, sizeof(*x));4850 IPW_DEBUG_INFO("TODO: Calibration\n");4851 break;4852 }4853 4854 IPW_ERROR4855 ("Calibration of wrong size %d (should be %zd)\n",4856 size, sizeof(*x));4857 break;4858 }4859 4860 case HOST_NOTIFICATION_NOISE_STATS:{4861 if (size == sizeof(u32)) {4862 priv->exp_avg_noise =4863 exponential_average(priv->exp_avg_noise,4864 (u8) (le32_to_cpu(notif->u.noise.value) & 0xff),4865 DEPTH_NOISE);4866 break;4867 }4868 4869 IPW_ERROR4870 ("Noise stat is wrong size %d (should be %zd)\n",4871 size, sizeof(u32));4872 break;4873 }4874 4875 default:4876 IPW_DEBUG_NOTIF("Unknown notification: "4877 "subtype=%d,flags=0x%2x,size=%d\n",4878 notif->subtype, notif->flags, size);4879 }4880}4881 4882/*4883 * Destroys all DMA structures and initialise them again4884 *4885 * @param priv4886 * @return error code4887 */4888static int ipw_queue_reset(struct ipw_priv *priv)4889{4890 int rc = 0;4891 /* @todo customize queue sizes */4892 int nTx = 64, nTxCmd = 8;4893 ipw_tx_queue_free(priv);4894 /* Tx CMD queue */4895 rc = ipw_queue_tx_init(priv, &priv->txq_cmd, nTxCmd,4896 IPW_TX_CMD_QUEUE_READ_INDEX,4897 IPW_TX_CMD_QUEUE_WRITE_INDEX,4898 IPW_TX_CMD_QUEUE_BD_BASE,4899 IPW_TX_CMD_QUEUE_BD_SIZE);4900 if (rc) {4901 IPW_ERROR("Tx Cmd queue init failed\n");4902 goto error;4903 }4904 /* Tx queue(s) */4905 rc = ipw_queue_tx_init(priv, &priv->txq[0], nTx,4906 IPW_TX_QUEUE_0_READ_INDEX,4907 IPW_TX_QUEUE_0_WRITE_INDEX,4908 IPW_TX_QUEUE_0_BD_BASE, IPW_TX_QUEUE_0_BD_SIZE);4909 if (rc) {4910 IPW_ERROR("Tx 0 queue init failed\n");4911 goto error;4912 }4913 rc = ipw_queue_tx_init(priv, &priv->txq[1], nTx,4914 IPW_TX_QUEUE_1_READ_INDEX,4915 IPW_TX_QUEUE_1_WRITE_INDEX,4916 IPW_TX_QUEUE_1_BD_BASE, IPW_TX_QUEUE_1_BD_SIZE);4917 if (rc) {4918 IPW_ERROR("Tx 1 queue init failed\n");4919 goto error;4920 }4921 rc = ipw_queue_tx_init(priv, &priv->txq[2], nTx,4922 IPW_TX_QUEUE_2_READ_INDEX,4923 IPW_TX_QUEUE_2_WRITE_INDEX,4924 IPW_TX_QUEUE_2_BD_BASE, IPW_TX_QUEUE_2_BD_SIZE);4925 if (rc) {4926 IPW_ERROR("Tx 2 queue init failed\n");4927 goto error;4928 }4929 rc = ipw_queue_tx_init(priv, &priv->txq[3], nTx,4930 IPW_TX_QUEUE_3_READ_INDEX,4931 IPW_TX_QUEUE_3_WRITE_INDEX,4932 IPW_TX_QUEUE_3_BD_BASE, IPW_TX_QUEUE_3_BD_SIZE);4933 if (rc) {4934 IPW_ERROR("Tx 3 queue init failed\n");4935 goto error;4936 }4937 /* statistics */4938 priv->rx_bufs_min = 0;4939 priv->rx_pend_max = 0;4940 return rc;4941 4942 error:4943 ipw_tx_queue_free(priv);4944 return rc;4945}4946 4947/*4948 * Reclaim Tx queue entries no more used by NIC.4949 *4950 * When FW advances 'R' index, all entries between old and4951 * new 'R' index need to be reclaimed. As result, some free space4952 * forms. If there is enough free space (> low mark), wake Tx queue.4953 *4954 * @note Need to protect against garbage in 'R' index4955 * @param priv4956 * @param txq4957 * @param qindex4958 * @return Number of used entries remains in the queue4959 */4960static int ipw_queue_tx_reclaim(struct ipw_priv *priv,4961 struct clx2_tx_queue *txq, int qindex)4962{4963 u32 hw_tail;4964 int used;4965 struct clx2_queue *q = &txq->q;4966 4967 hw_tail = ipw_read32(priv, q->reg_r);4968 if (hw_tail >= q->n_bd) {4969 IPW_ERROR4970 ("Read index for DMA queue (%d) is out of range [0-%d)\n",4971 hw_tail, q->n_bd);4972 goto done;4973 }4974 for (; q->last_used != hw_tail;4975 q->last_used = ipw_queue_inc_wrap(q->last_used, q->n_bd)) {4976 ipw_queue_tx_free_tfd(priv, txq);4977 priv->tx_packets++;4978 }4979 done:4980 if ((ipw_tx_queue_space(q) > q->low_mark) &&4981 (qindex >= 0))4982 netif_wake_queue(priv->net_dev);4983 used = q->first_empty - q->last_used;4984 if (used < 0)4985 used += q->n_bd;4986 4987 return used;4988}4989 4990static int ipw_queue_tx_hcmd(struct ipw_priv *priv, int hcmd, const void *buf,4991 int len, int sync)4992{4993 struct clx2_tx_queue *txq = &priv->txq_cmd;4994 struct clx2_queue *q = &txq->q;4995 struct tfd_frame *tfd;4996 4997 if (ipw_tx_queue_space(q) < (sync ? 1 : 2)) {4998 IPW_ERROR("No space for Tx\n");4999 return -EBUSY;5000 }5001 5002 tfd = &txq->bd[q->first_empty];5003 txq->txb[q->first_empty] = NULL;5004 5005 memset(tfd, 0, sizeof(*tfd));5006 tfd->control_flags.message_type = TX_HOST_COMMAND_TYPE;5007 tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK;5008 priv->hcmd_seq++;5009 tfd->u.cmd.index = hcmd;5010 tfd->u.cmd.length = len;5011 memcpy(tfd->u.cmd.payload, buf, len);5012 q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);5013 ipw_write32(priv, q->reg_w, q->first_empty);5014 _ipw_read32(priv, 0x90);5015 5016 return 0;5017}5018 5019/*5020 * Rx theory of operation5021 *5022 * The host allocates 32 DMA target addresses and passes the host address5023 * to the firmware at register IPW_RFDS_TABLE_LOWER + N * RFD_SIZE where N is5024 * 0 to 315025 *5026 * Rx Queue Indexes5027 * The host/firmware share two index registers for managing the Rx buffers.5028 *5029 * The READ index maps to the first position that the firmware may be writing5030 * to -- the driver can read up to (but not including) this position and get5031 * good data.5032 * The READ index is managed by the firmware once the card is enabled.5033 *5034 * The WRITE index maps to the last position the driver has read from -- the5035 * position preceding WRITE is the last slot the firmware can place a packet.5036 *5037 * The queue is empty (no good data) if WRITE = READ - 1, and is full if5038 * WRITE = READ.5039 *5040 * During initialization the host sets up the READ queue position to the first5041 * INDEX position, and WRITE to the last (READ - 1 wrapped)5042 *5043 * When the firmware places a packet in a buffer it will advance the READ index5044 * and fire the RX interrupt. The driver can then query the READ index and5045 * process as many packets as possible, moving the WRITE index forward as it5046 * resets the Rx queue buffers with new memory.5047 *5048 * The management in the driver is as follows:5049 * + A list of pre-allocated SKBs is stored in ipw->rxq->rx_free. When5050 * ipw->rxq->free_count drops to or below RX_LOW_WATERMARK, work is scheduled5051 * to replensish the ipw->rxq->rx_free.5052 * + In ipw_rx_queue_replenish (scheduled) if 'processed' != 'read' then the5053 * ipw->rxq is replenished and the READ INDEX is updated (updating the5054 * 'processed' and 'read' driver indexes as well)5055 * + A received packet is processed and handed to the kernel network stack,5056 * detached from the ipw->rxq. The driver 'processed' index is updated.5057 * + The Host/Firmware ipw->rxq is replenished at tasklet time from the rx_free5058 * list. If there are no allocated buffers in ipw->rxq->rx_free, the READ5059 * INDEX is not incremented and ipw->status(RX_STALLED) is set. If there5060 * were enough free buffers and RX_STALLED is set it is cleared.5061 *5062 *5063 * Driver sequence:5064 *5065 * ipw_rx_queue_alloc() Allocates rx_free5066 * ipw_rx_queue_replenish() Replenishes rx_free list from rx_used, and calls5067 * ipw_rx_queue_restock5068 * ipw_rx_queue_restock() Moves available buffers from rx_free into Rx5069 * queue, updates firmware pointers, and updates5070 * the WRITE index. If insufficient rx_free buffers5071 * are available, schedules ipw_rx_queue_replenish5072 *5073 * -- enable interrupts --5074 * ISR - ipw_rx() Detach ipw_rx_mem_buffers from pool up to the5075 * READ INDEX, detaching the SKB from the pool.5076 * Moves the packet buffer from queue to rx_used.5077 * Calls ipw_rx_queue_restock to refill any empty5078 * slots.5079 * ...5080 *5081 */5082 5083/*5084 * If there are slots in the RX queue that need to be restocked,5085 * and we have free pre-allocated buffers, fill the ranks as much5086 * as we can pulling from rx_free.5087 *5088 * This moves the 'write' index forward to catch up with 'processed', and5089 * also updates the memory address in the firmware to reference the new5090 * target buffer.5091 */5092static void ipw_rx_queue_restock(struct ipw_priv *priv)5093{5094 struct ipw_rx_queue *rxq = priv->rxq;5095 struct list_head *element;5096 struct ipw_rx_mem_buffer *rxb;5097 unsigned long flags;5098 int write;5099 5100 spin_lock_irqsave(&rxq->lock, flags);5101 write = rxq->write;5102 while ((ipw_rx_queue_space(rxq) > 0) && (rxq->free_count)) {5103 element = rxq->rx_free.next;5104 rxb = list_entry(element, struct ipw_rx_mem_buffer, list);5105 list_del(element);5106 5107 ipw_write32(priv, IPW_RFDS_TABLE_LOWER + rxq->write * RFD_SIZE,5108 rxb->dma_addr);5109 rxq->queue[rxq->write] = rxb;5110 rxq->write = (rxq->write + 1) % RX_QUEUE_SIZE;5111 rxq->free_count--;5112 }5113 spin_unlock_irqrestore(&rxq->lock, flags);5114 5115 /* If the pre-allocated buffer pool is dropping low, schedule to5116 * refill it */5117 if (rxq->free_count <= RX_LOW_WATERMARK)5118 schedule_work(&priv->rx_replenish);5119 5120 /* If we've added more space for the firmware to place data, tell it */5121 if (write != rxq->write)5122 ipw_write32(priv, IPW_RX_WRITE_INDEX, rxq->write);5123}5124 5125/*5126 * Move all used packet from rx_used to rx_free, allocating a new SKB for each.5127 * Also restock the Rx queue via ipw_rx_queue_restock.5128 *5129 * This is called as a scheduled work item (except for during initialization)5130 */5131static void ipw_rx_queue_replenish(void *data)5132{5133 struct ipw_priv *priv = data;5134 struct ipw_rx_queue *rxq = priv->rxq;5135 struct list_head *element;5136 struct ipw_rx_mem_buffer *rxb;5137 unsigned long flags;5138 5139 spin_lock_irqsave(&rxq->lock, flags);5140 while (!list_empty(&rxq->rx_used)) {5141 element = rxq->rx_used.next;5142 rxb = list_entry(element, struct ipw_rx_mem_buffer, list);5143 rxb->skb = alloc_skb(IPW_RX_BUF_SIZE, GFP_ATOMIC);5144 if (!rxb->skb) {5145 printk(KERN_CRIT "%s: Can not allocate SKB buffers.\n",5146 priv->net_dev->name);5147 /* We don't reschedule replenish work here -- we will5148 * call the restock method and if it still needs5149 * more buffers it will schedule replenish */5150 break;5151 }5152 list_del(element);5153 5154 rxb->dma_addr =5155 dma_map_single(&priv->pci_dev->dev, rxb->skb->data,5156 IPW_RX_BUF_SIZE, DMA_FROM_DEVICE);5157 5158 list_add_tail(&rxb->list, &rxq->rx_free);5159 rxq->free_count++;5160 }5161 spin_unlock_irqrestore(&rxq->lock, flags);5162 5163 ipw_rx_queue_restock(priv);5164}5165 5166static void ipw_bg_rx_queue_replenish(struct work_struct *work)5167{5168 struct ipw_priv *priv =5169 container_of(work, struct ipw_priv, rx_replenish);5170 mutex_lock(&priv->mutex);5171 ipw_rx_queue_replenish(priv);5172 mutex_unlock(&priv->mutex);5173}5174 5175/* Assumes that the skb field of the buffers in 'pool' is kept accurate.5176 * If an SKB has been detached, the POOL needs to have its SKB set to NULL5177 * This free routine walks the list of POOL entries and if SKB is set to5178 * non NULL it is unmapped and freed5179 */5180static void ipw_rx_queue_free(struct ipw_priv *priv, struct ipw_rx_queue *rxq)5181{5182 int i;5183 5184 if (!rxq)5185 return;5186 5187 for (i = 0; i < RX_QUEUE_SIZE + RX_FREE_BUFFERS; i++) {5188 if (rxq->pool[i].skb != NULL) {5189 dma_unmap_single(&priv->pci_dev->dev,5190 rxq->pool[i].dma_addr,5191 IPW_RX_BUF_SIZE, DMA_FROM_DEVICE);5192 dev_kfree_skb(rxq->pool[i].skb);5193 }5194 }5195 5196 kfree(rxq);5197}5198 5199static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *priv)5200{5201 struct ipw_rx_queue *rxq;5202 int i;5203 5204 rxq = kzalloc(sizeof(*rxq), GFP_KERNEL);5205 if (unlikely(!rxq)) {5206 IPW_ERROR("memory allocation failed\n");5207 return NULL;5208 }5209 spin_lock_init(&rxq->lock);5210 INIT_LIST_HEAD(&rxq->rx_free);5211 INIT_LIST_HEAD(&rxq->rx_used);5212 5213 /* Fill the rx_used queue with _all_ of the Rx buffers */5214 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)5215 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);5216 5217 /* Set us so that we have processed and used all buffers, but have5218 * not restocked the Rx queue with fresh buffers */5219 rxq->read = rxq->write = 0;5220 rxq->free_count = 0;5221 5222 return rxq;5223}5224 5225static int ipw_is_rate_in_mask(struct ipw_priv *priv, int ieee_mode, u8 rate)5226{5227 rate &= ~LIBIPW_BASIC_RATE_MASK;5228 if (ieee_mode == IEEE_A) {5229 switch (rate) {5230 case LIBIPW_OFDM_RATE_6MB:5231 return priv->rates_mask & LIBIPW_OFDM_RATE_6MB_MASK ?5232 1 : 0;5233 case LIBIPW_OFDM_RATE_9MB:5234 return priv->rates_mask & LIBIPW_OFDM_RATE_9MB_MASK ?5235 1 : 0;5236 case LIBIPW_OFDM_RATE_12MB:5237 return priv->5238 rates_mask & LIBIPW_OFDM_RATE_12MB_MASK ? 1 : 0;5239 case LIBIPW_OFDM_RATE_18MB:5240 return priv->5241 rates_mask & LIBIPW_OFDM_RATE_18MB_MASK ? 1 : 0;5242 case LIBIPW_OFDM_RATE_24MB:5243 return priv->5244 rates_mask & LIBIPW_OFDM_RATE_24MB_MASK ? 1 : 0;5245 case LIBIPW_OFDM_RATE_36MB:5246 return priv->5247 rates_mask & LIBIPW_OFDM_RATE_36MB_MASK ? 1 : 0;5248 case LIBIPW_OFDM_RATE_48MB:5249 return priv->5250 rates_mask & LIBIPW_OFDM_RATE_48MB_MASK ? 1 : 0;5251 case LIBIPW_OFDM_RATE_54MB:5252 return priv->5253 rates_mask & LIBIPW_OFDM_RATE_54MB_MASK ? 1 : 0;5254 default:5255 return 0;5256 }5257 }5258 5259 /* B and G mixed */5260 switch (rate) {5261 case LIBIPW_CCK_RATE_1MB:5262 return priv->rates_mask & LIBIPW_CCK_RATE_1MB_MASK ? 1 : 0;5263 case LIBIPW_CCK_RATE_2MB:5264 return priv->rates_mask & LIBIPW_CCK_RATE_2MB_MASK ? 1 : 0;5265 case LIBIPW_CCK_RATE_5MB:5266 return priv->rates_mask & LIBIPW_CCK_RATE_5MB_MASK ? 1 : 0;5267 case LIBIPW_CCK_RATE_11MB:5268 return priv->rates_mask & LIBIPW_CCK_RATE_11MB_MASK ? 1 : 0;5269 }5270 5271 /* If we are limited to B modulations, bail at this point */5272 if (ieee_mode == IEEE_B)5273 return 0;5274 5275 /* G */5276 switch (rate) {5277 case LIBIPW_OFDM_RATE_6MB:5278 return priv->rates_mask & LIBIPW_OFDM_RATE_6MB_MASK ? 1 : 0;5279 case LIBIPW_OFDM_RATE_9MB:5280 return priv->rates_mask & LIBIPW_OFDM_RATE_9MB_MASK ? 1 : 0;5281 case LIBIPW_OFDM_RATE_12MB:5282 return priv->rates_mask & LIBIPW_OFDM_RATE_12MB_MASK ? 1 : 0;5283 case LIBIPW_OFDM_RATE_18MB:5284 return priv->rates_mask & LIBIPW_OFDM_RATE_18MB_MASK ? 1 : 0;5285 case LIBIPW_OFDM_RATE_24MB:5286 return priv->rates_mask & LIBIPW_OFDM_RATE_24MB_MASK ? 1 : 0;5287 case LIBIPW_OFDM_RATE_36MB:5288 return priv->rates_mask & LIBIPW_OFDM_RATE_36MB_MASK ? 1 : 0;5289 case LIBIPW_OFDM_RATE_48MB:5290 return priv->rates_mask & LIBIPW_OFDM_RATE_48MB_MASK ? 1 : 0;5291 case LIBIPW_OFDM_RATE_54MB:5292 return priv->rates_mask & LIBIPW_OFDM_RATE_54MB_MASK ? 1 : 0;5293 }5294 5295 return 0;5296}5297 5298static int ipw_compatible_rates(struct ipw_priv *priv,5299 const struct libipw_network *network,5300 struct ipw_supported_rates *rates)5301{5302 int num_rates, i;5303 5304 memset(rates, 0, sizeof(*rates));5305 num_rates = min(network->rates_len, (u8) IPW_MAX_RATES);5306 rates->num_rates = 0;5307 for (i = 0; i < num_rates; i++) {5308 if (!ipw_is_rate_in_mask(priv, network->mode,5309 network->rates[i])) {5310 5311 if (network->rates[i] & LIBIPW_BASIC_RATE_MASK) {5312 IPW_DEBUG_SCAN("Adding masked mandatory "5313 "rate %02X\n",5314 network->rates[i]);5315 rates->supported_rates[rates->num_rates++] =5316 network->rates[i];5317 continue;5318 }5319 5320 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",5321 network->rates[i], priv->rates_mask);5322 continue;5323 }5324 5325 rates->supported_rates[rates->num_rates++] = network->rates[i];5326 }5327 5328 num_rates = min(network->rates_ex_len,5329 (u8) (IPW_MAX_RATES - num_rates));5330 for (i = 0; i < num_rates; i++) {5331 if (!ipw_is_rate_in_mask(priv, network->mode,5332 network->rates_ex[i])) {5333 if (network->rates_ex[i] & LIBIPW_BASIC_RATE_MASK) {5334 IPW_DEBUG_SCAN("Adding masked mandatory "5335 "rate %02X\n",5336 network->rates_ex[i]);5337 rates->supported_rates[rates->num_rates++] =5338 network->rates[i];5339 continue;5340 }5341 5342 IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",5343 network->rates_ex[i], priv->rates_mask);5344 continue;5345 }5346 5347 rates->supported_rates[rates->num_rates++] =5348 network->rates_ex[i];5349 }5350 5351 return 1;5352}5353 5354static void ipw_copy_rates(struct ipw_supported_rates *dest,5355 const struct ipw_supported_rates *src)5356{5357 u8 i;5358 for (i = 0; i < src->num_rates; i++)5359 dest->supported_rates[i] = src->supported_rates[i];5360 dest->num_rates = src->num_rates;5361}5362 5363/* TODO: Look at sniffed packets in the air to determine if the basic rate5364 * mask should ever be used -- right now all callers to add the scan rates are5365 * set with the modulation = CCK, so BASIC_RATE_MASK is never set... */5366static void ipw_add_cck_scan_rates(struct ipw_supported_rates *rates,5367 u8 modulation, u32 rate_mask)5368{5369 u8 basic_mask = (LIBIPW_OFDM_MODULATION == modulation) ?5370 LIBIPW_BASIC_RATE_MASK : 0;5371 5372 if (rate_mask & LIBIPW_CCK_RATE_1MB_MASK)5373 rates->supported_rates[rates->num_rates++] =5374 LIBIPW_BASIC_RATE_MASK | LIBIPW_CCK_RATE_1MB;5375 5376 if (rate_mask & LIBIPW_CCK_RATE_2MB_MASK)5377 rates->supported_rates[rates->num_rates++] =5378 LIBIPW_BASIC_RATE_MASK | LIBIPW_CCK_RATE_2MB;5379 5380 if (rate_mask & LIBIPW_CCK_RATE_5MB_MASK)5381 rates->supported_rates[rates->num_rates++] = basic_mask |5382 LIBIPW_CCK_RATE_5MB;5383 5384 if (rate_mask & LIBIPW_CCK_RATE_11MB_MASK)5385 rates->supported_rates[rates->num_rates++] = basic_mask |5386 LIBIPW_CCK_RATE_11MB;5387}5388 5389static void ipw_add_ofdm_scan_rates(struct ipw_supported_rates *rates,5390 u8 modulation, u32 rate_mask)5391{5392 u8 basic_mask = (LIBIPW_OFDM_MODULATION == modulation) ?5393 LIBIPW_BASIC_RATE_MASK : 0;5394 5395 if (rate_mask & LIBIPW_OFDM_RATE_6MB_MASK)5396 rates->supported_rates[rates->num_rates++] = basic_mask |5397 LIBIPW_OFDM_RATE_6MB;5398 5399 if (rate_mask & LIBIPW_OFDM_RATE_9MB_MASK)5400 rates->supported_rates[rates->num_rates++] =5401 LIBIPW_OFDM_RATE_9MB;5402 5403 if (rate_mask & LIBIPW_OFDM_RATE_12MB_MASK)5404 rates->supported_rates[rates->num_rates++] = basic_mask |5405 LIBIPW_OFDM_RATE_12MB;5406 5407 if (rate_mask & LIBIPW_OFDM_RATE_18MB_MASK)5408 rates->supported_rates[rates->num_rates++] =5409 LIBIPW_OFDM_RATE_18MB;5410 5411 if (rate_mask & LIBIPW_OFDM_RATE_24MB_MASK)5412 rates->supported_rates[rates->num_rates++] = basic_mask |5413 LIBIPW_OFDM_RATE_24MB;5414 5415 if (rate_mask & LIBIPW_OFDM_RATE_36MB_MASK)5416 rates->supported_rates[rates->num_rates++] =5417 LIBIPW_OFDM_RATE_36MB;5418 5419 if (rate_mask & LIBIPW_OFDM_RATE_48MB_MASK)5420 rates->supported_rates[rates->num_rates++] =5421 LIBIPW_OFDM_RATE_48MB;5422 5423 if (rate_mask & LIBIPW_OFDM_RATE_54MB_MASK)5424 rates->supported_rates[rates->num_rates++] =5425 LIBIPW_OFDM_RATE_54MB;5426}5427 5428struct ipw_network_match {5429 struct libipw_network *network;5430 struct ipw_supported_rates rates;5431};5432 5433static int ipw_find_adhoc_network(struct ipw_priv *priv,5434 struct ipw_network_match *match,5435 struct libipw_network *network,5436 int roaming)5437{5438 struct ipw_supported_rates rates;5439 5440 /* Verify that this network's capability is compatible with the5441 * current mode (AdHoc or Infrastructure) */5442 if ((priv->ieee->iw_mode == IW_MODE_ADHOC &&5443 !(network->capability & WLAN_CAPABILITY_IBSS))) {5444 IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded due to capability mismatch.\n",5445 network->ssid_len, network->ssid,5446 network->bssid);5447 return 0;5448 }5449 5450 if (unlikely(roaming)) {5451 /* If we are roaming, then ensure check if this is a valid5452 * network to try and roam to */5453 if ((network->ssid_len != match->network->ssid_len) ||5454 memcmp(network->ssid, match->network->ssid,5455 network->ssid_len)) {5456 IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of non-network ESSID.\n",5457 network->ssid_len, network->ssid,5458 network->bssid);5459 return 0;5460 }5461 } else {5462 /* If an ESSID has been configured then compare the broadcast5463 * ESSID to ours */5464 if ((priv->config & CFG_STATIC_ESSID) &&5465 ((network->ssid_len != priv->essid_len) ||5466 memcmp(network->ssid, priv->essid,5467 min(network->ssid_len, priv->essid_len)))) {5468 IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of ESSID mismatch: '%*pE'.\n",5469 network->ssid_len, network->ssid,5470 network->bssid, priv->essid_len,5471 priv->essid);5472 return 0;5473 }5474 }5475 5476 /* If the old network rate is better than this one, don't bother5477 * testing everything else. */5478 5479 if (network->time_stamp[0] < match->network->time_stamp[0]) {5480 IPW_DEBUG_MERGE("Network '%*pE excluded because newer than current network.\n",5481 match->network->ssid_len, match->network->ssid);5482 return 0;5483 } else if (network->time_stamp[1] < match->network->time_stamp[1]) {5484 IPW_DEBUG_MERGE("Network '%*pE excluded because newer than current network.\n",5485 match->network->ssid_len, match->network->ssid);5486 return 0;5487 }5488 5489 /* Now go through and see if the requested network is valid... */5490 if (priv->ieee->scan_age != 0 &&5491 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {5492 IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of age: %ums.\n",5493 network->ssid_len, network->ssid,5494 network->bssid,5495 jiffies_to_msecs(jiffies -5496 network->last_scanned));5497 return 0;5498 }5499 5500 if ((priv->config & CFG_STATIC_CHANNEL) &&5501 (network->channel != priv->channel)) {5502 IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of channel mismatch: %d != %d.\n",5503 network->ssid_len, network->ssid,5504 network->bssid,5505 network->channel, priv->channel);5506 return 0;5507 }5508 5509 /* Verify privacy compatibility */5510 if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=5511 ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {5512 IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of privacy mismatch: %s != %s.\n",5513 network->ssid_len, network->ssid,5514 network->bssid,5515 priv->5516 capability & CAP_PRIVACY_ON ? "on" : "off",5517 network->5518 capability & WLAN_CAPABILITY_PRIVACY ? "on" :5519 "off");5520 return 0;5521 }5522 5523 if (ether_addr_equal(network->bssid, priv->bssid)) {5524 IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of the same BSSID match: %pM.\n",5525 network->ssid_len, network->ssid,5526 network->bssid, priv->bssid);5527 return 0;5528 }5529 5530 /* Filter out any incompatible freq / mode combinations */5531 if (!libipw_is_valid_mode(priv->ieee, network->mode)) {5532 IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of invalid frequency/mode combination.\n",5533 network->ssid_len, network->ssid,5534 network->bssid);5535 return 0;5536 }5537 5538 /* Ensure that the rates supported by the driver are compatible with5539 * this AP, including verification of basic rates (mandatory) */5540 if (!ipw_compatible_rates(priv, network, &rates)) {5541 IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because configured rate mask excludes AP mandatory rate.\n",5542 network->ssid_len, network->ssid,5543 network->bssid);5544 return 0;5545 }5546 5547 if (rates.num_rates == 0) {5548 IPW_DEBUG_MERGE("Network '%*pE (%pM)' excluded because of no compatible rates.\n",5549 network->ssid_len, network->ssid,5550 network->bssid);5551 return 0;5552 }5553 5554 /* TODO: Perform any further minimal comparititive tests. We do not5555 * want to put too much policy logic here; intelligent scan selection5556 * should occur within a generic IEEE 802.11 user space tool. */5557 5558 /* Set up 'new' AP to this network */5559 ipw_copy_rates(&match->rates, &rates);5560 match->network = network;5561 IPW_DEBUG_MERGE("Network '%*pE (%pM)' is a viable match.\n",5562 network->ssid_len, network->ssid, network->bssid);5563 5564 return 1;5565}5566 5567static void ipw_merge_adhoc_network(struct work_struct *work)5568{5569 struct ipw_priv *priv =5570 container_of(work, struct ipw_priv, merge_networks);5571 struct libipw_network *network = NULL;5572 struct ipw_network_match match = {5573 .network = priv->assoc_network5574 };5575 5576 if ((priv->status & STATUS_ASSOCIATED) &&5577 (priv->ieee->iw_mode == IW_MODE_ADHOC)) {5578 /* First pass through ROAM process -- look for a better5579 * network */5580 unsigned long flags;5581 5582 spin_lock_irqsave(&priv->ieee->lock, flags);5583 list_for_each_entry(network, &priv->ieee->network_list, list) {5584 if (network != priv->assoc_network)5585 ipw_find_adhoc_network(priv, &match, network,5586 1);5587 }5588 spin_unlock_irqrestore(&priv->ieee->lock, flags);5589 5590 if (match.network == priv->assoc_network) {5591 IPW_DEBUG_MERGE("No better ADHOC in this network to "5592 "merge to.\n");5593 return;5594 }5595 5596 mutex_lock(&priv->mutex);5597 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {5598 IPW_DEBUG_MERGE("remove network %*pE\n",5599 priv->essid_len, priv->essid);5600 ipw_remove_current_network(priv);5601 }5602 5603 ipw_disassociate(priv);5604 priv->assoc_network = match.network;5605 mutex_unlock(&priv->mutex);5606 return;5607 }5608}5609 5610static int ipw_best_network(struct ipw_priv *priv,5611 struct ipw_network_match *match,5612 struct libipw_network *network, int roaming)5613{5614 struct ipw_supported_rates rates;5615 5616 /* Verify that this network's capability is compatible with the5617 * current mode (AdHoc or Infrastructure) */5618 if ((priv->ieee->iw_mode == IW_MODE_INFRA &&5619 !(network->capability & WLAN_CAPABILITY_ESS)) ||5620 (priv->ieee->iw_mode == IW_MODE_ADHOC &&5621 !(network->capability & WLAN_CAPABILITY_IBSS))) {5622 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded due to capability mismatch.\n",5623 network->ssid_len, network->ssid,5624 network->bssid);5625 return 0;5626 }5627 5628 if (unlikely(roaming)) {5629 /* If we are roaming, then ensure check if this is a valid5630 * network to try and roam to */5631 if ((network->ssid_len != match->network->ssid_len) ||5632 memcmp(network->ssid, match->network->ssid,5633 network->ssid_len)) {5634 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of non-network ESSID.\n",5635 network->ssid_len, network->ssid,5636 network->bssid);5637 return 0;5638 }5639 } else {5640 /* If an ESSID has been configured then compare the broadcast5641 * ESSID to ours */5642 if ((priv->config & CFG_STATIC_ESSID) &&5643 ((network->ssid_len != priv->essid_len) ||5644 memcmp(network->ssid, priv->essid,5645 min(network->ssid_len, priv->essid_len)))) {5646 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of ESSID mismatch: '%*pE'.\n",5647 network->ssid_len, network->ssid,5648 network->bssid, priv->essid_len,5649 priv->essid);5650 return 0;5651 }5652 }5653 5654 /* If the old network rate is better than this one, don't bother5655 * testing everything else. */5656 if (match->network && match->network->stats.rssi > network->stats.rssi) {5657 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because '%*pE (%pM)' has a stronger signal.\n",5658 network->ssid_len, network->ssid,5659 network->bssid, match->network->ssid_len,5660 match->network->ssid, match->network->bssid);5661 return 0;5662 }5663 5664 /* If this network has already had an association attempt within the5665 * last 3 seconds, do not try and associate again... */5666 if (network->last_associate &&5667 time_after(network->last_associate + (HZ * 3UL), jiffies)) {5668 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of storming (%ums since last assoc attempt).\n",5669 network->ssid_len, network->ssid,5670 network->bssid,5671 jiffies_to_msecs(jiffies -5672 network->last_associate));5673 return 0;5674 }5675 5676 /* Now go through and see if the requested network is valid... */5677 if (priv->ieee->scan_age != 0 &&5678 time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {5679 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of age: %ums.\n",5680 network->ssid_len, network->ssid,5681 network->bssid,5682 jiffies_to_msecs(jiffies -5683 network->last_scanned));5684 return 0;5685 }5686 5687 if ((priv->config & CFG_STATIC_CHANNEL) &&5688 (network->channel != priv->channel)) {5689 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of channel mismatch: %d != %d.\n",5690 network->ssid_len, network->ssid,5691 network->bssid,5692 network->channel, priv->channel);5693 return 0;5694 }5695 5696 /* Verify privacy compatibility */5697 if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=5698 ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {5699 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of privacy mismatch: %s != %s.\n",5700 network->ssid_len, network->ssid,5701 network->bssid,5702 priv->capability & CAP_PRIVACY_ON ? "on" :5703 "off",5704 network->capability &5705 WLAN_CAPABILITY_PRIVACY ? "on" : "off");5706 return 0;5707 }5708 5709 if ((priv->config & CFG_STATIC_BSSID) &&5710 !ether_addr_equal(network->bssid, priv->bssid)) {5711 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of BSSID mismatch: %pM.\n",5712 network->ssid_len, network->ssid,5713 network->bssid, priv->bssid);5714 return 0;5715 }5716 5717 /* Filter out any incompatible freq / mode combinations */5718 if (!libipw_is_valid_mode(priv->ieee, network->mode)) {5719 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of invalid frequency/mode combination.\n",5720 network->ssid_len, network->ssid,5721 network->bssid);5722 return 0;5723 }5724 5725 /* Filter out invalid channel in current GEO */5726 if (!libipw_is_valid_channel(priv->ieee, network->channel)) {5727 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of invalid channel in current GEO\n",5728 network->ssid_len, network->ssid,5729 network->bssid);5730 return 0;5731 }5732 5733 /* Ensure that the rates supported by the driver are compatible with5734 * this AP, including verification of basic rates (mandatory) */5735 if (!ipw_compatible_rates(priv, network, &rates)) {5736 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because configured rate mask excludes AP mandatory rate.\n",5737 network->ssid_len, network->ssid,5738 network->bssid);5739 return 0;5740 }5741 5742 if (rates.num_rates == 0) {5743 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' excluded because of no compatible rates.\n",5744 network->ssid_len, network->ssid,5745 network->bssid);5746 return 0;5747 }5748 5749 /* TODO: Perform any further minimal comparititive tests. We do not5750 * want to put too much policy logic here; intelligent scan selection5751 * should occur within a generic IEEE 802.11 user space tool. */5752 5753 /* Set up 'new' AP to this network */5754 ipw_copy_rates(&match->rates, &rates);5755 match->network = network;5756 5757 IPW_DEBUG_ASSOC("Network '%*pE (%pM)' is a viable match.\n",5758 network->ssid_len, network->ssid, network->bssid);5759 5760 return 1;5761}5762 5763static void ipw_adhoc_create(struct ipw_priv *priv,5764 struct libipw_network *network)5765{5766 const struct libipw_geo *geo = libipw_get_geo(priv->ieee);5767 int i;5768 5769 /*5770 * For the purposes of scanning, we can set our wireless mode5771 * to trigger scans across combinations of bands, but when it5772 * comes to creating a new ad-hoc network, we have tell the FW5773 * exactly which band to use.5774 *5775 * We also have the possibility of an invalid channel for the5776 * chossen band. Attempting to create a new ad-hoc network5777 * with an invalid channel for wireless mode will trigger a5778 * FW fatal error.5779 *5780 */5781 switch (libipw_is_valid_channel(priv->ieee, priv->channel)) {5782 case LIBIPW_52GHZ_BAND:5783 network->mode = IEEE_A;5784 i = libipw_channel_to_index(priv->ieee, priv->channel);5785 BUG_ON(i == -1);5786 if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY) {5787 IPW_WARNING("Overriding invalid channel\n");5788 priv->channel = geo->a[0].channel;5789 }5790 break;5791 5792 case LIBIPW_24GHZ_BAND:5793 if (priv->ieee->mode & IEEE_G)5794 network->mode = IEEE_G;5795 else5796 network->mode = IEEE_B;5797 i = libipw_channel_to_index(priv->ieee, priv->channel);5798 BUG_ON(i == -1);5799 if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY) {5800 IPW_WARNING("Overriding invalid channel\n");5801 priv->channel = geo->bg[0].channel;5802 }5803 break;5804 5805 default:5806 IPW_WARNING("Overriding invalid channel\n");5807 if (priv->ieee->mode & IEEE_A) {5808 network->mode = IEEE_A;5809 priv->channel = geo->a[0].channel;5810 } else if (priv->ieee->mode & IEEE_G) {5811 network->mode = IEEE_G;5812 priv->channel = geo->bg[0].channel;5813 } else {5814 network->mode = IEEE_B;5815 priv->channel = geo->bg[0].channel;5816 }5817 break;5818 }5819 5820 network->channel = priv->channel;5821 priv->config |= CFG_ADHOC_PERSIST;5822 ipw_create_bssid(priv, network->bssid);5823 network->ssid_len = priv->essid_len;5824 memcpy(network->ssid, priv->essid, priv->essid_len);5825 memset(&network->stats, 0, sizeof(network->stats));5826 network->capability = WLAN_CAPABILITY_IBSS;5827 if (!(priv->config & CFG_PREAMBLE_LONG))5828 network->capability |= WLAN_CAPABILITY_SHORT_PREAMBLE;5829 if (priv->capability & CAP_PRIVACY_ON)5830 network->capability |= WLAN_CAPABILITY_PRIVACY;5831 network->rates_len = min(priv->rates.num_rates, MAX_RATES_LENGTH);5832 memcpy(network->rates, priv->rates.supported_rates, network->rates_len);5833 network->rates_ex_len = priv->rates.num_rates - network->rates_len;5834 memcpy(network->rates_ex,5835 &priv->rates.supported_rates[network->rates_len],5836 network->rates_ex_len);5837 network->last_scanned = 0;5838 network->flags = 0;5839 network->last_associate = 0;5840 network->time_stamp[0] = 0;5841 network->time_stamp[1] = 0;5842 network->beacon_interval = 100; /* Default */5843 network->listen_interval = 10; /* Default */5844 network->atim_window = 0; /* Default */5845 network->wpa_ie_len = 0;5846 network->rsn_ie_len = 0;5847}5848 5849static void ipw_send_tgi_tx_key(struct ipw_priv *priv, int type, int index)5850{5851 struct ipw_tgi_tx_key key;5852 5853 if (!(priv->ieee->sec.flags & (1 << index)))5854 return;5855 5856 key.key_id = index;5857 memcpy(key.key, priv->ieee->sec.keys[index], SCM_TEMPORAL_KEY_LENGTH);5858 key.security_type = type;5859 key.station_index = 0; /* always 0 for BSS */5860 key.flags = 0;5861 /* 0 for new key; previous value of counter (after fatal error) */5862 key.tx_counter[0] = cpu_to_le32(0);5863 key.tx_counter[1] = cpu_to_le32(0);5864 5865 ipw_send_cmd_pdu(priv, IPW_CMD_TGI_TX_KEY, sizeof(key), &key);5866}5867 5868static void ipw_send_wep_keys(struct ipw_priv *priv, int type)5869{5870 struct ipw_wep_key key;5871 int i;5872 5873 key.cmd_id = DINO_CMD_WEP_KEY;5874 key.seq_num = 0;5875 5876 /* Note: AES keys cannot be set for multiple times.5877 * Only set it at the first time. */5878 for (i = 0; i < 4; i++) {5879 key.key_index = i | type;5880 if (!(priv->ieee->sec.flags & (1 << i))) {5881 key.key_size = 0;5882 continue;5883 }5884 5885 key.key_size = priv->ieee->sec.key_sizes[i];5886 memcpy(key.key, priv->ieee->sec.keys[i], key.key_size);5887 5888 ipw_send_cmd_pdu(priv, IPW_CMD_WEP_KEY, sizeof(key), &key);5889 }5890}5891 5892static void ipw_set_hw_decrypt_unicast(struct ipw_priv *priv, int level)5893{5894 if (priv->ieee->host_encrypt)5895 return;5896 5897 switch (level) {5898 case SEC_LEVEL_3:5899 priv->sys_config.disable_unicast_decryption = 0;5900 priv->ieee->host_decrypt = 0;5901 break;5902 case SEC_LEVEL_2:5903 priv->sys_config.disable_unicast_decryption = 1;5904 priv->ieee->host_decrypt = 1;5905 break;5906 case SEC_LEVEL_1:5907 priv->sys_config.disable_unicast_decryption = 0;5908 priv->ieee->host_decrypt = 0;5909 break;5910 case SEC_LEVEL_0:5911 priv->sys_config.disable_unicast_decryption = 1;5912 break;5913 default:5914 break;5915 }5916}5917 5918static void ipw_set_hw_decrypt_multicast(struct ipw_priv *priv, int level)5919{5920 if (priv->ieee->host_encrypt)5921 return;5922 5923 switch (level) {5924 case SEC_LEVEL_3:5925 priv->sys_config.disable_multicast_decryption = 0;5926 break;5927 case SEC_LEVEL_2:5928 priv->sys_config.disable_multicast_decryption = 1;5929 break;5930 case SEC_LEVEL_1:5931 priv->sys_config.disable_multicast_decryption = 0;5932 break;5933 case SEC_LEVEL_0:5934 priv->sys_config.disable_multicast_decryption = 1;5935 break;5936 default:5937 break;5938 }5939}5940 5941static void ipw_set_hwcrypto_keys(struct ipw_priv *priv)5942{5943 switch (priv->ieee->sec.level) {5944 case SEC_LEVEL_3:5945 if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)5946 ipw_send_tgi_tx_key(priv,5947 DCT_FLAG_EXT_SECURITY_CCM,5948 priv->ieee->sec.active_key);5949 5950 if (!priv->ieee->host_mc_decrypt)5951 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_CCM);5952 break;5953 case SEC_LEVEL_2:5954 if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)5955 ipw_send_tgi_tx_key(priv,5956 DCT_FLAG_EXT_SECURITY_TKIP,5957 priv->ieee->sec.active_key);5958 break;5959 case SEC_LEVEL_1:5960 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);5961 ipw_set_hw_decrypt_unicast(priv, priv->ieee->sec.level);5962 ipw_set_hw_decrypt_multicast(priv, priv->ieee->sec.level);5963 break;5964 case SEC_LEVEL_0:5965 default:5966 break;5967 }5968}5969 5970static void ipw_adhoc_check(void *data)5971{5972 struct ipw_priv *priv = data;5973 5974 if (priv->missed_adhoc_beacons++ > priv->disassociate_threshold &&5975 !(priv->config & CFG_ADHOC_PERSIST)) {5976 IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |5977 IPW_DL_STATE | IPW_DL_ASSOC,5978 "Missed beacon: %d - disassociate\n",5979 priv->missed_adhoc_beacons);5980 ipw_remove_current_network(priv);5981 ipw_disassociate(priv);5982 return;5983 }5984 5985 schedule_delayed_work(&priv->adhoc_check,5986 le16_to_cpu(priv->assoc_request.beacon_interval));5987}5988 5989static void ipw_bg_adhoc_check(struct work_struct *work)5990{5991 struct ipw_priv *priv =5992 container_of(work, struct ipw_priv, adhoc_check.work);5993 mutex_lock(&priv->mutex);5994 ipw_adhoc_check(priv);5995 mutex_unlock(&priv->mutex);5996}5997 5998static void ipw_debug_config(struct ipw_priv *priv)5999{6000 IPW_DEBUG_INFO("Scan completed, no valid APs matched "6001 "[CFG 0x%08X]\n", priv->config);6002 if (priv->config & CFG_STATIC_CHANNEL)6003 IPW_DEBUG_INFO("Channel locked to %d\n", priv->channel);6004 else6005 IPW_DEBUG_INFO("Channel unlocked.\n");6006 if (priv->config & CFG_STATIC_ESSID)6007 IPW_DEBUG_INFO("ESSID locked to '%*pE'\n",6008 priv->essid_len, priv->essid);6009 else6010 IPW_DEBUG_INFO("ESSID unlocked.\n");6011 if (priv->config & CFG_STATIC_BSSID)6012 IPW_DEBUG_INFO("BSSID locked to %pM\n", priv->bssid);6013 else6014 IPW_DEBUG_INFO("BSSID unlocked.\n");6015 if (priv->capability & CAP_PRIVACY_ON)6016 IPW_DEBUG_INFO("PRIVACY on\n");6017 else6018 IPW_DEBUG_INFO("PRIVACY off\n");6019 IPW_DEBUG_INFO("RATE MASK: 0x%08X\n", priv->rates_mask);6020}6021 6022static void ipw_set_fixed_rate(struct ipw_priv *priv, int mode)6023{6024 /* TODO: Verify that this works... */6025 struct ipw_fixed_rate fr;6026 u32 reg;6027 u16 mask = 0;6028 u16 new_tx_rates = priv->rates_mask;6029 6030 /* Identify 'current FW band' and match it with the fixed6031 * Tx rates */6032 6033 switch (priv->ieee->freq_band) {6034 case LIBIPW_52GHZ_BAND: /* A only */6035 /* IEEE_A */6036 if (priv->rates_mask & ~LIBIPW_OFDM_RATES_MASK) {6037 /* Invalid fixed rate mask */6038 IPW_DEBUG_WX6039 ("invalid fixed rate mask in ipw_set_fixed_rate\n");6040 new_tx_rates = 0;6041 break;6042 }6043 6044 new_tx_rates >>= LIBIPW_OFDM_SHIFT_MASK_A;6045 break;6046 6047 default: /* 2.4Ghz or Mixed */6048 /* IEEE_B */6049 if (mode == IEEE_B) {6050 if (new_tx_rates & ~LIBIPW_CCK_RATES_MASK) {6051 /* Invalid fixed rate mask */6052 IPW_DEBUG_WX6053 ("invalid fixed rate mask in ipw_set_fixed_rate\n");6054 new_tx_rates = 0;6055 }6056 break;6057 }6058 6059 /* IEEE_G */6060 if (new_tx_rates & ~(LIBIPW_CCK_RATES_MASK |6061 LIBIPW_OFDM_RATES_MASK)) {6062 /* Invalid fixed rate mask */6063 IPW_DEBUG_WX6064 ("invalid fixed rate mask in ipw_set_fixed_rate\n");6065 new_tx_rates = 0;6066 break;6067 }6068 6069 if (LIBIPW_OFDM_RATE_6MB_MASK & new_tx_rates) {6070 mask |= (LIBIPW_OFDM_RATE_6MB_MASK >> 1);6071 new_tx_rates &= ~LIBIPW_OFDM_RATE_6MB_MASK;6072 }6073 6074 if (LIBIPW_OFDM_RATE_9MB_MASK & new_tx_rates) {6075 mask |= (LIBIPW_OFDM_RATE_9MB_MASK >> 1);6076 new_tx_rates &= ~LIBIPW_OFDM_RATE_9MB_MASK;6077 }6078 6079 if (LIBIPW_OFDM_RATE_12MB_MASK & new_tx_rates) {6080 mask |= (LIBIPW_OFDM_RATE_12MB_MASK >> 1);6081 new_tx_rates &= ~LIBIPW_OFDM_RATE_12MB_MASK;6082 }6083 6084 new_tx_rates |= mask;6085 break;6086 }6087 6088 fr.tx_rates = cpu_to_le16(new_tx_rates);6089 6090 reg = ipw_read32(priv, IPW_MEM_FIXED_OVERRIDE);6091 ipw_write_reg32(priv, reg, *(u32 *) & fr);6092}6093 6094static void ipw_abort_scan(struct ipw_priv *priv)6095{6096 int err;6097 6098 if (priv->status & STATUS_SCAN_ABORTING) {6099 IPW_DEBUG_HC("Ignoring concurrent scan abort request.\n");6100 return;6101 }6102 priv->status |= STATUS_SCAN_ABORTING;6103 6104 err = ipw_send_scan_abort(priv);6105 if (err)6106 IPW_DEBUG_HC("Request to abort scan failed.\n");6107}6108 6109static void ipw_add_scan_channels(struct ipw_priv *priv,6110 struct ipw_scan_request_ext *scan,6111 int scan_type)6112{6113 int channel_index = 0;6114 const struct libipw_geo *geo;6115 int i;6116 6117 geo = libipw_get_geo(priv->ieee);6118 6119 if (priv->ieee->freq_band & LIBIPW_52GHZ_BAND) {6120 int start = channel_index;6121 for (i = 0; i < geo->a_channels; i++) {6122 if ((priv->status & STATUS_ASSOCIATED) &&6123 geo->a[i].channel == priv->channel)6124 continue;6125 channel_index++;6126 scan->channels_list[channel_index] = geo->a[i].channel;6127 ipw_set_scan_type(scan, channel_index,6128 geo->a[i].6129 flags & LIBIPW_CH_PASSIVE_ONLY ?6130 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN :6131 scan_type);6132 }6133 6134 if (start != channel_index) {6135 scan->channels_list[start] = (u8) (IPW_A_MODE << 6) |6136 (channel_index - start);6137 channel_index++;6138 }6139 }6140 6141 if (priv->ieee->freq_band & LIBIPW_24GHZ_BAND) {6142 int start = channel_index;6143 if (priv->config & CFG_SPEED_SCAN) {6144 int index;6145 u8 channels[LIBIPW_24GHZ_CHANNELS] = {6146 /* nop out the list */6147 [0] = 06148 };6149 6150 u8 channel;6151 while (channel_index < IPW_SCAN_CHANNELS - 1) {6152 channel =6153 priv->speed_scan[priv->speed_scan_pos];6154 if (channel == 0) {6155 priv->speed_scan_pos = 0;6156 channel = priv->speed_scan[0];6157 }6158 if ((priv->status & STATUS_ASSOCIATED) &&6159 channel == priv->channel) {6160 priv->speed_scan_pos++;6161 continue;6162 }6163 6164 /* If this channel has already been6165 * added in scan, break from loop6166 * and this will be the first channel6167 * in the next scan.6168 */6169 if (channels[channel - 1] != 0)6170 break;6171 6172 channels[channel - 1] = 1;6173 priv->speed_scan_pos++;6174 channel_index++;6175 scan->channels_list[channel_index] = channel;6176 index =6177 libipw_channel_to_index(priv->ieee, channel);6178 ipw_set_scan_type(scan, channel_index,6179 geo->bg[index].6180 flags &6181 LIBIPW_CH_PASSIVE_ONLY ?6182 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN6183 : scan_type);6184 }6185 } else {6186 for (i = 0; i < geo->bg_channels; i++) {6187 if ((priv->status & STATUS_ASSOCIATED) &&6188 geo->bg[i].channel == priv->channel)6189 continue;6190 channel_index++;6191 scan->channels_list[channel_index] =6192 geo->bg[i].channel;6193 ipw_set_scan_type(scan, channel_index,6194 geo->bg[i].6195 flags &6196 LIBIPW_CH_PASSIVE_ONLY ?6197 IPW_SCAN_PASSIVE_FULL_DWELL_SCAN6198 : scan_type);6199 }6200 }6201 6202 if (start != channel_index) {6203 scan->channels_list[start] = (u8) (IPW_B_MODE << 6) |6204 (channel_index - start);6205 }6206 }6207}6208 6209static int ipw_passive_dwell_time(struct ipw_priv *priv)6210{6211 /* staying on passive channels longer than the DTIM interval during a6212 * scan, while associated, causes the firmware to cancel the scan6213 * without notification. Hence, don't stay on passive channels longer6214 * than the beacon interval.6215 */6216 if (priv->status & STATUS_ASSOCIATED6217 && priv->assoc_network->beacon_interval > 10)6218 return priv->assoc_network->beacon_interval - 10;6219 else6220 return 120;6221}6222 6223static int ipw_request_scan_helper(struct ipw_priv *priv, int type, int direct)6224{6225 struct ipw_scan_request_ext scan;6226 int err = 0, scan_type;6227 6228 if (!(priv->status & STATUS_INIT) ||6229 (priv->status & STATUS_EXIT_PENDING))6230 return 0;6231 6232 mutex_lock(&priv->mutex);6233 6234 if (direct && (priv->direct_scan_ssid_len == 0)) {6235 IPW_DEBUG_HC("Direct scan requested but no SSID to scan for\n");6236 priv->status &= ~STATUS_DIRECT_SCAN_PENDING;6237 goto done;6238 }6239 6240 if (priv->status & STATUS_SCANNING) {6241 IPW_DEBUG_HC("Concurrent scan requested. Queuing.\n");6242 priv->status |= direct ? STATUS_DIRECT_SCAN_PENDING :6243 STATUS_SCAN_PENDING;6244 goto done;6245 }6246 6247 if (!(priv->status & STATUS_SCAN_FORCED) &&6248 priv->status & STATUS_SCAN_ABORTING) {6249 IPW_DEBUG_HC("Scan request while abort pending. Queuing.\n");6250 priv->status |= direct ? STATUS_DIRECT_SCAN_PENDING :6251 STATUS_SCAN_PENDING;6252 goto done;6253 }6254 6255 if (priv->status & STATUS_RF_KILL_MASK) {6256 IPW_DEBUG_HC("Queuing scan due to RF Kill activation\n");6257 priv->status |= direct ? STATUS_DIRECT_SCAN_PENDING :6258 STATUS_SCAN_PENDING;6259 goto done;6260 }6261 6262 memset(&scan, 0, sizeof(scan));6263 scan.full_scan_index = cpu_to_le32(libipw_get_scans(priv->ieee));6264 6265 if (type == IW_SCAN_TYPE_PASSIVE) {6266 IPW_DEBUG_WX("use passive scanning\n");6267 scan_type = IPW_SCAN_PASSIVE_FULL_DWELL_SCAN;6268 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =6269 cpu_to_le16(ipw_passive_dwell_time(priv));6270 ipw_add_scan_channels(priv, &scan, scan_type);6271 goto send_request;6272 }6273 6274 /* Use active scan by default. */6275 if (priv->config & CFG_SPEED_SCAN)6276 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =6277 cpu_to_le16(30);6278 else6279 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] =6280 cpu_to_le16(20);6281 6282 scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =6283 cpu_to_le16(20);6284 6285 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =6286 cpu_to_le16(ipw_passive_dwell_time(priv));6287 scan.dwell_time[IPW_SCAN_ACTIVE_DIRECT_SCAN] = cpu_to_le16(20);6288 6289#ifdef CONFIG_IPW2200_MONITOR6290 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {6291 u8 channel;6292 u8 band = 0;6293 6294 switch (libipw_is_valid_channel(priv->ieee, priv->channel)) {6295 case LIBIPW_52GHZ_BAND:6296 band = (u8) (IPW_A_MODE << 6) | 1;6297 channel = priv->channel;6298 break;6299 6300 case LIBIPW_24GHZ_BAND:6301 band = (u8) (IPW_B_MODE << 6) | 1;6302 channel = priv->channel;6303 break;6304 6305 default:6306 band = (u8) (IPW_B_MODE << 6) | 1;6307 channel = 9;6308 break;6309 }6310 6311 scan.channels_list[0] = band;6312 scan.channels_list[1] = channel;6313 ipw_set_scan_type(&scan, 1, IPW_SCAN_PASSIVE_FULL_DWELL_SCAN);6314 6315 /* NOTE: The card will sit on this channel for this time6316 * period. Scan aborts are timing sensitive and frequently6317 * result in firmware restarts. As such, it is best to6318 * set a small dwell_time here and just keep re-issuing6319 * scans. Otherwise fast channel hopping will not actually6320 * hop channels.6321 *6322 * TODO: Move SPEED SCAN support to all modes and bands */6323 scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =6324 cpu_to_le16(2000);6325 } else {6326#endif /* CONFIG_IPW2200_MONITOR */6327 /* Honor direct scans first, otherwise if we are roaming make6328 * this a direct scan for the current network. Finally,6329 * ensure that every other scan is a fast channel hop scan */6330 if (direct) {6331 err = ipw_send_ssid(priv, priv->direct_scan_ssid,6332 priv->direct_scan_ssid_len);6333 if (err) {6334 IPW_DEBUG_HC("Attempt to send SSID command "6335 "failed\n");6336 goto done;6337 }6338 6339 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;6340 } else if ((priv->status & STATUS_ROAMING)6341 || (!(priv->status & STATUS_ASSOCIATED)6342 && (priv->config & CFG_STATIC_ESSID)6343 && (le32_to_cpu(scan.full_scan_index) % 2))) {6344 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);6345 if (err) {6346 IPW_DEBUG_HC("Attempt to send SSID command "6347 "failed.\n");6348 goto done;6349 }6350 6351 scan_type = IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN;6352 } else6353 scan_type = IPW_SCAN_ACTIVE_BROADCAST_SCAN;6354 6355 ipw_add_scan_channels(priv, &scan, scan_type);6356#ifdef CONFIG_IPW2200_MONITOR6357 }6358#endif6359 6360send_request:6361 err = ipw_send_scan_request_ext(priv, &scan);6362 if (err) {6363 IPW_DEBUG_HC("Sending scan command failed: %08X\n", err);6364 goto done;6365 }6366 6367 priv->status |= STATUS_SCANNING;6368 if (direct) {6369 priv->status &= ~STATUS_DIRECT_SCAN_PENDING;6370 priv->direct_scan_ssid_len = 0;6371 } else6372 priv->status &= ~STATUS_SCAN_PENDING;6373 6374 schedule_delayed_work(&priv->scan_check, IPW_SCAN_CHECK_WATCHDOG);6375done:6376 mutex_unlock(&priv->mutex);6377 return err;6378}6379 6380static void ipw_request_passive_scan(struct work_struct *work)6381{6382 struct ipw_priv *priv =6383 container_of(work, struct ipw_priv, request_passive_scan.work);6384 ipw_request_scan_helper(priv, IW_SCAN_TYPE_PASSIVE, 0);6385}6386 6387static void ipw_request_scan(struct work_struct *work)6388{6389 struct ipw_priv *priv =6390 container_of(work, struct ipw_priv, request_scan.work);6391 ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE, 0);6392}6393 6394static void ipw_request_direct_scan(struct work_struct *work)6395{6396 struct ipw_priv *priv =6397 container_of(work, struct ipw_priv, request_direct_scan.work);6398 ipw_request_scan_helper(priv, IW_SCAN_TYPE_ACTIVE, 1);6399}6400 6401static void ipw_bg_abort_scan(struct work_struct *work)6402{6403 struct ipw_priv *priv =6404 container_of(work, struct ipw_priv, abort_scan);6405 mutex_lock(&priv->mutex);6406 ipw_abort_scan(priv);6407 mutex_unlock(&priv->mutex);6408}6409 6410static int ipw_wpa_enable(struct ipw_priv *priv, int value)6411{6412 /* This is called when wpa_supplicant loads and closes the driver6413 * interface. */6414 priv->ieee->wpa_enabled = value;6415 return 0;6416}6417 6418static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value)6419{6420 struct libipw_device *ieee = priv->ieee;6421 struct libipw_security sec = {6422 .flags = SEC_AUTH_MODE,6423 };6424 int ret = 0;6425 6426 if (value & IW_AUTH_ALG_SHARED_KEY) {6427 sec.auth_mode = WLAN_AUTH_SHARED_KEY;6428 ieee->open_wep = 0;6429 } else if (value & IW_AUTH_ALG_OPEN_SYSTEM) {6430 sec.auth_mode = WLAN_AUTH_OPEN;6431 ieee->open_wep = 1;6432 } else if (value & IW_AUTH_ALG_LEAP) {6433 sec.auth_mode = WLAN_AUTH_LEAP;6434 ieee->open_wep = 1;6435 } else6436 return -EINVAL;6437 6438 if (ieee->set_security)6439 ieee->set_security(ieee->dev, &sec);6440 else6441 ret = -EOPNOTSUPP;6442 6443 return ret;6444}6445 6446static void ipw_wpa_assoc_frame(struct ipw_priv *priv, char *wpa_ie,6447 int wpa_ie_len)6448{6449 /* make sure WPA is enabled */6450 ipw_wpa_enable(priv, 1);6451}6452 6453static int ipw_set_rsn_capa(struct ipw_priv *priv,6454 char *capabilities, int length)6455{6456 IPW_DEBUG_HC("HOST_CMD_RSN_CAPABILITIES\n");6457 6458 return ipw_send_cmd_pdu(priv, IPW_CMD_RSN_CAPABILITIES, length,6459 capabilities);6460}6461 6462/*6463 * WE-18 support6464 */6465 6466/* SIOCSIWGENIE */6467static int ipw_wx_set_genie(struct net_device *dev,6468 struct iw_request_info *info,6469 union iwreq_data *wrqu, char *extra)6470{6471 struct ipw_priv *priv = libipw_priv(dev);6472 struct libipw_device *ieee = priv->ieee;6473 u8 *buf;6474 int err = 0;6475 6476 if (wrqu->data.length > MAX_WPA_IE_LEN ||6477 (wrqu->data.length && extra == NULL))6478 return -EINVAL;6479 6480 if (wrqu->data.length) {6481 buf = kmemdup(extra, wrqu->data.length, GFP_KERNEL);6482 if (buf == NULL) {6483 err = -ENOMEM;6484 goto out;6485 }6486 6487 kfree(ieee->wpa_ie);6488 ieee->wpa_ie = buf;6489 ieee->wpa_ie_len = wrqu->data.length;6490 } else {6491 kfree(ieee->wpa_ie);6492 ieee->wpa_ie = NULL;6493 ieee->wpa_ie_len = 0;6494 }6495 6496 ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);6497 out:6498 return err;6499}6500 6501/* SIOCGIWGENIE */6502static int ipw_wx_get_genie(struct net_device *dev,6503 struct iw_request_info *info,6504 union iwreq_data *wrqu, char *extra)6505{6506 struct ipw_priv *priv = libipw_priv(dev);6507 struct libipw_device *ieee = priv->ieee;6508 int err = 0;6509 6510 if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {6511 wrqu->data.length = 0;6512 goto out;6513 }6514 6515 if (wrqu->data.length < ieee->wpa_ie_len) {6516 err = -E2BIG;6517 goto out;6518 }6519 6520 wrqu->data.length = ieee->wpa_ie_len;6521 memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);6522 6523 out:6524 return err;6525}6526 6527static int wext_cipher2level(int cipher)6528{6529 switch (cipher) {6530 case IW_AUTH_CIPHER_NONE:6531 return SEC_LEVEL_0;6532 case IW_AUTH_CIPHER_WEP40:6533 case IW_AUTH_CIPHER_WEP104:6534 return SEC_LEVEL_1;6535 case IW_AUTH_CIPHER_TKIP:6536 return SEC_LEVEL_2;6537 case IW_AUTH_CIPHER_CCMP:6538 return SEC_LEVEL_3;6539 default:6540 return -1;6541 }6542}6543 6544/* SIOCSIWAUTH */6545static int ipw_wx_set_auth(struct net_device *dev,6546 struct iw_request_info *info,6547 union iwreq_data *wrqu, char *extra)6548{6549 struct ipw_priv *priv = libipw_priv(dev);6550 struct libipw_device *ieee = priv->ieee;6551 struct iw_param *param = &wrqu->param;6552 struct lib80211_crypt_data *crypt;6553 unsigned long flags;6554 int ret = 0;6555 6556 switch (param->flags & IW_AUTH_INDEX) {6557 case IW_AUTH_WPA_VERSION:6558 break;6559 case IW_AUTH_CIPHER_PAIRWISE:6560 ipw_set_hw_decrypt_unicast(priv,6561 wext_cipher2level(param->value));6562 break;6563 case IW_AUTH_CIPHER_GROUP:6564 ipw_set_hw_decrypt_multicast(priv,6565 wext_cipher2level(param->value));6566 break;6567 case IW_AUTH_KEY_MGMT:6568 /*6569 * ipw2200 does not use these parameters6570 */6571 break;6572 6573 case IW_AUTH_TKIP_COUNTERMEASURES:6574 crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx];6575 if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)6576 break;6577 6578 flags = crypt->ops->get_flags(crypt->priv);6579 6580 if (param->value)6581 flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;6582 else6583 flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;6584 6585 crypt->ops->set_flags(flags, crypt->priv);6586 6587 break;6588 6589 case IW_AUTH_DROP_UNENCRYPTED:{6590 /* HACK:6591 *6592 * wpa_supplicant calls set_wpa_enabled when the driver6593 * is loaded and unloaded, regardless of if WPA is being6594 * used. No other calls are made which can be used to6595 * determine if encryption will be used or not prior to6596 * association being expected. If encryption is not being6597 * used, drop_unencrypted is set to false, else true -- we6598 * can use this to determine if the CAP_PRIVACY_ON bit should6599 * be set.6600 */6601 struct libipw_security sec = {6602 .flags = SEC_ENABLED,6603 .enabled = param->value,6604 };6605 priv->ieee->drop_unencrypted = param->value;6606 /* We only change SEC_LEVEL for open mode. Others6607 * are set by ipw_wpa_set_encryption.6608 */6609 if (!param->value) {6610 sec.flags |= SEC_LEVEL;6611 sec.level = SEC_LEVEL_0;6612 } else {6613 sec.flags |= SEC_LEVEL;6614 sec.level = SEC_LEVEL_1;6615 }6616 if (priv->ieee->set_security)6617 priv->ieee->set_security(priv->ieee->dev, &sec);6618 break;6619 }6620 6621 case IW_AUTH_80211_AUTH_ALG:6622 ret = ipw_wpa_set_auth_algs(priv, param->value);6623 break;6624 6625 case IW_AUTH_WPA_ENABLED:6626 ret = ipw_wpa_enable(priv, param->value);6627 ipw_disassociate(priv);6628 break;6629 6630 case IW_AUTH_RX_UNENCRYPTED_EAPOL:6631 ieee->ieee802_1x = param->value;6632 break;6633 6634 case IW_AUTH_PRIVACY_INVOKED:6635 ieee->privacy_invoked = param->value;6636 break;6637 6638 default:6639 return -EOPNOTSUPP;6640 }6641 return ret;6642}6643 6644/* SIOCGIWAUTH */6645static int ipw_wx_get_auth(struct net_device *dev,6646 struct iw_request_info *info,6647 union iwreq_data *wrqu, char *extra)6648{6649 struct ipw_priv *priv = libipw_priv(dev);6650 struct libipw_device *ieee = priv->ieee;6651 struct lib80211_crypt_data *crypt;6652 struct iw_param *param = &wrqu->param;6653 6654 switch (param->flags & IW_AUTH_INDEX) {6655 case IW_AUTH_WPA_VERSION:6656 case IW_AUTH_CIPHER_PAIRWISE:6657 case IW_AUTH_CIPHER_GROUP:6658 case IW_AUTH_KEY_MGMT:6659 /*6660 * wpa_supplicant will control these internally6661 */6662 return -EOPNOTSUPP;6663 6664 case IW_AUTH_TKIP_COUNTERMEASURES:6665 crypt = priv->ieee->crypt_info.crypt[priv->ieee->crypt_info.tx_keyidx];6666 if (!crypt || !crypt->ops->get_flags)6667 break;6668 6669 param->value = (crypt->ops->get_flags(crypt->priv) &6670 IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) ? 1 : 0;6671 6672 break;6673 6674 case IW_AUTH_DROP_UNENCRYPTED:6675 param->value = ieee->drop_unencrypted;6676 break;6677 6678 case IW_AUTH_80211_AUTH_ALG:6679 param->value = ieee->sec.auth_mode;6680 break;6681 6682 case IW_AUTH_WPA_ENABLED:6683 param->value = ieee->wpa_enabled;6684 break;6685 6686 case IW_AUTH_RX_UNENCRYPTED_EAPOL:6687 param->value = ieee->ieee802_1x;6688 break;6689 6690 case IW_AUTH_ROAMING_CONTROL:6691 case IW_AUTH_PRIVACY_INVOKED:6692 param->value = ieee->privacy_invoked;6693 break;6694 6695 default:6696 return -EOPNOTSUPP;6697 }6698 return 0;6699}6700 6701/* SIOCSIWENCODEEXT */6702static int ipw_wx_set_encodeext(struct net_device *dev,6703 struct iw_request_info *info,6704 union iwreq_data *wrqu, char *extra)6705{6706 struct ipw_priv *priv = libipw_priv(dev);6707 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;6708 6709 if (hwcrypto) {6710 if (ext->alg == IW_ENCODE_ALG_TKIP) {6711 /* IPW HW can't build TKIP MIC,6712 host decryption still needed */6713 if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)6714 priv->ieee->host_mc_decrypt = 1;6715 else {6716 priv->ieee->host_encrypt = 0;6717 priv->ieee->host_encrypt_msdu = 1;6718 priv->ieee->host_decrypt = 1;6719 }6720 } else {6721 priv->ieee->host_encrypt = 0;6722 priv->ieee->host_encrypt_msdu = 0;6723 priv->ieee->host_decrypt = 0;6724 priv->ieee->host_mc_decrypt = 0;6725 }6726 }6727 6728 return libipw_wx_set_encodeext(priv->ieee, info, wrqu, extra);6729}6730 6731/* SIOCGIWENCODEEXT */6732static int ipw_wx_get_encodeext(struct net_device *dev,6733 struct iw_request_info *info,6734 union iwreq_data *wrqu, char *extra)6735{6736 struct ipw_priv *priv = libipw_priv(dev);6737 return libipw_wx_get_encodeext(priv->ieee, info, wrqu, extra);6738}6739 6740/* SIOCSIWMLME */6741static int ipw_wx_set_mlme(struct net_device *dev,6742 struct iw_request_info *info,6743 union iwreq_data *wrqu, char *extra)6744{6745 struct ipw_priv *priv = libipw_priv(dev);6746 struct iw_mlme *mlme = (struct iw_mlme *)extra;6747 6748 switch (mlme->cmd) {6749 case IW_MLME_DEAUTH:6750 /* silently ignore */6751 break;6752 6753 case IW_MLME_DISASSOC:6754 ipw_disassociate(priv);6755 break;6756 6757 default:6758 return -EOPNOTSUPP;6759 }6760 return 0;6761}6762 6763#ifdef CONFIG_IPW2200_QOS6764 6765/* QoS */6766/*6767* get the modulation type of the current network or6768* the card current mode6769*/6770static u8 ipw_qos_current_mode(struct ipw_priv * priv)6771{6772 u8 mode = 0;6773 6774 if (priv->status & STATUS_ASSOCIATED) {6775 unsigned long flags;6776 6777 spin_lock_irqsave(&priv->ieee->lock, flags);6778 mode = priv->assoc_network->mode;6779 spin_unlock_irqrestore(&priv->ieee->lock, flags);6780 } else {6781 mode = priv->ieee->mode;6782 }6783 IPW_DEBUG_QOS("QoS network/card mode %d\n", mode);6784 return mode;6785}6786 6787/*6788* Handle management frame beacon and probe response6789*/6790static int ipw_qos_handle_probe_response(struct ipw_priv *priv,6791 int active_network,6792 struct libipw_network *network)6793{6794 u32 size = sizeof(struct libipw_qos_parameters);6795 6796 if (network->capability & WLAN_CAPABILITY_IBSS)6797 network->qos_data.active = network->qos_data.supported;6798 6799 if (network->flags & NETWORK_HAS_QOS_MASK) {6800 if (active_network &&6801 (network->flags & NETWORK_HAS_QOS_PARAMETERS))6802 network->qos_data.active = network->qos_data.supported;6803 6804 if ((network->qos_data.active == 1) && (active_network == 1) &&6805 (network->flags & NETWORK_HAS_QOS_PARAMETERS) &&6806 (network->qos_data.old_param_count !=6807 network->qos_data.param_count)) {6808 network->qos_data.old_param_count =6809 network->qos_data.param_count;6810 schedule_work(&priv->qos_activate);6811 IPW_DEBUG_QOS("QoS parameters change call "6812 "qos_activate\n");6813 }6814 } else {6815 if ((priv->ieee->mode == IEEE_B) || (network->mode == IEEE_B))6816 memcpy(&network->qos_data.parameters,6817 &def_parameters_CCK, size);6818 else6819 memcpy(&network->qos_data.parameters,6820 &def_parameters_OFDM, size);6821 6822 if ((network->qos_data.active == 1) && (active_network == 1)) {6823 IPW_DEBUG_QOS("QoS was disabled call qos_activate\n");6824 schedule_work(&priv->qos_activate);6825 }6826 6827 network->qos_data.active = 0;6828 network->qos_data.supported = 0;6829 }6830 if ((priv->status & STATUS_ASSOCIATED) &&6831 (priv->ieee->iw_mode == IW_MODE_ADHOC) && (active_network == 0)) {6832 if (!ether_addr_equal(network->bssid, priv->bssid))6833 if (network->capability & WLAN_CAPABILITY_IBSS)6834 if ((network->ssid_len ==6835 priv->assoc_network->ssid_len) &&6836 !memcmp(network->ssid,6837 priv->assoc_network->ssid,6838 network->ssid_len)) {6839 schedule_work(&priv->merge_networks);6840 }6841 }6842 6843 return 0;6844}6845 6846/*6847* This function set up the firmware to support QoS. It sends6848* IPW_CMD_QOS_PARAMETERS and IPW_CMD_WME_INFO6849*/6850static int ipw_qos_activate(struct ipw_priv *priv,6851 struct libipw_qos_data *qos_network_data)6852{6853 int err;6854 struct libipw_qos_parameters qos_parameters[QOS_QOS_SETS];6855 struct libipw_qos_parameters *active_one = NULL;6856 u32 size = sizeof(struct libipw_qos_parameters);6857 u32 burst_duration;6858 int i;6859 u8 type;6860 6861 type = ipw_qos_current_mode(priv);6862 6863 active_one = &(qos_parameters[QOS_PARAM_SET_DEF_CCK]);6864 memcpy(active_one, priv->qos_data.def_qos_parm_CCK, size);6865 active_one = &(qos_parameters[QOS_PARAM_SET_DEF_OFDM]);6866 memcpy(active_one, priv->qos_data.def_qos_parm_OFDM, size);6867 6868 if (qos_network_data == NULL) {6869 if (type == IEEE_B) {6870 IPW_DEBUG_QOS("QoS activate network mode %d\n", type);6871 active_one = &def_parameters_CCK;6872 } else6873 active_one = &def_parameters_OFDM;6874 6875 memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);6876 burst_duration = ipw_qos_get_burst_duration(priv);6877 for (i = 0; i < QOS_QUEUE_NUM; i++)6878 qos_parameters[QOS_PARAM_SET_ACTIVE].tx_op_limit[i] =6879 cpu_to_le16(burst_duration);6880 } else if (priv->ieee->iw_mode == IW_MODE_ADHOC) {6881 if (type == IEEE_B) {6882 IPW_DEBUG_QOS("QoS activate IBSS network mode %d\n",6883 type);6884 if (priv->qos_data.qos_enable == 0)6885 active_one = &def_parameters_CCK;6886 else6887 active_one = priv->qos_data.def_qos_parm_CCK;6888 } else {6889 if (priv->qos_data.qos_enable == 0)6890 active_one = &def_parameters_OFDM;6891 else6892 active_one = priv->qos_data.def_qos_parm_OFDM;6893 }6894 memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);6895 } else {6896 unsigned long flags;6897 int active;6898 6899 spin_lock_irqsave(&priv->ieee->lock, flags);6900 active_one = &(qos_network_data->parameters);6901 qos_network_data->old_param_count =6902 qos_network_data->param_count;6903 memcpy(&qos_parameters[QOS_PARAM_SET_ACTIVE], active_one, size);6904 active = qos_network_data->supported;6905 spin_unlock_irqrestore(&priv->ieee->lock, flags);6906 6907 if (active == 0) {6908 burst_duration = ipw_qos_get_burst_duration(priv);6909 for (i = 0; i < QOS_QUEUE_NUM; i++)6910 qos_parameters[QOS_PARAM_SET_ACTIVE].6911 tx_op_limit[i] = cpu_to_le16(burst_duration);6912 }6913 }6914 6915 IPW_DEBUG_QOS("QoS sending IPW_CMD_QOS_PARAMETERS\n");6916 err = ipw_send_qos_params_command(priv, &qos_parameters[0]);6917 if (err)6918 IPW_DEBUG_QOS("QoS IPW_CMD_QOS_PARAMETERS failed\n");6919 6920 return err;6921}6922 6923/*6924* send IPW_CMD_WME_INFO to the firmware6925*/6926static int ipw_qos_set_info_element(struct ipw_priv *priv)6927{6928 int ret = 0;6929 struct libipw_qos_information_element qos_info;6930 6931 if (priv == NULL)6932 return -1;6933 6934 qos_info.elementID = QOS_ELEMENT_ID;6935 qos_info.length = sizeof(struct libipw_qos_information_element) - 2;6936 6937 qos_info.version = QOS_VERSION_1;6938 qos_info.ac_info = 0;6939 6940 memcpy(qos_info.qui, qos_oui, QOS_OUI_LEN);6941 qos_info.qui_type = QOS_OUI_TYPE;6942 qos_info.qui_subtype = QOS_OUI_INFO_SUB_TYPE;6943 6944 ret = ipw_send_qos_info_command(priv, &qos_info);6945 if (ret != 0) {6946 IPW_DEBUG_QOS("QoS error calling ipw_send_qos_info_command\n");6947 }6948 return ret;6949}6950 6951/*6952* Set the QoS parameter with the association request structure6953*/6954static int ipw_qos_association(struct ipw_priv *priv,6955 struct libipw_network *network)6956{6957 int err = 0;6958 struct libipw_qos_data *qos_data = NULL;6959 struct libipw_qos_data ibss_data = {6960 .supported = 1,6961 .active = 1,6962 };6963 6964 switch (priv->ieee->iw_mode) {6965 case IW_MODE_ADHOC:6966 BUG_ON(!(network->capability & WLAN_CAPABILITY_IBSS));6967 6968 qos_data = &ibss_data;6969 break;6970 6971 case IW_MODE_INFRA:6972 qos_data = &network->qos_data;6973 break;6974 6975 default:6976 BUG();6977 break;6978 }6979 6980 err = ipw_qos_activate(priv, qos_data);6981 if (err) {6982 priv->assoc_request.policy_support &= ~HC_QOS_SUPPORT_ASSOC;6983 return err;6984 }6985 6986 if (priv->qos_data.qos_enable && qos_data->supported) {6987 IPW_DEBUG_QOS("QoS will be enabled for this association\n");6988 priv->assoc_request.policy_support |= HC_QOS_SUPPORT_ASSOC;6989 return ipw_qos_set_info_element(priv);6990 }6991 6992 return 0;6993}6994 6995/*6996* handling the beaconing responses. if we get different QoS setting6997* off the network from the associated setting, adjust the QoS6998* setting6999*/7000static void ipw_qos_association_resp(struct ipw_priv *priv,7001 struct libipw_network *network)7002{7003 unsigned long flags;7004 u32 size = sizeof(struct libipw_qos_parameters);7005 int set_qos_param = 0;7006 7007 if ((priv == NULL) || (network == NULL) ||7008 (priv->assoc_network == NULL))7009 return;7010 7011 if (!(priv->status & STATUS_ASSOCIATED))7012 return;7013 7014 if ((priv->ieee->iw_mode != IW_MODE_INFRA))7015 return;7016 7017 spin_lock_irqsave(&priv->ieee->lock, flags);7018 if (network->flags & NETWORK_HAS_QOS_PARAMETERS) {7019 memcpy(&priv->assoc_network->qos_data, &network->qos_data,7020 sizeof(struct libipw_qos_data));7021 priv->assoc_network->qos_data.active = 1;7022 if ((network->qos_data.old_param_count !=7023 network->qos_data.param_count)) {7024 set_qos_param = 1;7025 network->qos_data.old_param_count =7026 network->qos_data.param_count;7027 }7028 7029 } else {7030 if ((network->mode == IEEE_B) || (priv->ieee->mode == IEEE_B))7031 memcpy(&priv->assoc_network->qos_data.parameters,7032 &def_parameters_CCK, size);7033 else7034 memcpy(&priv->assoc_network->qos_data.parameters,7035 &def_parameters_OFDM, size);7036 priv->assoc_network->qos_data.active = 0;7037 priv->assoc_network->qos_data.supported = 0;7038 set_qos_param = 1;7039 }7040 7041 spin_unlock_irqrestore(&priv->ieee->lock, flags);7042 7043 if (set_qos_param == 1)7044 schedule_work(&priv->qos_activate);7045}7046 7047static u32 ipw_qos_get_burst_duration(struct ipw_priv *priv)7048{7049 u32 ret = 0;7050 7051 if (!priv)7052 return 0;7053 7054 if (!(priv->ieee->modulation & LIBIPW_OFDM_MODULATION))7055 ret = priv->qos_data.burst_duration_CCK;7056 else7057 ret = priv->qos_data.burst_duration_OFDM;7058 7059 return ret;7060}7061 7062/*7063* Initialize the setting of QoS global7064*/7065static void ipw_qos_init(struct ipw_priv *priv, int enable,7066 int burst_enable, u32 burst_duration_CCK,7067 u32 burst_duration_OFDM)7068{7069 priv->qos_data.qos_enable = enable;7070 7071 if (priv->qos_data.qos_enable) {7072 priv->qos_data.def_qos_parm_CCK = &def_qos_parameters_CCK;7073 priv->qos_data.def_qos_parm_OFDM = &def_qos_parameters_OFDM;7074 IPW_DEBUG_QOS("QoS is enabled\n");7075 } else {7076 priv->qos_data.def_qos_parm_CCK = &def_parameters_CCK;7077 priv->qos_data.def_qos_parm_OFDM = &def_parameters_OFDM;7078 IPW_DEBUG_QOS("QoS is not enabled\n");7079 }7080 7081 priv->qos_data.burst_enable = burst_enable;7082 7083 if (burst_enable) {7084 priv->qos_data.burst_duration_CCK = burst_duration_CCK;7085 priv->qos_data.burst_duration_OFDM = burst_duration_OFDM;7086 } else {7087 priv->qos_data.burst_duration_CCK = 0;7088 priv->qos_data.burst_duration_OFDM = 0;7089 }7090}7091 7092/*7093* map the packet priority to the right TX Queue7094*/7095static int ipw_get_tx_queue_number(struct ipw_priv *priv, u16 priority)7096{7097 if (priority > 7 || !priv->qos_data.qos_enable)7098 priority = 0;7099 7100 return from_priority_to_tx_queue[priority] - 1;7101}7102 7103static int ipw_is_qos_active(struct net_device *dev,7104 struct sk_buff *skb)7105{7106 struct ipw_priv *priv = libipw_priv(dev);7107 struct libipw_qos_data *qos_data = NULL;7108 int active, supported;7109 u8 *daddr = skb->data + ETH_ALEN;7110 int unicast = !is_multicast_ether_addr(daddr);7111 7112 if (!(priv->status & STATUS_ASSOCIATED))7113 return 0;7114 7115 qos_data = &priv->assoc_network->qos_data;7116 7117 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {7118 if (unicast == 0)7119 qos_data->active = 0;7120 else7121 qos_data->active = qos_data->supported;7122 }7123 active = qos_data->active;7124 supported = qos_data->supported;7125 IPW_DEBUG_QOS("QoS %d network is QoS active %d supported %d "7126 "unicast %d\n",7127 priv->qos_data.qos_enable, active, supported, unicast);7128 if (active && priv->qos_data.qos_enable)7129 return 1;7130 7131 return 0;7132 7133}7134/*7135* add QoS parameter to the TX command7136*/7137static int ipw_qos_set_tx_queue_command(struct ipw_priv *priv,7138 u16 priority,7139 struct tfd_data *tfd)7140{7141 int tx_queue_id = 0;7142 7143 7144 tx_queue_id = from_priority_to_tx_queue[priority] - 1;7145 tfd->tx_flags_ext |= DCT_FLAG_EXT_QOS_ENABLED;7146 7147 if (priv->qos_data.qos_no_ack_mask & (1UL << tx_queue_id)) {7148 tfd->tx_flags &= ~DCT_FLAG_ACK_REQD;7149 tfd->tfd.tfd_26.mchdr.qos_ctrl |= cpu_to_le16(CTRL_QOS_NO_ACK);7150 }7151 return 0;7152}7153 7154/*7155* background support to run QoS activate functionality7156*/7157static void ipw_bg_qos_activate(struct work_struct *work)7158{7159 struct ipw_priv *priv =7160 container_of(work, struct ipw_priv, qos_activate);7161 7162 mutex_lock(&priv->mutex);7163 7164 if (priv->status & STATUS_ASSOCIATED)7165 ipw_qos_activate(priv, &(priv->assoc_network->qos_data));7166 7167 mutex_unlock(&priv->mutex);7168}7169 7170static int ipw_handle_probe_response(struct net_device *dev,7171 struct libipw_probe_response *resp,7172 struct libipw_network *network)7173{7174 struct ipw_priv *priv = libipw_priv(dev);7175 int active_network = ((priv->status & STATUS_ASSOCIATED) &&7176 (network == priv->assoc_network));7177 7178 ipw_qos_handle_probe_response(priv, active_network, network);7179 7180 return 0;7181}7182 7183static int ipw_handle_beacon(struct net_device *dev,7184 struct libipw_beacon *resp,7185 struct libipw_network *network)7186{7187 struct ipw_priv *priv = libipw_priv(dev);7188 int active_network = ((priv->status & STATUS_ASSOCIATED) &&7189 (network == priv->assoc_network));7190 7191 ipw_qos_handle_probe_response(priv, active_network, network);7192 7193 return 0;7194}7195 7196static int ipw_handle_assoc_response(struct net_device *dev,7197 struct libipw_assoc_response *resp,7198 struct libipw_network *network)7199{7200 struct ipw_priv *priv = libipw_priv(dev);7201 ipw_qos_association_resp(priv, network);7202 return 0;7203}7204 7205static int ipw_send_qos_params_command(struct ipw_priv *priv, struct libipw_qos_parameters7206 *qos_param)7207{7208 return ipw_send_cmd_pdu(priv, IPW_CMD_QOS_PARAMETERS,7209 sizeof(*qos_param) * 3, qos_param);7210}7211 7212static int ipw_send_qos_info_command(struct ipw_priv *priv, struct libipw_qos_information_element7213 *qos_param)7214{7215 return ipw_send_cmd_pdu(priv, IPW_CMD_WME_INFO, sizeof(*qos_param),7216 qos_param);7217}7218 7219#endif /* CONFIG_IPW2200_QOS */7220 7221static int ipw_associate_network(struct ipw_priv *priv,7222 struct libipw_network *network,7223 struct ipw_supported_rates *rates, int roaming)7224{7225 int err;7226 7227 if (priv->config & CFG_FIXED_RATE)7228 ipw_set_fixed_rate(priv, network->mode);7229 7230 if (!(priv->config & CFG_STATIC_ESSID)) {7231 priv->essid_len = min(network->ssid_len,7232 (u8) IW_ESSID_MAX_SIZE);7233 memcpy(priv->essid, network->ssid, priv->essid_len);7234 }7235 7236 network->last_associate = jiffies;7237 7238 memset(&priv->assoc_request, 0, sizeof(priv->assoc_request));7239 priv->assoc_request.channel = network->channel;7240 priv->assoc_request.auth_key = 0;7241 7242 if ((priv->capability & CAP_PRIVACY_ON) &&7243 (priv->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY)) {7244 priv->assoc_request.auth_type = AUTH_SHARED_KEY;7245 priv->assoc_request.auth_key = priv->ieee->sec.active_key;7246 7247 if (priv->ieee->sec.level == SEC_LEVEL_1)7248 ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);7249 7250 } else if ((priv->capability & CAP_PRIVACY_ON) &&7251 (priv->ieee->sec.auth_mode == WLAN_AUTH_LEAP))7252 priv->assoc_request.auth_type = AUTH_LEAP;7253 else7254 priv->assoc_request.auth_type = AUTH_OPEN;7255 7256 if (priv->ieee->wpa_ie_len) {7257 priv->assoc_request.policy_support = cpu_to_le16(0x02); /* RSN active */7258 ipw_set_rsn_capa(priv, priv->ieee->wpa_ie,7259 priv->ieee->wpa_ie_len);7260 }7261 7262 /*7263 * It is valid for our ieee device to support multiple modes, but7264 * when it comes to associating to a given network we have to choose7265 * just one mode.7266 */7267 if (network->mode & priv->ieee->mode & IEEE_A)7268 priv->assoc_request.ieee_mode = IPW_A_MODE;7269 else if (network->mode & priv->ieee->mode & IEEE_G)7270 priv->assoc_request.ieee_mode = IPW_G_MODE;7271 else if (network->mode & priv->ieee->mode & IEEE_B)7272 priv->assoc_request.ieee_mode = IPW_B_MODE;7273 7274 priv->assoc_request.capability = cpu_to_le16(network->capability);7275 if ((network->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)7276 && !(priv->config & CFG_PREAMBLE_LONG)) {7277 priv->assoc_request.preamble_length = DCT_FLAG_SHORT_PREAMBLE;7278 } else {7279 priv->assoc_request.preamble_length = DCT_FLAG_LONG_PREAMBLE;7280 7281 /* Clear the short preamble if we won't be supporting it */7282 priv->assoc_request.capability &=7283 ~cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);7284 }7285 7286 /* Clear capability bits that aren't used in Ad Hoc */7287 if (priv->ieee->iw_mode == IW_MODE_ADHOC)7288 priv->assoc_request.capability &=7289 ~cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME);7290 7291 IPW_DEBUG_ASSOC("%ssociation attempt: '%*pE', channel %d, 802.11%c [%d], %s[:%s], enc=%s%s%s%c%c\n",7292 roaming ? "Rea" : "A",7293 priv->essid_len, priv->essid,7294 network->channel,7295 ipw_modes[priv->assoc_request.ieee_mode],7296 rates->num_rates,7297 (priv->assoc_request.preamble_length ==7298 DCT_FLAG_LONG_PREAMBLE) ? "long" : "short",7299 network->capability &7300 WLAN_CAPABILITY_SHORT_PREAMBLE ? "short" : "long",7301 priv->capability & CAP_PRIVACY_ON ? "on " : "off",7302 priv->capability & CAP_PRIVACY_ON ?7303 (priv->capability & CAP_SHARED_KEY ? "(shared)" :7304 "(open)") : "",7305 priv->capability & CAP_PRIVACY_ON ? " key=" : "",7306 priv->capability & CAP_PRIVACY_ON ?7307 '1' + priv->ieee->sec.active_key : '.',7308 priv->capability & CAP_PRIVACY_ON ? '.' : ' ');7309 7310 priv->assoc_request.beacon_interval = cpu_to_le16(network->beacon_interval);7311 if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&7312 (network->time_stamp[0] == 0) && (network->time_stamp[1] == 0)) {7313 priv->assoc_request.assoc_type = HC_IBSS_START;7314 priv->assoc_request.assoc_tsf_msw = 0;7315 priv->assoc_request.assoc_tsf_lsw = 0;7316 } else {7317 if (unlikely(roaming))7318 priv->assoc_request.assoc_type = HC_REASSOCIATE;7319 else7320 priv->assoc_request.assoc_type = HC_ASSOCIATE;7321 priv->assoc_request.assoc_tsf_msw = cpu_to_le32(network->time_stamp[1]);7322 priv->assoc_request.assoc_tsf_lsw = cpu_to_le32(network->time_stamp[0]);7323 }7324 7325 memcpy(priv->assoc_request.bssid, network->bssid, ETH_ALEN);7326 7327 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {7328 eth_broadcast_addr(priv->assoc_request.dest);7329 priv->assoc_request.atim_window = cpu_to_le16(network->atim_window);7330 } else {7331 memcpy(priv->assoc_request.dest, network->bssid, ETH_ALEN);7332 priv->assoc_request.atim_window = 0;7333 }7334 7335 priv->assoc_request.listen_interval = cpu_to_le16(network->listen_interval);7336 7337 err = ipw_send_ssid(priv, priv->essid, priv->essid_len);7338 if (err) {7339 IPW_DEBUG_HC("Attempt to send SSID command failed.\n");7340 return err;7341 }7342 7343 rates->ieee_mode = priv->assoc_request.ieee_mode;7344 rates->purpose = IPW_RATE_CONNECT;7345 ipw_send_supported_rates(priv, rates);7346 7347 if (priv->assoc_request.ieee_mode == IPW_G_MODE)7348 priv->sys_config.dot11g_auto_detection = 1;7349 else7350 priv->sys_config.dot11g_auto_detection = 0;7351 7352 if (priv->ieee->iw_mode == IW_MODE_ADHOC)7353 priv->sys_config.answer_broadcast_ssid_probe = 1;7354 else7355 priv->sys_config.answer_broadcast_ssid_probe = 0;7356 7357 err = ipw_send_system_config(priv);7358 if (err) {7359 IPW_DEBUG_HC("Attempt to send sys config command failed.\n");7360 return err;7361 }7362 7363 IPW_DEBUG_ASSOC("Association sensitivity: %d\n", network->stats.rssi);7364 err = ipw_set_sensitivity(priv, network->stats.rssi + IPW_RSSI_TO_DBM);7365 if (err) {7366 IPW_DEBUG_HC("Attempt to send associate command failed.\n");7367 return err;7368 }7369 7370 /*7371 * If preemption is enabled, it is possible for the association7372 * to complete before we return from ipw_send_associate. Therefore7373 * we have to be sure and update our priviate data first.7374 */7375 priv->channel = network->channel;7376 memcpy(priv->bssid, network->bssid, ETH_ALEN);7377 priv->status |= STATUS_ASSOCIATING;7378 priv->status &= ~STATUS_SECURITY_UPDATED;7379 7380 priv->assoc_network = network;7381 7382#ifdef CONFIG_IPW2200_QOS7383 ipw_qos_association(priv, network);7384#endif7385 7386 err = ipw_send_associate(priv, &priv->assoc_request);7387 if (err) {7388 IPW_DEBUG_HC("Attempt to send associate command failed.\n");7389 return err;7390 }7391 7392 IPW_DEBUG(IPW_DL_STATE, "associating: '%*pE' %pM\n",7393 priv->essid_len, priv->essid, priv->bssid);7394 7395 return 0;7396}7397 7398static void ipw_roam(void *data)7399{7400 struct ipw_priv *priv = data;7401 struct libipw_network *network = NULL;7402 struct ipw_network_match match = {7403 .network = priv->assoc_network7404 };7405 7406 /* The roaming process is as follows:7407 *7408 * 1. Missed beacon threshold triggers the roaming process by7409 * setting the status ROAM bit and requesting a scan.7410 * 2. When the scan completes, it schedules the ROAM work7411 * 3. The ROAM work looks at all of the known networks for one that7412 * is a better network than the currently associated. If none7413 * found, the ROAM process is over (ROAM bit cleared)7414 * 4. If a better network is found, a disassociation request is7415 * sent.7416 * 5. When the disassociation completes, the roam work is again7417 * scheduled. The second time through, the driver is no longer7418 * associated, and the newly selected network is sent an7419 * association request.7420 * 6. At this point ,the roaming process is complete and the ROAM7421 * status bit is cleared.7422 */7423 7424 /* If we are no longer associated, and the roaming bit is no longer7425 * set, then we are not actively roaming, so just return */7426 if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ROAMING)))7427 return;7428 7429 if (priv->status & STATUS_ASSOCIATED) {7430 /* First pass through ROAM process -- look for a better7431 * network */7432 unsigned long flags;7433 u8 rssi = priv->assoc_network->stats.rssi;7434 priv->assoc_network->stats.rssi = -128;7435 spin_lock_irqsave(&priv->ieee->lock, flags);7436 list_for_each_entry(network, &priv->ieee->network_list, list) {7437 if (network != priv->assoc_network)7438 ipw_best_network(priv, &match, network, 1);7439 }7440 spin_unlock_irqrestore(&priv->ieee->lock, flags);7441 priv->assoc_network->stats.rssi = rssi;7442 7443 if (match.network == priv->assoc_network) {7444 IPW_DEBUG_ASSOC("No better APs in this network to "7445 "roam to.\n");7446 priv->status &= ~STATUS_ROAMING;7447 ipw_debug_config(priv);7448 return;7449 }7450 7451 ipw_send_disassociate(priv, 1);7452 priv->assoc_network = match.network;7453 7454 return;7455 }7456 7457 /* Second pass through ROAM process -- request association */7458 ipw_compatible_rates(priv, priv->assoc_network, &match.rates);7459 ipw_associate_network(priv, priv->assoc_network, &match.rates, 1);7460 priv->status &= ~STATUS_ROAMING;7461}7462 7463static void ipw_bg_roam(struct work_struct *work)7464{7465 struct ipw_priv *priv =7466 container_of(work, struct ipw_priv, roam);7467 mutex_lock(&priv->mutex);7468 ipw_roam(priv);7469 mutex_unlock(&priv->mutex);7470}7471 7472static int ipw_associate(void *data)7473{7474 struct ipw_priv *priv = data;7475 7476 struct libipw_network *network = NULL;7477 struct ipw_network_match match = {7478 .network = NULL7479 };7480 struct ipw_supported_rates *rates;7481 struct list_head *element;7482 unsigned long flags;7483 7484 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {7485 IPW_DEBUG_ASSOC("Not attempting association (monitor mode)\n");7486 return 0;7487 }7488 7489 if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {7490 IPW_DEBUG_ASSOC("Not attempting association (already in "7491 "progress)\n");7492 return 0;7493 }7494 7495 if (priv->status & STATUS_DISASSOCIATING) {7496 IPW_DEBUG_ASSOC("Not attempting association (in disassociating)\n");7497 schedule_work(&priv->associate);7498 return 0;7499 }7500 7501 if (!ipw_is_init(priv) || (priv->status & STATUS_SCANNING)) {7502 IPW_DEBUG_ASSOC("Not attempting association (scanning or not "7503 "initialized)\n");7504 return 0;7505 }7506 7507 if (!(priv->config & CFG_ASSOCIATE) &&7508 !(priv->config & (CFG_STATIC_ESSID | CFG_STATIC_BSSID))) {7509 IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n");7510 return 0;7511 }7512 7513 /* Protect our use of the network_list */7514 spin_lock_irqsave(&priv->ieee->lock, flags);7515 list_for_each_entry(network, &priv->ieee->network_list, list)7516 ipw_best_network(priv, &match, network, 0);7517 7518 network = match.network;7519 rates = &match.rates;7520 7521 if (network == NULL &&7522 priv->ieee->iw_mode == IW_MODE_ADHOC &&7523 priv->config & CFG_ADHOC_CREATE &&7524 priv->config & CFG_STATIC_ESSID &&7525 priv->config & CFG_STATIC_CHANNEL) {7526 /* Use oldest network if the free list is empty */7527 if (list_empty(&priv->ieee->network_free_list)) {7528 struct libipw_network *oldest = NULL;7529 struct libipw_network *target;7530 7531 list_for_each_entry(target, &priv->ieee->network_list, list) {7532 if ((oldest == NULL) ||7533 (target->last_scanned < oldest->last_scanned))7534 oldest = target;7535 }7536 7537 /* If there are no more slots, expire the oldest */7538 list_del(&oldest->list);7539 target = oldest;7540 IPW_DEBUG_ASSOC("Expired '%*pE' (%pM) from network list.\n",7541 target->ssid_len, target->ssid,7542 target->bssid);7543 list_add_tail(&target->list,7544 &priv->ieee->network_free_list);7545 }7546 7547 element = priv->ieee->network_free_list.next;7548 network = list_entry(element, struct libipw_network, list);7549 ipw_adhoc_create(priv, network);7550 rates = &priv->rates;7551 list_del(element);7552 list_add_tail(&network->list, &priv->ieee->network_list);7553 }7554 spin_unlock_irqrestore(&priv->ieee->lock, flags);7555 7556 /* If we reached the end of the list, then we don't have any valid7557 * matching APs */7558 if (!network) {7559 ipw_debug_config(priv);7560 7561 if (!(priv->status & STATUS_SCANNING)) {7562 if (!(priv->config & CFG_SPEED_SCAN))7563 schedule_delayed_work(&priv->request_scan,7564 SCAN_INTERVAL);7565 else7566 schedule_delayed_work(&priv->request_scan, 0);7567 }7568 7569 return 0;7570 }7571 7572 ipw_associate_network(priv, network, rates, 0);7573 7574 return 1;7575}7576 7577static void ipw_bg_associate(struct work_struct *work)7578{7579 struct ipw_priv *priv =7580 container_of(work, struct ipw_priv, associate);7581 mutex_lock(&priv->mutex);7582 ipw_associate(priv);7583 mutex_unlock(&priv->mutex);7584}7585 7586static void ipw_rebuild_decrypted_skb(struct ipw_priv *priv,7587 struct sk_buff *skb)7588{7589 struct ieee80211_hdr *hdr;7590 u16 fc;7591 7592 hdr = (struct ieee80211_hdr *)skb->data;7593 fc = le16_to_cpu(hdr->frame_control);7594 if (!(fc & IEEE80211_FCTL_PROTECTED))7595 return;7596 7597 fc &= ~IEEE80211_FCTL_PROTECTED;7598 hdr->frame_control = cpu_to_le16(fc);7599 switch (priv->ieee->sec.level) {7600 case SEC_LEVEL_3:7601 /* Remove CCMP HDR */7602 memmove(skb->data + LIBIPW_3ADDR_LEN,7603 skb->data + LIBIPW_3ADDR_LEN + 8,7604 skb->len - LIBIPW_3ADDR_LEN - 8);7605 skb_trim(skb, skb->len - 16); /* CCMP_HDR_LEN + CCMP_MIC_LEN */7606 break;7607 case SEC_LEVEL_2:7608 break;7609 case SEC_LEVEL_1:7610 /* Remove IV */7611 memmove(skb->data + LIBIPW_3ADDR_LEN,7612 skb->data + LIBIPW_3ADDR_LEN + 4,7613 skb->len - LIBIPW_3ADDR_LEN - 4);7614 skb_trim(skb, skb->len - 8); /* IV + ICV */7615 break;7616 case SEC_LEVEL_0:7617 break;7618 default:7619 printk(KERN_ERR "Unknown security level %d\n",7620 priv->ieee->sec.level);7621 break;7622 }7623}7624 7625static void ipw_handle_data_packet(struct ipw_priv *priv,7626 struct ipw_rx_mem_buffer *rxb,7627 struct libipw_rx_stats *stats)7628{7629 struct net_device *dev = priv->net_dev;7630 struct libipw_hdr_4addr *hdr;7631 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;7632 7633 /* We received data from the HW, so stop the watchdog */7634 netif_trans_update(dev);7635 7636 /* We only process data packets if the7637 * interface is open */7638 if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >7639 skb_tailroom(rxb->skb))) {7640 dev->stats.rx_errors++;7641 priv->wstats.discard.misc++;7642 IPW_DEBUG_DROP("Corruption detected! Oh no!\n");7643 return;7644 } else if (unlikely(!netif_running(priv->net_dev))) {7645 dev->stats.rx_dropped++;7646 priv->wstats.discard.misc++;7647 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");7648 return;7649 }7650 7651 /* Advance skb->data to the start of the actual payload */7652 skb_reserve(rxb->skb, offsetof(struct ipw_rx_packet, u.frame.data));7653 7654 /* Set the size of the skb to the size of the frame */7655 skb_put(rxb->skb, le16_to_cpu(pkt->u.frame.length));7656 7657 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);7658 7659 /* HW decrypt will not clear the WEP bit, MIC, PN, etc. */7660 hdr = (struct libipw_hdr_4addr *)rxb->skb->data;7661 if (priv->ieee->iw_mode != IW_MODE_MONITOR &&7662 (is_multicast_ether_addr(hdr->addr1) ?7663 !priv->ieee->host_mc_decrypt : !priv->ieee->host_decrypt))7664 ipw_rebuild_decrypted_skb(priv, rxb->skb);7665 7666 if (!libipw_rx(priv->ieee, rxb->skb, stats))7667 dev->stats.rx_errors++;7668 else { /* libipw_rx succeeded, so it now owns the SKB */7669 rxb->skb = NULL;7670 __ipw_led_activity_on(priv);7671 }7672}7673 7674#ifdef CONFIG_IPW2200_RADIOTAP7675static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,7676 struct ipw_rx_mem_buffer *rxb,7677 struct libipw_rx_stats *stats)7678{7679 struct net_device *dev = priv->net_dev;7680 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;7681 struct ipw_rx_frame *frame = &pkt->u.frame;7682 7683 /* initial pull of some data */7684 u16 received_channel = frame->received_channel;7685 u8 antennaAndPhy = frame->antennaAndPhy;7686 s8 antsignal = frame->rssi_dbm - IPW_RSSI_TO_DBM; /* call it signed anyhow */7687 u16 pktrate = frame->rate;7688 7689 /* Magic struct that slots into the radiotap header -- no reason7690 * to build this manually element by element, we can write it much7691 * more efficiently than we can parse it. ORDER MATTERS HERE */7692 struct ipw_rt_hdr *ipw_rt;7693 7694 unsigned short len = le16_to_cpu(pkt->u.frame.length);7695 7696 /* We received data from the HW, so stop the watchdog */7697 netif_trans_update(dev);7698 7699 /* We only process data packets if the7700 * interface is open */7701 if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >7702 skb_tailroom(rxb->skb))) {7703 dev->stats.rx_errors++;7704 priv->wstats.discard.misc++;7705 IPW_DEBUG_DROP("Corruption detected! Oh no!\n");7706 return;7707 } else if (unlikely(!netif_running(priv->net_dev))) {7708 dev->stats.rx_dropped++;7709 priv->wstats.discard.misc++;7710 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");7711 return;7712 }7713 7714 /* Libpcap 0.9.3+ can handle variable length radiotap, so we'll use7715 * that now */7716 if (len > IPW_RX_BUF_SIZE - sizeof(struct ipw_rt_hdr)) {7717 /* FIXME: Should alloc bigger skb instead */7718 dev->stats.rx_dropped++;7719 priv->wstats.discard.misc++;7720 IPW_DEBUG_DROP("Dropping too large packet in monitor\n");7721 return;7722 }7723 7724 /* copy the frame itself */7725 memmove(rxb->skb->data + sizeof(struct ipw_rt_hdr),7726 rxb->skb->data + IPW_RX_FRAME_SIZE, len);7727 7728 ipw_rt = (struct ipw_rt_hdr *)rxb->skb->data;7729 7730 ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;7731 ipw_rt->rt_hdr.it_pad = 0; /* always good to zero */7732 ipw_rt->rt_hdr.it_len = cpu_to_le16(sizeof(struct ipw_rt_hdr)); /* total header+data */7733 7734 /* Big bitfield of all the fields we provide in radiotap */7735 ipw_rt->rt_hdr.it_present = cpu_to_le32(7736 (1 << IEEE80211_RADIOTAP_TSFT) |7737 (1 << IEEE80211_RADIOTAP_FLAGS) |7738 (1 << IEEE80211_RADIOTAP_RATE) |7739 (1 << IEEE80211_RADIOTAP_CHANNEL) |7740 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |7741 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |7742 (1 << IEEE80211_RADIOTAP_ANTENNA));7743 7744 /* Zero the flags, we'll add to them as we go */7745 ipw_rt->rt_flags = 0;7746 ipw_rt->rt_tsf = (u64)(frame->parent_tsf[3] << 24 |7747 frame->parent_tsf[2] << 16 |7748 frame->parent_tsf[1] << 8 |7749 frame->parent_tsf[0]);7750 7751 /* Convert signal to DBM */7752 ipw_rt->rt_dbmsignal = antsignal;7753 ipw_rt->rt_dbmnoise = (s8) le16_to_cpu(frame->noise);7754 7755 /* Convert the channel data and set the flags */7756 ipw_rt->rt_channel = cpu_to_le16(ieee80211chan2mhz(received_channel));7757 if (received_channel > 14) { /* 802.11a */7758 ipw_rt->rt_chbitmask =7759 cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ));7760 } else if (antennaAndPhy & 32) { /* 802.11b */7761 ipw_rt->rt_chbitmask =7762 cpu_to_le16((IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ));7763 } else { /* 802.11g */7764 ipw_rt->rt_chbitmask =7765 cpu_to_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ);7766 }7767 7768 /* set the rate in multiples of 500k/s */7769 switch (pktrate) {7770 case IPW_TX_RATE_1MB:7771 ipw_rt->rt_rate = 2;7772 break;7773 case IPW_TX_RATE_2MB:7774 ipw_rt->rt_rate = 4;7775 break;7776 case IPW_TX_RATE_5MB:7777 ipw_rt->rt_rate = 10;7778 break;7779 case IPW_TX_RATE_6MB:7780 ipw_rt->rt_rate = 12;7781 break;7782 case IPW_TX_RATE_9MB:7783 ipw_rt->rt_rate = 18;7784 break;7785 case IPW_TX_RATE_11MB:7786 ipw_rt->rt_rate = 22;7787 break;7788 case IPW_TX_RATE_12MB:7789 ipw_rt->rt_rate = 24;7790 break;7791 case IPW_TX_RATE_18MB:7792 ipw_rt->rt_rate = 36;7793 break;7794 case IPW_TX_RATE_24MB:7795 ipw_rt->rt_rate = 48;7796 break;7797 case IPW_TX_RATE_36MB:7798 ipw_rt->rt_rate = 72;7799 break;7800 case IPW_TX_RATE_48MB:7801 ipw_rt->rt_rate = 96;7802 break;7803 case IPW_TX_RATE_54MB:7804 ipw_rt->rt_rate = 108;7805 break;7806 default:7807 ipw_rt->rt_rate = 0;7808 break;7809 }7810 7811 /* antenna number */7812 ipw_rt->rt_antenna = (antennaAndPhy & 3); /* Is this right? */7813 7814 /* set the preamble flag if we have it */7815 if ((antennaAndPhy & 64))7816 ipw_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;7817 7818 /* Set the size of the skb to the size of the frame */7819 skb_put(rxb->skb, len + sizeof(struct ipw_rt_hdr));7820 7821 IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);7822 7823 if (!libipw_rx(priv->ieee, rxb->skb, stats))7824 dev->stats.rx_errors++;7825 else { /* libipw_rx succeeded, so it now owns the SKB */7826 rxb->skb = NULL;7827 /* no LED during capture */7828 }7829}7830#endif7831 7832#ifdef CONFIG_IPW2200_PROMISCUOUS7833#define libipw_is_probe_response(fc) \7834 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT && \7835 (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP )7836 7837#define libipw_is_management(fc) \7838 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT)7839 7840#define libipw_is_control(fc) \7841 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL)7842 7843#define libipw_is_data(fc) \7844 ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)7845 7846#define libipw_is_assoc_request(fc) \7847 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_ASSOC_REQ)7848 7849#define libipw_is_reassoc_request(fc) \7850 ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_REASSOC_REQ)7851 7852static void ipw_handle_promiscuous_rx(struct ipw_priv *priv,7853 struct ipw_rx_mem_buffer *rxb,7854 struct libipw_rx_stats *stats)7855{7856 struct net_device *dev = priv->prom_net_dev;7857 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;7858 struct ipw_rx_frame *frame = &pkt->u.frame;7859 struct ipw_rt_hdr *ipw_rt;7860 7861 /* First cache any information we need before we overwrite7862 * the information provided in the skb from the hardware */7863 struct ieee80211_hdr *hdr;7864 u16 channel = frame->received_channel;7865 u8 phy_flags = frame->antennaAndPhy;7866 s8 signal = frame->rssi_dbm - IPW_RSSI_TO_DBM;7867 s8 noise = (s8) le16_to_cpu(frame->noise);7868 u8 rate = frame->rate;7869 unsigned short len = le16_to_cpu(pkt->u.frame.length);7870 struct sk_buff *skb;7871 int hdr_only = 0;7872 u16 filter = priv->prom_priv->filter;7873 7874 /* If the filter is set to not include Rx frames then return */7875 if (filter & IPW_PROM_NO_RX)7876 return;7877 7878 /* We received data from the HW, so stop the watchdog */7879 netif_trans_update(dev);7880 7881 if (unlikely((len + IPW_RX_FRAME_SIZE) > skb_tailroom(rxb->skb))) {7882 dev->stats.rx_errors++;7883 IPW_DEBUG_DROP("Corruption detected! Oh no!\n");7884 return;7885 }7886 7887 /* We only process data packets if the interface is open */7888 if (unlikely(!netif_running(dev))) {7889 dev->stats.rx_dropped++;7890 IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");7891 return;7892 }7893 7894 /* Libpcap 0.9.3+ can handle variable length radiotap, so we'll use7895 * that now */7896 if (len > IPW_RX_BUF_SIZE - sizeof(struct ipw_rt_hdr)) {7897 /* FIXME: Should alloc bigger skb instead */7898 dev->stats.rx_dropped++;7899 IPW_DEBUG_DROP("Dropping too large packet in monitor\n");7900 return;7901 }7902 7903 hdr = (void *)rxb->skb->data + IPW_RX_FRAME_SIZE;7904 if (libipw_is_management(le16_to_cpu(hdr->frame_control))) {7905 if (filter & IPW_PROM_NO_MGMT)7906 return;7907 if (filter & IPW_PROM_MGMT_HEADER_ONLY)7908 hdr_only = 1;7909 } else if (libipw_is_control(le16_to_cpu(hdr->frame_control))) {7910 if (filter & IPW_PROM_NO_CTL)7911 return;7912 if (filter & IPW_PROM_CTL_HEADER_ONLY)7913 hdr_only = 1;7914 } else if (libipw_is_data(le16_to_cpu(hdr->frame_control))) {7915 if (filter & IPW_PROM_NO_DATA)7916 return;7917 if (filter & IPW_PROM_DATA_HEADER_ONLY)7918 hdr_only = 1;7919 }7920 7921 /* Copy the SKB since this is for the promiscuous side */7922 skb = skb_copy(rxb->skb, GFP_ATOMIC);7923 if (skb == NULL) {7924 IPW_ERROR("skb_clone failed for promiscuous copy.\n");7925 return;7926 }7927 7928 /* copy the frame data to write after where the radiotap header goes */7929 ipw_rt = (void *)skb->data;7930 7931 if (hdr_only)7932 len = libipw_get_hdrlen(le16_to_cpu(hdr->frame_control));7933 7934 memcpy(ipw_rt->payload, hdr, len);7935 7936 ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;7937 ipw_rt->rt_hdr.it_pad = 0; /* always good to zero */7938 ipw_rt->rt_hdr.it_len = cpu_to_le16(sizeof(*ipw_rt)); /* total header+data */7939 7940 /* Set the size of the skb to the size of the frame */7941 skb_put(skb, sizeof(*ipw_rt) + len);7942 7943 /* Big bitfield of all the fields we provide in radiotap */7944 ipw_rt->rt_hdr.it_present = cpu_to_le32(7945 (1 << IEEE80211_RADIOTAP_TSFT) |7946 (1 << IEEE80211_RADIOTAP_FLAGS) |7947 (1 << IEEE80211_RADIOTAP_RATE) |7948 (1 << IEEE80211_RADIOTAP_CHANNEL) |7949 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |7950 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) |7951 (1 << IEEE80211_RADIOTAP_ANTENNA));7952 7953 /* Zero the flags, we'll add to them as we go */7954 ipw_rt->rt_flags = 0;7955 ipw_rt->rt_tsf = (u64)(frame->parent_tsf[3] << 24 |7956 frame->parent_tsf[2] << 16 |7957 frame->parent_tsf[1] << 8 |7958 frame->parent_tsf[0]);7959 7960 /* Convert to DBM */7961 ipw_rt->rt_dbmsignal = signal;7962 ipw_rt->rt_dbmnoise = noise;7963 7964 /* Convert the channel data and set the flags */7965 ipw_rt->rt_channel = cpu_to_le16(ieee80211chan2mhz(channel));7966 if (channel > 14) { /* 802.11a */7967 ipw_rt->rt_chbitmask =7968 cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ));7969 } else if (phy_flags & (1 << 5)) { /* 802.11b */7970 ipw_rt->rt_chbitmask =7971 cpu_to_le16((IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ));7972 } else { /* 802.11g */7973 ipw_rt->rt_chbitmask =7974 cpu_to_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ);7975 }7976 7977 /* set the rate in multiples of 500k/s */7978 switch (rate) {7979 case IPW_TX_RATE_1MB:7980 ipw_rt->rt_rate = 2;7981 break;7982 case IPW_TX_RATE_2MB:7983 ipw_rt->rt_rate = 4;7984 break;7985 case IPW_TX_RATE_5MB:7986 ipw_rt->rt_rate = 10;7987 break;7988 case IPW_TX_RATE_6MB:7989 ipw_rt->rt_rate = 12;7990 break;7991 case IPW_TX_RATE_9MB:7992 ipw_rt->rt_rate = 18;7993 break;7994 case IPW_TX_RATE_11MB:7995 ipw_rt->rt_rate = 22;7996 break;7997 case IPW_TX_RATE_12MB:7998 ipw_rt->rt_rate = 24;7999 break;8000 case IPW_TX_RATE_18MB:8001 ipw_rt->rt_rate = 36;8002 break;8003 case IPW_TX_RATE_24MB:8004 ipw_rt->rt_rate = 48;8005 break;8006 case IPW_TX_RATE_36MB:8007 ipw_rt->rt_rate = 72;8008 break;8009 case IPW_TX_RATE_48MB:8010 ipw_rt->rt_rate = 96;8011 break;8012 case IPW_TX_RATE_54MB:8013 ipw_rt->rt_rate = 108;8014 break;8015 default:8016 ipw_rt->rt_rate = 0;8017 break;8018 }8019 8020 /* antenna number */8021 ipw_rt->rt_antenna = (phy_flags & 3);8022 8023 /* set the preamble flag if we have it */8024 if (phy_flags & (1 << 6))8025 ipw_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;8026 8027 IPW_DEBUG_RX("Rx packet of %d bytes.\n", skb->len);8028 8029 if (!libipw_rx(priv->prom_priv->ieee, skb, stats)) {8030 dev->stats.rx_errors++;8031 dev_kfree_skb_any(skb);8032 }8033}8034#endif8035 8036static int is_network_packet(struct ipw_priv *priv,8037 struct libipw_hdr_4addr *header)8038{8039 /* Filter incoming packets to determine if they are targeted toward8040 * this network, discarding packets coming from ourselves */8041 switch (priv->ieee->iw_mode) {8042 case IW_MODE_ADHOC: /* Header: Dest. | Source | BSSID */8043 /* packets from our adapter are dropped (echo) */8044 if (ether_addr_equal(header->addr2, priv->net_dev->dev_addr))8045 return 0;8046 8047 /* {broad,multi}cast packets to our BSSID go through */8048 if (is_multicast_ether_addr(header->addr1))8049 return ether_addr_equal(header->addr3, priv->bssid);8050 8051 /* packets to our adapter go through */8052 return ether_addr_equal(header->addr1,8053 priv->net_dev->dev_addr);8054 8055 case IW_MODE_INFRA: /* Header: Dest. | BSSID | Source */8056 /* packets from our adapter are dropped (echo) */8057 if (ether_addr_equal(header->addr3, priv->net_dev->dev_addr))8058 return 0;8059 8060 /* {broad,multi}cast packets to our BSS go through */8061 if (is_multicast_ether_addr(header->addr1))8062 return ether_addr_equal(header->addr2, priv->bssid);8063 8064 /* packets to our adapter go through */8065 return ether_addr_equal(header->addr1,8066 priv->net_dev->dev_addr);8067 }8068 8069 return 1;8070}8071 8072#define IPW_PACKET_RETRY_TIME HZ8073 8074static int is_duplicate_packet(struct ipw_priv *priv,8075 struct libipw_hdr_4addr *header)8076{8077 u16 sc = le16_to_cpu(header->seq_ctl);8078 u16 seq = WLAN_GET_SEQ_SEQ(sc);8079 u16 frag = WLAN_GET_SEQ_FRAG(sc);8080 u16 *last_seq, *last_frag;8081 unsigned long *last_time;8082 8083 switch (priv->ieee->iw_mode) {8084 case IW_MODE_ADHOC:8085 {8086 struct list_head *p;8087 struct ipw_ibss_seq *entry = NULL;8088 u8 *mac = header->addr2;8089 int index = mac[5] % IPW_IBSS_MAC_HASH_SIZE;8090 8091 list_for_each(p, &priv->ibss_mac_hash[index]) {8092 entry =8093 list_entry(p, struct ipw_ibss_seq, list);8094 if (ether_addr_equal(entry->mac, mac))8095 break;8096 }8097 if (p == &priv->ibss_mac_hash[index]) {8098 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);8099 if (!entry) {8100 IPW_ERROR8101 ("Cannot malloc new mac entry\n");8102 return 0;8103 }8104 memcpy(entry->mac, mac, ETH_ALEN);8105 entry->seq_num = seq;8106 entry->frag_num = frag;8107 entry->packet_time = jiffies;8108 list_add(&entry->list,8109 &priv->ibss_mac_hash[index]);8110 return 0;8111 }8112 last_seq = &entry->seq_num;8113 last_frag = &entry->frag_num;8114 last_time = &entry->packet_time;8115 break;8116 }8117 case IW_MODE_INFRA:8118 last_seq = &priv->last_seq_num;8119 last_frag = &priv->last_frag_num;8120 last_time = &priv->last_packet_time;8121 break;8122 default:8123 return 0;8124 }8125 if ((*last_seq == seq) &&8126 time_after(*last_time + IPW_PACKET_RETRY_TIME, jiffies)) {8127 if (*last_frag == frag)8128 goto drop;8129 if (*last_frag + 1 != frag)8130 /* out-of-order fragment */8131 goto drop;8132 } else8133 *last_seq = seq;8134 8135 *last_frag = frag;8136 *last_time = jiffies;8137 return 0;8138 8139 drop:8140 /* Comment this line now since we observed the card receives8141 * duplicate packets but the FCTL_RETRY bit is not set in the8142 * IBSS mode with fragmentation enabled.8143 BUG_ON(!(le16_to_cpu(header->frame_control) & IEEE80211_FCTL_RETRY)); */8144 return 1;8145}8146 8147static void ipw_handle_mgmt_packet(struct ipw_priv *priv,8148 struct ipw_rx_mem_buffer *rxb,8149 struct libipw_rx_stats *stats)8150{8151 struct sk_buff *skb = rxb->skb;8152 struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)skb->data;8153 struct libipw_hdr_4addr *header = (struct libipw_hdr_4addr *)8154 (skb->data + IPW_RX_FRAME_SIZE);8155 8156 libipw_rx_mgt(priv->ieee, header, stats);8157 8158 if (priv->ieee->iw_mode == IW_MODE_ADHOC &&8159 ((WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) ==8160 IEEE80211_STYPE_PROBE_RESP) ||8161 (WLAN_FC_GET_STYPE(le16_to_cpu(header->frame_ctl)) ==8162 IEEE80211_STYPE_BEACON))) {8163 if (ether_addr_equal(header->addr3, priv->bssid))8164 ipw_add_station(priv, header->addr2);8165 }8166 8167 if (priv->config & CFG_NET_STATS) {8168 IPW_DEBUG_HC("sending stat packet\n");8169 8170 /* Set the size of the skb to the size of the full8171 * ipw header and 802.11 frame */8172 skb_put(skb, le16_to_cpu(pkt->u.frame.length) +8173 IPW_RX_FRAME_SIZE);8174 8175 /* Advance past the ipw packet header to the 802.11 frame */8176 skb_pull(skb, IPW_RX_FRAME_SIZE);8177 8178 /* Push the libipw_rx_stats before the 802.11 frame */8179 memcpy(skb_push(skb, sizeof(*stats)), stats, sizeof(*stats));8180 8181 skb->dev = priv->ieee->dev;8182 8183 /* Point raw at the libipw_stats */8184 skb_reset_mac_header(skb);8185 8186 skb->pkt_type = PACKET_OTHERHOST;8187 skb->protocol = cpu_to_be16(ETH_P_80211_STATS);8188 memset(skb->cb, 0, sizeof(rxb->skb->cb));8189 netif_rx(skb);8190 rxb->skb = NULL;8191 }8192}8193 8194/*8195 * Main entry function for receiving a packet with 80211 headers. This8196 * should be called when ever the FW has notified us that there is a new8197 * skb in the receive queue.8198 */8199static void ipw_rx(struct ipw_priv *priv)8200{8201 struct ipw_rx_mem_buffer *rxb;8202 struct ipw_rx_packet *pkt;8203 struct libipw_hdr_4addr *header;8204 u32 r, i;8205 u8 network_packet;8206 u8 fill_rx = 0;8207 8208 r = ipw_read32(priv, IPW_RX_READ_INDEX);8209 ipw_read32(priv, IPW_RX_WRITE_INDEX);8210 i = priv->rxq->read;8211 8212 if (ipw_rx_queue_space (priv->rxq) > (RX_QUEUE_SIZE / 2))8213 fill_rx = 1;8214 8215 while (i != r) {8216 rxb = priv->rxq->queue[i];8217 if (unlikely(rxb == NULL)) {8218 printk(KERN_CRIT "Queue not allocated!\n");8219 break;8220 }8221 priv->rxq->queue[i] = NULL;8222 8223 dma_sync_single_for_cpu(&priv->pci_dev->dev, rxb->dma_addr,8224 IPW_RX_BUF_SIZE, DMA_FROM_DEVICE);8225 8226 pkt = (struct ipw_rx_packet *)rxb->skb->data;8227 IPW_DEBUG_RX("Packet: type=%02X seq=%02X bits=%02X\n",8228 pkt->header.message_type,8229 pkt->header.rx_seq_num, pkt->header.control_bits);8230 8231 switch (pkt->header.message_type) {8232 case RX_FRAME_TYPE: /* 802.11 frame */ {8233 struct libipw_rx_stats stats = {8234 .rssi = pkt->u.frame.rssi_dbm -8235 IPW_RSSI_TO_DBM,8236 .signal =8237 pkt->u.frame.rssi_dbm -8238 IPW_RSSI_TO_DBM + 0x100,8239 .noise =8240 le16_to_cpu(pkt->u.frame.noise),8241 .rate = pkt->u.frame.rate,8242 .mac_time = jiffies,8243 .received_channel =8244 pkt->u.frame.received_channel,8245 .freq =8246 (pkt->u.frame.8247 control & (1 << 0)) ?8248 LIBIPW_24GHZ_BAND :8249 LIBIPW_52GHZ_BAND,8250 .len = le16_to_cpu(pkt->u.frame.length),8251 };8252 8253 if (stats.rssi != 0)8254 stats.mask |= LIBIPW_STATMASK_RSSI;8255 if (stats.signal != 0)8256 stats.mask |= LIBIPW_STATMASK_SIGNAL;8257 if (stats.noise != 0)8258 stats.mask |= LIBIPW_STATMASK_NOISE;8259 if (stats.rate != 0)8260 stats.mask |= LIBIPW_STATMASK_RATE;8261 8262 priv->rx_packets++;8263 8264#ifdef CONFIG_IPW2200_PROMISCUOUS8265 if (priv->prom_net_dev && netif_running(priv->prom_net_dev))8266 ipw_handle_promiscuous_rx(priv, rxb, &stats);8267#endif8268 8269#ifdef CONFIG_IPW2200_MONITOR8270 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {8271#ifdef CONFIG_IPW2200_RADIOTAP8272 8273 ipw_handle_data_packet_monitor(priv,8274 rxb,8275 &stats);8276#else8277 ipw_handle_data_packet(priv, rxb,8278 &stats);8279#endif8280 break;8281 }8282#endif8283 8284 header =8285 (struct libipw_hdr_4addr *)(rxb->skb->8286 data +8287 IPW_RX_FRAME_SIZE);8288 /* TODO: Check Ad-Hoc dest/source and make sure8289 * that we are actually parsing these packets8290 * correctly -- we should probably use the8291 * frame control of the packet and disregard8292 * the current iw_mode */8293 8294 network_packet =8295 is_network_packet(priv, header);8296 if (network_packet && priv->assoc_network) {8297 priv->assoc_network->stats.rssi =8298 stats.rssi;8299 priv->exp_avg_rssi =8300 exponential_average(priv->exp_avg_rssi,8301 stats.rssi, DEPTH_RSSI);8302 }8303 8304 IPW_DEBUG_RX("Frame: len=%u\n",8305 le16_to_cpu(pkt->u.frame.length));8306 8307 if (le16_to_cpu(pkt->u.frame.length) <8308 libipw_get_hdrlen(le16_to_cpu(8309 header->frame_ctl))) {8310 IPW_DEBUG_DROP8311 ("Received packet is too small. "8312 "Dropping.\n");8313 priv->net_dev->stats.rx_errors++;8314 priv->wstats.discard.misc++;8315 break;8316 }8317 8318 switch (WLAN_FC_GET_TYPE8319 (le16_to_cpu(header->frame_ctl))) {8320 8321 case IEEE80211_FTYPE_MGMT:8322 ipw_handle_mgmt_packet(priv, rxb,8323 &stats);8324 break;8325 8326 case IEEE80211_FTYPE_CTL:8327 break;8328 8329 case IEEE80211_FTYPE_DATA:8330 if (unlikely(!network_packet ||8331 is_duplicate_packet(priv,8332 header)))8333 {8334 IPW_DEBUG_DROP("Dropping: "8335 "%pM, "8336 "%pM, "8337 "%pM\n",8338 header->addr1,8339 header->addr2,8340 header->addr3);8341 break;8342 }8343 8344 ipw_handle_data_packet(priv, rxb,8345 &stats);8346 8347 break;8348 }8349 break;8350 }8351 8352 case RX_HOST_NOTIFICATION_TYPE:{8353 IPW_DEBUG_RX8354 ("Notification: subtype=%02X flags=%02X size=%d\n",8355 pkt->u.notification.subtype,8356 pkt->u.notification.flags,8357 le16_to_cpu(pkt->u.notification.size));8358 ipw_rx_notification(priv, &pkt->u.notification);8359 break;8360 }8361 8362 default:8363 IPW_DEBUG_RX("Bad Rx packet of type %d\n",8364 pkt->header.message_type);8365 break;8366 }8367 8368 /* For now we just don't re-use anything. We can tweak this8369 * later to try and re-use notification packets and SKBs that8370 * fail to Rx correctly */8371 if (rxb->skb != NULL) {8372 dev_kfree_skb_any(rxb->skb);8373 rxb->skb = NULL;8374 }8375 8376 dma_unmap_single(&priv->pci_dev->dev, rxb->dma_addr,8377 IPW_RX_BUF_SIZE, DMA_FROM_DEVICE);8378 list_add_tail(&rxb->list, &priv->rxq->rx_used);8379 8380 i = (i + 1) % RX_QUEUE_SIZE;8381 8382 /* If there are a lot of unsued frames, restock the Rx queue8383 * so the ucode won't assert */8384 if (fill_rx) {8385 priv->rxq->read = i;8386 ipw_rx_queue_replenish(priv);8387 }8388 }8389 8390 /* Backtrack one entry */8391 priv->rxq->read = i;8392 ipw_rx_queue_restock(priv);8393}8394 8395#define DEFAULT_RTS_THRESHOLD 2304U8396#define MIN_RTS_THRESHOLD 1U8397#define MAX_RTS_THRESHOLD 2304U8398#define DEFAULT_BEACON_INTERVAL 100U8399#define DEFAULT_SHORT_RETRY_LIMIT 7U8400#define DEFAULT_LONG_RETRY_LIMIT 4U8401 8402/*8403 * ipw_sw_reset8404 * @option: options to control different reset behaviour8405 * 0 = reset everything except the 'disable' module_param8406 * 1 = reset everything and print out driver info (for probe only)8407 * 2 = reset everything8408 */8409static int ipw_sw_reset(struct ipw_priv *priv, int option)8410{8411 int band, modulation;8412 int old_mode = priv->ieee->iw_mode;8413 8414 /* Initialize module parameter values here */8415 priv->config = 0;8416 8417 /* We default to disabling the LED code as right now it causes8418 * too many systems to lock up... */8419 if (!led_support)8420 priv->config |= CFG_NO_LED;8421 8422 if (associate)8423 priv->config |= CFG_ASSOCIATE;8424 else8425 IPW_DEBUG_INFO("Auto associate disabled.\n");8426 8427 if (auto_create)8428 priv->config |= CFG_ADHOC_CREATE;8429 else8430 IPW_DEBUG_INFO("Auto adhoc creation disabled.\n");8431 8432 priv->config &= ~CFG_STATIC_ESSID;8433 priv->essid_len = 0;8434 memset(priv->essid, 0, IW_ESSID_MAX_SIZE);8435 8436 if (disable && option) {8437 priv->status |= STATUS_RF_KILL_SW;8438 IPW_DEBUG_INFO("Radio disabled.\n");8439 }8440 8441 if (default_channel != 0) {8442 priv->config |= CFG_STATIC_CHANNEL;8443 priv->channel = default_channel;8444 IPW_DEBUG_INFO("Bind to static channel %d\n", default_channel);8445 /* TODO: Validate that provided channel is in range */8446 }8447#ifdef CONFIG_IPW2200_QOS8448 ipw_qos_init(priv, qos_enable, qos_burst_enable,8449 burst_duration_CCK, burst_duration_OFDM);8450#endif /* CONFIG_IPW2200_QOS */8451 8452 switch (network_mode) {8453 case 1:8454 priv->ieee->iw_mode = IW_MODE_ADHOC;8455 priv->net_dev->type = ARPHRD_ETHER;8456 8457 break;8458#ifdef CONFIG_IPW2200_MONITOR8459 case 2:8460 priv->ieee->iw_mode = IW_MODE_MONITOR;8461#ifdef CONFIG_IPW2200_RADIOTAP8462 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;8463#else8464 priv->net_dev->type = ARPHRD_IEEE80211;8465#endif8466 break;8467#endif8468 default:8469 case 0:8470 priv->net_dev->type = ARPHRD_ETHER;8471 priv->ieee->iw_mode = IW_MODE_INFRA;8472 break;8473 }8474 8475 if (hwcrypto) {8476 priv->ieee->host_encrypt = 0;8477 priv->ieee->host_encrypt_msdu = 0;8478 priv->ieee->host_decrypt = 0;8479 priv->ieee->host_mc_decrypt = 0;8480 }8481 IPW_DEBUG_INFO("Hardware crypto [%s]\n", hwcrypto ? "on" : "off");8482 8483 /* IPW2200/2915 is abled to do hardware fragmentation. */8484 priv->ieee->host_open_frag = 0;8485 8486 if ((priv->pci_dev->device == 0x4223) ||8487 (priv->pci_dev->device == 0x4224)) {8488 if (option == 1)8489 printk(KERN_INFO DRV_NAME8490 ": Detected Intel PRO/Wireless 2915ABG Network "8491 "Connection\n");8492 priv->ieee->abg_true = 1;8493 band = LIBIPW_52GHZ_BAND | LIBIPW_24GHZ_BAND;8494 modulation = LIBIPW_OFDM_MODULATION |8495 LIBIPW_CCK_MODULATION;8496 priv->adapter = IPW_2915ABG;8497 priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B;8498 } else {8499 if (option == 1)8500 printk(KERN_INFO DRV_NAME8501 ": Detected Intel PRO/Wireless 2200BG Network "8502 "Connection\n");8503 8504 priv->ieee->abg_true = 0;8505 band = LIBIPW_24GHZ_BAND;8506 modulation = LIBIPW_OFDM_MODULATION |8507 LIBIPW_CCK_MODULATION;8508 priv->adapter = IPW_2200BG;8509 priv->ieee->mode = IEEE_G | IEEE_B;8510 }8511 8512 priv->ieee->freq_band = band;8513 priv->ieee->modulation = modulation;8514 8515 priv->rates_mask = LIBIPW_DEFAULT_RATES_MASK;8516 8517 priv->disassociate_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT;8518 priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT;8519 8520 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;8521 priv->short_retry_limit = DEFAULT_SHORT_RETRY_LIMIT;8522 priv->long_retry_limit = DEFAULT_LONG_RETRY_LIMIT;8523 8524 /* If power management is turned on, default to AC mode */8525 priv->power_mode = IPW_POWER_AC;8526 priv->tx_power = IPW_TX_POWER_DEFAULT;8527 8528 return old_mode == priv->ieee->iw_mode;8529}8530 8531/*8532 * This file defines the Wireless Extension handlers. It does not8533 * define any methods of hardware manipulation and relies on the8534 * functions defined in ipw_main to provide the HW interaction.8535 *8536 * The exception to this is the use of the ipw_get_ordinal()8537 * function used to poll the hardware vs. making unnecessary calls.8538 *8539 */8540 8541static int ipw_set_channel(struct ipw_priv *priv, u8 channel)8542{8543 if (channel == 0) {8544 IPW_DEBUG_INFO("Setting channel to ANY (0)\n");8545 priv->config &= ~CFG_STATIC_CHANNEL;8546 IPW_DEBUG_ASSOC("Attempting to associate with new "8547 "parameters.\n");8548 ipw_associate(priv);8549 return 0;8550 }8551 8552 priv->config |= CFG_STATIC_CHANNEL;8553 8554 if (priv->channel == channel) {8555 IPW_DEBUG_INFO("Request to set channel to current value (%d)\n",8556 channel);8557 return 0;8558 }8559 8560 IPW_DEBUG_INFO("Setting channel to %i\n", (int)channel);8561 priv->channel = channel;8562 8563#ifdef CONFIG_IPW2200_MONITOR8564 if (priv->ieee->iw_mode == IW_MODE_MONITOR) {8565 int i;8566 if (priv->status & STATUS_SCANNING) {8567 IPW_DEBUG_SCAN("Scan abort triggered due to "8568 "channel change.\n");8569 ipw_abort_scan(priv);8570 }8571 8572 for (i = 1000; i && (priv->status & STATUS_SCANNING); i--)8573 udelay(10);8574 8575 if (priv->status & STATUS_SCANNING)8576 IPW_DEBUG_SCAN("Still scanning...\n");8577 else8578 IPW_DEBUG_SCAN("Took %dms to abort current scan\n",8579 1000 - i);8580 8581 return 0;8582 }8583#endif /* CONFIG_IPW2200_MONITOR */8584 8585 /* Network configuration changed -- force [re]association */8586 IPW_DEBUG_ASSOC("[re]association triggered due to channel change.\n");8587 if (!ipw_disassociate(priv))8588 ipw_associate(priv);8589 8590 return 0;8591}8592 8593static int ipw_wx_set_freq(struct net_device *dev,8594 struct iw_request_info *info,8595 union iwreq_data *wrqu, char *extra)8596{8597 struct ipw_priv *priv = libipw_priv(dev);8598 const struct libipw_geo *geo = libipw_get_geo(priv->ieee);8599 struct iw_freq *fwrq = &wrqu->freq;8600 int ret = 0, i;8601 u8 channel, flags;8602 int band;8603 8604 if (fwrq->m == 0) {8605 IPW_DEBUG_WX("SET Freq/Channel -> any\n");8606 mutex_lock(&priv->mutex);8607 ret = ipw_set_channel(priv, 0);8608 mutex_unlock(&priv->mutex);8609 return ret;8610 }8611 /* if setting by freq convert to channel */8612 if (fwrq->e == 1) {8613 channel = libipw_freq_to_channel(priv->ieee, fwrq->m);8614 if (channel == 0)8615 return -EINVAL;8616 } else8617 channel = fwrq->m;8618 8619 if (!(band = libipw_is_valid_channel(priv->ieee, channel)))8620 return -EINVAL;8621 8622 if (priv->ieee->iw_mode == IW_MODE_ADHOC) {8623 i = libipw_channel_to_index(priv->ieee, channel);8624 if (i == -1)8625 return -EINVAL;8626 8627 flags = (band == LIBIPW_24GHZ_BAND) ?8628 geo->bg[i].flags : geo->a[i].flags;8629 if (flags & LIBIPW_CH_PASSIVE_ONLY) {8630 IPW_DEBUG_WX("Invalid Ad-Hoc channel for 802.11a\n");8631 return -EINVAL;8632 }8633 }8634 8635 IPW_DEBUG_WX("SET Freq/Channel -> %d\n", fwrq->m);8636 mutex_lock(&priv->mutex);8637 ret = ipw_set_channel(priv, channel);8638 mutex_unlock(&priv->mutex);8639 return ret;8640}8641 8642static int ipw_wx_get_freq(struct net_device *dev,8643 struct iw_request_info *info,8644 union iwreq_data *wrqu, char *extra)8645{8646 struct ipw_priv *priv = libipw_priv(dev);8647 8648 wrqu->freq.e = 0;8649 8650 /* If we are associated, trying to associate, or have a statically8651 * configured CHANNEL then return that; otherwise return ANY */8652 mutex_lock(&priv->mutex);8653 if (priv->config & CFG_STATIC_CHANNEL ||8654 priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED)) {8655 int i;8656 8657 i = libipw_channel_to_index(priv->ieee, priv->channel);8658 BUG_ON(i == -1);8659 wrqu->freq.e = 1;8660 8661 switch (libipw_is_valid_channel(priv->ieee, priv->channel)) {8662 case LIBIPW_52GHZ_BAND:8663 wrqu->freq.m = priv->ieee->geo.a[i].freq * 100000;8664 break;8665 8666 case LIBIPW_24GHZ_BAND:8667 wrqu->freq.m = priv->ieee->geo.bg[i].freq * 100000;8668 break;8669 8670 default:8671 BUG();8672 }8673 } else8674 wrqu->freq.m = 0;8675 8676 mutex_unlock(&priv->mutex);8677 IPW_DEBUG_WX("GET Freq/Channel -> %d\n", priv->channel);8678 return 0;8679}8680 8681static int ipw_wx_set_mode(struct net_device *dev,8682 struct iw_request_info *info,8683 union iwreq_data *wrqu, char *extra)8684{8685 struct ipw_priv *priv = libipw_priv(dev);8686 int err = 0;8687 8688 IPW_DEBUG_WX("Set MODE: %d\n", wrqu->mode);8689 8690 switch (wrqu->mode) {8691#ifdef CONFIG_IPW2200_MONITOR8692 case IW_MODE_MONITOR:8693#endif8694 case IW_MODE_ADHOC:8695 case IW_MODE_INFRA:8696 break;8697 case IW_MODE_AUTO:8698 wrqu->mode = IW_MODE_INFRA;8699 break;8700 default:8701 return -EINVAL;8702 }8703 if (wrqu->mode == priv->ieee->iw_mode)8704 return 0;8705 8706 mutex_lock(&priv->mutex);8707 8708 ipw_sw_reset(priv, 0);8709 8710#ifdef CONFIG_IPW2200_MONITOR8711 if (priv->ieee->iw_mode == IW_MODE_MONITOR)8712 priv->net_dev->type = ARPHRD_ETHER;8713 8714 if (wrqu->mode == IW_MODE_MONITOR)8715#ifdef CONFIG_IPW2200_RADIOTAP8716 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;8717#else8718 priv->net_dev->type = ARPHRD_IEEE80211;8719#endif8720#endif /* CONFIG_IPW2200_MONITOR */8721 8722 /* Free the existing firmware and reset the fw_loaded8723 * flag so ipw_load() will bring in the new firmware */8724 free_firmware();8725 8726 priv->ieee->iw_mode = wrqu->mode;8727 8728 schedule_work(&priv->adapter_restart);8729 mutex_unlock(&priv->mutex);8730 return err;8731}8732 8733static int ipw_wx_get_mode(struct net_device *dev,8734 struct iw_request_info *info,8735 union iwreq_data *wrqu, char *extra)8736{8737 struct ipw_priv *priv = libipw_priv(dev);8738 mutex_lock(&priv->mutex);8739 wrqu->mode = priv->ieee->iw_mode;8740 IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode);8741 mutex_unlock(&priv->mutex);8742 return 0;8743}8744 8745/* Values are in microsecond */8746static const s32 timeout_duration[] = {8747 350000,8748 250000,8749 75000,8750 37000,8751 25000,8752};8753 8754static const s32 period_duration[] = {8755 400000,8756 700000,8757 1000000,8758 1000000,8759 10000008760};8761 8762static int ipw_wx_get_range(struct net_device *dev,8763 struct iw_request_info *info,8764 union iwreq_data *wrqu, char *extra)8765{8766 struct ipw_priv *priv = libipw_priv(dev);8767 struct iw_range *range = (struct iw_range *)extra;8768 const struct libipw_geo *geo = libipw_get_geo(priv->ieee);8769 int i = 0, j;8770 8771 wrqu->data.length = sizeof(*range);8772 memset(range, 0, sizeof(*range));8773 8774 /* 54Mbs == ~27 Mb/s real (802.11g) */8775 range->throughput = 27 * 1000 * 1000;8776 8777 range->max_qual.qual = 100;8778 /* TODO: Find real max RSSI and stick here */8779 range->max_qual.level = 0;8780 range->max_qual.noise = 0;8781 range->max_qual.updated = 7; /* Updated all three */8782 8783 range->avg_qual.qual = 70;8784 /* TODO: Find real 'good' to 'bad' threshold value for RSSI */8785 range->avg_qual.level = 0; /* FIXME to real average level */8786 range->avg_qual.noise = 0;8787 range->avg_qual.updated = 7; /* Updated all three */8788 mutex_lock(&priv->mutex);8789 range->num_bitrates = min(priv->rates.num_rates, (u8) IW_MAX_BITRATES);8790 8791 for (i = 0; i < range->num_bitrates; i++)8792 range->bitrate[i] = (priv->rates.supported_rates[i] & 0x7F) *8793 500000;8794 8795 range->max_rts = DEFAULT_RTS_THRESHOLD;8796 range->min_frag = MIN_FRAG_THRESHOLD;8797 range->max_frag = MAX_FRAG_THRESHOLD;8798 8799 range->encoding_size[0] = 5;8800 range->encoding_size[1] = 13;8801 range->num_encoding_sizes = 2;8802 range->max_encoding_tokens = WEP_KEYS;8803 8804 /* Set the Wireless Extension versions */8805 range->we_version_compiled = WIRELESS_EXT;8806 range->we_version_source = 18;8807 8808 i = 0;8809 if (priv->ieee->mode & (IEEE_B | IEEE_G)) {8810 for (j = 0; j < geo->bg_channels && i < IW_MAX_FREQUENCIES; j++) {8811 if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&8812 (geo->bg[j].flags & LIBIPW_CH_PASSIVE_ONLY))8813 continue;8814 8815 range->freq[i].i = geo->bg[j].channel;8816 range->freq[i].m = geo->bg[j].freq * 100000;8817 range->freq[i].e = 1;8818 i++;8819 }8820 }8821 8822 if (priv->ieee->mode & IEEE_A) {8823 for (j = 0; j < geo->a_channels && i < IW_MAX_FREQUENCIES; j++) {8824 if ((priv->ieee->iw_mode == IW_MODE_ADHOC) &&8825 (geo->a[j].flags & LIBIPW_CH_PASSIVE_ONLY))8826 continue;8827 8828 range->freq[i].i = geo->a[j].channel;8829 range->freq[i].m = geo->a[j].freq * 100000;8830 range->freq[i].e = 1;8831 i++;8832 }8833 }8834 8835 range->num_channels = i;8836 range->num_frequency = i;8837 8838 mutex_unlock(&priv->mutex);8839 8840 /* Event capability (kernel + driver) */8841 range->event_capa[0] = (IW_EVENT_CAPA_K_0 |8842 IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |8843 IW_EVENT_CAPA_MASK(SIOCGIWAP) |8844 IW_EVENT_CAPA_MASK(SIOCGIWSCAN));8845 range->event_capa[1] = IW_EVENT_CAPA_K_1;8846 8847 range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |8848 IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;8849 8850 range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE;8851 8852 IPW_DEBUG_WX("GET Range\n");8853 return 0;8854}8855 8856static int ipw_wx_set_wap(struct net_device *dev,8857 struct iw_request_info *info,8858 union iwreq_data *wrqu, char *extra)8859{8860 struct ipw_priv *priv = libipw_priv(dev);8861 8862 if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)8863 return -EINVAL;8864 mutex_lock(&priv->mutex);8865 if (is_broadcast_ether_addr(wrqu->ap_addr.sa_data) ||8866 is_zero_ether_addr(wrqu->ap_addr.sa_data)) {8867 /* we disable mandatory BSSID association */8868 IPW_DEBUG_WX("Setting AP BSSID to ANY\n");8869 priv->config &= ~CFG_STATIC_BSSID;8870 IPW_DEBUG_ASSOC("Attempting to associate with new "8871 "parameters.\n");8872 ipw_associate(priv);8873 mutex_unlock(&priv->mutex);8874 return 0;8875 }8876 8877 priv->config |= CFG_STATIC_BSSID;8878 if (ether_addr_equal(priv->bssid, wrqu->ap_addr.sa_data)) {8879 IPW_DEBUG_WX("BSSID set to current BSSID.\n");8880 mutex_unlock(&priv->mutex);8881 return 0;8882 }8883 8884 IPW_DEBUG_WX("Setting mandatory BSSID to %pM\n",8885 wrqu->ap_addr.sa_data);8886 8887 memcpy(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN);8888 8889 /* Network configuration changed -- force [re]association */8890 IPW_DEBUG_ASSOC("[re]association triggered due to BSSID change.\n");8891 if (!ipw_disassociate(priv))8892 ipw_associate(priv);8893 8894 mutex_unlock(&priv->mutex);8895 return 0;8896}8897 8898static int ipw_wx_get_wap(struct net_device *dev,8899 struct iw_request_info *info,8900 union iwreq_data *wrqu, char *extra)8901{8902 struct ipw_priv *priv = libipw_priv(dev);8903 8904 /* If we are associated, trying to associate, or have a statically8905 * configured BSSID then return that; otherwise return ANY */8906 mutex_lock(&priv->mutex);8907 if (priv->config & CFG_STATIC_BSSID ||8908 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {8909 wrqu->ap_addr.sa_family = ARPHRD_ETHER;8910 memcpy(wrqu->ap_addr.sa_data, priv->bssid, ETH_ALEN);8911 } else8912 eth_zero_addr(wrqu->ap_addr.sa_data);8913 8914 IPW_DEBUG_WX("Getting WAP BSSID: %pM\n",8915 wrqu->ap_addr.sa_data);8916 mutex_unlock(&priv->mutex);8917 return 0;8918}8919 8920static int ipw_wx_set_essid(struct net_device *dev,8921 struct iw_request_info *info,8922 union iwreq_data *wrqu, char *extra)8923{8924 struct ipw_priv *priv = libipw_priv(dev);8925 int length;8926 8927 mutex_lock(&priv->mutex);8928 8929 if (!wrqu->essid.flags)8930 {8931 IPW_DEBUG_WX("Setting ESSID to ANY\n");8932 ipw_disassociate(priv);8933 priv->config &= ~CFG_STATIC_ESSID;8934 ipw_associate(priv);8935 mutex_unlock(&priv->mutex);8936 return 0;8937 }8938 8939 length = min((int)wrqu->essid.length, IW_ESSID_MAX_SIZE);8940 8941 priv->config |= CFG_STATIC_ESSID;8942 8943 if (priv->essid_len == length && !memcmp(priv->essid, extra, length)8944 && (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) {8945 IPW_DEBUG_WX("ESSID set to current ESSID.\n");8946 mutex_unlock(&priv->mutex);8947 return 0;8948 }8949 8950 IPW_DEBUG_WX("Setting ESSID: '%*pE' (%d)\n", length, extra, length);8951 8952 priv->essid_len = length;8953 memcpy(priv->essid, extra, priv->essid_len);8954 8955 /* Network configuration changed -- force [re]association */8956 IPW_DEBUG_ASSOC("[re]association triggered due to ESSID change.\n");8957 if (!ipw_disassociate(priv))8958 ipw_associate(priv);8959 8960 mutex_unlock(&priv->mutex);8961 return 0;8962}8963 8964static int ipw_wx_get_essid(struct net_device *dev,8965 struct iw_request_info *info,8966 union iwreq_data *wrqu, char *extra)8967{8968 struct ipw_priv *priv = libipw_priv(dev);8969 8970 /* If we are associated, trying to associate, or have a statically8971 * configured ESSID then return that; otherwise return ANY */8972 mutex_lock(&priv->mutex);8973 if (priv->config & CFG_STATIC_ESSID ||8974 priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {8975 IPW_DEBUG_WX("Getting essid: '%*pE'\n",8976 priv->essid_len, priv->essid);8977 memcpy(extra, priv->essid, priv->essid_len);8978 wrqu->essid.length = priv->essid_len;8979 wrqu->essid.flags = 1; /* active */8980 } else {8981 IPW_DEBUG_WX("Getting essid: ANY\n");8982 wrqu->essid.length = 0;8983 wrqu->essid.flags = 0; /* active */8984 }8985 mutex_unlock(&priv->mutex);8986 return 0;8987}8988 8989static int ipw_wx_set_nick(struct net_device *dev,8990 struct iw_request_info *info,8991 union iwreq_data *wrqu, char *extra)8992{8993 struct ipw_priv *priv = libipw_priv(dev);8994 8995 IPW_DEBUG_WX("Setting nick to '%s'\n", extra);8996 if (wrqu->data.length > IW_ESSID_MAX_SIZE)8997 return -E2BIG;8998 mutex_lock(&priv->mutex);8999 wrqu->data.length = min_t(size_t, wrqu->data.length, sizeof(priv->nick));9000 memset(priv->nick, 0, sizeof(priv->nick));9001 memcpy(priv->nick, extra, wrqu->data.length);9002 IPW_DEBUG_TRACE("<<\n");9003 mutex_unlock(&priv->mutex);9004 return 0;9005 9006}9007 9008static int ipw_wx_get_nick(struct net_device *dev,9009 struct iw_request_info *info,9010 union iwreq_data *wrqu, char *extra)9011{9012 struct ipw_priv *priv = libipw_priv(dev);9013 IPW_DEBUG_WX("Getting nick\n");9014 mutex_lock(&priv->mutex);9015 wrqu->data.length = strlen(priv->nick);9016 memcpy(extra, priv->nick, wrqu->data.length);9017 wrqu->data.flags = 1; /* active */9018 mutex_unlock(&priv->mutex);9019 return 0;9020}9021 9022static int ipw_wx_set_sens(struct net_device *dev,9023 struct iw_request_info *info,9024 union iwreq_data *wrqu, char *extra)9025{9026 struct ipw_priv *priv = libipw_priv(dev);9027 int err = 0;9028 9029 IPW_DEBUG_WX("Setting roaming threshold to %d\n", wrqu->sens.value);9030 IPW_DEBUG_WX("Setting disassociate threshold to %d\n", 3*wrqu->sens.value);9031 mutex_lock(&priv->mutex);9032 9033 if (wrqu->sens.fixed == 0)9034 {9035 priv->roaming_threshold = IPW_MB_ROAMING_THRESHOLD_DEFAULT;9036 priv->disassociate_threshold = IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT;9037 goto out;9038 }9039 if ((wrqu->sens.value > IPW_MB_ROAMING_THRESHOLD_MAX) ||9040 (wrqu->sens.value < IPW_MB_ROAMING_THRESHOLD_MIN)) {9041 err = -EINVAL;9042 goto out;9043 }9044 9045 priv->roaming_threshold = wrqu->sens.value;9046 priv->disassociate_threshold = 3*wrqu->sens.value;9047 out:9048 mutex_unlock(&priv->mutex);9049 return err;9050}9051 9052static int ipw_wx_get_sens(struct net_device *dev,9053 struct iw_request_info *info,9054 union iwreq_data *wrqu, char *extra)9055{9056 struct ipw_priv *priv = libipw_priv(dev);9057 mutex_lock(&priv->mutex);9058 wrqu->sens.fixed = 1;9059 wrqu->sens.value = priv->roaming_threshold;9060 mutex_unlock(&priv->mutex);9061 9062 IPW_DEBUG_WX("GET roaming threshold -> %s %d\n",9063 wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);9064 9065 return 0;9066}9067 9068static int ipw_wx_set_rate(struct net_device *dev,9069 struct iw_request_info *info,9070 union iwreq_data *wrqu, char *extra)9071{9072 /* TODO: We should use semaphores or locks for access to priv */9073 struct ipw_priv *priv = libipw_priv(dev);9074 u32 target_rate = wrqu->bitrate.value;9075 u32 fixed, mask;9076 9077 /* value = -1, fixed = 0 means auto only, so we should use all rates offered by AP */9078 /* value = X, fixed = 1 means only rate X */9079 /* value = X, fixed = 0 means all rates lower equal X */9080 9081 if (target_rate == -1) {9082 fixed = 0;9083 mask = LIBIPW_DEFAULT_RATES_MASK;9084 /* Now we should reassociate */9085 goto apply;9086 }9087 9088 mask = 0;9089 fixed = wrqu->bitrate.fixed;9090 9091 if (target_rate == 1000000 || !fixed)9092 mask |= LIBIPW_CCK_RATE_1MB_MASK;9093 if (target_rate == 1000000)9094 goto apply;9095 9096 if (target_rate == 2000000 || !fixed)9097 mask |= LIBIPW_CCK_RATE_2MB_MASK;9098 if (target_rate == 2000000)9099 goto apply;9100 9101 if (target_rate == 5500000 || !fixed)9102 mask |= LIBIPW_CCK_RATE_5MB_MASK;9103 if (target_rate == 5500000)9104 goto apply;9105 9106 if (target_rate == 6000000 || !fixed)9107 mask |= LIBIPW_OFDM_RATE_6MB_MASK;9108 if (target_rate == 6000000)9109 goto apply;9110 9111 if (target_rate == 9000000 || !fixed)9112 mask |= LIBIPW_OFDM_RATE_9MB_MASK;9113 if (target_rate == 9000000)9114 goto apply;9115 9116 if (target_rate == 11000000 || !fixed)9117 mask |= LIBIPW_CCK_RATE_11MB_MASK;9118 if (target_rate == 11000000)9119 goto apply;9120 9121 if (target_rate == 12000000 || !fixed)9122 mask |= LIBIPW_OFDM_RATE_12MB_MASK;9123 if (target_rate == 12000000)9124 goto apply;9125 9126 if (target_rate == 18000000 || !fixed)9127 mask |= LIBIPW_OFDM_RATE_18MB_MASK;9128 if (target_rate == 18000000)9129 goto apply;9130 9131 if (target_rate == 24000000 || !fixed)9132 mask |= LIBIPW_OFDM_RATE_24MB_MASK;9133 if (target_rate == 24000000)9134 goto apply;9135 9136 if (target_rate == 36000000 || !fixed)9137 mask |= LIBIPW_OFDM_RATE_36MB_MASK;9138 if (target_rate == 36000000)9139 goto apply;9140 9141 if (target_rate == 48000000 || !fixed)9142 mask |= LIBIPW_OFDM_RATE_48MB_MASK;9143 if (target_rate == 48000000)9144 goto apply;9145 9146 if (target_rate == 54000000 || !fixed)9147 mask |= LIBIPW_OFDM_RATE_54MB_MASK;9148 if (target_rate == 54000000)9149 goto apply;9150 9151 IPW_DEBUG_WX("invalid rate specified, returning error\n");9152 return -EINVAL;9153 9154 apply:9155 IPW_DEBUG_WX("Setting rate mask to 0x%08X [%s]\n",9156 mask, fixed ? "fixed" : "sub-rates");9157 mutex_lock(&priv->mutex);9158 if (mask == LIBIPW_DEFAULT_RATES_MASK) {9159 priv->config &= ~CFG_FIXED_RATE;9160 ipw_set_fixed_rate(priv, priv->ieee->mode);9161 } else9162 priv->config |= CFG_FIXED_RATE;9163 9164 if (priv->rates_mask == mask) {9165 IPW_DEBUG_WX("Mask set to current mask.\n");9166 mutex_unlock(&priv->mutex);9167 return 0;9168 }9169 9170 priv->rates_mask = mask;9171 9172 /* Network configuration changed -- force [re]association */9173 IPW_DEBUG_ASSOC("[re]association triggered due to rates change.\n");9174 if (!ipw_disassociate(priv))9175 ipw_associate(priv);9176 9177 mutex_unlock(&priv->mutex);9178 return 0;9179}9180 9181static int ipw_wx_get_rate(struct net_device *dev,9182 struct iw_request_info *info,9183 union iwreq_data *wrqu, char *extra)9184{9185 struct ipw_priv *priv = libipw_priv(dev);9186 mutex_lock(&priv->mutex);9187 wrqu->bitrate.value = priv->last_rate;9188 wrqu->bitrate.fixed = (priv->config & CFG_FIXED_RATE) ? 1 : 0;9189 mutex_unlock(&priv->mutex);9190 IPW_DEBUG_WX("GET Rate -> %d\n", wrqu->bitrate.value);9191 return 0;9192}9193 9194static int ipw_wx_set_rts(struct net_device *dev,9195 struct iw_request_info *info,9196 union iwreq_data *wrqu, char *extra)9197{9198 struct ipw_priv *priv = libipw_priv(dev);9199 mutex_lock(&priv->mutex);9200 if (wrqu->rts.disabled || !wrqu->rts.fixed)9201 priv->rts_threshold = DEFAULT_RTS_THRESHOLD;9202 else {9203 if (wrqu->rts.value < MIN_RTS_THRESHOLD ||9204 wrqu->rts.value > MAX_RTS_THRESHOLD) {9205 mutex_unlock(&priv->mutex);9206 return -EINVAL;9207 }9208 priv->rts_threshold = wrqu->rts.value;9209 }9210 9211 ipw_send_rts_threshold(priv, priv->rts_threshold);9212 mutex_unlock(&priv->mutex);9213 IPW_DEBUG_WX("SET RTS Threshold -> %d\n", priv->rts_threshold);9214 return 0;9215}9216 9217static int ipw_wx_get_rts(struct net_device *dev,9218 struct iw_request_info *info,9219 union iwreq_data *wrqu, char *extra)9220{9221 struct ipw_priv *priv = libipw_priv(dev);9222 mutex_lock(&priv->mutex);9223 wrqu->rts.value = priv->rts_threshold;9224 wrqu->rts.fixed = 0; /* no auto select */9225 wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);9226 mutex_unlock(&priv->mutex);9227 IPW_DEBUG_WX("GET RTS Threshold -> %d\n", wrqu->rts.value);9228 return 0;9229}9230 9231static int ipw_wx_set_txpow(struct net_device *dev,9232 struct iw_request_info *info,9233 union iwreq_data *wrqu, char *extra)9234{9235 struct ipw_priv *priv = libipw_priv(dev);9236 int err = 0;9237 9238 mutex_lock(&priv->mutex);9239 if (ipw_radio_kill_sw(priv, wrqu->power.disabled)) {9240 err = -EINPROGRESS;9241 goto out;9242 }9243 9244 if (!wrqu->power.fixed)9245 wrqu->power.value = IPW_TX_POWER_DEFAULT;9246 9247 if (wrqu->power.flags != IW_TXPOW_DBM) {9248 err = -EINVAL;9249 goto out;9250 }9251 9252 if ((wrqu->power.value > IPW_TX_POWER_MAX) ||9253 (wrqu->power.value < IPW_TX_POWER_MIN)) {9254 err = -EINVAL;9255 goto out;9256 }9257 9258 priv->tx_power = wrqu->power.value;9259 err = ipw_set_tx_power(priv);9260 out:9261 mutex_unlock(&priv->mutex);9262 return err;9263}9264 9265static int ipw_wx_get_txpow(struct net_device *dev,9266 struct iw_request_info *info,9267 union iwreq_data *wrqu, char *extra)9268{9269 struct ipw_priv *priv = libipw_priv(dev);9270 mutex_lock(&priv->mutex);9271 wrqu->power.value = priv->tx_power;9272 wrqu->power.fixed = 1;9273 wrqu->power.flags = IW_TXPOW_DBM;9274 wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0;9275 mutex_unlock(&priv->mutex);9276 9277 IPW_DEBUG_WX("GET TX Power -> %s %d\n",9278 wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);9279 9280 return 0;9281}9282 9283static int ipw_wx_set_frag(struct net_device *dev,9284 struct iw_request_info *info,9285 union iwreq_data *wrqu, char *extra)9286{9287 struct ipw_priv *priv = libipw_priv(dev);9288 mutex_lock(&priv->mutex);9289 if (wrqu->frag.disabled || !wrqu->frag.fixed)9290 priv->ieee->fts = DEFAULT_FTS;9291 else {9292 if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||9293 wrqu->frag.value > MAX_FRAG_THRESHOLD) {9294 mutex_unlock(&priv->mutex);9295 return -EINVAL;9296 }9297 9298 priv->ieee->fts = wrqu->frag.value & ~0x1;9299 }9300 9301 ipw_send_frag_threshold(priv, wrqu->frag.value);9302 mutex_unlock(&priv->mutex);9303 IPW_DEBUG_WX("SET Frag Threshold -> %d\n", wrqu->frag.value);9304 return 0;9305}9306 9307static int ipw_wx_get_frag(struct net_device *dev,9308 struct iw_request_info *info,9309 union iwreq_data *wrqu, char *extra)9310{9311 struct ipw_priv *priv = libipw_priv(dev);9312 mutex_lock(&priv->mutex);9313 wrqu->frag.value = priv->ieee->fts;9314 wrqu->frag.fixed = 0; /* no auto select */9315 wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS);9316 mutex_unlock(&priv->mutex);9317 IPW_DEBUG_WX("GET Frag Threshold -> %d\n", wrqu->frag.value);9318 9319 return 0;9320}9321 9322static int ipw_wx_set_retry(struct net_device *dev,9323 struct iw_request_info *info,9324 union iwreq_data *wrqu, char *extra)9325{9326 struct ipw_priv *priv = libipw_priv(dev);9327 9328 if (wrqu->retry.flags & IW_RETRY_LIFETIME || wrqu->retry.disabled)9329 return -EINVAL;9330 9331 if (!(wrqu->retry.flags & IW_RETRY_LIMIT))9332 return 0;9333 9334 if (wrqu->retry.value < 0 || wrqu->retry.value >= 255)9335 return -EINVAL;9336 9337 mutex_lock(&priv->mutex);9338 if (wrqu->retry.flags & IW_RETRY_SHORT)9339 priv->short_retry_limit = (u8) wrqu->retry.value;9340 else if (wrqu->retry.flags & IW_RETRY_LONG)9341 priv->long_retry_limit = (u8) wrqu->retry.value;9342 else {9343 priv->short_retry_limit = (u8) wrqu->retry.value;9344 priv->long_retry_limit = (u8) wrqu->retry.value;9345 }9346 9347 ipw_send_retry_limit(priv, priv->short_retry_limit,9348 priv->long_retry_limit);9349 mutex_unlock(&priv->mutex);9350 IPW_DEBUG_WX("SET retry limit -> short:%d long:%d\n",9351 priv->short_retry_limit, priv->long_retry_limit);9352 return 0;9353}9354 9355static int ipw_wx_get_retry(struct net_device *dev,9356 struct iw_request_info *info,9357 union iwreq_data *wrqu, char *extra)9358{9359 struct ipw_priv *priv = libipw_priv(dev);9360 9361 mutex_lock(&priv->mutex);9362 wrqu->retry.disabled = 0;9363 9364 if ((wrqu->retry.flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {9365 mutex_unlock(&priv->mutex);9366 return -EINVAL;9367 }9368 9369 if (wrqu->retry.flags & IW_RETRY_LONG) {9370 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_LONG;9371 wrqu->retry.value = priv->long_retry_limit;9372 } else if (wrqu->retry.flags & IW_RETRY_SHORT) {9373 wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_SHORT;9374 wrqu->retry.value = priv->short_retry_limit;9375 } else {9376 wrqu->retry.flags = IW_RETRY_LIMIT;9377 wrqu->retry.value = priv->short_retry_limit;9378 }9379 mutex_unlock(&priv->mutex);9380 9381 IPW_DEBUG_WX("GET retry -> %d\n", wrqu->retry.value);9382 9383 return 0;9384}9385 9386static int ipw_wx_set_scan(struct net_device *dev,9387 struct iw_request_info *info,9388 union iwreq_data *wrqu, char *extra)9389{9390 struct ipw_priv *priv = libipw_priv(dev);9391 struct iw_scan_req *req = (struct iw_scan_req *)extra;9392 struct delayed_work *work = NULL;9393 9394 mutex_lock(&priv->mutex);9395 9396 priv->user_requested_scan = 1;9397 9398 if (wrqu->data.length == sizeof(struct iw_scan_req)) {9399 if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {9400 int len = min((int)req->essid_len,9401 (int)sizeof(priv->direct_scan_ssid));9402 memcpy(priv->direct_scan_ssid, req->essid, len);9403 priv->direct_scan_ssid_len = len;9404 work = &priv->request_direct_scan;9405 } else if (req->scan_type == IW_SCAN_TYPE_PASSIVE) {9406 work = &priv->request_passive_scan;9407 }9408 } else {9409 /* Normal active broadcast scan */9410 work = &priv->request_scan;9411 }9412 9413 mutex_unlock(&priv->mutex);9414 9415 IPW_DEBUG_WX("Start scan\n");9416 9417 schedule_delayed_work(work, 0);9418 9419 return 0;9420}9421 9422static int ipw_wx_get_scan(struct net_device *dev,9423 struct iw_request_info *info,9424 union iwreq_data *wrqu, char *extra)9425{9426 struct ipw_priv *priv = libipw_priv(dev);9427 return libipw_wx_get_scan(priv->ieee, info, wrqu, extra);9428}9429 9430static int ipw_wx_set_encode(struct net_device *dev,9431 struct iw_request_info *info,9432 union iwreq_data *wrqu, char *key)9433{9434 struct ipw_priv *priv = libipw_priv(dev);9435 int ret;9436 u32 cap = priv->capability;9437 9438 mutex_lock(&priv->mutex);9439 ret = libipw_wx_set_encode(priv->ieee, info, wrqu, key);9440 9441 /* In IBSS mode, we need to notify the firmware to update9442 * the beacon info after we changed the capability. */9443 if (cap != priv->capability &&9444 priv->ieee->iw_mode == IW_MODE_ADHOC &&9445 priv->status & STATUS_ASSOCIATED)9446 ipw_disassociate(priv);9447 9448 mutex_unlock(&priv->mutex);9449 return ret;9450}9451 9452static int ipw_wx_get_encode(struct net_device *dev,9453 struct iw_request_info *info,9454 union iwreq_data *wrqu, char *key)9455{9456 struct ipw_priv *priv = libipw_priv(dev);9457 return libipw_wx_get_encode(priv->ieee, info, wrqu, key);9458}9459 9460static int ipw_wx_set_power(struct net_device *dev,9461 struct iw_request_info *info,9462 union iwreq_data *wrqu, char *extra)9463{9464 struct ipw_priv *priv = libipw_priv(dev);9465 int err;9466 mutex_lock(&priv->mutex);9467 if (wrqu->power.disabled) {9468 priv->power_mode = IPW_POWER_LEVEL(priv->power_mode);9469 err = ipw_send_power_mode(priv, IPW_POWER_MODE_CAM);9470 if (err) {9471 IPW_DEBUG_WX("failed setting power mode.\n");9472 mutex_unlock(&priv->mutex);9473 return err;9474 }9475 IPW_DEBUG_WX("SET Power Management Mode -> off\n");9476 mutex_unlock(&priv->mutex);9477 return 0;9478 }9479 9480 switch (wrqu->power.flags & IW_POWER_MODE) {9481 case IW_POWER_ON: /* If not specified */9482 case IW_POWER_MODE: /* If set all mask */9483 case IW_POWER_ALL_R: /* If explicitly state all */9484 break;9485 default: /* Otherwise we don't support it */9486 IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",9487 wrqu->power.flags);9488 mutex_unlock(&priv->mutex);9489 return -EOPNOTSUPP;9490 }9491 9492 /* If the user hasn't specified a power management mode yet, default9493 * to BATTERY */9494 if (IPW_POWER_LEVEL(priv->power_mode) == IPW_POWER_AC)9495 priv->power_mode = IPW_POWER_ENABLED | IPW_POWER_BATTERY;9496 else9497 priv->power_mode = IPW_POWER_ENABLED | priv->power_mode;9498 9499 err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));9500 if (err) {9501 IPW_DEBUG_WX("failed setting power mode.\n");9502 mutex_unlock(&priv->mutex);9503 return err;9504 }9505 9506 IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode);9507 mutex_unlock(&priv->mutex);9508 return 0;9509}9510 9511static int ipw_wx_get_power(struct net_device *dev,9512 struct iw_request_info *info,9513 union iwreq_data *wrqu, char *extra)9514{9515 struct ipw_priv *priv = libipw_priv(dev);9516 mutex_lock(&priv->mutex);9517 if (!(priv->power_mode & IPW_POWER_ENABLED))9518 wrqu->power.disabled = 1;9519 else9520 wrqu->power.disabled = 0;9521 9522 mutex_unlock(&priv->mutex);9523 IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode);9524 9525 return 0;9526}9527 9528static int ipw_wx_set_powermode(struct net_device *dev,9529 struct iw_request_info *info,9530 union iwreq_data *wrqu, char *extra)9531{9532 struct ipw_priv *priv = libipw_priv(dev);9533 int mode = *(int *)extra;9534 int err;9535 9536 mutex_lock(&priv->mutex);9537 if ((mode < 1) || (mode > IPW_POWER_LIMIT))9538 mode = IPW_POWER_AC;9539 9540 if (IPW_POWER_LEVEL(priv->power_mode) != mode) {9541 err = ipw_send_power_mode(priv, mode);9542 if (err) {9543 IPW_DEBUG_WX("failed setting power mode.\n");9544 mutex_unlock(&priv->mutex);9545 return err;9546 }9547 priv->power_mode = IPW_POWER_ENABLED | mode;9548 }9549 mutex_unlock(&priv->mutex);9550 return 0;9551}9552 9553#define MAX_WX_STRING 809554static int ipw_wx_get_powermode(struct net_device *dev,9555 struct iw_request_info *info,9556 union iwreq_data *wrqu, char *extra)9557{9558 struct ipw_priv *priv = libipw_priv(dev);9559 int level = IPW_POWER_LEVEL(priv->power_mode);9560 char *p = extra;9561 9562 p += scnprintf(p, MAX_WX_STRING, "Power save level: %d ", level);9563 9564 switch (level) {9565 case IPW_POWER_AC:9566 p += scnprintf(p, MAX_WX_STRING - (p - extra), "(AC)");9567 break;9568 case IPW_POWER_BATTERY:9569 p += scnprintf(p, MAX_WX_STRING - (p - extra), "(BATTERY)");9570 break;9571 default:9572 p += scnprintf(p, MAX_WX_STRING - (p - extra),9573 "(Timeout %dms, Period %dms)",9574 timeout_duration[level - 1] / 1000,9575 period_duration[level - 1] / 1000);9576 }9577 9578 if (!(priv->power_mode & IPW_POWER_ENABLED))9579 p += scnprintf(p, MAX_WX_STRING - (p - extra), " OFF");9580 9581 wrqu->data.length = p - extra + 1;9582 9583 return 0;9584}9585 9586static int ipw_wx_set_wireless_mode(struct net_device *dev,9587 struct iw_request_info *info,9588 union iwreq_data *wrqu, char *extra)9589{9590 struct ipw_priv *priv = libipw_priv(dev);9591 int mode = *(int *)extra;9592 u8 band = 0, modulation = 0;9593 9594 if (mode == 0 || mode & ~IEEE_MODE_MASK) {9595 IPW_WARNING("Attempt to set invalid wireless mode: %d\n", mode);9596 return -EINVAL;9597 }9598 mutex_lock(&priv->mutex);9599 if (priv->adapter == IPW_2915ABG) {9600 priv->ieee->abg_true = 1;9601 if (mode & IEEE_A) {9602 band |= LIBIPW_52GHZ_BAND;9603 modulation |= LIBIPW_OFDM_MODULATION;9604 } else9605 priv->ieee->abg_true = 0;9606 } else {9607 if (mode & IEEE_A) {9608 IPW_WARNING("Attempt to set 2200BG into "9609 "802.11a mode\n");9610 mutex_unlock(&priv->mutex);9611 return -EINVAL;9612 }9613 9614 priv->ieee->abg_true = 0;9615 }9616 9617 if (mode & IEEE_B) {9618 band |= LIBIPW_24GHZ_BAND;9619 modulation |= LIBIPW_CCK_MODULATION;9620 } else9621 priv->ieee->abg_true = 0;9622 9623 if (mode & IEEE_G) {9624 band |= LIBIPW_24GHZ_BAND;9625 modulation |= LIBIPW_OFDM_MODULATION;9626 } else9627 priv->ieee->abg_true = 0;9628 9629 priv->ieee->mode = mode;9630 priv->ieee->freq_band = band;9631 priv->ieee->modulation = modulation;9632 init_supported_rates(priv, &priv->rates);9633 9634 /* Network configuration changed -- force [re]association */9635 IPW_DEBUG_ASSOC("[re]association triggered due to mode change.\n");9636 if (!ipw_disassociate(priv)) {9637 ipw_send_supported_rates(priv, &priv->rates);9638 ipw_associate(priv);9639 }9640 9641 /* Update the band LEDs */9642 ipw_led_band_on(priv);9643 9644 IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n",9645 mode & IEEE_A ? 'a' : '.',9646 mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.');9647 mutex_unlock(&priv->mutex);9648 return 0;9649}9650 9651static int ipw_wx_get_wireless_mode(struct net_device *dev,9652 struct iw_request_info *info,9653 union iwreq_data *wrqu, char *extra)9654{9655 struct ipw_priv *priv = libipw_priv(dev);9656 mutex_lock(&priv->mutex);9657 switch (priv->ieee->mode) {9658 case IEEE_A:9659 strscpy_pad(extra, "802.11a (1)", MAX_WX_STRING);9660 break;9661 case IEEE_B:9662 strscpy_pad(extra, "802.11b (2)", MAX_WX_STRING);9663 break;9664 case IEEE_A | IEEE_B:9665 strscpy_pad(extra, "802.11ab (3)", MAX_WX_STRING);9666 break;9667 case IEEE_G:9668 strscpy_pad(extra, "802.11g (4)", MAX_WX_STRING);9669 break;9670 case IEEE_A | IEEE_G:9671 strscpy_pad(extra, "802.11ag (5)", MAX_WX_STRING);9672 break;9673 case IEEE_B | IEEE_G:9674 strscpy_pad(extra, "802.11bg (6)", MAX_WX_STRING);9675 break;9676 case IEEE_A | IEEE_B | IEEE_G:9677 strscpy_pad(extra, "802.11abg (7)", MAX_WX_STRING);9678 break;9679 default:9680 strscpy_pad(extra, "unknown", MAX_WX_STRING);9681 break;9682 }9683 9684 IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra);9685 9686 wrqu->data.length = strlen(extra) + 1;9687 mutex_unlock(&priv->mutex);9688 9689 return 0;9690}9691 9692static int ipw_wx_set_preamble(struct net_device *dev,9693 struct iw_request_info *info,9694 union iwreq_data *wrqu, char *extra)9695{9696 struct ipw_priv *priv = libipw_priv(dev);9697 int mode = *(int *)extra;9698 mutex_lock(&priv->mutex);9699 /* Switching from SHORT -> LONG requires a disassociation */9700 if (mode == 1) {9701 if (!(priv->config & CFG_PREAMBLE_LONG)) {9702 priv->config |= CFG_PREAMBLE_LONG;9703 9704 /* Network configuration changed -- force [re]association */9705 IPW_DEBUG_ASSOC9706 ("[re]association triggered due to preamble change.\n");9707 if (!ipw_disassociate(priv))9708 ipw_associate(priv);9709 }9710 goto done;9711 }9712 9713 if (mode == 0) {9714 priv->config &= ~CFG_PREAMBLE_LONG;9715 goto done;9716 }9717 mutex_unlock(&priv->mutex);9718 return -EINVAL;9719 9720 done:9721 mutex_unlock(&priv->mutex);9722 return 0;9723}9724 9725static int ipw_wx_get_preamble(struct net_device *dev,9726 struct iw_request_info *info,9727 union iwreq_data *wrqu, char *extra)9728{9729 struct ipw_priv *priv = libipw_priv(dev);9730 mutex_lock(&priv->mutex);9731 if (priv->config & CFG_PREAMBLE_LONG)9732 snprintf(wrqu->name, IFNAMSIZ, "long (1)");9733 else9734 snprintf(wrqu->name, IFNAMSIZ, "auto (0)");9735 mutex_unlock(&priv->mutex);9736 return 0;9737}9738 9739#ifdef CONFIG_IPW2200_MONITOR9740static int ipw_wx_set_monitor(struct net_device *dev,9741 struct iw_request_info *info,9742 union iwreq_data *wrqu, char *extra)9743{9744 struct ipw_priv *priv = libipw_priv(dev);9745 int *parms = (int *)extra;9746 int enable = (parms[0] > 0);9747 mutex_lock(&priv->mutex);9748 IPW_DEBUG_WX("SET MONITOR: %d %d\n", enable, parms[1]);9749 if (enable) {9750 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {9751#ifdef CONFIG_IPW2200_RADIOTAP9752 priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;9753#else9754 priv->net_dev->type = ARPHRD_IEEE80211;9755#endif9756 schedule_work(&priv->adapter_restart);9757 }9758 9759 ipw_set_channel(priv, parms[1]);9760 } else {9761 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {9762 mutex_unlock(&priv->mutex);9763 return 0;9764 }9765 priv->net_dev->type = ARPHRD_ETHER;9766 schedule_work(&priv->adapter_restart);9767 }9768 mutex_unlock(&priv->mutex);9769 return 0;9770}9771 9772#endif /* CONFIG_IPW2200_MONITOR */9773 9774static int ipw_wx_reset(struct net_device *dev,9775 struct iw_request_info *info,9776 union iwreq_data *wrqu, char *extra)9777{9778 struct ipw_priv *priv = libipw_priv(dev);9779 IPW_DEBUG_WX("RESET\n");9780 schedule_work(&priv->adapter_restart);9781 return 0;9782}9783 9784static int ipw_wx_sw_reset(struct net_device *dev,9785 struct iw_request_info *info,9786 union iwreq_data *wrqu, char *extra)9787{9788 struct ipw_priv *priv = libipw_priv(dev);9789 union iwreq_data wrqu_sec = {9790 .encoding = {9791 .flags = IW_ENCODE_DISABLED,9792 },9793 };9794 int ret;9795 9796 IPW_DEBUG_WX("SW_RESET\n");9797 9798 mutex_lock(&priv->mutex);9799 9800 ret = ipw_sw_reset(priv, 2);9801 if (!ret) {9802 free_firmware();9803 ipw_adapter_restart(priv);9804 }9805 9806 /* The SW reset bit might have been toggled on by the 'disable'9807 * module parameter, so take appropriate action */9808 ipw_radio_kill_sw(priv, priv->status & STATUS_RF_KILL_SW);9809 9810 mutex_unlock(&priv->mutex);9811 libipw_wx_set_encode(priv->ieee, info, &wrqu_sec, NULL);9812 mutex_lock(&priv->mutex);9813 9814 if (!(priv->status & STATUS_RF_KILL_MASK)) {9815 /* Configuration likely changed -- force [re]association */9816 IPW_DEBUG_ASSOC("[re]association triggered due to sw "9817 "reset.\n");9818 if (!ipw_disassociate(priv))9819 ipw_associate(priv);9820 }9821 9822 mutex_unlock(&priv->mutex);9823 9824 return 0;9825}9826 9827/* Rebase the WE IOCTLs to zero for the handler array */9828static iw_handler ipw_wx_handlers[] = {9829 IW_HANDLER(SIOCGIWNAME, cfg80211_wext_giwname),9830 IW_HANDLER(SIOCSIWFREQ, ipw_wx_set_freq),9831 IW_HANDLER(SIOCGIWFREQ, ipw_wx_get_freq),9832 IW_HANDLER(SIOCSIWMODE, ipw_wx_set_mode),9833 IW_HANDLER(SIOCGIWMODE, ipw_wx_get_mode),9834 IW_HANDLER(SIOCSIWSENS, ipw_wx_set_sens),9835 IW_HANDLER(SIOCGIWSENS, ipw_wx_get_sens),9836 IW_HANDLER(SIOCGIWRANGE, ipw_wx_get_range),9837 IW_HANDLER(SIOCSIWAP, ipw_wx_set_wap),9838 IW_HANDLER(SIOCGIWAP, ipw_wx_get_wap),9839 IW_HANDLER(SIOCSIWSCAN, ipw_wx_set_scan),9840 IW_HANDLER(SIOCGIWSCAN, ipw_wx_get_scan),9841 IW_HANDLER(SIOCSIWESSID, ipw_wx_set_essid),9842 IW_HANDLER(SIOCGIWESSID, ipw_wx_get_essid),9843 IW_HANDLER(SIOCSIWNICKN, ipw_wx_set_nick),9844 IW_HANDLER(SIOCGIWNICKN, ipw_wx_get_nick),9845 IW_HANDLER(SIOCSIWRATE, ipw_wx_set_rate),9846 IW_HANDLER(SIOCGIWRATE, ipw_wx_get_rate),9847 IW_HANDLER(SIOCSIWRTS, ipw_wx_set_rts),9848 IW_HANDLER(SIOCGIWRTS, ipw_wx_get_rts),9849 IW_HANDLER(SIOCSIWFRAG, ipw_wx_set_frag),9850 IW_HANDLER(SIOCGIWFRAG, ipw_wx_get_frag),9851 IW_HANDLER(SIOCSIWTXPOW, ipw_wx_set_txpow),9852 IW_HANDLER(SIOCGIWTXPOW, ipw_wx_get_txpow),9853 IW_HANDLER(SIOCSIWRETRY, ipw_wx_set_retry),9854 IW_HANDLER(SIOCGIWRETRY, ipw_wx_get_retry),9855 IW_HANDLER(SIOCSIWENCODE, ipw_wx_set_encode),9856 IW_HANDLER(SIOCGIWENCODE, ipw_wx_get_encode),9857 IW_HANDLER(SIOCSIWPOWER, ipw_wx_set_power),9858 IW_HANDLER(SIOCGIWPOWER, ipw_wx_get_power),9859 IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),9860 IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),9861 IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),9862 IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),9863 IW_HANDLER(SIOCSIWGENIE, ipw_wx_set_genie),9864 IW_HANDLER(SIOCGIWGENIE, ipw_wx_get_genie),9865 IW_HANDLER(SIOCSIWMLME, ipw_wx_set_mlme),9866 IW_HANDLER(SIOCSIWAUTH, ipw_wx_set_auth),9867 IW_HANDLER(SIOCGIWAUTH, ipw_wx_get_auth),9868 IW_HANDLER(SIOCSIWENCODEEXT, ipw_wx_set_encodeext),9869 IW_HANDLER(SIOCGIWENCODEEXT, ipw_wx_get_encodeext),9870};9871 9872enum {9873 IPW_PRIV_SET_POWER = SIOCIWFIRSTPRIV,9874 IPW_PRIV_GET_POWER,9875 IPW_PRIV_SET_MODE,9876 IPW_PRIV_GET_MODE,9877 IPW_PRIV_SET_PREAMBLE,9878 IPW_PRIV_GET_PREAMBLE,9879 IPW_PRIV_RESET,9880 IPW_PRIV_SW_RESET,9881#ifdef CONFIG_IPW2200_MONITOR9882 IPW_PRIV_SET_MONITOR,9883#endif9884};9885 9886static struct iw_priv_args ipw_priv_args[] = {9887 {9888 .cmd = IPW_PRIV_SET_POWER,9889 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,9890 .name = "set_power"},9891 {9892 .cmd = IPW_PRIV_GET_POWER,9893 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,9894 .name = "get_power"},9895 {9896 .cmd = IPW_PRIV_SET_MODE,9897 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,9898 .name = "set_mode"},9899 {9900 .cmd = IPW_PRIV_GET_MODE,9901 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,9902 .name = "get_mode"},9903 {9904 .cmd = IPW_PRIV_SET_PREAMBLE,9905 .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,9906 .name = "set_preamble"},9907 {9908 .cmd = IPW_PRIV_GET_PREAMBLE,9909 .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ,9910 .name = "get_preamble"},9911 {9912 IPW_PRIV_RESET,9913 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "reset"},9914 {9915 IPW_PRIV_SW_RESET,9916 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 0, 0, "sw_reset"},9917#ifdef CONFIG_IPW2200_MONITOR9918 {9919 IPW_PRIV_SET_MONITOR,9920 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "monitor"},9921#endif /* CONFIG_IPW2200_MONITOR */9922};9923 9924static iw_handler ipw_priv_handler[] = {9925 ipw_wx_set_powermode,9926 ipw_wx_get_powermode,9927 ipw_wx_set_wireless_mode,9928 ipw_wx_get_wireless_mode,9929 ipw_wx_set_preamble,9930 ipw_wx_get_preamble,9931 ipw_wx_reset,9932 ipw_wx_sw_reset,9933#ifdef CONFIG_IPW2200_MONITOR9934 ipw_wx_set_monitor,9935#endif9936};9937 9938static const struct iw_handler_def ipw_wx_handler_def = {9939 .standard = ipw_wx_handlers,9940 .num_standard = ARRAY_SIZE(ipw_wx_handlers),9941 .num_private = ARRAY_SIZE(ipw_priv_handler),9942 .num_private_args = ARRAY_SIZE(ipw_priv_args),9943 .private = ipw_priv_handler,9944 .private_args = ipw_priv_args,9945 .get_wireless_stats = ipw_get_wireless_stats,9946};9947 9948/*9949 * Get wireless statistics.9950 * Called by /proc/net/wireless9951 * Also called by SIOCGIWSTATS9952 */9953static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev)9954{9955 struct ipw_priv *priv = libipw_priv(dev);9956 struct iw_statistics *wstats;9957 9958 wstats = &priv->wstats;9959 9960 /* if hw is disabled, then ipw_get_ordinal() can't be called.9961 * netdev->get_wireless_stats seems to be called before fw is9962 * initialized. STATUS_ASSOCIATED will only be set if the hw is up9963 * and associated; if not associcated, the values are all meaningless9964 * anyway, so set them all to NULL and INVALID */9965 if (!(priv->status & STATUS_ASSOCIATED)) {9966 wstats->miss.beacon = 0;9967 wstats->discard.retries = 0;9968 wstats->qual.qual = 0;9969 wstats->qual.level = 0;9970 wstats->qual.noise = 0;9971 wstats->qual.updated = 7;9972 wstats->qual.updated |= IW_QUAL_NOISE_INVALID |9973 IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID;9974 return wstats;9975 }9976 9977 wstats->qual.qual = priv->quality;9978 wstats->qual.level = priv->exp_avg_rssi;9979 wstats->qual.noise = priv->exp_avg_noise;9980 wstats->qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED |9981 IW_QUAL_NOISE_UPDATED | IW_QUAL_DBM;9982 9983 wstats->miss.beacon = average_value(&priv->average_missed_beacons);9984 wstats->discard.retries = priv->last_tx_failures;9985 wstats->discard.code = priv->ieee->ieee_stats.rx_discards_undecryptable;9986 9987/* if (ipw_get_ordinal(priv, IPW_ORD_STAT_TX_RETRY, &tx_retry, &len))9988 goto fail_get_ordinal;9989 wstats->discard.retries += tx_retry; */9990 9991 return wstats;9992}9993 9994/* net device stuff */9995 9996static void init_sys_config(struct ipw_sys_config *sys_config)9997{9998 memset(sys_config, 0, sizeof(struct ipw_sys_config));9999 sys_config->bt_coexistence = 0;10000 sys_config->answer_broadcast_ssid_probe = 0;10001 sys_config->accept_all_data_frames = 0;10002 sys_config->accept_non_directed_frames = 1;10003 sys_config->exclude_unicast_unencrypted = 0;10004 sys_config->disable_unicast_decryption = 1;10005 sys_config->exclude_multicast_unencrypted = 0;10006 sys_config->disable_multicast_decryption = 1;10007 if (antenna < CFG_SYS_ANTENNA_BOTH || antenna > CFG_SYS_ANTENNA_B)10008 antenna = CFG_SYS_ANTENNA_BOTH;10009 sys_config->antenna_diversity = antenna;10010 sys_config->pass_crc_to_host = 0; /* TODO: See if 1 gives us FCS */10011 sys_config->dot11g_auto_detection = 0;10012 sys_config->enable_cts_to_self = 0;10013 sys_config->bt_coexist_collision_thr = 0;10014 sys_config->pass_noise_stats_to_host = 1; /* 1 -- fix for 256 */10015 sys_config->silence_threshold = 0x1e;10016}10017 10018static int ipw_net_open(struct net_device *dev)10019{10020 IPW_DEBUG_INFO("dev->open\n");10021 netif_start_queue(dev);10022 return 0;10023}10024 10025static int ipw_net_stop(struct net_device *dev)10026{10027 IPW_DEBUG_INFO("dev->close\n");10028 netif_stop_queue(dev);10029 return 0;10030}10031 10032/*10033todo:10034 10035modify to send one tfd per fragment instead of using chunking. otherwise10036we need to heavily modify the libipw_skb_to_txb.10037*/10038 10039static int ipw_tx_skb(struct ipw_priv *priv, struct libipw_txb *txb,10040 int pri)10041{10042 struct libipw_hdr_3addrqos *hdr = (struct libipw_hdr_3addrqos *)10043 txb->fragments[0]->data;10044 int i = 0;10045 struct tfd_frame *tfd;10046#ifdef CONFIG_IPW2200_QOS10047 int tx_id = ipw_get_tx_queue_number(priv, pri);10048 struct clx2_tx_queue *txq = &priv->txq[tx_id];10049#else10050 struct clx2_tx_queue *txq = &priv->txq[0];10051#endif10052 struct clx2_queue *q = &txq->q;10053 u8 id, hdr_len, unicast;10054 int fc;10055 10056 if (!(priv->status & STATUS_ASSOCIATED))10057 goto drop;10058 10059 hdr_len = libipw_get_hdrlen(le16_to_cpu(hdr->frame_ctl));10060 switch (priv->ieee->iw_mode) {10061 case IW_MODE_ADHOC:10062 unicast = !is_multicast_ether_addr(hdr->addr1);10063 id = ipw_find_station(priv, hdr->addr1);10064 if (id == IPW_INVALID_STATION) {10065 id = ipw_add_station(priv, hdr->addr1);10066 if (id == IPW_INVALID_STATION) {10067 IPW_WARNING("Attempt to send data to "10068 "invalid cell: %pM\n",10069 hdr->addr1);10070 goto drop;10071 }10072 }10073 break;10074 10075 case IW_MODE_INFRA:10076 default:10077 unicast = !is_multicast_ether_addr(hdr->addr3);10078 id = 0;10079 break;10080 }10081 10082 tfd = &txq->bd[q->first_empty];10083 txq->txb[q->first_empty] = txb;10084 memset(tfd, 0, sizeof(*tfd));10085 tfd->u.data.station_number = id;10086 10087 tfd->control_flags.message_type = TX_FRAME_TYPE;10088 tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK;10089 10090 tfd->u.data.cmd_id = DINO_CMD_TX;10091 tfd->u.data.len = cpu_to_le16(txb->payload_size);10092 10093 if (priv->assoc_request.ieee_mode == IPW_B_MODE)10094 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_MODE_CCK;10095 else10096 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_MODE_OFDM;10097 10098 if (priv->assoc_request.preamble_length == DCT_FLAG_SHORT_PREAMBLE)10099 tfd->u.data.tx_flags |= DCT_FLAG_SHORT_PREAMBLE;10100 10101 fc = le16_to_cpu(hdr->frame_ctl);10102 hdr->frame_ctl = cpu_to_le16(fc & ~IEEE80211_FCTL_MOREFRAGS);10103 10104 memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len);10105 10106 if (likely(unicast))10107 tfd->u.data.tx_flags |= DCT_FLAG_ACK_REQD;10108 10109 if (txb->encrypted && !priv->ieee->host_encrypt) {10110 switch (priv->ieee->sec.level) {10111 case SEC_LEVEL_3:10112 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=10113 cpu_to_le16(IEEE80211_FCTL_PROTECTED);10114 /* XXX: ACK flag must be set for CCMP even if it10115 * is a multicast/broadcast packet, because CCMP10116 * group communication encrypted by GTK is10117 * actually done by the AP. */10118 if (!unicast)10119 tfd->u.data.tx_flags |= DCT_FLAG_ACK_REQD;10120 10121 tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP;10122 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_CCM;10123 tfd->u.data.key_index = 0;10124 tfd->u.data.key_index |= DCT_WEP_INDEX_USE_IMMEDIATE;10125 break;10126 case SEC_LEVEL_2:10127 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=10128 cpu_to_le16(IEEE80211_FCTL_PROTECTED);10129 tfd->u.data.tx_flags &= ~DCT_FLAG_NO_WEP;10130 tfd->u.data.tx_flags_ext |= DCT_FLAG_EXT_SECURITY_TKIP;10131 tfd->u.data.key_index = DCT_WEP_INDEX_USE_IMMEDIATE;10132 break;10133 case SEC_LEVEL_1:10134 tfd->u.data.tfd.tfd_24.mchdr.frame_ctl |=10135 cpu_to_le16(IEEE80211_FCTL_PROTECTED);10136 tfd->u.data.key_index = priv->ieee->crypt_info.tx_keyidx;10137 if (priv->ieee->sec.key_sizes[priv->ieee->crypt_info.tx_keyidx] <=10138 40)10139 tfd->u.data.key_index |= DCT_WEP_KEY_64Bit;10140 else10141 tfd->u.data.key_index |= DCT_WEP_KEY_128Bit;10142 break;10143 case SEC_LEVEL_0:10144 break;10145 default:10146 printk(KERN_ERR "Unknown security level %d\n",10147 priv->ieee->sec.level);10148 break;10149 }10150 } else10151 /* No hardware encryption */10152 tfd->u.data.tx_flags |= DCT_FLAG_NO_WEP;10153 10154#ifdef CONFIG_IPW2200_QOS10155 if (fc & IEEE80211_STYPE_QOS_DATA)10156 ipw_qos_set_tx_queue_command(priv, pri, &(tfd->u.data));10157#endif /* CONFIG_IPW2200_QOS */10158 10159 /* payload */10160 tfd->u.data.num_chunks = cpu_to_le32(min((u8) (NUM_TFD_CHUNKS - 2),10161 txb->nr_frags));10162 IPW_DEBUG_FRAG("%i fragments being sent as %i chunks.\n",10163 txb->nr_frags, le32_to_cpu(tfd->u.data.num_chunks));10164 for (i = 0; i < le32_to_cpu(tfd->u.data.num_chunks); i++) {10165 IPW_DEBUG_FRAG("Adding fragment %i of %i (%d bytes).\n",10166 i, le32_to_cpu(tfd->u.data.num_chunks),10167 txb->fragments[i]->len - hdr_len);10168 IPW_DEBUG_TX("Dumping TX packet frag %i of %i (%d bytes):\n",10169 i, tfd->u.data.num_chunks,10170 txb->fragments[i]->len - hdr_len);10171 printk_buf(IPW_DL_TX, txb->fragments[i]->data + hdr_len,10172 txb->fragments[i]->len - hdr_len);10173 10174 tfd->u.data.chunk_ptr[i] =10175 cpu_to_le32(dma_map_single(&priv->pci_dev->dev,10176 txb->fragments[i]->data + hdr_len,10177 txb->fragments[i]->len - hdr_len,10178 DMA_TO_DEVICE));10179 tfd->u.data.chunk_len[i] =10180 cpu_to_le16(txb->fragments[i]->len - hdr_len);10181 }10182 10183 if (i != txb->nr_frags) {10184 struct sk_buff *skb;10185 u16 remaining_bytes = 0;10186 int j;10187 10188 for (j = i; j < txb->nr_frags; j++)10189 remaining_bytes += txb->fragments[j]->len - hdr_len;10190 10191 printk(KERN_INFO "Trying to reallocate for %d bytes\n",10192 remaining_bytes);10193 skb = alloc_skb(remaining_bytes, GFP_ATOMIC);10194 if (skb != NULL) {10195 tfd->u.data.chunk_len[i] = cpu_to_le16(remaining_bytes);10196 for (j = i; j < txb->nr_frags; j++) {10197 int size = txb->fragments[j]->len - hdr_len;10198 10199 printk(KERN_INFO "Adding frag %d %d...\n",10200 j, size);10201 skb_put_data(skb,10202 txb->fragments[j]->data + hdr_len,10203 size);10204 }10205 dev_kfree_skb_any(txb->fragments[i]);10206 txb->fragments[i] = skb;10207 tfd->u.data.chunk_ptr[i] =10208 cpu_to_le32(dma_map_single(&priv->pci_dev->dev,10209 skb->data,10210 remaining_bytes,10211 DMA_TO_DEVICE));10212 10213 le32_add_cpu(&tfd->u.data.num_chunks, 1);10214 }10215 }10216 10217 /* kick DMA */10218 q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);10219 ipw_write32(priv, q->reg_w, q->first_empty);10220 10221 if (ipw_tx_queue_space(q) < q->high_mark)10222 netif_stop_queue(priv->net_dev);10223 10224 return NETDEV_TX_OK;10225 10226 drop:10227 IPW_DEBUG_DROP("Silently dropping Tx packet.\n");10228 libipw_txb_free(txb);10229 return NETDEV_TX_OK;10230}10231 10232static int ipw_net_is_queue_full(struct net_device *dev, int pri)10233{10234 struct ipw_priv *priv = libipw_priv(dev);10235#ifdef CONFIG_IPW2200_QOS10236 int tx_id = ipw_get_tx_queue_number(priv, pri);10237 struct clx2_tx_queue *txq = &priv->txq[tx_id];10238#else10239 struct clx2_tx_queue *txq = &priv->txq[0];10240#endif /* CONFIG_IPW2200_QOS */10241 10242 if (ipw_tx_queue_space(&txq->q) < txq->q.high_mark)10243 return 1;10244 10245 return 0;10246}10247 10248#ifdef CONFIG_IPW2200_PROMISCUOUS10249static void ipw_handle_promiscuous_tx(struct ipw_priv *priv,10250 struct libipw_txb *txb)10251{10252 struct libipw_rx_stats dummystats;10253 struct ieee80211_hdr *hdr;10254 u8 n;10255 u16 filter = priv->prom_priv->filter;10256 int hdr_only = 0;10257 10258 if (filter & IPW_PROM_NO_TX)10259 return;10260 10261 memset(&dummystats, 0, sizeof(dummystats));10262 10263 /* Filtering of fragment chains is done against the first fragment */10264 hdr = (void *)txb->fragments[0]->data;10265 if (libipw_is_management(le16_to_cpu(hdr->frame_control))) {10266 if (filter & IPW_PROM_NO_MGMT)10267 return;10268 if (filter & IPW_PROM_MGMT_HEADER_ONLY)10269 hdr_only = 1;10270 } else if (libipw_is_control(le16_to_cpu(hdr->frame_control))) {10271 if (filter & IPW_PROM_NO_CTL)10272 return;10273 if (filter & IPW_PROM_CTL_HEADER_ONLY)10274 hdr_only = 1;10275 } else if (libipw_is_data(le16_to_cpu(hdr->frame_control))) {10276 if (filter & IPW_PROM_NO_DATA)10277 return;10278 if (filter & IPW_PROM_DATA_HEADER_ONLY)10279 hdr_only = 1;10280 }10281 10282 for(n=0; n<txb->nr_frags; ++n) {10283 struct sk_buff *src = txb->fragments[n];10284 struct sk_buff *dst;10285 struct ieee80211_radiotap_header *rt_hdr;10286 int len;10287 10288 if (hdr_only) {10289 hdr = (void *)src->data;10290 len = libipw_get_hdrlen(le16_to_cpu(hdr->frame_control));10291 } else10292 len = src->len;10293 10294 dst = alloc_skb(len + sizeof(*rt_hdr) + sizeof(u16)*2, GFP_ATOMIC);10295 if (!dst)10296 continue;10297 10298 rt_hdr = skb_put(dst, sizeof(*rt_hdr));10299 10300 rt_hdr->it_version = PKTHDR_RADIOTAP_VERSION;10301 rt_hdr->it_pad = 0;10302 rt_hdr->it_present = 0; /* after all, it's just an idea */10303 rt_hdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_CHANNEL);10304 10305 *(__le16*)skb_put(dst, sizeof(u16)) = cpu_to_le16(10306 ieee80211chan2mhz(priv->channel));10307 if (priv->channel > 14) /* 802.11a */10308 *(__le16*)skb_put(dst, sizeof(u16)) =10309 cpu_to_le16(IEEE80211_CHAN_OFDM |10310 IEEE80211_CHAN_5GHZ);10311 else if (priv->ieee->mode == IEEE_B) /* 802.11b */10312 *(__le16*)skb_put(dst, sizeof(u16)) =10313 cpu_to_le16(IEEE80211_CHAN_CCK |10314 IEEE80211_CHAN_2GHZ);10315 else /* 802.11g */10316 *(__le16*)skb_put(dst, sizeof(u16)) =10317 cpu_to_le16(IEEE80211_CHAN_OFDM |10318 IEEE80211_CHAN_2GHZ);10319 10320 rt_hdr->it_len = cpu_to_le16(dst->len);10321 10322 skb_copy_from_linear_data(src, skb_put(dst, len), len);10323 10324 if (!libipw_rx(priv->prom_priv->ieee, dst, &dummystats))10325 dev_kfree_skb_any(dst);10326 }10327}10328#endif10329 10330static netdev_tx_t ipw_net_hard_start_xmit(struct libipw_txb *txb,10331 struct net_device *dev, int pri)10332{10333 struct ipw_priv *priv = libipw_priv(dev);10334 unsigned long flags;10335 netdev_tx_t ret;10336 10337 IPW_DEBUG_TX("dev->xmit(%d bytes)\n", txb->payload_size);10338 spin_lock_irqsave(&priv->lock, flags);10339 10340#ifdef CONFIG_IPW2200_PROMISCUOUS10341 if (rtap_iface && netif_running(priv->prom_net_dev))10342 ipw_handle_promiscuous_tx(priv, txb);10343#endif10344 10345 ret = ipw_tx_skb(priv, txb, pri);10346 if (ret == NETDEV_TX_OK)10347 __ipw_led_activity_on(priv);10348 spin_unlock_irqrestore(&priv->lock, flags);10349 10350 return ret;10351}10352 10353static void ipw_net_set_multicast_list(struct net_device *dev)10354{10355 10356}10357 10358static int ipw_net_set_mac_address(struct net_device *dev, void *p)10359{10360 struct ipw_priv *priv = libipw_priv(dev);10361 struct sockaddr *addr = p;10362 10363 if (!is_valid_ether_addr(addr->sa_data))10364 return -EADDRNOTAVAIL;10365 mutex_lock(&priv->mutex);10366 priv->config |= CFG_CUSTOM_MAC;10367 memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);10368 printk(KERN_INFO "%s: Setting MAC to %pM\n",10369 priv->net_dev->name, priv->mac_addr);10370 schedule_work(&priv->adapter_restart);10371 mutex_unlock(&priv->mutex);10372 return 0;10373}10374 10375static void ipw_ethtool_get_drvinfo(struct net_device *dev,10376 struct ethtool_drvinfo *info)10377{10378 struct ipw_priv *p = libipw_priv(dev);10379 char vers[64];10380 u32 len;10381 10382 strscpy(info->driver, DRV_NAME, sizeof(info->driver));10383 strscpy(info->version, DRV_VERSION, sizeof(info->version));10384 10385 len = sizeof(vers);10386 ipw_get_ordinal(p, IPW_ORD_STAT_FW_VERSION, vers, &len);10387 10388 strscpy(info->fw_version, vers, sizeof(info->fw_version));10389 strscpy(info->bus_info, pci_name(p->pci_dev),10390 sizeof(info->bus_info));10391}10392 10393static u32 ipw_ethtool_get_link(struct net_device *dev)10394{10395 struct ipw_priv *priv = libipw_priv(dev);10396 return (priv->status & STATUS_ASSOCIATED) != 0;10397}10398 10399static int ipw_ethtool_get_eeprom_len(struct net_device *dev)10400{10401 return IPW_EEPROM_IMAGE_SIZE;10402}10403 10404static int ipw_ethtool_get_eeprom(struct net_device *dev,10405 struct ethtool_eeprom *eeprom, u8 * bytes)10406{10407 struct ipw_priv *p = libipw_priv(dev);10408 10409 if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)10410 return -EINVAL;10411 mutex_lock(&p->mutex);10412 memcpy(bytes, &p->eeprom[eeprom->offset], eeprom->len);10413 mutex_unlock(&p->mutex);10414 return 0;10415}10416 10417static int ipw_ethtool_set_eeprom(struct net_device *dev,10418 struct ethtool_eeprom *eeprom, u8 * bytes)10419{10420 struct ipw_priv *p = libipw_priv(dev);10421 int i;10422 10423 if (eeprom->offset + eeprom->len > IPW_EEPROM_IMAGE_SIZE)10424 return -EINVAL;10425 mutex_lock(&p->mutex);10426 memcpy(&p->eeprom[eeprom->offset], bytes, eeprom->len);10427 for (i = 0; i < IPW_EEPROM_IMAGE_SIZE; i++)10428 ipw_write8(p, i + IPW_EEPROM_DATA, p->eeprom[i]);10429 mutex_unlock(&p->mutex);10430 return 0;10431}10432 10433static const struct ethtool_ops ipw_ethtool_ops = {10434 .get_link = ipw_ethtool_get_link,10435 .get_drvinfo = ipw_ethtool_get_drvinfo,10436 .get_eeprom_len = ipw_ethtool_get_eeprom_len,10437 .get_eeprom = ipw_ethtool_get_eeprom,10438 .set_eeprom = ipw_ethtool_set_eeprom,10439};10440 10441static irqreturn_t ipw_isr(int irq, void *data)10442{10443 struct ipw_priv *priv = data;10444 u32 inta, inta_mask;10445 10446 if (!priv)10447 return IRQ_NONE;10448 10449 spin_lock(&priv->irq_lock);10450 10451 if (!(priv->status & STATUS_INT_ENABLED)) {10452 /* IRQ is disabled */10453 goto none;10454 }10455 10456 inta = ipw_read32(priv, IPW_INTA_RW);10457 inta_mask = ipw_read32(priv, IPW_INTA_MASK_R);10458 10459 if (inta == 0xFFFFFFFF) {10460 /* Hardware disappeared */10461 IPW_WARNING("IRQ INTA == 0xFFFFFFFF\n");10462 goto none;10463 }10464 10465 if (!(inta & (IPW_INTA_MASK_ALL & inta_mask))) {10466 /* Shared interrupt */10467 goto none;10468 }10469 10470 /* tell the device to stop sending interrupts */10471 __ipw_disable_interrupts(priv);10472 10473 /* ack current interrupts */10474 inta &= (IPW_INTA_MASK_ALL & inta_mask);10475 ipw_write32(priv, IPW_INTA_RW, inta);10476 10477 /* Cache INTA value for our tasklet */10478 priv->isr_inta = inta;10479 10480 tasklet_schedule(&priv->irq_tasklet);10481 10482 spin_unlock(&priv->irq_lock);10483 10484 return IRQ_HANDLED;10485 none:10486 spin_unlock(&priv->irq_lock);10487 return IRQ_NONE;10488}10489 10490static void ipw_rf_kill(void *adapter)10491{10492 struct ipw_priv *priv = adapter;10493 unsigned long flags;10494 10495 spin_lock_irqsave(&priv->lock, flags);10496 10497 if (rf_kill_active(priv)) {10498 IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n");10499 schedule_delayed_work(&priv->rf_kill, 2 * HZ);10500 goto exit_unlock;10501 }10502 10503 /* RF Kill is now disabled, so bring the device back up */10504 10505 if (!(priv->status & STATUS_RF_KILL_MASK)) {10506 IPW_DEBUG_RF_KILL("HW RF Kill no longer active, restarting "10507 "device\n");10508 10509 /* we can not do an adapter restart while inside an irq lock */10510 schedule_work(&priv->adapter_restart);10511 } else10512 IPW_DEBUG_RF_KILL("HW RF Kill deactivated. SW RF Kill still "10513 "enabled\n");10514 10515 exit_unlock:10516 spin_unlock_irqrestore(&priv->lock, flags);10517}10518 10519static void ipw_bg_rf_kill(struct work_struct *work)10520{10521 struct ipw_priv *priv =10522 container_of(work, struct ipw_priv, rf_kill.work);10523 mutex_lock(&priv->mutex);10524 ipw_rf_kill(priv);10525 mutex_unlock(&priv->mutex);10526}10527 10528static void ipw_link_up(struct ipw_priv *priv)10529{10530 priv->last_seq_num = -1;10531 priv->last_frag_num = -1;10532 priv->last_packet_time = 0;10533 10534 netif_carrier_on(priv->net_dev);10535 10536 cancel_delayed_work(&priv->request_scan);10537 cancel_delayed_work(&priv->request_direct_scan);10538 cancel_delayed_work(&priv->request_passive_scan);10539 cancel_delayed_work(&priv->scan_event);10540 ipw_reset_stats(priv);10541 /* Ensure the rate is updated immediately */10542 priv->last_rate = ipw_get_current_rate(priv);10543 ipw_gather_stats(priv);10544 ipw_led_link_up(priv);10545 notify_wx_assoc_event(priv);10546 10547 if (priv->config & CFG_BACKGROUND_SCAN)10548 schedule_delayed_work(&priv->request_scan, HZ);10549}10550 10551static void ipw_bg_link_up(struct work_struct *work)10552{10553 struct ipw_priv *priv =10554 container_of(work, struct ipw_priv, link_up);10555 mutex_lock(&priv->mutex);10556 ipw_link_up(priv);10557 mutex_unlock(&priv->mutex);10558}10559 10560static void ipw_link_down(struct ipw_priv *priv)10561{10562 ipw_led_link_down(priv);10563 netif_carrier_off(priv->net_dev);10564 notify_wx_assoc_event(priv);10565 10566 /* Cancel any queued work ... */10567 cancel_delayed_work(&priv->request_scan);10568 cancel_delayed_work(&priv->request_direct_scan);10569 cancel_delayed_work(&priv->request_passive_scan);10570 cancel_delayed_work(&priv->adhoc_check);10571 cancel_delayed_work(&priv->gather_stats);10572 10573 ipw_reset_stats(priv);10574 10575 if (!(priv->status & STATUS_EXIT_PENDING)) {10576 /* Queue up another scan... */10577 schedule_delayed_work(&priv->request_scan, 0);10578 } else10579 cancel_delayed_work(&priv->scan_event);10580}10581 10582static void ipw_bg_link_down(struct work_struct *work)10583{10584 struct ipw_priv *priv =10585 container_of(work, struct ipw_priv, link_down);10586 mutex_lock(&priv->mutex);10587 ipw_link_down(priv);10588 mutex_unlock(&priv->mutex);10589}10590 10591static void ipw_setup_deferred_work(struct ipw_priv *priv)10592{10593 init_waitqueue_head(&priv->wait_command_queue);10594 init_waitqueue_head(&priv->wait_state);10595 10596 INIT_DELAYED_WORK(&priv->adhoc_check, ipw_bg_adhoc_check);10597 INIT_WORK(&priv->associate, ipw_bg_associate);10598 INIT_WORK(&priv->disassociate, ipw_bg_disassociate);10599 INIT_WORK(&priv->system_config, ipw_system_config);10600 INIT_WORK(&priv->rx_replenish, ipw_bg_rx_queue_replenish);10601 INIT_WORK(&priv->adapter_restart, ipw_bg_adapter_restart);10602 INIT_DELAYED_WORK(&priv->rf_kill, ipw_bg_rf_kill);10603 INIT_WORK(&priv->up, ipw_bg_up);10604 INIT_WORK(&priv->down, ipw_bg_down);10605 INIT_DELAYED_WORK(&priv->request_scan, ipw_request_scan);10606 INIT_DELAYED_WORK(&priv->request_direct_scan, ipw_request_direct_scan);10607 INIT_DELAYED_WORK(&priv->request_passive_scan, ipw_request_passive_scan);10608 INIT_DELAYED_WORK(&priv->scan_event, ipw_scan_event);10609 INIT_DELAYED_WORK(&priv->gather_stats, ipw_bg_gather_stats);10610 INIT_WORK(&priv->abort_scan, ipw_bg_abort_scan);10611 INIT_WORK(&priv->roam, ipw_bg_roam);10612 INIT_DELAYED_WORK(&priv->scan_check, ipw_bg_scan_check);10613 INIT_WORK(&priv->link_up, ipw_bg_link_up);10614 INIT_WORK(&priv->link_down, ipw_bg_link_down);10615 INIT_DELAYED_WORK(&priv->led_link_on, ipw_bg_led_link_on);10616 INIT_DELAYED_WORK(&priv->led_link_off, ipw_bg_led_link_off);10617 INIT_DELAYED_WORK(&priv->led_act_off, ipw_bg_led_activity_off);10618 INIT_WORK(&priv->merge_networks, ipw_merge_adhoc_network);10619 10620#ifdef CONFIG_IPW2200_QOS10621 INIT_WORK(&priv->qos_activate, ipw_bg_qos_activate);10622#endif /* CONFIG_IPW2200_QOS */10623 10624 tasklet_setup(&priv->irq_tasklet, ipw_irq_tasklet);10625}10626 10627static void shim__set_security(struct net_device *dev,10628 struct libipw_security *sec)10629{10630 struct ipw_priv *priv = libipw_priv(dev);10631 int i;10632 for (i = 0; i < 4; i++) {10633 if (sec->flags & (1 << i)) {10634 priv->ieee->sec.encode_alg[i] = sec->encode_alg[i];10635 priv->ieee->sec.key_sizes[i] = sec->key_sizes[i];10636 if (sec->key_sizes[i] == 0)10637 priv->ieee->sec.flags &= ~(1 << i);10638 else {10639 memcpy(priv->ieee->sec.keys[i], sec->keys[i],10640 sec->key_sizes[i]);10641 priv->ieee->sec.flags |= (1 << i);10642 }10643 priv->status |= STATUS_SECURITY_UPDATED;10644 } else if (sec->level != SEC_LEVEL_1)10645 priv->ieee->sec.flags &= ~(1 << i);10646 }10647 10648 if (sec->flags & SEC_ACTIVE_KEY) {10649 priv->ieee->sec.active_key = sec->active_key;10650 priv->ieee->sec.flags |= SEC_ACTIVE_KEY;10651 priv->status |= STATUS_SECURITY_UPDATED;10652 } else10653 priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;10654 10655 if ((sec->flags & SEC_AUTH_MODE) &&10656 (priv->ieee->sec.auth_mode != sec->auth_mode)) {10657 priv->ieee->sec.auth_mode = sec->auth_mode;10658 priv->ieee->sec.flags |= SEC_AUTH_MODE;10659 if (sec->auth_mode == WLAN_AUTH_SHARED_KEY)10660 priv->capability |= CAP_SHARED_KEY;10661 else10662 priv->capability &= ~CAP_SHARED_KEY;10663 priv->status |= STATUS_SECURITY_UPDATED;10664 }10665 10666 if (sec->flags & SEC_ENABLED && priv->ieee->sec.enabled != sec->enabled) {10667 priv->ieee->sec.flags |= SEC_ENABLED;10668 priv->ieee->sec.enabled = sec->enabled;10669 priv->status |= STATUS_SECURITY_UPDATED;10670 if (sec->enabled)10671 priv->capability |= CAP_PRIVACY_ON;10672 else10673 priv->capability &= ~CAP_PRIVACY_ON;10674 }10675 10676 if (sec->flags & SEC_ENCRYPT)10677 priv->ieee->sec.encrypt = sec->encrypt;10678 10679 if (sec->flags & SEC_LEVEL && priv->ieee->sec.level != sec->level) {10680 priv->ieee->sec.level = sec->level;10681 priv->ieee->sec.flags |= SEC_LEVEL;10682 priv->status |= STATUS_SECURITY_UPDATED;10683 }10684 10685 if (!priv->ieee->host_encrypt && (sec->flags & SEC_ENCRYPT))10686 ipw_set_hwcrypto_keys(priv);10687 10688 /* To match current functionality of ipw2100 (which works well w/10689 * various supplicants, we don't force a disassociate if the10690 * privacy capability changes ... */10691#if 010692 if ((priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) &&10693 (((priv->assoc_request.capability &10694 cpu_to_le16(WLAN_CAPABILITY_PRIVACY)) && !sec->enabled) ||10695 (!(priv->assoc_request.capability &10696 cpu_to_le16(WLAN_CAPABILITY_PRIVACY)) && sec->enabled))) {10697 IPW_DEBUG_ASSOC("Disassociating due to capability "10698 "change.\n");10699 ipw_disassociate(priv);10700 }10701#endif10702}10703 10704static int init_supported_rates(struct ipw_priv *priv,10705 struct ipw_supported_rates *rates)10706{10707 /* TODO: Mask out rates based on priv->rates_mask */10708 10709 memset(rates, 0, sizeof(*rates));10710 /* configure supported rates */10711 switch (priv->ieee->freq_band) {10712 case LIBIPW_52GHZ_BAND:10713 rates->ieee_mode = IPW_A_MODE;10714 rates->purpose = IPW_RATE_CAPABILITIES;10715 ipw_add_ofdm_scan_rates(rates, LIBIPW_CCK_MODULATION,10716 LIBIPW_OFDM_DEFAULT_RATES_MASK);10717 break;10718 10719 default: /* Mixed or 2.4Ghz */10720 rates->ieee_mode = IPW_G_MODE;10721 rates->purpose = IPW_RATE_CAPABILITIES;10722 ipw_add_cck_scan_rates(rates, LIBIPW_CCK_MODULATION,10723 LIBIPW_CCK_DEFAULT_RATES_MASK);10724 if (priv->ieee->modulation & LIBIPW_OFDM_MODULATION) {10725 ipw_add_ofdm_scan_rates(rates, LIBIPW_CCK_MODULATION,10726 LIBIPW_OFDM_DEFAULT_RATES_MASK);10727 }10728 break;10729 }10730 10731 return 0;10732}10733 10734static int ipw_config(struct ipw_priv *priv)10735{10736 /* This is only called from ipw_up, which resets/reloads the firmware10737 so, we don't need to first disable the card before we configure10738 it */10739 if (ipw_set_tx_power(priv))10740 goto error;10741 10742 /* initialize adapter address */10743 if (ipw_send_adapter_address(priv, priv->net_dev->dev_addr))10744 goto error;10745 10746 /* set basic system config settings */10747 init_sys_config(&priv->sys_config);10748 10749 /* Support Bluetooth if we have BT h/w on board, and user wants to.10750 * Does not support BT priority yet (don't abort or defer our Tx) */10751 if (bt_coexist) {10752 unsigned char bt_caps = priv->eeprom[EEPROM_SKU_CAPABILITY];10753 10754 if (bt_caps & EEPROM_SKU_CAP_BT_CHANNEL_SIG)10755 priv->sys_config.bt_coexistence10756 |= CFG_BT_COEXISTENCE_SIGNAL_CHNL;10757 if (bt_caps & EEPROM_SKU_CAP_BT_OOB)10758 priv->sys_config.bt_coexistence10759 |= CFG_BT_COEXISTENCE_OOB;10760 }10761 10762#ifdef CONFIG_IPW2200_PROMISCUOUS10763 if (priv->prom_net_dev && netif_running(priv->prom_net_dev)) {10764 priv->sys_config.accept_all_data_frames = 1;10765 priv->sys_config.accept_non_directed_frames = 1;10766 priv->sys_config.accept_all_mgmt_bcpr = 1;10767 priv->sys_config.accept_all_mgmt_frames = 1;10768 }10769#endif10770 10771 if (priv->ieee->iw_mode == IW_MODE_ADHOC)10772 priv->sys_config.answer_broadcast_ssid_probe = 1;10773 else10774 priv->sys_config.answer_broadcast_ssid_probe = 0;10775 10776 if (ipw_send_system_config(priv))10777 goto error;10778 10779 init_supported_rates(priv, &priv->rates);10780 if (ipw_send_supported_rates(priv, &priv->rates))10781 goto error;10782 10783 /* Set request-to-send threshold */10784 if (priv->rts_threshold) {10785 if (ipw_send_rts_threshold(priv, priv->rts_threshold))10786 goto error;10787 }10788#ifdef CONFIG_IPW2200_QOS10789 IPW_DEBUG_QOS("QoS: call ipw_qos_activate\n");10790 ipw_qos_activate(priv, NULL);10791#endif /* CONFIG_IPW2200_QOS */10792 10793 if (ipw_set_random_seed(priv))10794 goto error;10795 10796 /* final state transition to the RUN state */10797 if (ipw_send_host_complete(priv))10798 goto error;10799 10800 priv->status |= STATUS_INIT;10801 10802 ipw_led_init(priv);10803 ipw_led_radio_on(priv);10804 priv->notif_missed_beacons = 0;10805 10806 /* Set hardware WEP key if it is configured. */10807 if ((priv->capability & CAP_PRIVACY_ON) &&10808 (priv->ieee->sec.level == SEC_LEVEL_1) &&10809 !(priv->ieee->host_encrypt || priv->ieee->host_decrypt))10810 ipw_set_hwcrypto_keys(priv);10811 10812 return 0;10813 10814 error:10815 return -EIO;10816}10817 10818/*10819 * NOTE:10820 *10821 * These tables have been tested in conjunction with the10822 * Intel PRO/Wireless 2200BG and 2915ABG Network Connection Adapters.10823 *10824 * Altering this values, using it on other hardware, or in geographies10825 * not intended for resale of the above mentioned Intel adapters has10826 * not been tested.10827 *10828 * Remember to update the table in README.ipw2200 when changing this10829 * table.10830 *10831 */10832static const struct libipw_geo ipw_geos[] = {10833 { /* Restricted */10834 "---",10835 .bg_channels = 11,10836 .bg = {{2412, 1}, {2417, 2}, {2422, 3},10837 {2427, 4}, {2432, 5}, {2437, 6},10838 {2442, 7}, {2447, 8}, {2452, 9},10839 {2457, 10}, {2462, 11}},10840 },10841 10842 { /* Custom US/Canada */10843 "ZZF",10844 .bg_channels = 11,10845 .bg = {{2412, 1}, {2417, 2}, {2422, 3},10846 {2427, 4}, {2432, 5}, {2437, 6},10847 {2442, 7}, {2447, 8}, {2452, 9},10848 {2457, 10}, {2462, 11}},10849 .a_channels = 8,10850 .a = {{5180, 36},10851 {5200, 40},10852 {5220, 44},10853 {5240, 48},10854 {5260, 52, LIBIPW_CH_PASSIVE_ONLY},10855 {5280, 56, LIBIPW_CH_PASSIVE_ONLY},10856 {5300, 60, LIBIPW_CH_PASSIVE_ONLY},10857 {5320, 64, LIBIPW_CH_PASSIVE_ONLY}},10858 },10859 10860 { /* Rest of World */10861 "ZZD",10862 .bg_channels = 13,10863 .bg = {{2412, 1}, {2417, 2}, {2422, 3},10864 {2427, 4}, {2432, 5}, {2437, 6},10865 {2442, 7}, {2447, 8}, {2452, 9},10866 {2457, 10}, {2462, 11}, {2467, 12},10867 {2472, 13}},10868 },10869 10870 { /* Custom USA & Europe & High */10871 "ZZA",10872 .bg_channels = 11,10873 .bg = {{2412, 1}, {2417, 2}, {2422, 3},10874 {2427, 4}, {2432, 5}, {2437, 6},10875 {2442, 7}, {2447, 8}, {2452, 9},10876 {2457, 10}, {2462, 11}},10877 .a_channels = 13,10878 .a = {{5180, 36},10879 {5200, 40},10880 {5220, 44},10881 {5240, 48},10882 {5260, 52, LIBIPW_CH_PASSIVE_ONLY},10883 {5280, 56, LIBIPW_CH_PASSIVE_ONLY},10884 {5300, 60, LIBIPW_CH_PASSIVE_ONLY},10885 {5320, 64, LIBIPW_CH_PASSIVE_ONLY},10886 {5745, 149},10887 {5765, 153},10888 {5785, 157},10889 {5805, 161},10890 {5825, 165}},10891 },10892 10893 { /* Custom NA & Europe */10894 "ZZB",10895 .bg_channels = 11,10896 .bg = {{2412, 1}, {2417, 2}, {2422, 3},10897 {2427, 4}, {2432, 5}, {2437, 6},10898 {2442, 7}, {2447, 8}, {2452, 9},10899 {2457, 10}, {2462, 11}},10900 .a_channels = 13,10901 .a = {{5180, 36},10902 {5200, 40},10903 {5220, 44},10904 {5240, 48},10905 {5260, 52, LIBIPW_CH_PASSIVE_ONLY},10906 {5280, 56, LIBIPW_CH_PASSIVE_ONLY},10907 {5300, 60, LIBIPW_CH_PASSIVE_ONLY},10908 {5320, 64, LIBIPW_CH_PASSIVE_ONLY},10909 {5745, 149, LIBIPW_CH_PASSIVE_ONLY},10910 {5765, 153, LIBIPW_CH_PASSIVE_ONLY},10911 {5785, 157, LIBIPW_CH_PASSIVE_ONLY},10912 {5805, 161, LIBIPW_CH_PASSIVE_ONLY},10913 {5825, 165, LIBIPW_CH_PASSIVE_ONLY}},10914 },10915 10916 { /* Custom Japan */10917 "ZZC",10918 .bg_channels = 11,10919 .bg = {{2412, 1}, {2417, 2}, {2422, 3},10920 {2427, 4}, {2432, 5}, {2437, 6},10921 {2442, 7}, {2447, 8}, {2452, 9},10922 {2457, 10}, {2462, 11}},10923 .a_channels = 4,10924 .a = {{5170, 34}, {5190, 38},10925 {5210, 42}, {5230, 46}},10926 },10927 10928 { /* Custom */10929 "ZZM",10930 .bg_channels = 11,10931 .bg = {{2412, 1}, {2417, 2}, {2422, 3},10932 {2427, 4}, {2432, 5}, {2437, 6},10933 {2442, 7}, {2447, 8}, {2452, 9},10934 {2457, 10}, {2462, 11}},10935 },10936 10937 { /* Europe */10938 "ZZE",10939 .bg_channels = 13,10940 .bg = {{2412, 1}, {2417, 2}, {2422, 3},10941 {2427, 4}, {2432, 5}, {2437, 6},10942 {2442, 7}, {2447, 8}, {2452, 9},10943 {2457, 10}, {2462, 11}, {2467, 12},10944 {2472, 13}},10945 .a_channels = 19,10946 .a = {{5180, 36},10947 {5200, 40},10948 {5220, 44},10949 {5240, 48},10950 {5260, 52, LIBIPW_CH_PASSIVE_ONLY},10951 {5280, 56, LIBIPW_CH_PASSIVE_ONLY},10952 {5300, 60, LIBIPW_CH_PASSIVE_ONLY},10953 {5320, 64, LIBIPW_CH_PASSIVE_ONLY},10954 {5500, 100, LIBIPW_CH_PASSIVE_ONLY},10955 {5520, 104, LIBIPW_CH_PASSIVE_ONLY},10956 {5540, 108, LIBIPW_CH_PASSIVE_ONLY},10957 {5560, 112, LIBIPW_CH_PASSIVE_ONLY},10958 {5580, 116, LIBIPW_CH_PASSIVE_ONLY},10959 {5600, 120, LIBIPW_CH_PASSIVE_ONLY},10960 {5620, 124, LIBIPW_CH_PASSIVE_ONLY},10961 {5640, 128, LIBIPW_CH_PASSIVE_ONLY},10962 {5660, 132, LIBIPW_CH_PASSIVE_ONLY},10963 {5680, 136, LIBIPW_CH_PASSIVE_ONLY},10964 {5700, 140, LIBIPW_CH_PASSIVE_ONLY}},10965 },10966 10967 { /* Custom Japan */10968 "ZZJ",10969 .bg_channels = 14,10970 .bg = {{2412, 1}, {2417, 2}, {2422, 3},10971 {2427, 4}, {2432, 5}, {2437, 6},10972 {2442, 7}, {2447, 8}, {2452, 9},10973 {2457, 10}, {2462, 11}, {2467, 12},10974 {2472, 13}, {2484, 14, LIBIPW_CH_B_ONLY}},10975 .a_channels = 4,10976 .a = {{5170, 34}, {5190, 38},10977 {5210, 42}, {5230, 46}},10978 },10979 10980 { /* Rest of World */10981 "ZZR",10982 .bg_channels = 14,10983 .bg = {{2412, 1}, {2417, 2}, {2422, 3},10984 {2427, 4}, {2432, 5}, {2437, 6},10985 {2442, 7}, {2447, 8}, {2452, 9},10986 {2457, 10}, {2462, 11}, {2467, 12},10987 {2472, 13}, {2484, 14, LIBIPW_CH_B_ONLY |10988 LIBIPW_CH_PASSIVE_ONLY}},10989 },10990 10991 { /* High Band */10992 "ZZH",10993 .bg_channels = 13,10994 .bg = {{2412, 1}, {2417, 2}, {2422, 3},10995 {2427, 4}, {2432, 5}, {2437, 6},10996 {2442, 7}, {2447, 8}, {2452, 9},10997 {2457, 10}, {2462, 11},10998 {2467, 12, LIBIPW_CH_PASSIVE_ONLY},10999 {2472, 13, LIBIPW_CH_PASSIVE_ONLY}},11000 .a_channels = 4,11001 .a = {{5745, 149}, {5765, 153},11002 {5785, 157}, {5805, 161}},11003 },11004 11005 { /* Custom Europe */11006 "ZZG",11007 .bg_channels = 13,11008 .bg = {{2412, 1}, {2417, 2}, {2422, 3},11009 {2427, 4}, {2432, 5}, {2437, 6},11010 {2442, 7}, {2447, 8}, {2452, 9},11011 {2457, 10}, {2462, 11},11012 {2467, 12}, {2472, 13}},11013 .a_channels = 4,11014 .a = {{5180, 36}, {5200, 40},11015 {5220, 44}, {5240, 48}},11016 },11017 11018 { /* Europe */11019 "ZZK",11020 .bg_channels = 13,11021 .bg = {{2412, 1}, {2417, 2}, {2422, 3},11022 {2427, 4}, {2432, 5}, {2437, 6},11023 {2442, 7}, {2447, 8}, {2452, 9},11024 {2457, 10}, {2462, 11},11025 {2467, 12, LIBIPW_CH_PASSIVE_ONLY},11026 {2472, 13, LIBIPW_CH_PASSIVE_ONLY}},11027 .a_channels = 24,11028 .a = {{5180, 36, LIBIPW_CH_PASSIVE_ONLY},11029 {5200, 40, LIBIPW_CH_PASSIVE_ONLY},11030 {5220, 44, LIBIPW_CH_PASSIVE_ONLY},11031 {5240, 48, LIBIPW_CH_PASSIVE_ONLY},11032 {5260, 52, LIBIPW_CH_PASSIVE_ONLY},11033 {5280, 56, LIBIPW_CH_PASSIVE_ONLY},11034 {5300, 60, LIBIPW_CH_PASSIVE_ONLY},11035 {5320, 64, LIBIPW_CH_PASSIVE_ONLY},11036 {5500, 100, LIBIPW_CH_PASSIVE_ONLY},11037 {5520, 104, LIBIPW_CH_PASSIVE_ONLY},11038 {5540, 108, LIBIPW_CH_PASSIVE_ONLY},11039 {5560, 112, LIBIPW_CH_PASSIVE_ONLY},11040 {5580, 116, LIBIPW_CH_PASSIVE_ONLY},11041 {5600, 120, LIBIPW_CH_PASSIVE_ONLY},11042 {5620, 124, LIBIPW_CH_PASSIVE_ONLY},11043 {5640, 128, LIBIPW_CH_PASSIVE_ONLY},11044 {5660, 132, LIBIPW_CH_PASSIVE_ONLY},11045 {5680, 136, LIBIPW_CH_PASSIVE_ONLY},11046 {5700, 140, LIBIPW_CH_PASSIVE_ONLY},11047 {5745, 149, LIBIPW_CH_PASSIVE_ONLY},11048 {5765, 153, LIBIPW_CH_PASSIVE_ONLY},11049 {5785, 157, LIBIPW_CH_PASSIVE_ONLY},11050 {5805, 161, LIBIPW_CH_PASSIVE_ONLY},11051 {5825, 165, LIBIPW_CH_PASSIVE_ONLY}},11052 },11053 11054 { /* Europe */11055 "ZZL",11056 .bg_channels = 11,11057 .bg = {{2412, 1}, {2417, 2}, {2422, 3},11058 {2427, 4}, {2432, 5}, {2437, 6},11059 {2442, 7}, {2447, 8}, {2452, 9},11060 {2457, 10}, {2462, 11}},11061 .a_channels = 13,11062 .a = {{5180, 36, LIBIPW_CH_PASSIVE_ONLY},11063 {5200, 40, LIBIPW_CH_PASSIVE_ONLY},11064 {5220, 44, LIBIPW_CH_PASSIVE_ONLY},11065 {5240, 48, LIBIPW_CH_PASSIVE_ONLY},11066 {5260, 52, LIBIPW_CH_PASSIVE_ONLY},11067 {5280, 56, LIBIPW_CH_PASSIVE_ONLY},11068 {5300, 60, LIBIPW_CH_PASSIVE_ONLY},11069 {5320, 64, LIBIPW_CH_PASSIVE_ONLY},11070 {5745, 149, LIBIPW_CH_PASSIVE_ONLY},11071 {5765, 153, LIBIPW_CH_PASSIVE_ONLY},11072 {5785, 157, LIBIPW_CH_PASSIVE_ONLY},11073 {5805, 161, LIBIPW_CH_PASSIVE_ONLY},11074 {5825, 165, LIBIPW_CH_PASSIVE_ONLY}},11075 }11076};11077 11078static void ipw_set_geo(struct ipw_priv *priv)11079{11080 int j;11081 11082 for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) {11083 if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE],11084 ipw_geos[j].name, 3))11085 break;11086 }11087 11088 if (j == ARRAY_SIZE(ipw_geos)) {11089 IPW_WARNING("SKU [%c%c%c] not recognized.\n",11090 priv->eeprom[EEPROM_COUNTRY_CODE + 0],11091 priv->eeprom[EEPROM_COUNTRY_CODE + 1],11092 priv->eeprom[EEPROM_COUNTRY_CODE + 2]);11093 j = 0;11094 }11095 11096 libipw_set_geo(priv->ieee, &ipw_geos[j]);11097}11098 11099#define MAX_HW_RESTARTS 511100static int ipw_up(struct ipw_priv *priv)11101{11102 int rc, i;11103 11104 /* Age scan list entries found before suspend */11105 if (priv->suspend_time) {11106 libipw_networks_age(priv->ieee, priv->suspend_time);11107 priv->suspend_time = 0;11108 }11109 11110 if (priv->status & STATUS_EXIT_PENDING)11111 return -EIO;11112 11113 if (cmdlog && !priv->cmdlog) {11114 priv->cmdlog = kcalloc(cmdlog, sizeof(*priv->cmdlog),11115 GFP_KERNEL);11116 if (priv->cmdlog == NULL) {11117 IPW_ERROR("Error allocating %d command log entries.\n",11118 cmdlog);11119 return -ENOMEM;11120 } else {11121 priv->cmdlog_len = cmdlog;11122 }11123 }11124 11125 for (i = 0; i < MAX_HW_RESTARTS; i++) {11126 /* Load the microcode, firmware, and eeprom.11127 * Also start the clocks. */11128 rc = ipw_load(priv);11129 if (rc) {11130 IPW_ERROR("Unable to load firmware: %d\n", rc);11131 return rc;11132 }11133 11134 ipw_init_ordinals(priv);11135 if (!(priv->config & CFG_CUSTOM_MAC))11136 eeprom_parse_mac(priv, priv->mac_addr);11137 eth_hw_addr_set(priv->net_dev, priv->mac_addr);11138 11139 ipw_set_geo(priv);11140 11141 if (priv->status & STATUS_RF_KILL_SW) {11142 IPW_WARNING("Radio disabled by module parameter.\n");11143 return 0;11144 } else if (rf_kill_active(priv)) {11145 IPW_WARNING("Radio Frequency Kill Switch is On:\n"11146 "Kill switch must be turned off for "11147 "wireless networking to work.\n");11148 schedule_delayed_work(&priv->rf_kill, 2 * HZ);11149 return 0;11150 }11151 11152 rc = ipw_config(priv);11153 if (!rc) {11154 IPW_DEBUG_INFO("Configured device on count %i\n", i);11155 11156 /* If configure to try and auto-associate, kick11157 * off a scan. */11158 schedule_delayed_work(&priv->request_scan, 0);11159 11160 return 0;11161 }11162 11163 IPW_DEBUG_INFO("Device configuration failed: 0x%08X\n", rc);11164 IPW_DEBUG_INFO("Failed to config device on retry %d of %d\n",11165 i, MAX_HW_RESTARTS);11166 11167 /* We had an error bringing up the hardware, so take it11168 * all the way back down so we can try again */11169 ipw_down(priv);11170 }11171 11172 /* tried to restart and config the device for as long as our11173 * patience could withstand */11174 IPW_ERROR("Unable to initialize device after %d attempts.\n", i);11175 11176 return -EIO;11177}11178 11179static void ipw_bg_up(struct work_struct *work)11180{11181 struct ipw_priv *priv =11182 container_of(work, struct ipw_priv, up);11183 mutex_lock(&priv->mutex);11184 ipw_up(priv);11185 mutex_unlock(&priv->mutex);11186}11187 11188static void ipw_deinit(struct ipw_priv *priv)11189{11190 int i;11191 11192 if (priv->status & STATUS_SCANNING) {11193 IPW_DEBUG_INFO("Aborting scan during shutdown.\n");11194 ipw_abort_scan(priv);11195 }11196 11197 if (priv->status & STATUS_ASSOCIATED) {11198 IPW_DEBUG_INFO("Disassociating during shutdown.\n");11199 ipw_disassociate(priv);11200 }11201 11202 ipw_led_shutdown(priv);11203 11204 /* Wait up to 1s for status to change to not scanning and not11205 * associated (disassociation can take a while for a ful 802.1111206 * exchange */11207 for (i = 1000; i && (priv->status &11208 (STATUS_DISASSOCIATING |11209 STATUS_ASSOCIATED | STATUS_SCANNING)); i--)11210 udelay(10);11211 11212 if (priv->status & (STATUS_DISASSOCIATING |11213 STATUS_ASSOCIATED | STATUS_SCANNING))11214 IPW_DEBUG_INFO("Still associated or scanning...\n");11215 else11216 IPW_DEBUG_INFO("Took %dms to de-init\n", 1000 - i);11217 11218 /* Attempt to disable the card */11219 ipw_send_card_disable(priv, 0);11220 11221 priv->status &= ~STATUS_INIT;11222}11223 11224static void ipw_down(struct ipw_priv *priv)11225{11226 int exit_pending = priv->status & STATUS_EXIT_PENDING;11227 11228 priv->status |= STATUS_EXIT_PENDING;11229 11230 if (ipw_is_init(priv))11231 ipw_deinit(priv);11232 11233 /* Wipe out the EXIT_PENDING status bit if we are not actually11234 * exiting the module */11235 if (!exit_pending)11236 priv->status &= ~STATUS_EXIT_PENDING;11237 11238 /* tell the device to stop sending interrupts */11239 ipw_disable_interrupts(priv);11240 11241 /* Clear all bits but the RF Kill */11242 priv->status &= STATUS_RF_KILL_MASK | STATUS_EXIT_PENDING;11243 netif_carrier_off(priv->net_dev);11244 11245 ipw_stop_nic(priv);11246 11247 ipw_led_radio_off(priv);11248}11249 11250static void ipw_bg_down(struct work_struct *work)11251{11252 struct ipw_priv *priv =11253 container_of(work, struct ipw_priv, down);11254 mutex_lock(&priv->mutex);11255 ipw_down(priv);11256 mutex_unlock(&priv->mutex);11257}11258 11259static int ipw_wdev_init(struct net_device *dev)11260{11261 int i, rc = 0;11262 struct ipw_priv *priv = libipw_priv(dev);11263 const struct libipw_geo *geo = libipw_get_geo(priv->ieee);11264 struct wireless_dev *wdev = &priv->ieee->wdev;11265 11266 memcpy(wdev->wiphy->perm_addr, priv->mac_addr, ETH_ALEN);11267 11268 /* fill-out priv->ieee->bg_band */11269 if (geo->bg_channels) {11270 struct ieee80211_supported_band *bg_band = &priv->ieee->bg_band;11271 11272 bg_band->band = NL80211_BAND_2GHZ;11273 bg_band->n_channels = geo->bg_channels;11274 bg_band->channels = kcalloc(geo->bg_channels,11275 sizeof(struct ieee80211_channel),11276 GFP_KERNEL);11277 if (!bg_band->channels) {11278 rc = -ENOMEM;11279 goto out;11280 }11281 /* translate geo->bg to bg_band.channels */11282 for (i = 0; i < geo->bg_channels; i++) {11283 bg_band->channels[i].band = NL80211_BAND_2GHZ;11284 bg_band->channels[i].center_freq = geo->bg[i].freq;11285 bg_band->channels[i].hw_value = geo->bg[i].channel;11286 bg_band->channels[i].max_power = geo->bg[i].max_power;11287 if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY)11288 bg_band->channels[i].flags |=11289 IEEE80211_CHAN_NO_IR;11290 if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS)11291 bg_band->channels[i].flags |=11292 IEEE80211_CHAN_NO_IR;11293 if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT)11294 bg_band->channels[i].flags |=11295 IEEE80211_CHAN_RADAR;11296 /* No equivalent for LIBIPW_CH_80211H_RULES,11297 LIBIPW_CH_UNIFORM_SPREADING, or11298 LIBIPW_CH_B_ONLY... */11299 }11300 /* point at bitrate info */11301 bg_band->bitrates = ipw2200_bg_rates;11302 bg_band->n_bitrates = ipw2200_num_bg_rates;11303 11304 wdev->wiphy->bands[NL80211_BAND_2GHZ] = bg_band;11305 }11306 11307 /* fill-out priv->ieee->a_band */11308 if (geo->a_channels) {11309 struct ieee80211_supported_band *a_band = &priv->ieee->a_band;11310 11311 a_band->band = NL80211_BAND_5GHZ;11312 a_band->n_channels = geo->a_channels;11313 a_band->channels = kcalloc(geo->a_channels,11314 sizeof(struct ieee80211_channel),11315 GFP_KERNEL);11316 if (!a_band->channels) {11317 rc = -ENOMEM;11318 goto out;11319 }11320 /* translate geo->a to a_band.channels */11321 for (i = 0; i < geo->a_channels; i++) {11322 a_band->channels[i].band = NL80211_BAND_5GHZ;11323 a_band->channels[i].center_freq = geo->a[i].freq;11324 a_band->channels[i].hw_value = geo->a[i].channel;11325 a_band->channels[i].max_power = geo->a[i].max_power;11326 if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY)11327 a_band->channels[i].flags |=11328 IEEE80211_CHAN_NO_IR;11329 if (geo->a[i].flags & LIBIPW_CH_NO_IBSS)11330 a_band->channels[i].flags |=11331 IEEE80211_CHAN_NO_IR;11332 if (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT)11333 a_band->channels[i].flags |=11334 IEEE80211_CHAN_RADAR;11335 /* No equivalent for LIBIPW_CH_80211H_RULES,11336 LIBIPW_CH_UNIFORM_SPREADING, or11337 LIBIPW_CH_B_ONLY... */11338 }11339 /* point at bitrate info */11340 a_band->bitrates = ipw2200_a_rates;11341 a_band->n_bitrates = ipw2200_num_a_rates;11342 11343 wdev->wiphy->bands[NL80211_BAND_5GHZ] = a_band;11344 }11345 11346 wdev->wiphy->cipher_suites = ipw_cipher_suites;11347 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(ipw_cipher_suites);11348 11349 set_wiphy_dev(wdev->wiphy, &priv->pci_dev->dev);11350 11351 /* With that information in place, we can now register the wiphy... */11352 rc = wiphy_register(wdev->wiphy);11353 if (rc)11354 goto out;11355 11356 return 0;11357out:11358 kfree(priv->ieee->a_band.channels);11359 kfree(priv->ieee->bg_band.channels);11360 return rc;11361}11362 11363/* PCI driver stuff */11364static const struct pci_device_id card_ids[] = {11365 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2701, 0, 0, 0},11366 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2702, 0, 0, 0},11367 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2711, 0, 0, 0},11368 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2712, 0, 0, 0},11369 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2721, 0, 0, 0},11370 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2722, 0, 0, 0},11371 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2731, 0, 0, 0},11372 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2732, 0, 0, 0},11373 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2741, 0, 0, 0},11374 {PCI_VENDOR_ID_INTEL, 0x1043, 0x103c, 0x2741, 0, 0, 0},11375 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2742, 0, 0, 0},11376 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2751, 0, 0, 0},11377 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2752, 0, 0, 0},11378 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2753, 0, 0, 0},11379 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2754, 0, 0, 0},11380 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2761, 0, 0, 0},11381 {PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2762, 0, 0, 0},11382 {PCI_VDEVICE(INTEL, 0x104f), 0},11383 {PCI_VDEVICE(INTEL, 0x4220), 0}, /* BG */11384 {PCI_VDEVICE(INTEL, 0x4221), 0}, /* BG */11385 {PCI_VDEVICE(INTEL, 0x4223), 0}, /* ABG */11386 {PCI_VDEVICE(INTEL, 0x4224), 0}, /* ABG */11387 11388 /* required last entry */11389 {0,}11390};11391 11392MODULE_DEVICE_TABLE(pci, card_ids);11393 11394static struct attribute *ipw_sysfs_entries[] = {11395 &dev_attr_rf_kill.attr,11396 &dev_attr_direct_dword.attr,11397 &dev_attr_indirect_byte.attr,11398 &dev_attr_indirect_dword.attr,11399 &dev_attr_mem_gpio_reg.attr,11400 &dev_attr_command_event_reg.attr,11401 &dev_attr_nic_type.attr,11402 &dev_attr_status.attr,11403 &dev_attr_cfg.attr,11404 &dev_attr_error.attr,11405 &dev_attr_event_log.attr,11406 &dev_attr_cmd_log.attr,11407 &dev_attr_eeprom_delay.attr,11408 &dev_attr_ucode_version.attr,11409 &dev_attr_rtc.attr,11410 &dev_attr_scan_age.attr,11411 &dev_attr_led.attr,11412 &dev_attr_speed_scan.attr,11413 &dev_attr_net_stats.attr,11414 &dev_attr_channels.attr,11415#ifdef CONFIG_IPW2200_PROMISCUOUS11416 &dev_attr_rtap_iface.attr,11417 &dev_attr_rtap_filter.attr,11418#endif11419 NULL11420};11421 11422static const struct attribute_group ipw_attribute_group = {11423 .name = NULL, /* put in device directory */11424 .attrs = ipw_sysfs_entries,11425};11426 11427#ifdef CONFIG_IPW2200_PROMISCUOUS11428static int ipw_prom_open(struct net_device *dev)11429{11430 struct ipw_prom_priv *prom_priv = libipw_priv(dev);11431 struct ipw_priv *priv = prom_priv->priv;11432 11433 IPW_DEBUG_INFO("prom dev->open\n");11434 netif_carrier_off(dev);11435 11436 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {11437 priv->sys_config.accept_all_data_frames = 1;11438 priv->sys_config.accept_non_directed_frames = 1;11439 priv->sys_config.accept_all_mgmt_bcpr = 1;11440 priv->sys_config.accept_all_mgmt_frames = 1;11441 11442 ipw_send_system_config(priv);11443 }11444 11445 return 0;11446}11447 11448static int ipw_prom_stop(struct net_device *dev)11449{11450 struct ipw_prom_priv *prom_priv = libipw_priv(dev);11451 struct ipw_priv *priv = prom_priv->priv;11452 11453 IPW_DEBUG_INFO("prom dev->stop\n");11454 11455 if (priv->ieee->iw_mode != IW_MODE_MONITOR) {11456 priv->sys_config.accept_all_data_frames = 0;11457 priv->sys_config.accept_non_directed_frames = 0;11458 priv->sys_config.accept_all_mgmt_bcpr = 0;11459 priv->sys_config.accept_all_mgmt_frames = 0;11460 11461 ipw_send_system_config(priv);11462 }11463 11464 return 0;11465}11466 11467static netdev_tx_t ipw_prom_hard_start_xmit(struct sk_buff *skb,11468 struct net_device *dev)11469{11470 IPW_DEBUG_INFO("prom dev->xmit\n");11471 dev_kfree_skb(skb);11472 return NETDEV_TX_OK;11473}11474 11475static const struct net_device_ops ipw_prom_netdev_ops = {11476 .ndo_open = ipw_prom_open,11477 .ndo_stop = ipw_prom_stop,11478 .ndo_start_xmit = ipw_prom_hard_start_xmit,11479 .ndo_set_mac_address = eth_mac_addr,11480 .ndo_validate_addr = eth_validate_addr,11481};11482 11483static int ipw_prom_alloc(struct ipw_priv *priv)11484{11485 int rc = 0;11486 11487 if (priv->prom_net_dev)11488 return -EPERM;11489 11490 priv->prom_net_dev = alloc_libipw(sizeof(struct ipw_prom_priv), 1);11491 if (priv->prom_net_dev == NULL)11492 return -ENOMEM;11493 11494 priv->prom_priv = libipw_priv(priv->prom_net_dev);11495 priv->prom_priv->ieee = netdev_priv(priv->prom_net_dev);11496 priv->prom_priv->priv = priv;11497 11498 strcpy(priv->prom_net_dev->name, "rtap%d");11499 eth_hw_addr_set(priv->prom_net_dev, priv->mac_addr);11500 11501 priv->prom_net_dev->type = ARPHRD_IEEE80211_RADIOTAP;11502 priv->prom_net_dev->netdev_ops = &ipw_prom_netdev_ops;11503 11504 priv->prom_net_dev->min_mtu = 68;11505 priv->prom_net_dev->max_mtu = LIBIPW_DATA_LEN;11506 11507 priv->prom_priv->ieee->iw_mode = IW_MODE_MONITOR;11508 SET_NETDEV_DEV(priv->prom_net_dev, &priv->pci_dev->dev);11509 11510 rc = register_netdev(priv->prom_net_dev);11511 if (rc) {11512 free_libipw(priv->prom_net_dev, 1);11513 priv->prom_net_dev = NULL;11514 return rc;11515 }11516 11517 return 0;11518}11519 11520static void ipw_prom_free(struct ipw_priv *priv)11521{11522 if (!priv->prom_net_dev)11523 return;11524 11525 unregister_netdev(priv->prom_net_dev);11526 free_libipw(priv->prom_net_dev, 1);11527 11528 priv->prom_net_dev = NULL;11529}11530 11531#endif11532 11533static const struct net_device_ops ipw_netdev_ops = {11534 .ndo_open = ipw_net_open,11535 .ndo_stop = ipw_net_stop,11536 .ndo_set_rx_mode = ipw_net_set_multicast_list,11537 .ndo_set_mac_address = ipw_net_set_mac_address,11538 .ndo_start_xmit = libipw_xmit,11539 .ndo_validate_addr = eth_validate_addr,11540};11541 11542static int ipw_pci_probe(struct pci_dev *pdev,11543 const struct pci_device_id *ent)11544{11545 int err = 0;11546 struct net_device *net_dev;11547 void __iomem *base;11548 u32 length, val;11549 struct ipw_priv *priv;11550 int i;11551 11552 net_dev = alloc_libipw(sizeof(struct ipw_priv), 0);11553 if (net_dev == NULL) {11554 err = -ENOMEM;11555 goto out;11556 }11557 11558 priv = libipw_priv(net_dev);11559 priv->ieee = netdev_priv(net_dev);11560 11561 priv->net_dev = net_dev;11562 priv->pci_dev = pdev;11563 ipw_debug_level = debug;11564 spin_lock_init(&priv->irq_lock);11565 spin_lock_init(&priv->lock);11566 for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++)11567 INIT_LIST_HEAD(&priv->ibss_mac_hash[i]);11568 11569 mutex_init(&priv->mutex);11570 if (pci_enable_device(pdev)) {11571 err = -ENODEV;11572 goto out_free_libipw;11573 }11574 11575 pci_set_master(pdev);11576 11577 err = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));11578 if (!err)11579 err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));11580 if (err) {11581 printk(KERN_WARNING DRV_NAME ": No suitable DMA available.\n");11582 goto out_pci_disable_device;11583 }11584 11585 pci_set_drvdata(pdev, priv);11586 11587 err = pci_request_regions(pdev, DRV_NAME);11588 if (err)11589 goto out_pci_disable_device;11590 11591 /* We disable the RETRY_TIMEOUT register (0x41) to keep11592 * PCI Tx retries from interfering with C3 CPU state */11593 pci_read_config_dword(pdev, 0x40, &val);11594 if ((val & 0x0000ff00) != 0)11595 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);11596 11597 length = pci_resource_len(pdev, 0);11598 priv->hw_len = length;11599 11600 base = pci_ioremap_bar(pdev, 0);11601 if (!base) {11602 err = -ENODEV;11603 goto out_pci_release_regions;11604 }11605 11606 priv->hw_base = base;11607 IPW_DEBUG_INFO("pci_resource_len = 0x%08x\n", length);11608 IPW_DEBUG_INFO("pci_resource_base = %p\n", base);11609 11610 ipw_setup_deferred_work(priv);11611 11612 ipw_sw_reset(priv, 1);11613 11614 err = request_irq(pdev->irq, ipw_isr, IRQF_SHARED, DRV_NAME, priv);11615 if (err) {11616 IPW_ERROR("Error allocating IRQ %d\n", pdev->irq);11617 goto out_iounmap;11618 }11619 11620 SET_NETDEV_DEV(net_dev, &pdev->dev);11621 11622 mutex_lock(&priv->mutex);11623 11624 priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit;11625 priv->ieee->set_security = shim__set_security;11626 priv->ieee->is_queue_full = ipw_net_is_queue_full;11627 11628#ifdef CONFIG_IPW2200_QOS11629 priv->ieee->is_qos_active = ipw_is_qos_active;11630 priv->ieee->handle_probe_response = ipw_handle_beacon;11631 priv->ieee->handle_beacon = ipw_handle_probe_response;11632 priv->ieee->handle_assoc_response = ipw_handle_assoc_response;11633#endif /* CONFIG_IPW2200_QOS */11634 11635 priv->ieee->perfect_rssi = -20;11636 priv->ieee->worst_rssi = -85;11637 11638 net_dev->netdev_ops = &ipw_netdev_ops;11639 priv->wireless_data.spy_data = &priv->ieee->spy_data;11640 net_dev->wireless_data = &priv->wireless_data;11641 net_dev->wireless_handlers = &ipw_wx_handler_def;11642 net_dev->ethtool_ops = &ipw_ethtool_ops;11643 11644 net_dev->min_mtu = 68;11645 net_dev->max_mtu = LIBIPW_DATA_LEN;11646 11647 err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group);11648 if (err) {11649 IPW_ERROR("failed to create sysfs device attributes\n");11650 mutex_unlock(&priv->mutex);11651 goto out_release_irq;11652 }11653 11654 if (ipw_up(priv)) {11655 mutex_unlock(&priv->mutex);11656 err = -EIO;11657 goto out_remove_sysfs;11658 }11659 11660 mutex_unlock(&priv->mutex);11661 11662 err = ipw_wdev_init(net_dev);11663 if (err) {11664 IPW_ERROR("failed to register wireless device\n");11665 goto out_remove_sysfs;11666 }11667 11668 err = register_netdev(net_dev);11669 if (err) {11670 IPW_ERROR("failed to register network device\n");11671 goto out_unregister_wiphy;11672 }11673 11674#ifdef CONFIG_IPW2200_PROMISCUOUS11675 if (rtap_iface) {11676 err = ipw_prom_alloc(priv);11677 if (err) {11678 IPW_ERROR("Failed to register promiscuous network "11679 "device (error %d).\n", err);11680 unregister_netdev(priv->net_dev);11681 goto out_unregister_wiphy;11682 }11683 }11684#endif11685 11686 printk(KERN_INFO DRV_NAME ": Detected geography %s (%d 802.11bg "11687 "channels, %d 802.11a channels)\n",11688 priv->ieee->geo.name, priv->ieee->geo.bg_channels,11689 priv->ieee->geo.a_channels);11690 11691 return 0;11692 11693 out_unregister_wiphy:11694 wiphy_unregister(priv->ieee->wdev.wiphy);11695 kfree(priv->ieee->a_band.channels);11696 kfree(priv->ieee->bg_band.channels);11697 out_remove_sysfs:11698 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);11699 out_release_irq:11700 free_irq(pdev->irq, priv);11701 out_iounmap:11702 iounmap(priv->hw_base);11703 out_pci_release_regions:11704 pci_release_regions(pdev);11705 out_pci_disable_device:11706 pci_disable_device(pdev);11707 out_free_libipw:11708 free_libipw(priv->net_dev, 0);11709 out:11710 return err;11711}11712 11713static void ipw_pci_remove(struct pci_dev *pdev)11714{11715 struct ipw_priv *priv = pci_get_drvdata(pdev);11716 struct list_head *p, *q;11717 int i;11718 11719 if (!priv)11720 return;11721 11722 mutex_lock(&priv->mutex);11723 11724 priv->status |= STATUS_EXIT_PENDING;11725 ipw_down(priv);11726 sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);11727 11728 mutex_unlock(&priv->mutex);11729 11730 unregister_netdev(priv->net_dev);11731 11732 if (priv->rxq) {11733 ipw_rx_queue_free(priv, priv->rxq);11734 priv->rxq = NULL;11735 }11736 ipw_tx_queue_free(priv);11737 11738 if (priv->cmdlog) {11739 kfree(priv->cmdlog);11740 priv->cmdlog = NULL;11741 }11742 11743 /* make sure all works are inactive */11744 cancel_delayed_work_sync(&priv->adhoc_check);11745 cancel_work_sync(&priv->associate);11746 cancel_work_sync(&priv->disassociate);11747 cancel_work_sync(&priv->system_config);11748 cancel_work_sync(&priv->rx_replenish);11749 cancel_work_sync(&priv->adapter_restart);11750 cancel_delayed_work_sync(&priv->rf_kill);11751 cancel_work_sync(&priv->up);11752 cancel_work_sync(&priv->down);11753 cancel_delayed_work_sync(&priv->request_scan);11754 cancel_delayed_work_sync(&priv->request_direct_scan);11755 cancel_delayed_work_sync(&priv->request_passive_scan);11756 cancel_delayed_work_sync(&priv->scan_event);11757 cancel_delayed_work_sync(&priv->gather_stats);11758 cancel_work_sync(&priv->abort_scan);11759 cancel_work_sync(&priv->roam);11760 cancel_delayed_work_sync(&priv->scan_check);11761 cancel_work_sync(&priv->link_up);11762 cancel_work_sync(&priv->link_down);11763 cancel_delayed_work_sync(&priv->led_link_on);11764 cancel_delayed_work_sync(&priv->led_link_off);11765 cancel_delayed_work_sync(&priv->led_act_off);11766 cancel_work_sync(&priv->merge_networks);11767 11768 /* Free MAC hash list for ADHOC */11769 for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) {11770 list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) {11771 list_del(p);11772 kfree(list_entry(p, struct ipw_ibss_seq, list));11773 }11774 }11775 11776 kfree(priv->error);11777 priv->error = NULL;11778 11779#ifdef CONFIG_IPW2200_PROMISCUOUS11780 ipw_prom_free(priv);11781#endif11782 11783 free_irq(pdev->irq, priv);11784 iounmap(priv->hw_base);11785 pci_release_regions(pdev);11786 pci_disable_device(pdev);11787 /* wiphy_unregister needs to be here, before free_libipw */11788 wiphy_unregister(priv->ieee->wdev.wiphy);11789 kfree(priv->ieee->a_band.channels);11790 kfree(priv->ieee->bg_band.channels);11791 free_libipw(priv->net_dev, 0);11792 free_firmware();11793}11794 11795static int __maybe_unused ipw_pci_suspend(struct device *dev_d)11796{11797 struct ipw_priv *priv = dev_get_drvdata(dev_d);11798 struct net_device *dev = priv->net_dev;11799 11800 printk(KERN_INFO "%s: Going into suspend...\n", dev->name);11801 11802 /* Take down the device; powers it off, etc. */11803 ipw_down(priv);11804 11805 /* Remove the PRESENT state of the device */11806 netif_device_detach(dev);11807 11808 priv->suspend_at = ktime_get_boottime_seconds();11809 11810 return 0;11811}11812 11813static int __maybe_unused ipw_pci_resume(struct device *dev_d)11814{11815 struct pci_dev *pdev = to_pci_dev(dev_d);11816 struct ipw_priv *priv = pci_get_drvdata(pdev);11817 struct net_device *dev = priv->net_dev;11818 u32 val;11819 11820 printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name);11821 11822 /*11823 * Suspend/Resume resets the PCI configuration space, so we have to11824 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries11825 * from interfering with C3 CPU state. pci_restore_state won't help11826 * here since it only restores the first 64 bytes pci config header.11827 */11828 pci_read_config_dword(pdev, 0x40, &val);11829 if ((val & 0x0000ff00) != 0)11830 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);11831 11832 /* Set the device back into the PRESENT state; this will also wake11833 * the queue of needed */11834 netif_device_attach(dev);11835 11836 priv->suspend_time = ktime_get_boottime_seconds() - priv->suspend_at;11837 11838 /* Bring the device back up */11839 schedule_work(&priv->up);11840 11841 return 0;11842}11843 11844static void ipw_pci_shutdown(struct pci_dev *pdev)11845{11846 struct ipw_priv *priv = pci_get_drvdata(pdev);11847 11848 /* Take down the device; powers it off, etc. */11849 ipw_down(priv);11850 11851 pci_disable_device(pdev);11852}11853 11854static SIMPLE_DEV_PM_OPS(ipw_pci_pm_ops, ipw_pci_suspend, ipw_pci_resume);11855 11856/* driver initialization stuff */11857static struct pci_driver ipw_driver = {11858 .name = DRV_NAME,11859 .id_table = card_ids,11860 .probe = ipw_pci_probe,11861 .remove = ipw_pci_remove,11862 .driver.pm = &ipw_pci_pm_ops,11863 .shutdown = ipw_pci_shutdown,11864};11865 11866static int __init ipw_init(void)11867{11868 int ret;11869 11870 printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");11871 printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");11872 11873 ret = pci_register_driver(&ipw_driver);11874 if (ret) {11875 IPW_ERROR("Unable to initialize PCI module\n");11876 return ret;11877 }11878 11879 ret = driver_create_file(&ipw_driver.driver, &driver_attr_debug_level);11880 if (ret) {11881 IPW_ERROR("Unable to create driver sysfs file\n");11882 pci_unregister_driver(&ipw_driver);11883 return ret;11884 }11885 11886 return ret;11887}11888 11889static void __exit ipw_exit(void)11890{11891 driver_remove_file(&ipw_driver.driver, &driver_attr_debug_level);11892 pci_unregister_driver(&ipw_driver);11893}11894 11895module_param(disable, int, 0444);11896MODULE_PARM_DESC(disable, "manually disable the radio (default 0 [radio on])");11897 11898module_param(associate, int, 0444);11899MODULE_PARM_DESC(associate, "auto associate when scanning (default off)");11900 11901module_param(auto_create, int, 0444);11902MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");11903 11904module_param_named(led, led_support, int, 0444);11905MODULE_PARM_DESC(led, "enable led control on some systems (default 1 on)");11906 11907module_param(debug, int, 0444);11908MODULE_PARM_DESC(debug, "debug output mask");11909 11910module_param_named(channel, default_channel, int, 0444);11911MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])");11912 11913#ifdef CONFIG_IPW2200_PROMISCUOUS11914module_param(rtap_iface, int, 0444);11915MODULE_PARM_DESC(rtap_iface, "create the rtap interface (1 - create, default 0)");11916#endif11917 11918#ifdef CONFIG_IPW2200_QOS11919module_param(qos_enable, int, 0444);11920MODULE_PARM_DESC(qos_enable, "enable all QoS functionalities");11921 11922module_param(qos_burst_enable, int, 0444);11923MODULE_PARM_DESC(qos_burst_enable, "enable QoS burst mode");11924 11925module_param(qos_no_ack_mask, int, 0444);11926MODULE_PARM_DESC(qos_no_ack_mask, "mask Tx_Queue to no ack");11927 11928module_param(burst_duration_CCK, int, 0444);11929MODULE_PARM_DESC(burst_duration_CCK, "set CCK burst value");11930 11931module_param(burst_duration_OFDM, int, 0444);11932MODULE_PARM_DESC(burst_duration_OFDM, "set OFDM burst value");11933#endif /* CONFIG_IPW2200_QOS */11934 11935#ifdef CONFIG_IPW2200_MONITOR11936module_param_named(mode, network_mode, int, 0444);11937MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)");11938#else11939module_param_named(mode, network_mode, int, 0444);11940MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS)");11941#endif11942 11943module_param(bt_coexist, int, 0444);11944MODULE_PARM_DESC(bt_coexist, "enable bluetooth coexistence (default off)");11945 11946module_param(hwcrypto, int, 0444);11947MODULE_PARM_DESC(hwcrypto, "enable hardware crypto (default off)");11948 11949module_param(cmdlog, int, 0444);11950MODULE_PARM_DESC(cmdlog,11951 "allocate a ring buffer for logging firmware commands");11952 11953module_param(roaming, int, 0444);11954MODULE_PARM_DESC(roaming, "enable roaming support (default on)");11955 11956module_param(antenna, int, 0444);11957MODULE_PARM_DESC(antenna, "select antenna 1=Main, 3=Aux, default 0 [both], 2=slow_diversity (choose the one with lower background noise)");11958 11959module_exit(ipw_exit);11960module_init(ipw_init);11961