1 From a2c94c94994d49114faad8439d7e5c90cae47cae Mon Sep 17 00:00:00 2001
2 From: Greg Kroah-Hartman <gregkh@suse.de>
3 Date: Thu, 4 Dec 2008 20:01:41 -0800
4 Subject: Staging: add rtl8187se driver
7 From: Greg Kroah-Hartman <gregkh@suse.de>
9 This is a driver for the Ralink 8187 "SE" wireless PCI devices
10 in some netbook computers (MSI Wind, and others). It includes
11 its own copy of the ieee80211 stack, but it is compiled into
12 the driver to prevend duplicate symbol issues.
14 This version comes from Ralink with no authorship, but it is based
15 on an old version of the rtl8180 driver from Andrea Merello. It was
16 hacked up a bit to get it to build properly within the kernel tree and
17 to properly handle the merged wireless stack within the driver.
19 Cc: Andrea Merello <andreamrl@tiscali.it>
20 Cc: linux-wireless <linux-wireless@vger.kernel.org>
21 Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
24 drivers/staging/Kconfig | 2
25 drivers/staging/Makefile | 1
26 drivers/staging/rtl8187se/Kconfig | 5
27 drivers/staging/rtl8187se/Makefile | 55
28 drivers/staging/rtl8187se/dot11d.h | 101
29 drivers/staging/rtl8187se/ieee80211.h | 1755 +++
30 drivers/staging/rtl8187se/ieee80211/dot11d.c | 246
31 drivers/staging/rtl8187se/ieee80211/dot11d.h | 102
32 drivers/staging/rtl8187se/ieee80211/ieee80211.h | 1755 +++
33 drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c | 265
34 drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h | 86
35 drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c | 533 +
36 drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c | 1001 +
37 drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c | 394
38 drivers/staging/rtl8187se/ieee80211/ieee80211_module.c | 299
39 drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c | 1971 +++
40 drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c | 4029 +++++++
41 drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c | 602 +
42 drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c | 828 +
43 drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c | 884 +
44 drivers/staging/rtl8187se/ieee80211/internal.h | 115
45 drivers/staging/rtl8187se/ieee80211/rtl_crypto.h | 399
46 drivers/staging/rtl8187se/ieee80211_crypt.h | 86
47 drivers/staging/rtl8187se/r8180.h | 761 +
48 drivers/staging/rtl8187se/r8180_93cx6.c | 146
49 drivers/staging/rtl8187se/r8180_93cx6.h | 59
50 drivers/staging/rtl8187se/r8180_core.c | 6828 +++++++++++++
51 drivers/staging/rtl8187se/r8180_dm.c | 1725 +++
52 drivers/staging/rtl8187se/r8180_dm.h | 41
53 drivers/staging/rtl8187se/r8180_gct.c | 296
54 drivers/staging/rtl8187se/r8180_gct.h | 25
55 drivers/staging/rtl8187se/r8180_hw.h | 956 +
56 drivers/staging/rtl8187se/r8180_max2820.c | 240
57 drivers/staging/rtl8187se/r8180_max2820.h | 21
58 drivers/staging/rtl8187se/r8180_pm.c | 90
59 drivers/staging/rtl8187se/r8180_pm.h | 28
60 drivers/staging/rtl8187se/r8180_rtl8225.c | 933 +
61 drivers/staging/rtl8187se/r8180_rtl8225.h | 44
62 drivers/staging/rtl8187se/r8180_rtl8225z2.c | 1587 +++
63 drivers/staging/rtl8187se/r8180_rtl8255.c | 1838 +++
64 drivers/staging/rtl8187se/r8180_rtl8255.h | 19
65 drivers/staging/rtl8187se/r8180_sa2400.c | 233
66 drivers/staging/rtl8187se/r8180_sa2400.h | 26
67 drivers/staging/rtl8187se/r8180_wx.c | 1644 +++
68 drivers/staging/rtl8187se/r8180_wx.h | 21
69 drivers/staging/rtl8187se/r8185b_init.c | 3342 ++++++
70 46 files changed, 36417 insertions(+)
72 --- a/drivers/staging/Kconfig
73 +++ b/drivers/staging/Kconfig
74 @@ -51,4 +51,6 @@ source "drivers/staging/rt2860/Kconfig"
76 source "drivers/staging/benet/Kconfig"
78 +source "drivers/staging/rtl8187se/Kconfig"
81 --- a/drivers/staging/Makefile
82 +++ b/drivers/staging/Makefile
83 @@ -17,3 +17,4 @@ obj-$(CONFIG_AGNX) += agnx/
84 obj-$(CONFIG_OTUS) += otus/
85 obj-$(CONFIG_RT2860) += rt2860/
86 obj-$(CONFIG_BENET) += benet/
87 +obj-$(CONFIG_RTL8187SE) += rtl8187se/
89 +++ b/drivers/staging/rtl8187se/dot11d.h
91 +#ifndef __INC_DOT11D_H
92 +#define __INC_DOT11D_H
94 +#include "ieee80211.h"
96 +//#define ENABLE_DOT11D
98 +//#define DOT11D_MAX_CHNL_NUM 83
100 +typedef struct _CHNL_TXPOWER_TRIPLE {
103 + u8 MaxTxPowerInDbm;
104 +}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
106 +typedef enum _DOT11D_STATE {
107 + DOT11D_STATE_NONE = 0,
108 + DOT11D_STATE_LEARNED,
112 +typedef struct _RT_DOT11D_INFO {
113 + //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
115 + bool bEnabled; // dot11MultiDomainCapabilityEnabled
117 + u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
118 + u8 CountryIeBuf[MAX_IE_LEN];
119 + u8 CountryIeSrcAddr[6]; // Source AP of the country IE.
120 + u8 CountryIeWatchdog;
122 + u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
123 + //u8 ChnlListLen; // #Bytes valid in ChnlList[].
124 + //u8 ChnlList[DOT11D_MAX_CHNL_NUM];
125 + u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
127 + DOT11D_STATE State;
128 +}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
129 +#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
130 +#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
131 +#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
133 +#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
134 +#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
136 +#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
137 +#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
139 +#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
140 + (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
142 + (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
144 +#define CIE_WATCHDOG_TH 1
145 +#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
146 +#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
147 +#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
149 +#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
154 + struct ieee80211_device *dev
159 + struct ieee80211_device *dev
163 +Dot11d_UpdateCountryIe(
164 + struct ieee80211_device *dev,
171 +DOT11D_GetMaxTxPwrInDbm(
172 + struct ieee80211_device *dev,
177 +DOT11D_ScanComplete(
178 + struct ieee80211_device * dev
182 + struct ieee80211_device * dev,
187 + struct ieee80211_device * dev,
191 +#endif // #ifndef __INC_DOT11D_H
193 +++ b/drivers/staging/rtl8187se/ieee80211_crypt.h
196 + * Original code based on Host AP (software wireless LAN access point) driver
197 + * for Intersil Prism2/2.5/3.
199 + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
200 + * <jkmaline@cc.hut.fi>
201 + * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
203 + * Adaption to a generic IEEE 802.11 stack by James Ketrenos
204 + * <jketreno@linux.intel.com>
206 + * Copyright (c) 2004, Intel Corporation
208 + * This program is free software; you can redistribute it and/or modify
209 + * it under the terms of the GNU General Public License version 2 as
210 + * published by the Free Software Foundation. See README and COPYING for
215 + * This file defines the interface to the ieee80211 crypto module.
217 +#ifndef IEEE80211_CRYPT_H
218 +#define IEEE80211_CRYPT_H
220 +#include <linux/skbuff.h>
222 +struct ieee80211_crypto_ops {
225 + /* init new crypto context (e.g., allocate private data space,
226 + * select IV, etc.); returns NULL on failure or pointer to allocated
227 + * private data on success */
228 + void * (*init)(int keyidx);
230 + /* deinitialize crypto context and free allocated private data */
231 + void (*deinit)(void *priv);
233 + /* encrypt/decrypt return < 0 on error or >= 0 on success. The return
234 + * value from decrypt_mpdu is passed as the keyidx value for
235 + * decrypt_msdu. skb must have enough head and tail room for the
236 + * encryption; if not, error will be returned; these functions are
237 + * called for all MPDUs (i.e., fragments).
239 + int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
240 + int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
242 + /* These functions are called for full MSDUs, i.e. full frames.
243 + * These can be NULL if full MSDU operations are not needed. */
244 + int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
245 + int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
248 + int (*set_key)(void *key, int len, u8 *seq, void *priv);
249 + int (*get_key)(void *key, int len, u8 *seq, void *priv);
251 + /* procfs handler for printing out key information and possible
253 + char * (*print_stats)(char *p, void *priv);
255 + /* maximum number of bytes added by encryption; encrypt buf is
256 + * allocated with extra_prefix_len bytes, copy of in_buf, and
257 + * extra_postfix_len; encrypt need not use all this space, but
258 + * the result must start at the beginning of the buffer and correct
259 + * length must be returned */
260 + int extra_prefix_len, extra_postfix_len;
262 + struct module *owner;
265 +struct ieee80211_crypt_data {
266 + struct list_head list; /* delayed deletion list */
267 + struct ieee80211_crypto_ops *ops;
272 +int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
273 +int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
274 +struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name);
275 +void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
276 +void ieee80211_crypt_deinit_handler(unsigned long);
277 +void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
278 + struct ieee80211_crypt_data **crypt);
282 +++ b/drivers/staging/rtl8187se/ieee80211/dot11d.c
284 +#ifdef ENABLE_DOT11D
285 +//-----------------------------------------------------------------------------
290 +// Implement 802.11d.
292 +//-----------------------------------------------------------------------------
297 +Dot11d_Init(struct ieee80211_device *ieee)
299 + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
301 + pDot11dInfo->bEnabled = 0;
303 + pDot11dInfo->State = DOT11D_STATE_NONE;
304 + pDot11dInfo->CountryIeLen = 0;
305 + memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
306 + memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
307 + RESET_CIE_WATCHDOG(ieee);
309 + printk("Dot11d_Init()\n");
314 +// Reset to the state as we are just entering a regulatory domain.
317 +Dot11d_Reset(struct ieee80211_device *ieee)
320 + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
322 + // Clear old channel map
323 + memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
324 + memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
325 + // Set new channel map
326 + for (i=1; i<=11; i++) {
327 + (pDot11dInfo->channel_map)[i] = 1;
329 + for (i=12; i<=14; i++) {
330 + (pDot11dInfo->channel_map)[i] = 2;
333 + pDot11dInfo->State = DOT11D_STATE_NONE;
334 + pDot11dInfo->CountryIeLen = 0;
335 + RESET_CIE_WATCHDOG(ieee);
337 + //printk("Dot11d_Reset()\n");
342 +// Update country IE from Beacon or Probe Resopnse
343 +// and configure PHY for operation in the regulatory domain.
346 +// Configure Tx power.
349 +// 1. IS_DOT11D_ENABLE() is TRUE.
350 +// 2. Input IE is an valid one.
353 +Dot11d_UpdateCountryIe(
354 + struct ieee80211_device *dev,
360 + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
361 + u8 i, j, NumTriples, MaxChnlNum;
362 + PCHNL_TXPOWER_TRIPLE pTriple;
364 + if((CoutryIeLen - 3)%3 != 0)
366 + printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
371 + memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
372 + memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
374 + NumTriples = (CoutryIeLen - 3) / 3; // skip 3-byte country string.
375 + pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3);
376 + for(i = 0; i < NumTriples; i++)
378 + if(MaxChnlNum >= pTriple->FirstChnl)
379 + { // It is not in a monotonically increasing order, so stop processing.
380 + printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
384 + if(MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + pTriple->NumChnls))
385 + { // It is not a valid set of channel id, so stop processing.
386 + printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
391 + for(j = 0 ; j < pTriple->NumChnls; j++)
393 + pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1;
394 + pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = pTriple->MaxTxPowerInDbm;
395 + MaxChnlNum = pTriple->FirstChnl + j;
398 + pTriple = (PCHNL_TXPOWER_TRIPLE)((u8*)pTriple + 3);
401 + //printk("Dot11d_UpdateCountryIe(): Channel List:\n");
402 + printk("Channel List:");
403 + for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
404 + if(pDot11dInfo->channel_map[i] > 0)
409 + UPDATE_CIE_SRC(dev, pTaddr);
411 + pDot11dInfo->CountryIeLen = CoutryIeLen;
412 + memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe,CoutryIeLen);
413 + pDot11dInfo->State = DOT11D_STATE_LEARNED;
416 +void dump_chnl_map(u8 * channel_map)
419 + printk("Channel List:");
420 + for(i=1; i<= MAX_CHANNEL_NUMBER; i++)
421 + if(channel_map[i] > 0)
422 + printk(" %d(%d)", i, channel_map[i]);
427 +DOT11D_GetMaxTxPwrInDbm(
428 + struct ieee80211_device *dev,
432 + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
433 + u8 MaxTxPwrInDbm = 255;
435 + if(MAX_CHANNEL_NUMBER < Channel)
437 + printk("DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
438 + return MaxTxPwrInDbm;
440 + if(pDot11dInfo->channel_map[Channel])
442 + MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel];
445 + return MaxTxPwrInDbm;
450 +DOT11D_ScanComplete(
451 + struct ieee80211_device * dev
454 + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
456 + switch(pDot11dInfo->State)
458 + case DOT11D_STATE_LEARNED:
459 + pDot11dInfo->State = DOT11D_STATE_DONE;
462 + case DOT11D_STATE_DONE:
463 + if( GET_CIE_WATCHDOG(dev) == 0 )
464 + { // Reset country IE if previous one is gone.
468 + case DOT11D_STATE_NONE:
474 + struct ieee80211_device * dev,
478 + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
480 + if(MAX_CHANNEL_NUMBER < channel)
482 + printk("IsLegalChannel(): Invalid Channel\n");
485 + if(pDot11dInfo->channel_map[channel] > 0)
491 + struct ieee80211_device * dev,
495 + PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
496 + u8 default_chn = 0;
499 + for (i=1; i<= MAX_CHANNEL_NUMBER; i++)
501 + if(pDot11dInfo->channel_map[i] > 0)
508 + if(MAX_CHANNEL_NUMBER < channel)
510 + printk("IsLegalChannel(): Invalid Channel\n");
511 + return default_chn;
514 + if(pDot11dInfo->channel_map[channel] > 0)
517 + return default_chn;
521 +EXPORT_SYMBOL(Dot11d_Init);
522 +EXPORT_SYMBOL(Dot11d_Reset);
523 +EXPORT_SYMBOL(Dot11d_UpdateCountryIe);
524 +EXPORT_SYMBOL(DOT11D_GetMaxTxPwrInDbm);
525 +EXPORT_SYMBOL(DOT11D_ScanComplete);
526 +EXPORT_SYMBOL(IsLegalChannel);
527 +EXPORT_SYMBOL(ToLegalChannel);
531 +++ b/drivers/staging/rtl8187se/ieee80211/dot11d.h
533 +#ifndef __INC_DOT11D_H
534 +#define __INC_DOT11D_H
536 +#include "ieee80211.h"
538 +//#define ENABLE_DOT11D
540 +//#define DOT11D_MAX_CHNL_NUM 83
542 +typedef struct _CHNL_TXPOWER_TRIPLE {
545 + u8 MaxTxPowerInDbm;
546 +}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
548 +typedef enum _DOT11D_STATE {
549 + DOT11D_STATE_NONE = 0,
550 + DOT11D_STATE_LEARNED,
554 +typedef struct _RT_DOT11D_INFO {
555 + //DECLARE_RT_OBJECT(RT_DOT11D_INFO);
557 + bool bEnabled; // dot11MultiDomainCapabilityEnabled
559 + u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element.
560 + u8 CountryIeBuf[MAX_IE_LEN];
561 + u8 CountryIeSrcAddr[6]; // Source AP of the country IE.
562 + u8 CountryIeWatchdog;
564 + u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan)
565 + //u8 ChnlListLen; // #Bytes valid in ChnlList[].
566 + //u8 ChnlList[DOT11D_MAX_CHNL_NUM];
567 + u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
569 + DOT11D_STATE State;
570 +}RT_DOT11D_INFO, *PRT_DOT11D_INFO;
571 +#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
572 +#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
573 +#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
575 +#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
576 +#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
578 +#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
579 +#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
581 +#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
582 + (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
584 + (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
586 +#define CIE_WATCHDOG_TH 1
587 +#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
588 +#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
589 +#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
591 +#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
596 + struct ieee80211_device *dev
601 + struct ieee80211_device *dev
605 +Dot11d_UpdateCountryIe(
606 + struct ieee80211_device *dev,
613 +DOT11D_GetMaxTxPwrInDbm(
614 + struct ieee80211_device *dev,
619 +DOT11D_ScanComplete(
620 + struct ieee80211_device * dev
624 + struct ieee80211_device * dev,
629 + struct ieee80211_device * dev,
633 +void dump_chnl_map(u8 * channel_map);
634 +#endif // #ifndef __INC_DOT11D_H
636 +++ b/drivers/staging/rtl8187se/ieee80211.h
639 + * Merged with mainline ieee80211.h in Aug 2004. Original ieee802_11
640 + * remains copyright by the original authors
642 + * Portions of the merged code are based on Host AP (software wireless
643 + * LAN access point) driver for Intersil Prism2/2.5/3.
645 + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
646 + * <jkmaline@cc.hut.fi>
647 + * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
649 + * Adaption to a generic IEEE 802.11 stack by James Ketrenos
650 + * <jketreno@linux.intel.com>
651 + * Copyright (c) 2004, Intel Corporation
653 + * Modified for Realtek's wi-fi cards by Andrea Merello
654 + * <andreamrl@tiscali.it>
656 + * This program is free software; you can redistribute it and/or modify
657 + * it under the terms of the GNU General Public License version 2 as
658 + * published by the Free Software Foundation. See README and COPYING for
663 +#include <linux/if_ether.h> /* ETH_ALEN */
664 +#include <linux/kernel.h> /* ARRAY_SIZE */
665 +#include <linux/version.h>
666 +#include <linux/jiffies.h>
667 +#include <linux/timer.h>
668 +#include <linux/sched.h>
670 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13))
671 +#include <linux/wireless.h>
687 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
689 +typedef enum{false = 0, true} bool;
693 +#define KEY_TYPE_NA 0x0
694 +#define KEY_TYPE_WEP40 0x1
695 +#define KEY_TYPE_TKIP 0x2
696 +#define KEY_TYPE_CCMP 0x4
697 +#define KEY_TYPE_WEP104 0x5
701 +#define aSifsTime 10
703 +#define MGMT_QUEUE_NUM 5
706 +#define IEEE_CMD_SET_WPA_PARAM 1
707 +#define IEEE_CMD_SET_WPA_IE 2
708 +#define IEEE_CMD_SET_ENCRYPTION 3
709 +#define IEEE_CMD_MLME 4
711 +#define IEEE_PARAM_WPA_ENABLED 1
712 +#define IEEE_PARAM_TKIP_COUNTERMEASURES 2
713 +#define IEEE_PARAM_DROP_UNENCRYPTED 3
714 +#define IEEE_PARAM_PRIVACY_INVOKED 4
715 +#define IEEE_PARAM_AUTH_ALGS 5
716 +#define IEEE_PARAM_IEEE_802_1X 6
717 +//It should consistent with the driver_XXX.c
719 +#define IEEE_PARAM_WPAX_SELECT 7
720 +//Added for notify the encryption type selection
722 +#define IEEE_PROTO_WPA 1
723 +#define IEEE_PROTO_RSN 2
724 +//Added for notify the encryption type selection
726 +#define IEEE_WPAX_USEGROUP 0
727 +#define IEEE_WPAX_WEP40 1
728 +#define IEEE_WPAX_TKIP 2
729 +#define IEEE_WPAX_WRAP 3
730 +#define IEEE_WPAX_CCMP 4
731 +#define IEEE_WPAX_WEP104 5
733 +#define IEEE_KEY_MGMT_IEEE8021X 1
734 +#define IEEE_KEY_MGMT_PSK 2
738 +#define IEEE_MLME_STA_DEAUTH 1
739 +#define IEEE_MLME_STA_DISASSOC 2
742 +#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2
743 +#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3
744 +#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4
745 +#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5
746 +#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6
747 +#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7
750 +#define IEEE_CRYPT_ALG_NAME_LEN 16
752 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10))
753 +#define ieee80211_wx_get_scan ieee80211_wx_get_scan_rtl
754 +#define ieee80211_wx_set_encode ieee80211_wx_set_encode_rtl
755 +#define ieee80211_wx_get_encode ieee80211_wx_get_encode_rtl
756 +////////////////////////////////
757 +// added for kernel conflict under FC5
758 +#define ieee80211_wx_get_name ieee80211_wx_get_name_rtl
759 +#define free_ieee80211 free_ieee80211_rtl
760 +#define alloc_ieee80211 alloc_ieee80211_rtl
761 +///////////////////////////////
763 +//error in ubuntu2.6.22,so add these
764 +#define ieee80211_wake_queue ieee80211_wake_queue_rtl
765 +#define ieee80211_stop_queue ieee80211_stop_queue_rtl
767 +#define ieee80211_rx ieee80211_rx_rtl
769 +#define ieee80211_register_crypto_ops ieee80211_register_crypto_ops_rtl
770 +#define ieee80211_unregister_crypto_ops ieee80211_unregister_crypto_ops_rtl
771 +#define ieee80211_get_crypto_ops ieee80211_get_crypto_ops_rtl
772 +#define ieee80211_crypt_deinit_entries ieee80211_crypt_deinit_entries_rtl
773 +#define ieee80211_crypt_deinit_handler ieee80211_crypt_deinit_handler_rtl
774 +#define ieee80211_crypt_delayed_deinit ieee80211_crypt_delayed_deinit_rtl
776 +#define ieee80211_txb_free ieee80211_txb_free_rtl
777 +#define ieee80211_wx_get_essid ieee80211_wx_get_essid_rtl
778 +#define ieee80211_wx_set_essid ieee80211_wx_set_essid_rtl
779 +#define ieee80211_wx_set_rate ieee80211_wx_set_rate_rtl
780 +#define ieee80211_wx_get_rate ieee80211_wx_get_rate_rtl
781 +#define ieee80211_wx_set_wap ieee80211_wx_set_wap_rtl
782 +#define ieee80211_wx_get_wap ieee80211_wx_get_wap_rtl
783 +#define ieee80211_wx_set_mode ieee80211_wx_set_mode_rtl
784 +#define ieee80211_wx_get_mode ieee80211_wx_get_mode_rtl
785 +#define ieee80211_wx_set_scan ieee80211_wx_set_scan_rtl
786 +#define ieee80211_wx_get_freq ieee80211_wx_get_freq_rtl
787 +#define ieee80211_wx_set_freq ieee80211_wx_set_freq_rtl
788 +#define ieee80211_wx_set_rawtx ieee80211_wx_set_rawtx_rtl
789 +#define ieee80211_wx_set_power ieee80211_wx_set_power_rtl
790 +#define ieee80211_wx_get_power ieee80211_wx_get_power_rtl
791 +#define ieee80211_wlan_frequencies ieee80211_wlan_frequencies_rtl
792 +#define ieee80211_softmac_stop_protocol ieee80211_softmac_stop_protocol_rtl
793 +#define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rtl
794 +#define ieee80211_start_protocol ieee80211_start_protocol_rtl
795 +#define ieee80211_stop_protocol ieee80211_stop_protocol_rtl
796 +#define ieee80211_rx_mgt ieee80211_rx_mgt_rtl
798 +#define ieee80211_wx_set_auth ieee80211_wx_set_auth_rtl
800 +#define notify_wx_assoc_event notify_wx_assoc_event_rtl
801 +#define ieee80211_stop_send_beacons ieee80211_stop_send_beacons_rtl
802 +#define ieee80211_disassociate ieee80211_disassociate_rtl
803 +#define ieee80211_start_scan ieee80211_start_scan_rtl
805 +typedef struct ieee_param {
807 + u8 sta_addr[ETH_ALEN];
823 + u8 alg[IEEE_CRYPT_ALG_NAME_LEN];
827 + u8 seq[8]; /* sequence counter (set: RX, get: TX) */
836 +#if WIRELESS_EXT < 17
837 +#define IW_QUAL_QUAL_INVALID 0x10
838 +#define IW_QUAL_LEVEL_INVALID 0x20
839 +#define IW_QUAL_NOISE_INVALID 0x40
840 +#define IW_QUAL_QUAL_UPDATED 0x1
841 +#define IW_QUAL_LEVEL_UPDATED 0x2
842 +#define IW_QUAL_NOISE_UPDATED 0x4
845 +// linux under 2.6.9 release may not support it, so modify it for common use
846 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
847 +#define MSECS(t) (1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ)
848 +static inline unsigned long msleep_interruptible_rtl(unsigned int msecs)
850 + unsigned long timeout = MSECS(msecs) + 1;
853 + set_current_state(TASK_UNINTERRUPTIBLE);
854 + timeout = schedule_timeout(timeout);
859 +#define MSECS(t) msecs_to_jiffies(t)
860 +#define msleep_interruptible_rtl msleep_interruptible
863 +#define IEEE80211_DATA_LEN 2304
864 +/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
867 + The figure in section 7.1.2 suggests a body size of up to 2312
868 + bytes is allowed, which is a bit confusing, I suspect this
869 + represents the 2304 bytes of real data, plus a possible 8 bytes of
870 + WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
873 +#define IEEE80211_HLEN 30
874 +#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
876 +/* this is stolen and modified from the madwifi driver*/
877 +#define IEEE80211_FC0_TYPE_MASK 0x0c
878 +#define IEEE80211_FC0_TYPE_DATA 0x08
879 +#define IEEE80211_FC0_SUBTYPE_MASK 0xB0
880 +#define IEEE80211_FC0_SUBTYPE_QOS 0x80
882 +#define IEEE80211_QOS_HAS_SEQ(fc) \
883 + (((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \
884 + (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
886 +/* this is stolen from ipw2200 driver */
887 +#define IEEE_IBSS_MAC_HASH_SIZE 31
888 +struct ieee_ibss_seq {
892 + unsigned long packet_time[17];
893 + struct list_head list;
896 +struct ieee80211_hdr {
899 + u8 addr1[ETH_ALEN];
900 + u8 addr2[ETH_ALEN];
901 + u8 addr3[ETH_ALEN];
903 + u8 addr4[ETH_ALEN];
904 +} __attribute__ ((packed));
906 +struct ieee80211_hdr_QOS {
909 + u8 addr1[ETH_ALEN];
910 + u8 addr2[ETH_ALEN];
911 + u8 addr3[ETH_ALEN];
913 + u8 addr4[ETH_ALEN];
915 +} __attribute__ ((packed));
917 +struct ieee80211_hdr_3addr {
920 + u8 addr1[ETH_ALEN];
921 + u8 addr2[ETH_ALEN];
922 + u8 addr3[ETH_ALEN];
924 +} __attribute__ ((packed));
926 +struct ieee80211_hdr_3addr_QOS {
929 + u8 addr1[ETH_ALEN];
930 + u8 addr2[ETH_ALEN];
931 + u8 addr3[ETH_ALEN];
934 +} __attribute__ ((packed));
941 + EAPOL_ENCAP_ASF_ALERT
944 +static const char *eap_types[] = {
945 + [EAP_PACKET] = "EAP-Packet",
946 + [EAPOL_START] = "EAPOL-Start",
947 + [EAPOL_LOGOFF] = "EAPOL-Logoff",
948 + [EAPOL_KEY] = "EAPOL-Key",
949 + [EAPOL_ENCAP_ASF_ALERT] = "EAPOL-Encap-ASF-Alert"
952 +static inline const char *eap_get_type(int type)
954 + return (type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
963 +} __attribute__ ((packed));
965 +#define IEEE80211_3ADDR_LEN 24
966 +#define IEEE80211_4ADDR_LEN 30
967 +#define IEEE80211_FCS_LEN 4
969 +#define MIN_FRAG_THRESHOLD 256U
970 +#define MAX_FRAG_THRESHOLD 2346U
972 +/* Frame control field constants */
973 +#define IEEE80211_FCTL_VERS 0x0002
974 +#define IEEE80211_FCTL_FTYPE 0x000c
975 +#define IEEE80211_FCTL_STYPE 0x00f0
976 +#define IEEE80211_FCTL_TODS 0x0100
977 +#define IEEE80211_FCTL_FROMDS 0x0200
978 +#define IEEE80211_FCTL_DSTODS 0x0300 //added by david
979 +#define IEEE80211_FCTL_MOREFRAGS 0x0400
980 +#define IEEE80211_FCTL_RETRY 0x0800
981 +#define IEEE80211_FCTL_PM 0x1000
982 +#define IEEE80211_FCTL_MOREDATA 0x2000
983 +#define IEEE80211_FCTL_WEP 0x4000
984 +#define IEEE80211_FCTL_ORDER 0x8000
986 +#define IEEE80211_FTYPE_MGMT 0x0000
987 +#define IEEE80211_FTYPE_CTL 0x0004
988 +#define IEEE80211_FTYPE_DATA 0x0008
991 +#define IEEE80211_STYPE_ASSOC_REQ 0x0000
992 +#define IEEE80211_STYPE_ASSOC_RESP 0x0010
993 +#define IEEE80211_STYPE_REASSOC_REQ 0x0020
994 +#define IEEE80211_STYPE_REASSOC_RESP 0x0030
995 +#define IEEE80211_STYPE_PROBE_REQ 0x0040
996 +#define IEEE80211_STYPE_PROBE_RESP 0x0050
997 +#define IEEE80211_STYPE_BEACON 0x0080
998 +#define IEEE80211_STYPE_ATIM 0x0090
999 +#define IEEE80211_STYPE_DISASSOC 0x00A0
1000 +#define IEEE80211_STYPE_AUTH 0x00B0
1001 +#define IEEE80211_STYPE_DEAUTH 0x00C0
1002 +#define IEEE80211_STYPE_MANAGE_ACT 0x00D0
1005 +#define IEEE80211_STYPE_PSPOLL 0x00A0
1006 +#define IEEE80211_STYPE_RTS 0x00B0
1007 +#define IEEE80211_STYPE_CTS 0x00C0
1008 +#define IEEE80211_STYPE_ACK 0x00D0
1009 +#define IEEE80211_STYPE_CFEND 0x00E0
1010 +#define IEEE80211_STYPE_CFENDACK 0x00F0
1013 +#define IEEE80211_STYPE_DATA 0x0000
1014 +#define IEEE80211_STYPE_DATA_CFACK 0x0010
1015 +#define IEEE80211_STYPE_DATA_CFPOLL 0x0020
1016 +#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030
1017 +#define IEEE80211_STYPE_NULLFUNC 0x0040
1018 +#define IEEE80211_STYPE_CFACK 0x0050
1019 +#define IEEE80211_STYPE_CFPOLL 0x0060
1020 +#define IEEE80211_STYPE_CFACKPOLL 0x0070
1021 +#define IEEE80211_STYPE_QOS_DATA 0x0080 //added for WMM 2006/8/2
1022 +#define IEEE80211_STYPE_QOS_NULL 0x00C0
1025 +#define IEEE80211_SCTL_FRAG 0x000F
1026 +#define IEEE80211_SCTL_SEQ 0xFFF0
1031 +#ifdef CONFIG_IEEE80211_DEBUG
1032 +extern u32 ieee80211_debug_level;
1033 +#define IEEE80211_DEBUG(level, fmt, args...) \
1034 +do { if (ieee80211_debug_level & (level)) \
1035 + printk(KERN_DEBUG "ieee80211: %c %s " fmt, \
1036 + in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
1038 +#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
1039 +#endif /* CONFIG_IEEE80211_DEBUG */
1042 + * To use the debug system;
1044 + * If you are defining a new debug classification, simply add it to the #define
1045 + * list here in the form of:
1047 + * #define IEEE80211_DL_xxxx VALUE
1049 + * shifting value to the left one bit from the previous entry. xxxx should be
1050 + * the name of the classification (for example, WEP)
1052 + * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your
1053 + * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want
1054 + * to send output to that classification.
1056 + * To add your debug level to the list of levels seen when you perform
1058 + * % cat /proc/net/ipw/debug_level
1060 + * you simply need to add your entry to the ipw_debug_levels array.
1062 + * If you do not see debug_level in /proc/net/ipw then you do not have
1063 + * CONFIG_IEEE80211_DEBUG defined in your kernel configuration
1067 +#define IEEE80211_DL_INFO (1<<0)
1068 +#define IEEE80211_DL_WX (1<<1)
1069 +#define IEEE80211_DL_SCAN (1<<2)
1070 +#define IEEE80211_DL_STATE (1<<3)
1071 +#define IEEE80211_DL_MGMT (1<<4)
1072 +#define IEEE80211_DL_FRAG (1<<5)
1073 +#define IEEE80211_DL_EAP (1<<6)
1074 +#define IEEE80211_DL_DROP (1<<7)
1076 +#define IEEE80211_DL_TX (1<<8)
1077 +#define IEEE80211_DL_RX (1<<9)
1079 +#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
1080 +#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
1081 +#define IEEE80211_DEBUG_INFO(f, a...) IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a)
1083 +#define IEEE80211_DEBUG_WX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a)
1084 +#define IEEE80211_DEBUG_SCAN(f, a...) IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a)
1085 +//#define IEEE_DEBUG_SCAN IEEE80211_WARNING
1086 +#define IEEE80211_DEBUG_STATE(f, a...) IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a)
1087 +#define IEEE80211_DEBUG_MGMT(f, a...) IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a)
1088 +#define IEEE80211_DEBUG_FRAG(f, a...) IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a)
1089 +#define IEEE80211_DEBUG_EAP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a)
1090 +#define IEEE80211_DEBUG_DROP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
1091 +#define IEEE80211_DEBUG_TX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
1092 +#define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
1093 +#include <linux/netdevice.h>
1094 +#include <linux/wireless.h>
1095 +#include <linux/if_arp.h> /* ARPHRD_ETHER */
1097 +#ifndef WIRELESS_SPY
1098 +#define WIRELESS_SPY // enable iwspy support
1100 +#include <net/iw_handler.h> // new driver API
1103 +#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
1104 +#endif /* ETH_P_PAE */
1106 +#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
1108 +#ifndef ETH_P_80211_RAW
1109 +#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
1112 +/* IEEE 802.11 defines */
1114 +#define P80211_OUI_LEN 3
1116 +struct ieee80211_snap_hdr {
1118 + u8 dsap; /* always 0xAA */
1119 + u8 ssap; /* always 0xAA */
1120 + u8 ctrl; /* always 0x03 */
1121 + u8 oui[P80211_OUI_LEN]; /* organizational universal id */
1123 +} __attribute__ ((packed));
1125 +#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
1127 +#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
1128 +#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
1130 +#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
1131 +#define WLAN_GET_SEQ_SEQ(seq) ((seq) & IEEE80211_SCTL_SEQ)
1133 +/* Authentication algorithms */
1134 +#define WLAN_AUTH_OPEN 0
1135 +#define WLAN_AUTH_SHARED_KEY 1
1137 +#define WLAN_AUTH_CHALLENGE_LEN 128
1139 +#define WLAN_CAPABILITY_BSS (1<<0)
1140 +#define WLAN_CAPABILITY_IBSS (1<<1)
1141 +#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
1142 +#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
1143 +#define WLAN_CAPABILITY_PRIVACY (1<<4)
1144 +#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
1145 +#define WLAN_CAPABILITY_PBCC (1<<6)
1146 +#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
1147 +#define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
1150 +#define WLAN_STATUS_SUCCESS 0
1151 +#define WLAN_STATUS_UNSPECIFIED_FAILURE 1
1152 +#define WLAN_STATUS_CAPS_UNSUPPORTED 10
1153 +#define WLAN_STATUS_REASSOC_NO_ASSOC 11
1154 +#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12
1155 +#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13
1156 +#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14
1157 +#define WLAN_STATUS_CHALLENGE_FAIL 15
1158 +#define WLAN_STATUS_AUTH_TIMEOUT 16
1159 +#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17
1160 +#define WLAN_STATUS_ASSOC_DENIED_RATES 18
1162 +#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19
1163 +#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20
1164 +#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21
1167 +#define WLAN_REASON_UNSPECIFIED 1
1168 +#define WLAN_REASON_PREV_AUTH_NOT_VALID 2
1169 +#define WLAN_REASON_DEAUTH_LEAVING 3
1170 +#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4
1171 +#define WLAN_REASON_DISASSOC_AP_BUSY 5
1172 +#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6
1173 +#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7
1174 +#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8
1175 +#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9
1178 +/* Information Element IDs */
1179 +#define WLAN_EID_SSID 0
1180 +#define WLAN_EID_SUPP_RATES 1
1181 +#define WLAN_EID_FH_PARAMS 2
1182 +#define WLAN_EID_DS_PARAMS 3
1183 +#define WLAN_EID_CF_PARAMS 4
1184 +#define WLAN_EID_TIM 5
1185 +#define WLAN_EID_IBSS_PARAMS 6
1186 +#define WLAN_EID_CHALLENGE 16
1187 +#define WLAN_EID_RSN 48
1188 +#define WLAN_EID_GENERIC 221
1190 +#define IEEE80211_MGMT_HDR_LEN 24
1191 +#define IEEE80211_DATA_HDR3_LEN 24
1192 +#define IEEE80211_DATA_HDR4_LEN 30
1195 +#define IEEE80211_STATMASK_SIGNAL (1<<0)
1196 +#define IEEE80211_STATMASK_RSSI (1<<1)
1197 +#define IEEE80211_STATMASK_NOISE (1<<2)
1198 +#define IEEE80211_STATMASK_RATE (1<<3)
1199 +#define IEEE80211_STATMASK_WEMASK 0x7
1202 +#define IEEE80211_CCK_MODULATION (1<<0)
1203 +#define IEEE80211_OFDM_MODULATION (1<<1)
1205 +#define IEEE80211_24GHZ_BAND (1<<0)
1206 +#define IEEE80211_52GHZ_BAND (1<<1)
1208 +#define IEEE80211_CCK_RATE_LEN 4
1209 +#define IEEE80211_CCK_RATE_1MB 0x02
1210 +#define IEEE80211_CCK_RATE_2MB 0x04
1211 +#define IEEE80211_CCK_RATE_5MB 0x0B
1212 +#define IEEE80211_CCK_RATE_11MB 0x16
1213 +#define IEEE80211_OFDM_RATE_LEN 8
1214 +#define IEEE80211_OFDM_RATE_6MB 0x0C
1215 +#define IEEE80211_OFDM_RATE_9MB 0x12
1216 +#define IEEE80211_OFDM_RATE_12MB 0x18
1217 +#define IEEE80211_OFDM_RATE_18MB 0x24
1218 +#define IEEE80211_OFDM_RATE_24MB 0x30
1219 +#define IEEE80211_OFDM_RATE_36MB 0x48
1220 +#define IEEE80211_OFDM_RATE_48MB 0x60
1221 +#define IEEE80211_OFDM_RATE_54MB 0x6C
1222 +#define IEEE80211_BASIC_RATE_MASK 0x80
1224 +#define IEEE80211_CCK_RATE_1MB_MASK (1<<0)
1225 +#define IEEE80211_CCK_RATE_2MB_MASK (1<<1)
1226 +#define IEEE80211_CCK_RATE_5MB_MASK (1<<2)
1227 +#define IEEE80211_CCK_RATE_11MB_MASK (1<<3)
1228 +#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4)
1229 +#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5)
1230 +#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6)
1231 +#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7)
1232 +#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8)
1233 +#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9)
1234 +#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10)
1235 +#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11)
1237 +#define IEEE80211_CCK_RATES_MASK 0x0000000F
1238 +#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \
1239 + IEEE80211_CCK_RATE_2MB_MASK)
1240 +#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \
1241 + IEEE80211_CCK_RATE_5MB_MASK | \
1242 + IEEE80211_CCK_RATE_11MB_MASK)
1244 +#define IEEE80211_OFDM_RATES_MASK 0x00000FF0
1245 +#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \
1246 + IEEE80211_OFDM_RATE_12MB_MASK | \
1247 + IEEE80211_OFDM_RATE_24MB_MASK)
1248 +#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \
1249 + IEEE80211_OFDM_RATE_9MB_MASK | \
1250 + IEEE80211_OFDM_RATE_18MB_MASK | \
1251 + IEEE80211_OFDM_RATE_36MB_MASK | \
1252 + IEEE80211_OFDM_RATE_48MB_MASK | \
1253 + IEEE80211_OFDM_RATE_54MB_MASK)
1254 +#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
1255 + IEEE80211_CCK_DEFAULT_RATES_MASK)
1257 +#define IEEE80211_NUM_OFDM_RATES 8
1258 +#define IEEE80211_NUM_CCK_RATES 4
1259 +#define IEEE80211_OFDM_SHIFT_MASK_A 4
1264 +/* NOTE: This data is for statistical purposes; not all hardware provides this
1265 + * information for frames received. Not setting these will not cause
1266 + * any adverse affects. */
1267 +struct ieee80211_rx_stats {
1269 + u8 signalstrength;
1273 + u16 rate; /* in 100 kbps */
1274 + u8 received_channel;
1282 +/* IEEE 802.11 requires that STA supports concurrent reception of at least
1283 + * three fragmented frames. This define can be increased to support more
1284 + * concurrent frames, but it should be noted that each entry can consume about
1285 + * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
1286 +#define IEEE80211_FRAG_CACHE_LEN 4
1288 +struct ieee80211_frag_entry {
1289 + unsigned long first_frag_time;
1291 + unsigned int last_frag;
1292 + struct sk_buff *skb;
1293 + u8 src_addr[ETH_ALEN];
1294 + u8 dst_addr[ETH_ALEN];
1297 +struct ieee80211_stats {
1298 + unsigned int tx_unicast_frames;
1299 + unsigned int tx_multicast_frames;
1300 + unsigned int tx_fragments;
1301 + unsigned int tx_unicast_octets;
1302 + unsigned int tx_multicast_octets;
1303 + unsigned int tx_deferred_transmissions;
1304 + unsigned int tx_single_retry_frames;
1305 + unsigned int tx_multiple_retry_frames;
1306 + unsigned int tx_retry_limit_exceeded;
1307 + unsigned int tx_discards;
1308 + unsigned int rx_unicast_frames;
1309 + unsigned int rx_multicast_frames;
1310 + unsigned int rx_fragments;
1311 + unsigned int rx_unicast_octets;
1312 + unsigned int rx_multicast_octets;
1313 + unsigned int rx_fcs_errors;
1314 + unsigned int rx_discards_no_buffer;
1315 + unsigned int tx_discards_wrong_sa;
1316 + unsigned int rx_discards_undecryptable;
1317 + unsigned int rx_message_in_msg_fragments;
1318 + unsigned int rx_message_in_bad_msg_fragments;
1321 +struct ieee80211_softmac_stats{
1322 + unsigned int rx_ass_ok;
1323 + unsigned int rx_ass_err;
1324 + unsigned int rx_probe_rq;
1325 + unsigned int tx_probe_rs;
1326 + unsigned int tx_beacons;
1327 + unsigned int rx_auth_rq;
1328 + unsigned int rx_auth_rs_ok;
1329 + unsigned int rx_auth_rs_err;
1330 + unsigned int tx_auth_rq;
1331 + unsigned int no_auth_rs;
1332 + unsigned int no_ass_rs;
1333 + unsigned int tx_ass_rq;
1334 + unsigned int rx_ass_rq;
1335 + unsigned int tx_probe_rq;
1336 + unsigned int reassoc;
1337 + unsigned int swtxstop;
1338 + unsigned int swtxawake;
1341 +struct ieee80211_device;
1343 +#include "ieee80211_crypt.h"
1345 +#define SEC_KEY_1 (1<<0)
1346 +#define SEC_KEY_2 (1<<1)
1347 +#define SEC_KEY_3 (1<<2)
1348 +#define SEC_KEY_4 (1<<3)
1349 +#define SEC_ACTIVE_KEY (1<<4)
1350 +#define SEC_AUTH_MODE (1<<5)
1351 +#define SEC_UNICAST_GROUP (1<<6)
1352 +#define SEC_LEVEL (1<<7)
1353 +#define SEC_ENABLED (1<<8)
1355 +#define SEC_LEVEL_0 0 /* None */
1356 +#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */
1357 +#define SEC_LEVEL_2 2 /* Level 1 + TKIP */
1358 +#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
1359 +#define SEC_LEVEL_3 4 /* Level 2 + CCMP */
1362 +#define WEP_KEY_LEN 13
1364 +#define WEP_KEY_LEN_MODIF 32
1366 +struct ieee80211_security {
1371 + unicast_uses_group:1;
1372 + u8 key_sizes[WEP_KEYS];
1373 + u8 keys[WEP_KEYS][WEP_KEY_LEN_MODIF];
1376 +} __attribute__ ((packed));
1381 + 802.11 data frame from AP
1383 + ,-------------------------------------------------------------------.
1384 +Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
1385 + |------|------|---------|---------|---------|------|---------|------|
1386 +Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs |
1387 + | | tion | (BSSID) | | | ence | data | |
1388 + `-------------------------------------------------------------------'
1390 +Total: 28-2340 bytes
1394 +struct ieee80211_header_data {
1403 +#define BEACON_PROBE_SSID_ID_POSITION 12
1405 +/* Management Frame Information Element Types */
1406 +#define MFIE_TYPE_SSID 0
1407 +#define MFIE_TYPE_RATES 1
1408 +#define MFIE_TYPE_FH_SET 2
1409 +#define MFIE_TYPE_DS_SET 3
1410 +#define MFIE_TYPE_CF_SET 4
1411 +#define MFIE_TYPE_TIM 5
1412 +#define MFIE_TYPE_IBSS_SET 6
1413 +#define MFIE_TYPE_COUNTRY 7 //+YJ,080625
1414 +#define MFIE_TYPE_CHALLENGE 16
1415 +#define MFIE_TYPE_ERP 42
1416 +#define MFIE_TYPE_RSN 48
1417 +#define MFIE_TYPE_RATES_EX 50
1418 +#define MFIE_TYPE_GENERIC 221
1420 +#ifdef ENABLE_DOT11D
1423 + COUNTRY_CODE_FCC = 0,
1424 + COUNTRY_CODE_IC = 1,
1425 + COUNTRY_CODE_ETSI = 2,
1426 + COUNTRY_CODE_SPAIN = 3,
1427 + COUNTRY_CODE_FRANCE = 4,
1428 + COUNTRY_CODE_MKK = 5,
1429 + COUNTRY_CODE_MKK1 = 6,
1430 + COUNTRY_CODE_ISRAEL = 7,
1431 + COUNTRY_CODE_TELEC = 8,
1432 + COUNTRY_CODE_GLOBAL_DOMAIN = 9,
1433 + COUNTRY_CODE_WORLD_WIDE_13_INDEX = 10
1434 +}country_code_type_t;
1437 +struct ieee80211_info_element_hdr {
1440 +} __attribute__ ((packed));
1442 +struct ieee80211_info_element {
1446 +} __attribute__ ((packed));
1449 + * These are the data types that can make up management packets
1451 + u16 auth_algorithm;
1452 + u16 auth_sequence;
1453 + u16 beacon_interval;
1455 + u8 current_ap[ETH_ALEN];
1456 + u16 listen_interval;
1458 + u16 association_id:14, reserved:2;
1459 + } __attribute__ ((packed));
1460 + u32 time_stamp[2];
1465 +#define IEEE80211_DEFAULT_TX_ESSID "Penguin"
1466 +#define IEEE80211_DEFAULT_BASIC_RATE 10
1468 +struct ieee80211_authentication {
1469 + struct ieee80211_header_data header;
1473 + //struct ieee80211_info_element_hdr info_element;
1474 +} __attribute__ ((packed));
1477 +struct ieee80211_probe_response {
1478 + struct ieee80211_header_data header;
1479 + u32 time_stamp[2];
1480 + u16 beacon_interval;
1482 + struct ieee80211_info_element info_element;
1483 +} __attribute__ ((packed));
1485 +struct ieee80211_probe_request {
1486 + struct ieee80211_header_data header;
1487 + /*struct ieee80211_info_element info_element;*/
1488 +} __attribute__ ((packed));
1490 +struct ieee80211_assoc_request_frame {
1491 + struct ieee80211_hdr_3addr header;
1493 + u16 listen_interval;
1494 + //u8 current_ap[ETH_ALEN];
1495 + struct ieee80211_info_element_hdr info_element;
1496 +} __attribute__ ((packed));
1498 +struct ieee80211_assoc_response_frame {
1499 + struct ieee80211_hdr_3addr header;
1503 + struct ieee80211_info_element info_element; /* supported rates */
1504 +} __attribute__ ((packed));
1506 +struct ieee80211_disassoc_frame{
1507 + struct ieee80211_hdr_3addr header;
1509 +}__attribute__ ((packed));
1511 +struct ieee80211_txb {
1517 + struct sk_buff *fragments[0];
1520 +struct ieee80211_wmm_ac_param {
1521 + u8 ac_aci_acm_aifsn;
1522 + u8 ac_ecwmin_ecwmax;
1523 + u16 ac_txop_limit;
1526 +struct ieee80211_wmm_ts_info {
1530 +} __attribute__ ((packed));
1532 +struct ieee80211_wmm_tspec_elem {
1533 + struct ieee80211_wmm_ts_info ts_info;
1534 + u16 norm_msdu_size;
1535 + u16 max_msdu_size;
1536 + u32 min_serv_inter;
1537 + u32 max_serv_inter;
1540 + u32 serv_start_time;
1541 + u32 min_data_rate;
1542 + u32 mean_data_rate;
1543 + u32 peak_data_rate;
1544 + u32 max_burst_size;
1547 + u16 surp_band_allow;
1549 +}__attribute__((packed));
1551 +enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame};
1552 +#define MAX_SP_Len (WMM_all_frame << 4)
1553 +#define IEEE80211_QOS_TID 0x0f
1554 +#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5)
1556 +/* SWEEP TABLE ENTRIES NUMBER*/
1557 +#define MAX_SWEEP_TAB_ENTRIES 42
1558 +#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7
1559 +/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs
1560 + * only use 8, and then use extended rates for the remaining supported
1561 + * rates. Other APs, however, stick all of their supported rates on the
1562 + * main rates information element... */
1563 +#define MAX_RATES_LENGTH ((u8)12)
1564 +#define MAX_RATES_EX_LENGTH ((u8)16)
1565 +#define MAX_NETWORK_COUNT 128
1566 +//#define MAX_CHANNEL_NUMBER 161
1567 +#define MAX_CHANNEL_NUMBER 165 //YJ,modified,080625
1568 +#define MAX_IE_LEN 0xFF //+YJ,080625
1570 +typedef struct _CHANNEL_LIST{
1571 + u8 Channel[MAX_CHANNEL_NUMBER + 1];
1573 +}CHANNEL_LIST, *PCHANNEL_LIST;
1575 +#define IEEE80211_SOFTMAC_SCAN_TIME 100//400
1578 +#define IEEE80211_WATCH_DOG_TIME 2000
1580 +//by amy for antenna
1581 +#define ANTENNA_DIVERSITY_TIMER_PERIOD 1000 // 1000 m
1582 +//by amy for antenna
1583 +#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2)
1585 +#define CRC_LENGTH 4U
1587 +#define MAX_WPA_IE_LEN 64
1589 +#define NETWORK_EMPTY_ESSID (1<<0)
1590 +#define NETWORK_HAS_OFDM (1<<1)
1591 +#define NETWORK_HAS_CCK (1<<2)
1593 +#define IEEE80211_DTIM_MBCAST 4
1594 +#define IEEE80211_DTIM_UCAST 2
1595 +#define IEEE80211_DTIM_VALID 1
1596 +#define IEEE80211_DTIM_INVALID 0
1598 +#define IEEE80211_PS_DISABLED 0
1599 +#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST
1600 +#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST
1601 +#define IEEE80211_PS_ENABLE IEEE80211_DTIM_VALID
1602 +//added by David for QoS 2006/6/30
1603 +//#define WMM_Hang_8187
1604 +#ifdef WMM_Hang_8187
1605 +#undef WMM_Hang_8187
1608 +#define WME_AC_BE 0x00
1609 +#define WME_AC_BK 0x01
1610 +#define WME_AC_VI 0x02
1611 +#define WME_AC_VO 0x03
1612 +#define WME_ACI_MASK 0x03
1613 +#define WME_AIFSN_MASK 0x03
1614 +#define WME_AC_PRAM_LEN 16
1616 +//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP
1617 +//#define UP2AC(up) ((up<3) ? ((up==0)?1:0) : (up>>1))
1618 +#define UP2AC(up) ( \
1619 + ((up) < 1) ? WME_AC_BE : \
1620 + ((up) < 3) ? WME_AC_BK : \
1621 + ((up) < 4) ? WME_AC_BE : \
1622 + ((up) < 6) ? WME_AC_VI : \
1624 +//AC Mapping to UP, using in Tx part for selecting the corresponding TX queue
1625 +#define AC2UP(_ac) ( \
1626 + ((_ac) == WME_AC_VO) ? 6 : \
1627 + ((_ac) == WME_AC_VI) ? 5 : \
1628 + ((_ac) == WME_AC_BK) ? 1 : \
1631 +#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */
1632 +struct ether_header {
1633 + u8 ether_dhost[ETHER_ADDR_LEN];
1634 + u8 ether_shost[ETHER_ADDR_LEN];
1636 +} __attribute__((packed));
1638 +#ifndef ETHERTYPE_PAE
1639 +#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */
1641 +#ifndef ETHERTYPE_IP
1642 +#define ETHERTYPE_IP 0x0800 /* IP protocol */
1645 +struct ieee80211_network {
1646 + /* These entries are used to identify a unique network */
1647 + u8 bssid[ETH_ALEN];
1649 + /* Ensure null-terminated for any debug msgs */
1650 + u8 ssid[IW_ESSID_MAX_SIZE + 1];
1653 + /* These are network statistics */
1654 + struct ieee80211_rx_stats stats;
1656 + u8 rates[MAX_RATES_LENGTH];
1658 + u8 rates_ex[MAX_RATES_EX_LENGTH];
1660 + unsigned long last_scanned;
1663 + u32 last_associate;
1664 + u32 time_stamp[2];
1665 + u16 beacon_interval;
1666 + u16 listen_interval;
1668 + u8 wpa_ie[MAX_WPA_IE_LEN];
1669 + size_t wpa_ie_len;
1670 + u8 rsn_ie[MAX_WPA_IE_LEN];
1671 + size_t rsn_ie_len;
1674 + u32 last_dtim_sta_time[2];
1675 + struct list_head list;
1678 + struct ieee80211_wmm_ac_param wmm_param[4];
1680 + u8 SignalStrength;
1682 + u8 HighestOperaRate;
1684 +#ifdef THOMAS_TURBO
1685 + u8 Turbo_Enable;//enable turbo mode, added by thomas
1687 +#ifdef ENABLE_DOT11D
1689 + u8 CountryIeBuf[MAX_IE_LEN];
1693 +enum ieee80211_state {
1695 + /* the card is not linked at all */
1696 + IEEE80211_NOLINK = 0,
1698 + /* IEEE80211_ASSOCIATING* are for BSS client mode
1699 + * the driver shall not perform RX filtering unless
1700 + * the state is LINKED.
1701 + * The driver shall just check for the state LINKED and
1702 + * defaults to NOLINK for ALL the other states (including
1703 + * LINKED_SCANNING)
1706 + /* the association procedure will start (wq scheduling)*/
1707 + IEEE80211_ASSOCIATING,
1708 + IEEE80211_ASSOCIATING_RETRY,
1710 + /* the association procedure is sending AUTH request*/
1711 + IEEE80211_ASSOCIATING_AUTHENTICATING,
1713 + /* the association procedure has successfully authentcated
1714 + * and is sending association request
1716 + IEEE80211_ASSOCIATING_AUTHENTICATED,
1718 + /* the link is ok. the card associated to a BSS or linked
1719 + * to a ibss cell or acting as an AP and creating the bss
1723 + /* same as LINKED, but the driver shall apply RX filter
1724 + * rules as we are in NO_LINK mode. As the card is still
1725 + * logically linked, but it is doing a syncro site survey
1726 + * then it will be back to LINKED state.
1728 + IEEE80211_LINKED_SCANNING,
1732 +#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
1733 +#define DEFAULT_FTS 2346
1734 +#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
1735 +#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
1738 +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11))
1739 +extern inline int is_multicast_ether_addr(const u8 *addr)
1741 + return ((addr[0] != 0xff) && (0x01 & addr[0]));
1745 +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13))
1746 +extern inline int is_broadcast_ether_addr(const u8 *addr)
1748 + return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \
1749 + (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
1753 +#define CFG_IEEE80211_RESERVE_FCS (1<<0)
1754 +#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
1756 +typedef struct tx_pending_t{
1758 + struct ieee80211_txb *txb;
1762 +struct ieee80211_device {
1763 + struct net_device *dev;
1765 + /* Bookkeeping structures */
1766 + struct net_device_stats stats;
1767 + struct ieee80211_stats ieee_stats;
1768 + struct ieee80211_softmac_stats softmac_stats;
1770 + /* Probe / Beacon management */
1771 + struct list_head network_free_list;
1772 + struct list_head network_list;
1773 + struct ieee80211_network *networks;
1777 + int iw_mode; /* operating mode (IW_MODE_*) */
1780 + spinlock_t wpax_suitlist_lock;
1782 + int tx_headroom; /* Set to size of any additional room needed at front
1783 + * of allocated Tx SKBs */
1786 + /* WEP and other encryption related settings at the device level */
1787 + int open_wep; /* Set to 1 to allow unencrypted frames */
1789 + int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
1790 + * WEP key changes */
1792 + /* If the host performs {en,de}cryption, then set to 1 */
1795 + int ieee802_1x; /* is IEEE 802.1X used */
1799 + int drop_unencrypted;
1800 + int tkip_countermeasures;
1801 + int privacy_invoked;
1802 + size_t wpa_ie_len;
1805 + u8 ap_mac_addr[6];
1806 + u16 pairwise_key_type;
1807 + u16 broadcast_key_type;
1809 + struct list_head crypt_deinit_list;
1810 + struct ieee80211_crypt_data *crypt[WEP_KEYS];
1811 + int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
1812 + struct timer_list crypt_deinit_timer;
1814 + int bcrx_sta_key; /* use individual keys to override default keys even
1815 + * with RX of broad/multicast frames */
1817 + /* Fragmentation structures */
1818 + // each streaming contain a entry
1819 + struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN];
1820 + unsigned int frag_next_idx[17];
1821 + u16 fts; /* Fragmentation Threshold */
1823 + /* This stores infos for the current network.
1824 + * Either the network we are associated in INFRASTRUCTURE
1825 + * or the network that we are creating in MASTER mode.
1826 + * ad-hoc is a mixture ;-).
1827 + * Note that in infrastructure mode, even when not associated,
1828 + * fields bssid and essid may be valid (if wpa_set and essid_set
1829 + * are true) as thy carry the value set by the user via iwconfig
1831 + struct ieee80211_network current_network;
1834 + enum ieee80211_state state;
1837 + int mode; /* A, B, G */
1838 + int modulation; /* CCK, OFDM */
1839 + int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */
1840 + int abg_true; /* ABG flag */
1842 + /* used for forcing the ibss workqueue to terminate
1843 + * without wait for the syncro scan to terminate
1845 + short sync_scan_hurryup;
1847 +#ifdef ENABLE_DOT11D
1848 + void * pDot11dInfo;
1849 + bool bGlobalDomain;
1851 + // For Liteon Ch12~13 passive scan
1852 + u8 MinPassiveChnlNum;
1855 + /* map of allowed channels. 0 is dummy */
1856 + // FIXME: remeber to default to a basic channel plan depending of the PHY type
1857 + int channel_map[MAX_CHANNEL_NUMBER+1];
1860 + int rate; /* current rate */
1862 + //FIXME: pleace callback, see if redundant with softmac_features
1863 + short active_scan;
1865 + /* this contains flags for selectively enable softmac support */
1866 + u16 softmac_features;
1868 + /* if the sequence control field is not filled by HW */
1871 + /* association procedure transaction sequence number */
1872 + u16 associate_seq;
1874 + /* AID for RTXed association responses */
1877 + /* power save mode related*/
1881 + struct tasklet_struct ps_task;
1886 + /* used if IEEE_SOFTMAC_TX_QUEUE is set */
1889 + short proto_started;
1891 + struct semaphore wx_sem;
1892 + struct semaphore scan_sem;
1894 + spinlock_t mgmt_tx_lock;
1895 + spinlock_t beacon_lock;
1897 + short beacon_txing;
1902 + u8 wpax_type_set; //{added by David, 2006.9.28}
1903 + u32 wpax_type_notify; //{added by David, 2006.9.26}
1905 + /* QoS related flag */
1906 + char init_wmmparam_flag;
1908 + /* for discarding duplicated packets in IBSS */
1909 + struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE];
1911 + /* for discarding duplicated packets in BSS */
1912 + u16 last_rxseq_num[17]; /* rx seq previous per-tid */
1913 + u16 last_rxfrag_num[17];/* tx frag previous per-tid */
1914 + unsigned long last_packet_time[17];
1917 + unsigned long last_rx_ps_time;
1919 + /* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */
1920 + struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM];
1921 + int mgmt_queue_head;
1922 + int mgmt_queue_tail;
1925 + /* used if IEEE_SOFTMAC_TX_QUEUE is set */
1926 + struct tx_pending_t tx_pending;
1928 + /* used if IEEE_SOFTMAC_ASSOCIATE is set */
1929 + struct timer_list associate_timer;
1931 + /* used if IEEE_SOFTMAC_BEACONS is set */
1932 + struct timer_list beacon_timer;
1934 + struct work_struct associate_complete_wq;
1935 +// struct work_struct associate_retry_wq;
1936 + struct work_struct associate_procedure_wq;
1937 +// struct work_struct softmac_scan_wq;
1938 + struct work_struct wx_sync_scan_wq;
1939 + struct work_struct wmm_param_update_wq;
1940 + struct work_struct ps_request_tx_ack_wq;//for ps
1941 +// struct work_struct hw_wakeup_wq;
1942 +// struct work_struct hw_sleep_wq;
1943 +// struct work_struct watch_dog_wq;
1947 + u16 ListenInterval;
1948 + unsigned long NumRxDataInPeriod; //YJ,add,080828
1949 + unsigned long NumRxBcnInPeriod; //YJ,add,080828
1950 + unsigned long NumRxOkTotal;
1951 + unsigned long NumRxUnicast;//YJ,add,080828,for keep alive
1953 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
1954 + struct delayed_work softmac_scan_wq;
1955 + struct delayed_work associate_retry_wq;
1956 + struct delayed_work hw_wakeup_wq;
1957 + struct delayed_work hw_sleep_wq;//+by amy 080324
1958 + struct delayed_work watch_dog_wq;
1959 + struct delayed_work sw_antenna_wq;
1960 + struct delayed_work start_ibss_wq;
1961 +//by amy for rate adaptive 080312
1962 + struct delayed_work rate_adapter_wq;
1963 +//by amy for rate adaptive
1964 + struct delayed_work hw_dig_wq;
1965 + struct delayed_work tx_pw_wq;
1967 +//Added for RF power on power off by lizhaoming 080512
1968 + struct delayed_work GPIOChangeRFWorkItem;
1971 + struct work_struct start_ibss_wq;
1972 + struct work_struct softmac_scan_wq;
1973 + struct work_struct associate_retry_wq;
1974 + struct work_struct hw_wakeup_wq;
1975 + struct work_struct hw_sleep_wq;
1976 + struct work_struct watch_dog_wq;
1977 + struct work_struct sw_antenna_wq;
1978 +//by amy for rate adaptive 080312
1979 + struct work_struct rate_adapter_wq;
1980 +//by amy for rate adaptive
1981 + struct work_struct hw_dig_wq;
1982 + struct work_struct tx_pw_wq;
1984 +//Added for RF power on power off by lizhaoming 080512
1985 + struct work_struct GPIOChangeRFWorkItem;
1987 + struct workqueue_struct *wq;
1989 + /* Callback functions */
1990 + void (*set_security)(struct net_device *dev,
1991 + struct ieee80211_security *sec);
1993 + /* Used to TX data frame by using txb structs.
1994 + * this is not used if in the softmac_features
1995 + * is set the flag IEEE_SOFTMAC_TX_QUEUE
1997 + int (*hard_start_xmit)(struct ieee80211_txb *txb,
1998 + struct net_device *dev);
2000 + int (*reset_port)(struct net_device *dev);
2002 + /* Softmac-generated frames (mamagement) are TXed via this
2003 + * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
2004 + * not set. As some cards may have different HW queues that
2005 + * one might want to use for data and management frames
2006 + * the option to have two callbacks might be useful.
2007 + * This fucntion can't sleep.
2009 + int (*softmac_hard_start_xmit)(struct sk_buff *skb,
2010 + struct net_device *dev);
2012 + /* used instead of hard_start_xmit (not softmac_hard_start_xmit)
2013 + * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
2014 + * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
2015 + * then also management frames are sent via this callback.
2016 + * This function can't sleep.
2018 + void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
2019 + struct net_device *dev,int rate);
2021 + /* stops the HW queue for DATA frames. Useful to avoid
2022 + * waste time to TX data frame when we are reassociating
2023 + * This function can sleep.
2025 + void (*data_hard_stop)(struct net_device *dev);
2027 + /* OK this is complementar to data_poll_hard_stop */
2028 + void (*data_hard_resume)(struct net_device *dev);
2030 + /* ask to the driver to retune the radio .
2031 + * This function can sleep. the driver should ensure
2032 + * the radio has been swithced before return.
2034 + void (*set_chan)(struct net_device *dev,short ch);
2036 + /* These are not used if the ieee stack takes care of
2037 + * scanning (IEEE_SOFTMAC_SCAN feature set).
2038 + * In this case only the set_chan is used.
2040 + * The syncro version is similar to the start_scan but
2041 + * does not return until all channels has been scanned.
2042 + * this is called in user context and should sleep,
2043 + * it is called in a work_queue when swithcing to ad-hoc mode
2044 + * or in behalf of iwlist scan when the card is associated
2045 + * and root user ask for a scan.
2046 + * the fucntion stop_scan should stop both the syncro and
2047 + * background scanning and can sleep.
2048 + * The fucntion start_scan should initiate the background
2049 + * scanning and can't sleep.
2051 + void (*scan_syncro)(struct net_device *dev);
2052 + void (*start_scan)(struct net_device *dev);
2053 + void (*stop_scan)(struct net_device *dev);
2055 + /* indicate the driver that the link state is changed
2056 + * for example it may indicate the card is associated now.
2057 + * Driver might be interested in this to apply RX filter
2058 + * rules or simply light the LINK led
2060 + void (*link_change)(struct net_device *dev);
2062 + /* these two function indicates to the HW when to start
2063 + * and stop to send beacons. This is used when the
2064 + * IEEE_SOFTMAC_BEACONS is not set. For now the
2065 + * stop_send_bacons is NOT guaranteed to be called only
2066 + * after start_send_beacons.
2068 + void (*start_send_beacons) (struct net_device *dev);
2069 + void (*stop_send_beacons) (struct net_device *dev);
2071 + /* power save mode related */
2072 + void (*sta_wake_up) (struct net_device *dev);
2073 + void (*ps_request_tx_ack) (struct net_device *dev);
2074 + void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl);
2075 + short (*ps_is_queue_empty) (struct net_device *dev);
2078 + //void (*wmm_param_update) (struct net_device *dev, u8 *ac_param);
2079 + //void (*wmm_param_update) (struct ieee80211_device *ieee);
2081 + /* This must be the last item so that it points to the data
2082 + * allocated beyond this structure by alloc_ieee80211 */
2086 +#define IEEE_A (1<<0)
2087 +#define IEEE_B (1<<1)
2088 +#define IEEE_G (1<<2)
2089 +#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G)
2091 +/* Generate a 802.11 header */
2093 +/* Uses the channel change callback directly
2094 + * instead of [start/stop] scan callbacks
2096 +#define IEEE_SOFTMAC_SCAN (1<<2)
2098 +/* Perform authentication and association handshake */
2099 +#define IEEE_SOFTMAC_ASSOCIATE (1<<3)
2101 +/* Generate probe requests */
2102 +#define IEEE_SOFTMAC_PROBERQ (1<<4)
2104 +/* Generate respones to probe requests */
2105 +#define IEEE_SOFTMAC_PROBERS (1<<5)
2107 +/* The ieee802.11 stack will manages the netif queue
2108 + * wake/stop for the driver, taking care of 802.11
2109 + * fragmentation. See softmac.c for details. */
2110 +#define IEEE_SOFTMAC_TX_QUEUE (1<<7)
2112 +/* Uses only the softmac_data_hard_start_xmit
2113 + * even for TX management frames.
2115 +#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8)
2117 +/* Generate beacons. The stack will enqueue beacons
2120 +#define IEEE_SOFTMAC_BEACONS (1<<6)
2124 +static inline void *ieee80211_priv(struct net_device *dev)
2126 + return ((struct ieee80211_device *)netdev_priv(dev))->priv;
2129 +extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
2131 + /* Single white space is for Linksys APs */
2132 + if (essid_len == 1 && essid[0] == ' ')
2135 + /* Otherwise, if the entire essid is 0, we assume it is hidden */
2136 + while (essid_len) {
2138 + if (essid[essid_len] != '\0')
2145 +extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
2148 + * It is possible for both access points and our device to support
2149 + * combinations of modes, so as long as there is one valid combination
2150 + * of ap/device supported modes, then return success
2153 + if ((mode & IEEE_A) &&
2154 + (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
2155 + (ieee->freq_band & IEEE80211_52GHZ_BAND))
2158 + if ((mode & IEEE_G) &&
2159 + (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
2160 + (ieee->freq_band & IEEE80211_24GHZ_BAND))
2163 + if ((mode & IEEE_B) &&
2164 + (ieee->modulation & IEEE80211_CCK_MODULATION) &&
2165 + (ieee->freq_band & IEEE80211_24GHZ_BAND))
2171 +extern inline int ieee80211_get_hdrlen(u16 fc)
2175 + switch (WLAN_FC_GET_TYPE(fc)) {
2176 + case IEEE80211_FTYPE_DATA:
2177 + if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
2178 + hdrlen = 30; /* Addr4 */
2179 + if(IEEE80211_QOS_HAS_SEQ(fc))
2180 + hdrlen += 2; /* QOS ctrl*/
2182 + case IEEE80211_FTYPE_CTL:
2183 + switch (WLAN_FC_GET_STYPE(fc)) {
2184 + case IEEE80211_STYPE_CTS:
2185 + case IEEE80211_STYPE_ACK:
2201 +extern void free_ieee80211(struct net_device *dev);
2202 +extern struct net_device *alloc_ieee80211(int sizeof_priv);
2204 +extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
2206 +/* ieee80211_tx.c */
2208 +extern int ieee80211_encrypt_fragment(
2209 + struct ieee80211_device *ieee,
2210 + struct sk_buff *frag,
2213 +extern int ieee80211_xmit(struct sk_buff *skb,
2214 + struct net_device *dev);
2215 +extern void ieee80211_txb_free(struct ieee80211_txb *);
2218 +/* ieee80211_rx.c */
2219 +extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
2220 + struct ieee80211_rx_stats *rx_stats);
2221 +extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
2222 + struct ieee80211_hdr *header,
2223 + struct ieee80211_rx_stats *stats);
2225 +/* ieee80211_wx.c */
2226 +extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
2227 + struct iw_request_info *info,
2228 + union iwreq_data *wrqu, char *key);
2229 +extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
2230 + struct iw_request_info *info,
2231 + union iwreq_data *wrqu, char *key);
2232 +extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
2233 + struct iw_request_info *info,
2234 + union iwreq_data *wrqu, char *key);
2235 +extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
2236 + struct iw_request_info *info,
2237 + union iwreq_data* wrqu, char *extra);
2238 +int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
2239 + struct iw_request_info *info,
2240 + struct iw_param *data, char *extra);
2241 +int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
2242 + struct iw_request_info *info,
2243 + union iwreq_data *wrqu, char *extra);
2245 +int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len);
2246 +/* ieee80211_softmac.c */
2247 +extern short ieee80211_is_54g(struct ieee80211_network net);
2248 +extern short ieee80211_is_shortslot(struct ieee80211_network net);
2249 +extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
2250 + struct ieee80211_rx_stats *rx_stats, u16 type,
2252 +extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net);
2254 +extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee);
2255 +extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee);
2256 +extern void ieee80211_start_bss(struct ieee80211_device *ieee);
2257 +extern void ieee80211_start_master_bss(struct ieee80211_device *ieee);
2258 +extern void ieee80211_start_ibss(struct ieee80211_device *ieee);
2259 +extern void ieee80211_softmac_init(struct ieee80211_device *ieee);
2260 +extern void ieee80211_softmac_free(struct ieee80211_device *ieee);
2261 +extern void ieee80211_associate_abort(struct ieee80211_device *ieee);
2262 +extern void ieee80211_disassociate(struct ieee80211_device *ieee);
2263 +extern void ieee80211_stop_scan(struct ieee80211_device *ieee);
2264 +extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee);
2265 +extern void ieee80211_check_all_nets(struct ieee80211_device *ieee);
2266 +extern void ieee80211_start_protocol(struct ieee80211_device *ieee);
2267 +extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
2268 +extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
2269 +extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
2270 +extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
2271 +extern void ieee80211_wake_queue(struct ieee80211_device *ieee);
2272 +extern void ieee80211_stop_queue(struct ieee80211_device *ieee);
2273 +extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
2274 +extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
2275 +extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
2276 +extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p);
2277 +extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
2278 +extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success);
2279 +extern void SendDisassociation(struct ieee80211_device *ieee,u8* asSta,u8 asRsn);
2280 +extern void ieee80211_start_scan(struct ieee80211_device *ieee);
2282 +//Add for RF power on power off by lizhaoming 080512
2283 +extern void SendDisassociation(struct ieee80211_device *ieee,
2287 +/* ieee80211_crypt_ccmp&tkip&wep.c */
2288 +extern void ieee80211_tkip_null(void);
2289 +extern void ieee80211_wep_null(void);
2290 +extern void ieee80211_ccmp_null(void);
2291 +/* ieee80211_softmac_wx.c */
2293 +extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
2294 + struct iw_request_info *info,
2295 + union iwreq_data *wrqu, char *ext);
2297 +extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
2298 + struct iw_request_info *info,
2299 + union iwreq_data *awrq,
2302 +extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b);
2304 +extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
2305 + struct iw_request_info *info,
2306 + union iwreq_data *wrqu, char *extra);
2308 +extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
2309 + struct iw_request_info *info,
2310 + union iwreq_data *wrqu, char *extra);
2312 +extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
2313 + union iwreq_data *wrqu, char *b);
2315 +extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
2316 + union iwreq_data *wrqu, char *b);
2318 +extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
2319 + struct iw_request_info *a,
2320 + union iwreq_data *wrqu, char *extra);
2322 +extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
2323 + union iwreq_data *wrqu, char *b);
2325 +extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
2326 + union iwreq_data *wrqu, char *b);
2328 +extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
2329 + union iwreq_data *wrqu, char *b);
2330 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
2331 +extern void ieee80211_wx_sync_scan_wq(struct work_struct *work);
2333 + extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
2335 +//extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
2337 +extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
2338 + struct iw_request_info *info,
2339 + union iwreq_data *wrqu, char *extra);
2341 +extern int ieee80211_wx_get_name(struct ieee80211_device *ieee,
2342 + struct iw_request_info *info,
2343 + union iwreq_data *wrqu, char *extra);
2345 +extern int ieee80211_wx_set_power(struct ieee80211_device *ieee,
2346 + struct iw_request_info *info,
2347 + union iwreq_data *wrqu, char *extra);
2349 +extern int ieee80211_wx_get_power(struct ieee80211_device *ieee,
2350 + struct iw_request_info *info,
2351 + union iwreq_data *wrqu, char *extra);
2353 +extern void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee);
2355 +extern void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr);
2357 +extern const long ieee80211_wlan_frequencies[];
2359 +extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
2364 +extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
2366 + return ieee->scans;
2369 +static inline const char *escape_essid(const char *essid, u8 essid_len) {
2370 + static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
2371 + const char *s = essid;
2372 + char *d = escaped;
2374 + if (ieee80211_is_empty_essid(essid, essid_len)) {
2375 + memcpy(escaped, "<hidden>", sizeof("<hidden>"));
2379 + essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
2380 + while (essid_len--) {
2392 +#endif /* IEEE80211_H */
2394 +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
2397 + * Host AP crypto routines
2399 + * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
2400 + * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.com>
2402 + * This program is free software; you can redistribute it and/or modify
2403 + * it under the terms of the GNU General Public License version 2 as
2404 + * published by the Free Software Foundation. See README and COPYING for
2409 +//#include <linux/config.h>
2410 +#include <linux/version.h>
2411 +#include <linux/module.h>
2412 +#include <linux/init.h>
2413 +#include <linux/slab.h>
2414 +#include <asm/string.h>
2415 +#include <asm/errno.h>
2417 +#if (LINUX_VERSION_CODE<KERNEL_VERSION(2,6,18))
2418 +#include<linux/config.h>
2421 +#include "ieee80211.h"
2423 +MODULE_AUTHOR("Jouni Malinen");
2424 +MODULE_DESCRIPTION("HostAP crypto");
2425 +MODULE_LICENSE("GPL");
2427 +struct ieee80211_crypto_alg {
2428 + struct list_head list;
2429 + struct ieee80211_crypto_ops *ops;
2433 +struct ieee80211_crypto {
2434 + struct list_head algs;
2438 +static struct ieee80211_crypto *hcrypt;
2440 +void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee,
2443 + struct list_head *ptr, *n;
2444 + struct ieee80211_crypt_data *entry;
2446 + for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
2447 + ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
2448 + entry = list_entry(ptr, struct ieee80211_crypt_data, list);
2450 + if (atomic_read(&entry->refcnt) != 0 && !force)
2456 + entry->ops->deinit(entry->priv);
2457 + module_put(entry->ops->owner);
2463 +void ieee80211_crypt_deinit_handler(unsigned long data)
2465 + struct ieee80211_device *ieee = (struct ieee80211_device *)data;
2466 + unsigned long flags;
2468 + spin_lock_irqsave(&ieee->lock, flags);
2469 + ieee80211_crypt_deinit_entries(ieee, 0);
2470 + if (!list_empty(&ieee->crypt_deinit_list)) {
2471 + printk(KERN_DEBUG "%s: entries remaining in delayed crypt "
2472 + "deletion list\n", ieee->dev->name);
2473 + ieee->crypt_deinit_timer.expires = jiffies + HZ;
2474 + add_timer(&ieee->crypt_deinit_timer);
2476 + spin_unlock_irqrestore(&ieee->lock, flags);
2480 +void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
2481 + struct ieee80211_crypt_data **crypt)
2483 + struct ieee80211_crypt_data *tmp;
2484 + unsigned long flags;
2486 + if (*crypt == NULL)
2492 + /* must not run ops->deinit() while there may be pending encrypt or
2493 + * decrypt operations. Use a list of delayed deinits to avoid needing
2496 + spin_lock_irqsave(&ieee->lock, flags);
2497 + list_add(&tmp->list, &ieee->crypt_deinit_list);
2498 + if (!timer_pending(&ieee->crypt_deinit_timer)) {
2499 + ieee->crypt_deinit_timer.expires = jiffies + HZ;
2500 + add_timer(&ieee->crypt_deinit_timer);
2502 + spin_unlock_irqrestore(&ieee->lock, flags);
2505 +int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
2507 + unsigned long flags;
2508 + struct ieee80211_crypto_alg *alg;
2510 + if (hcrypt == NULL)
2513 + alg = kmalloc(sizeof(*alg), GFP_KERNEL);
2517 + memset(alg, 0, sizeof(*alg));
2520 + spin_lock_irqsave(&hcrypt->lock, flags);
2521 + list_add(&alg->list, &hcrypt->algs);
2522 + spin_unlock_irqrestore(&hcrypt->lock, flags);
2524 + printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n",
2530 +int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
2532 + unsigned long flags;
2533 + struct list_head *ptr;
2534 + struct ieee80211_crypto_alg *del_alg = NULL;
2536 + if (hcrypt == NULL)
2539 + spin_lock_irqsave(&hcrypt->lock, flags);
2540 + for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
2541 + struct ieee80211_crypto_alg *alg =
2542 + (struct ieee80211_crypto_alg *) ptr;
2543 + if (alg->ops == ops) {
2544 + list_del(&alg->list);
2549 + spin_unlock_irqrestore(&hcrypt->lock, flags);
2552 + printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
2553 + "'%s'\n", ops->name);
2557 + return del_alg ? 0 : -1;
2561 +struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name)
2563 + unsigned long flags;
2564 + struct list_head *ptr;
2565 + struct ieee80211_crypto_alg *found_alg = NULL;
2567 + if (hcrypt == NULL)
2570 + spin_lock_irqsave(&hcrypt->lock, flags);
2571 + for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
2572 + struct ieee80211_crypto_alg *alg =
2573 + (struct ieee80211_crypto_alg *) ptr;
2574 + if (strcmp(alg->ops->name, name) == 0) {
2579 + spin_unlock_irqrestore(&hcrypt->lock, flags);
2582 + return found_alg->ops;
2588 +static void * ieee80211_crypt_null_init(int keyidx) { return (void *) 1; }
2589 +static void ieee80211_crypt_null_deinit(void *priv) {}
2591 +static struct ieee80211_crypto_ops ieee80211_crypt_null = {
2593 + .init = ieee80211_crypt_null_init,
2594 + .deinit = ieee80211_crypt_null_deinit,
2595 + .encrypt_mpdu = NULL,
2596 + .decrypt_mpdu = NULL,
2597 + .encrypt_msdu = NULL,
2598 + .decrypt_msdu = NULL,
2601 + .extra_prefix_len = 0,
2602 + .extra_postfix_len = 0,
2603 + .owner = THIS_MODULE,
2607 +int ieee80211_crypto_init(void)
2609 + int ret = -ENOMEM;
2611 + hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL);
2615 + memset(hcrypt, 0, sizeof(*hcrypt));
2616 + INIT_LIST_HEAD(&hcrypt->algs);
2617 + spin_lock_init(&hcrypt->lock);
2619 + ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null);
2629 +void ieee80211_crypto_deinit(void)
2631 + struct list_head *ptr, *n;
2633 + if (hcrypt == NULL)
2636 + for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
2637 + ptr = n, n = ptr->next) {
2638 + struct ieee80211_crypto_alg *alg =
2639 + (struct ieee80211_crypto_alg *) ptr;
2641 + printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
2642 + "'%s' (deinit)\n", alg->ops->name);
2650 +EXPORT_SYMBOL(ieee80211_crypt_deinit_entries);
2651 +EXPORT_SYMBOL(ieee80211_crypt_deinit_handler);
2652 +EXPORT_SYMBOL(ieee80211_crypt_delayed_deinit);
2654 +EXPORT_SYMBOL(ieee80211_register_crypto_ops);
2655 +EXPORT_SYMBOL(ieee80211_unregister_crypto_ops);
2656 +EXPORT_SYMBOL(ieee80211_get_crypto_ops);
2659 +//module_init(ieee80211_crypto_init);
2660 +//module_exit(ieee80211_crypto_deinit);
2662 +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
2665 + * Host AP crypt: host-based CCMP encryption implementation for Host AP driver
2667 + * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
2669 + * This program is free software; you can redistribute it and/or modify
2670 + * it under the terms of the GNU General Public License version 2 as
2671 + * published by the Free Software Foundation. See README and COPYING for
2675 +//#include <linux/config.h>
2676 +#include <linux/version.h>
2677 +#include <linux/module.h>
2678 +#include <linux/init.h>
2679 +#include <linux/slab.h>
2680 +#include <linux/random.h>
2681 +#include <linux/skbuff.h>
2682 +#include <linux/netdevice.h>
2683 +#include <linux/if_ether.h>
2684 +#include <linux/if_arp.h>
2685 +#include <asm/string.h>
2686 +#include <linux/wireless.h>
2688 +#include "ieee80211.h"
2690 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
2691 +#include "rtl_crypto.h"
2693 +#include <linux/crypto.h>
2695 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
2696 + #include <asm/scatterlist.h>
2698 + #include <linux/scatterlist.h>
2701 +//#include <asm/scatterlist.h>
2703 +MODULE_AUTHOR("Jouni Malinen");
2704 +MODULE_DESCRIPTION("Host AP crypt: CCMP");
2705 +MODULE_LICENSE("GPL");
2707 +#ifdef OPENSUSE_SLED
2708 +#ifndef IN_OPENSUSE_SLED
2709 +#define IN_OPENSUSE_SLED 1
2713 +#define AES_BLOCK_LEN 16
2714 +#define CCMP_HDR_LEN 8
2715 +#define CCMP_MIC_LEN 8
2716 +#define CCMP_TK_LEN 16
2717 +#define CCMP_PN_LEN 6
2719 +struct ieee80211_ccmp_data {
2720 + u8 key[CCMP_TK_LEN];
2723 + u8 tx_pn[CCMP_PN_LEN];
2724 + u8 rx_pn[CCMP_PN_LEN];
2726 + u32 dot11RSNAStatsCCMPFormatErrors;
2727 + u32 dot11RSNAStatsCCMPReplays;
2728 + u32 dot11RSNAStatsCCMPDecryptErrors;
2732 + struct crypto_tfm *tfm;
2734 + /* scratch buffers for virt_to_page() (crypto API) */
2735 + u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN],
2736 + tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN];
2737 + u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN];
2740 +void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm,
2741 + const u8 pt[16], u8 ct[16])
2743 + #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))||(IN_OPENSUSE_SLED))
2744 + crypto_cipher_encrypt_one((void *)tfm, ct, pt);
2746 + struct scatterlist src, dst;
2748 + src.page = virt_to_page(pt);
2749 + src.offset = offset_in_page(pt);
2750 + src.length = AES_BLOCK_LEN;
2752 + dst.page = virt_to_page(ct);
2753 + dst.offset = offset_in_page(ct);
2754 + dst.length = AES_BLOCK_LEN;
2756 + crypto_cipher_encrypt(tfm, &dst, &src, AES_BLOCK_LEN);
2760 +static void * ieee80211_ccmp_init(int key_idx)
2762 + struct ieee80211_ccmp_data *priv;
2764 + priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
2767 + memset(priv, 0, sizeof(*priv));
2768 + priv->key_idx = key_idx;
2770 + #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!IN_OPENSUSE_SLED))
2771 + priv->tfm = crypto_alloc_tfm("aes", 0);
2772 + if (priv->tfm == NULL) {
2773 + printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
2774 + "crypto API aes\n");
2778 + priv->tfm = (void *)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
2779 + if (IS_ERR(priv->tfm)) {
2780 + printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate "
2781 + "crypto API aes\n");
2791 + //#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
2792 + #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!IN_OPENSUSE_SLED))
2793 + crypto_free_tfm(priv->tfm);
2795 + crypto_free_cipher((void *)priv->tfm);
2804 +static void ieee80211_ccmp_deinit(void *priv)
2806 + struct ieee80211_ccmp_data *_priv = priv;
2807 + if (_priv && _priv->tfm)
2808 + //#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
2809 + #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!IN_OPENSUSE_SLED))
2810 + crypto_free_tfm(_priv->tfm);
2812 + crypto_free_cipher((void *)_priv->tfm);
2818 +static inline void xor_block(u8 *b, u8 *a, size_t len)
2821 + for (i = 0; i < len; i++)
2826 +static void ccmp_init_blocks(struct crypto_tfm *tfm,
2827 + struct ieee80211_hdr *hdr,
2828 + u8 *pn, size_t dlen, u8 *b0, u8 *auth,
2834 + int a4_included, qc_included;
2835 + u8 aad[2 * AES_BLOCK_LEN];
2837 + fc = le16_to_cpu(hdr->frame_ctl);
2838 + a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
2839 + (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS));
2841 + qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
2842 + (WLAN_FC_GET_STYPE(fc) & 0x08));
2844 + // fixed by David :2006.9.6
2845 + qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
2846 + (WLAN_FC_GET_STYPE(fc) & 0x80));
2850 + if (qc_included) {
2851 + pos = (u8 *) &hdr->addr4;
2857 + /* CCM Initial Block:
2858 + * Flag (Include authentication header, M=3 (8-octet MIC),
2859 + * L=1 (2-octet Dlen))
2860 + * Nonce: 0x00 | A2 | PN
2864 + memcpy(b0 + 2, hdr->addr2, ETH_ALEN);
2865 + memcpy(b0 + 8, pn, CCMP_PN_LEN);
2866 + b0[14] = (dlen >> 8) & 0xff;
2867 + b0[15] = dlen & 0xff;
2870 + * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
2872 + * SC with bits 4..15 (seq#) masked to zero
2877 + aad[0] = 0; /* aad_len >> 8 */
2878 + aad[1] = aad_len & 0xff;
2879 + aad[2] = pos[0] & 0x8f;
2880 + aad[3] = pos[1] & 0xc7;
2881 + memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN);
2882 + pos = (u8 *) &hdr->seq_ctl;
2883 + aad[22] = pos[0] & 0x0f;
2884 + aad[23] = 0; /* all bits masked */
2885 + memset(aad + 24, 0, 8);
2887 + memcpy(aad + 24, hdr->addr4, ETH_ALEN);
2888 + if (qc_included) {
2889 + aad[a4_included ? 30 : 24] = qc;
2890 + /* rest of QC masked */
2893 + /* Start with the first block and AAD */
2894 + ieee80211_ccmp_aes_encrypt(tfm, b0, auth);
2895 + xor_block(auth, aad, AES_BLOCK_LEN);
2896 + ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
2897 + xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN);
2898 + ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
2900 + b0[14] = b0[15] = 0;
2901 + ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
2905 +static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
2907 + struct ieee80211_ccmp_data *key = priv;
2910 + struct ieee80211_hdr *hdr;
2912 + int blocks, last, len;
2914 + u8 *b0 = key->tx_b0;
2915 + u8 *b = key->tx_b;
2916 + u8 *e = key->tx_e;
2917 + u8 *s0 = key->tx_s0;
2919 + if (skb_headroom(skb) < CCMP_HDR_LEN ||
2920 + skb_tailroom(skb) < CCMP_MIC_LEN ||
2921 + skb->len < hdr_len)
2924 + data_len = skb->len - hdr_len;
2925 + pos = skb_push(skb, CCMP_HDR_LEN);
2926 + memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
2928 +// mic = skb_put(skb, CCMP_MIC_LEN);
2930 + i = CCMP_PN_LEN - 1;
2933 + if (key->tx_pn[i] != 0)
2938 + *pos++ = key->tx_pn[5];
2939 + *pos++ = key->tx_pn[4];
2941 + *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */;
2942 + *pos++ = key->tx_pn[3];
2943 + *pos++ = key->tx_pn[2];
2944 + *pos++ = key->tx_pn[1];
2945 + *pos++ = key->tx_pn[0];
2947 + hdr = (struct ieee80211_hdr *) skb->data;
2949 + //mic is moved to here by john
2950 + mic = skb_put(skb, CCMP_MIC_LEN);
2952 + ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
2954 + blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
2955 + last = data_len % AES_BLOCK_LEN;
2957 + for (i = 1; i <= blocks; i++) {
2958 + len = (i == blocks && last) ? last : AES_BLOCK_LEN;
2959 + /* Authentication */
2960 + xor_block(b, pos, len);
2961 + ieee80211_ccmp_aes_encrypt(key->tfm, b, b);
2962 + /* Encryption, with counter */
2963 + b0[14] = (i >> 8) & 0xff;
2964 + b0[15] = i & 0xff;
2965 + ieee80211_ccmp_aes_encrypt(key->tfm, b0, e);
2966 + xor_block(pos, e, len);
2970 + for (i = 0; i < CCMP_MIC_LEN; i++)
2971 + mic[i] = b[i] ^ s0[i];
2977 +static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
2979 + struct ieee80211_ccmp_data *key = priv;
2981 + struct ieee80211_hdr *hdr;
2984 + size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN;
2985 + u8 *mic = skb->data + skb->len - CCMP_MIC_LEN;
2986 + u8 *b0 = key->rx_b0;
2987 + u8 *b = key->rx_b;
2988 + u8 *a = key->rx_a;
2989 + int i, blocks, last, len;
2991 + if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
2992 + key->dot11RSNAStatsCCMPFormatErrors++;
2996 + hdr = (struct ieee80211_hdr *) skb->data;
2997 + pos = skb->data + hdr_len;
2999 + if (!(keyidx & (1 << 5))) {
3000 + if (net_ratelimit()) {
3001 + printk(KERN_DEBUG "CCMP: received packet without ExtIV"
3002 + " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
3004 + key->dot11RSNAStatsCCMPFormatErrors++;
3008 + if (key->key_idx != keyidx) {
3009 + printk(KERN_DEBUG "CCMP: RX tkey->key_idx=%d frame "
3010 + "keyidx=%d priv=%p\n", key->key_idx, keyidx, priv);
3013 + if (!key->key_set) {
3014 + if (net_ratelimit()) {
3015 + printk(KERN_DEBUG "CCMP: received packet from " MAC_FMT
3016 + " with keyid=%d that does not have a configured"
3017 + " key\n", MAC_ARG(hdr->addr2), keyidx);
3030 + if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
3031 + if (net_ratelimit()) {
3032 + printk(KERN_DEBUG "CCMP: replay detected: STA=" MAC_FMT
3033 + " previous PN %02x%02x%02x%02x%02x%02x "
3034 + "received PN %02x%02x%02x%02x%02x%02x\n",
3035 + MAC_ARG(hdr->addr2), MAC_ARG(key->rx_pn),
3038 + key->dot11RSNAStatsCCMPReplays++;
3043 + ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b);
3044 + xor_block(mic, b, CCMP_MIC_LEN);
3046 + blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
3047 + last = data_len % AES_BLOCK_LEN;
3049 + for (i = 1; i <= blocks; i++) {
3050 + len = (i == blocks && last) ? last : AES_BLOCK_LEN;
3051 + /* Decrypt, with counter */
3052 + b0[14] = (i >> 8) & 0xff;
3053 + b0[15] = i & 0xff;
3054 + ieee80211_ccmp_aes_encrypt(key->tfm, b0, b);
3055 + xor_block(pos, b, len);
3056 + /* Authentication */
3057 + xor_block(a, pos, len);
3058 + ieee80211_ccmp_aes_encrypt(key->tfm, a, a);
3062 + if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
3063 + if (net_ratelimit()) {
3064 + printk(KERN_DEBUG "CCMP: decrypt failed: STA="
3065 + MAC_FMT "\n", MAC_ARG(hdr->addr2));
3067 + key->dot11RSNAStatsCCMPDecryptErrors++;
3071 + memcpy(key->rx_pn, pn, CCMP_PN_LEN);
3074 + /* Remove hdr and MIC */
3075 + memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len);
3076 + skb_pull(skb, CCMP_HDR_LEN);
3077 + skb_trim(skb, skb->len - CCMP_MIC_LEN);
3083 +static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
3085 + struct ieee80211_ccmp_data *data = priv;
3087 + struct crypto_tfm *tfm = data->tfm;
3089 + keyidx = data->key_idx;
3090 + memset(data, 0, sizeof(*data));
3091 + data->key_idx = keyidx;
3093 + if (len == CCMP_TK_LEN) {
3094 + memcpy(data->key, key, CCMP_TK_LEN);
3095 + data->key_set = 1;
3097 + data->rx_pn[0] = seq[5];
3098 + data->rx_pn[1] = seq[4];
3099 + data->rx_pn[2] = seq[3];
3100 + data->rx_pn[3] = seq[2];
3101 + data->rx_pn[4] = seq[1];
3102 + data->rx_pn[5] = seq[0];
3104 + crypto_cipher_setkey((void *)data->tfm, data->key, CCMP_TK_LEN);
3105 + } else if (len == 0)
3106 + data->key_set = 0;
3114 +static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
3116 + struct ieee80211_ccmp_data *data = priv;
3118 + if (len < CCMP_TK_LEN)
3121 + if (!data->key_set)
3123 + memcpy(key, data->key, CCMP_TK_LEN);
3126 + seq[0] = data->tx_pn[5];
3127 + seq[1] = data->tx_pn[4];
3128 + seq[2] = data->tx_pn[3];
3129 + seq[3] = data->tx_pn[2];
3130 + seq[4] = data->tx_pn[1];
3131 + seq[5] = data->tx_pn[0];
3134 + return CCMP_TK_LEN;
3138 +static char * ieee80211_ccmp_print_stats(char *p, void *priv)
3140 + struct ieee80211_ccmp_data *ccmp = priv;
3141 + p += sprintf(p, "key[%d] alg=CCMP key_set=%d "
3142 + "tx_pn=%02x%02x%02x%02x%02x%02x "
3143 + "rx_pn=%02x%02x%02x%02x%02x%02x "
3144 + "format_errors=%d replays=%d decrypt_errors=%d\n",
3145 + ccmp->key_idx, ccmp->key_set,
3146 + MAC_ARG(ccmp->tx_pn), MAC_ARG(ccmp->rx_pn),
3147 + ccmp->dot11RSNAStatsCCMPFormatErrors,
3148 + ccmp->dot11RSNAStatsCCMPReplays,
3149 + ccmp->dot11RSNAStatsCCMPDecryptErrors);
3154 +void ieee80211_ccmp_null(void)
3156 +// printk("============>%s()\n", __FUNCTION__);
3159 +static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
3161 + .init = ieee80211_ccmp_init,
3162 + .deinit = ieee80211_ccmp_deinit,
3163 + .encrypt_mpdu = ieee80211_ccmp_encrypt,
3164 + .decrypt_mpdu = ieee80211_ccmp_decrypt,
3165 + .encrypt_msdu = NULL,
3166 + .decrypt_msdu = NULL,
3167 + .set_key = ieee80211_ccmp_set_key,
3168 + .get_key = ieee80211_ccmp_get_key,
3169 + .print_stats = ieee80211_ccmp_print_stats,
3170 + .extra_prefix_len = CCMP_HDR_LEN,
3171 + .extra_postfix_len = CCMP_MIC_LEN,
3172 + .owner = THIS_MODULE,
3176 +int ieee80211_crypto_ccmp_init(void)
3178 + return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
3182 +void ieee80211_crypto_ccmp_exit(void)
3184 + ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
3188 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
3189 +EXPORT_SYMBOL(ieee80211_ccmp_null);
3191 +EXPORT_SYMBOL_NOVERS(ieee80211_ccmp_null);
3195 +//module_init(ieee80211_crypto_ccmp_init);
3196 +//module_exit(ieee80211_crypto_ccmp_exit);
3198 +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h
3201 + * Original code based on Host AP (software wireless LAN access point) driver
3202 + * for Intersil Prism2/2.5/3.
3204 + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
3205 + * <jkmaline@cc.hut.fi>
3206 + * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
3208 + * Adaption to a generic IEEE 802.11 stack by James Ketrenos
3209 + * <jketreno@linux.intel.com>
3211 + * Copyright (c) 2004, Intel Corporation
3213 + * This program is free software; you can redistribute it and/or modify
3214 + * it under the terms of the GNU General Public License version 2 as
3215 + * published by the Free Software Foundation. See README and COPYING for
3220 + * This file defines the interface to the ieee80211 crypto module.
3222 +#ifndef IEEE80211_CRYPT_H
3223 +#define IEEE80211_CRYPT_H
3225 +#include <linux/skbuff.h>
3227 +struct ieee80211_crypto_ops {
3230 + /* init new crypto context (e.g., allocate private data space,
3231 + * select IV, etc.); returns NULL on failure or pointer to allocated
3232 + * private data on success */
3233 + void * (*init)(int keyidx);
3235 + /* deinitialize crypto context and free allocated private data */
3236 + void (*deinit)(void *priv);
3238 + /* encrypt/decrypt return < 0 on error or >= 0 on success. The return
3239 + * value from decrypt_mpdu is passed as the keyidx value for
3240 + * decrypt_msdu. skb must have enough head and tail room for the
3241 + * encryption; if not, error will be returned; these functions are
3242 + * called for all MPDUs (i.e., fragments).
3244 + int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
3245 + int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
3247 + /* These functions are called for full MSDUs, i.e. full frames.
3248 + * These can be NULL if full MSDU operations are not needed. */
3249 + int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
3250 + int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
3253 + int (*set_key)(void *key, int len, u8 *seq, void *priv);
3254 + int (*get_key)(void *key, int len, u8 *seq, void *priv);
3256 + /* procfs handler for printing out key information and possible
3258 + char * (*print_stats)(char *p, void *priv);
3260 + /* maximum number of bytes added by encryption; encrypt buf is
3261 + * allocated with extra_prefix_len bytes, copy of in_buf, and
3262 + * extra_postfix_len; encrypt need not use all this space, but
3263 + * the result must start at the beginning of the buffer and correct
3264 + * length must be returned */
3265 + int extra_prefix_len, extra_postfix_len;
3267 + struct module *owner;
3270 +struct ieee80211_crypt_data {
3271 + struct list_head list; /* delayed deletion list */
3272 + struct ieee80211_crypto_ops *ops;
3277 +int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
3278 +int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
3279 +struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name);
3280 +void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
3281 +void ieee80211_crypt_deinit_handler(unsigned long);
3282 +void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
3283 + struct ieee80211_crypt_data **crypt);
3287 +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c
3290 + * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
3292 + * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
3294 + * This program is free software; you can redistribute it and/or modify
3295 + * it under the terms of the GNU General Public License version 2 as
3296 + * published by the Free Software Foundation. See README and COPYING for
3300 +//#include <linux/config.h>
3301 +#include <linux/version.h>
3302 +#include <linux/module.h>
3303 +#include <linux/init.h>
3304 +#include <linux/slab.h>
3305 +#include <linux/random.h>
3306 +#include <linux/skbuff.h>
3307 +#include <linux/netdevice.h>
3308 +#include <linux/if_ether.h>
3309 +#include <linux/if_arp.h>
3310 +#include <asm/string.h>
3312 +#include "ieee80211.h"
3314 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
3315 +#include "rtl_crypto.h"
3317 +#include <linux/crypto.h>
3319 +//#include <asm/scatterlist.h>
3320 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
3321 + #include <asm/scatterlist.h>
3323 + #include <linux/scatterlist.h>
3326 +#include <linux/crc32.h>
3328 +MODULE_AUTHOR("Jouni Malinen");
3329 +MODULE_DESCRIPTION("Host AP crypt: TKIP");
3330 +MODULE_LICENSE("GPL");
3332 +#ifdef OPENSUSE_SLED
3333 +#ifndef IN_OPENSUSE_SLED
3334 +#define IN_OPENSUSE_SLED 1
3338 +struct ieee80211_tkip_data {
3339 +#define TKIP_KEY_LEN 32
3340 + u8 key[TKIP_KEY_LEN];
3346 + int tx_phase1_done;
3351 + int rx_phase1_done;
3355 + u32 dot11RSNAStatsTKIPReplays;
3356 + u32 dot11RSNAStatsTKIPICVErrors;
3357 + u32 dot11RSNAStatsTKIPLocalMICFailures;
3361 + #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))||(IN_OPENSUSE_SLED))
3362 + struct crypto_blkcipher *rx_tfm_arc4;
3363 + struct crypto_hash *rx_tfm_michael;
3364 + struct crypto_blkcipher *tx_tfm_arc4;
3365 + struct crypto_hash *tx_tfm_michael;
3368 + struct crypto_tfm *tfm_arc4;
3369 + struct crypto_tfm *tfm_michael;
3371 + /* scratch buffers for virt_to_page() (crypto API) */
3372 + u8 rx_hdr[16], tx_hdr[16];
3375 +static void * ieee80211_tkip_init(int key_idx)
3377 + struct ieee80211_tkip_data *priv;
3379 + priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
3382 + memset(priv, 0, sizeof(*priv));
3383 + priv->key_idx = key_idx;
3385 + #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
3386 + priv->tfm_arc4 = crypto_alloc_tfm("arc4", 0);
3387 + if (priv->tfm_arc4 == NULL) {
3388 + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
3389 + "crypto API arc4\n");
3393 + priv->tfm_michael = crypto_alloc_tfm("michael_mic", 0);
3394 + if (priv->tfm_michael == NULL) {
3395 + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
3396 + "crypto API michael_mic\n");
3401 + priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
3402 + CRYPTO_ALG_ASYNC);
3403 + if (IS_ERR(priv->tx_tfm_arc4)) {
3404 + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
3405 + "crypto API arc4\n");
3406 + priv->tx_tfm_arc4 = NULL;
3410 + priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
3411 + CRYPTO_ALG_ASYNC);
3412 + if (IS_ERR(priv->tx_tfm_michael)) {
3413 + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
3414 + "crypto API michael_mic\n");
3415 + priv->tx_tfm_michael = NULL;
3419 + priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
3420 + CRYPTO_ALG_ASYNC);
3421 + if (IS_ERR(priv->rx_tfm_arc4)) {
3422 + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
3423 + "crypto API arc4\n");
3424 + priv->rx_tfm_arc4 = NULL;
3428 + priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
3429 + CRYPTO_ALG_ASYNC);
3430 + if (IS_ERR(priv->rx_tfm_michael)) {
3431 + printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
3432 + "crypto API michael_mic\n");
3433 + priv->rx_tfm_michael = NULL;
3441 + #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
3442 + if (priv->tfm_michael)
3443 + crypto_free_tfm(priv->tfm_michael);
3444 + if (priv->tfm_arc4)
3445 + crypto_free_tfm(priv->tfm_arc4);
3447 + if (priv->tx_tfm_michael)
3448 + crypto_free_hash(priv->tx_tfm_michael);
3449 + if (priv->tx_tfm_arc4)
3450 + crypto_free_blkcipher(priv->tx_tfm_arc4);
3451 + if (priv->rx_tfm_michael)
3452 + crypto_free_hash(priv->rx_tfm_michael);
3453 + if (priv->rx_tfm_arc4)
3454 + crypto_free_blkcipher(priv->rx_tfm_arc4);
3463 +static void ieee80211_tkip_deinit(void *priv)
3465 + struct ieee80211_tkip_data *_priv = priv;
3466 + #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
3467 + if (_priv && _priv->tfm_michael)
3468 + crypto_free_tfm(_priv->tfm_michael);
3469 + if (_priv && _priv->tfm_arc4)
3470 + crypto_free_tfm(_priv->tfm_arc4);
3473 + if (_priv->tx_tfm_michael)
3474 + crypto_free_hash(_priv->tx_tfm_michael);
3475 + if (_priv->tx_tfm_arc4)
3476 + crypto_free_blkcipher(_priv->tx_tfm_arc4);
3477 + if (_priv->rx_tfm_michael)
3478 + crypto_free_hash(_priv->rx_tfm_michael);
3479 + if (_priv->rx_tfm_arc4)
3480 + crypto_free_blkcipher(_priv->rx_tfm_arc4);
3487 +static inline u16 RotR1(u16 val)
3489 + return (val >> 1) | (val << 15);
3493 +static inline u8 Lo8(u16 val)
3495 + return val & 0xff;
3499 +static inline u8 Hi8(u16 val)
3505 +static inline u16 Lo16(u32 val)
3507 + return val & 0xffff;
3511 +static inline u16 Hi16(u32 val)
3517 +static inline u16 Mk16(u8 hi, u8 lo)
3519 + return lo | (((u16) hi) << 8);
3523 +static inline u16 Mk16_le(u16 *v)
3525 + return le16_to_cpu(*v);
3529 +static const u16 Sbox[256] =
3531 + 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
3532 + 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
3533 + 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
3534 + 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
3535 + 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
3536 + 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
3537 + 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
3538 + 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
3539 + 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
3540 + 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
3541 + 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
3542 + 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
3543 + 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
3544 + 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
3545 + 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
3546 + 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
3547 + 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
3548 + 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
3549 + 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
3550 + 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
3551 + 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
3552 + 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
3553 + 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
3554 + 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
3555 + 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
3556 + 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
3557 + 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
3558 + 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
3559 + 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
3560 + 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
3561 + 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
3562 + 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
3566 +static inline u16 _S_(u16 v)
3568 + u16 t = Sbox[Hi8(v)];
3569 + return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
3573 +#define PHASE1_LOOP_COUNT 8
3575 +static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
3579 + /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
3580 + TTAK[0] = Lo16(IV32);
3581 + TTAK[1] = Hi16(IV32);
3582 + TTAK[2] = Mk16(TA[1], TA[0]);
3583 + TTAK[3] = Mk16(TA[3], TA[2]);
3584 + TTAK[4] = Mk16(TA[5], TA[4]);
3586 + for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
3588 + TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
3589 + TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
3590 + TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
3591 + TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
3592 + TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
3597 +static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
3600 + /* Make temporary area overlap WEP seed so that the final copy can be
3601 + * avoided on little endian hosts. */
3602 + u16 *PPK = (u16 *) &WEPSeed[4];
3604 + /* Step 1 - make copy of TTAK and bring in TSC */
3610 + PPK[5] = TTAK[4] + IV16;
3612 + /* Step 2 - 96-bit bijective mixing using S-box */
3613 + PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0]));
3614 + PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2]));
3615 + PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4]));
3616 + PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6]));
3617 + PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8]));
3618 + PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10]));
3620 + PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12]));
3621 + PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14]));
3622 + PPK[2] += RotR1(PPK[1]);
3623 + PPK[3] += RotR1(PPK[2]);
3624 + PPK[4] += RotR1(PPK[3]);
3625 + PPK[5] += RotR1(PPK[4]);
3627 + /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
3628 + * WEPSeed[0..2] is transmitted as WEP IV */
3629 + WEPSeed[0] = Hi8(IV16);
3630 + WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
3631 + WEPSeed[2] = Lo8(IV16);
3632 + WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1);
3634 +#ifdef __BIG_ENDIAN
3637 + for (i = 0; i < 6; i++)
3638 + PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
3643 +static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
3645 + struct ieee80211_tkip_data *tkey = priv;
3646 + #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))||(IN_OPENSUSE_SLED))
3647 + struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4};
3651 + struct ieee80211_hdr *hdr;
3653 + u8 rc4key[16],*icv;
3655 + struct scatterlist sg;
3660 + if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
3661 + skb->len < hdr_len)
3664 + hdr = (struct ieee80211_hdr *) skb->data;
3666 +printk("@@ tkey\n");
3667 +printk("%x|", ((u32*)tkey->key)[0]);
3668 +printk("%x|", ((u32*)tkey->key)[1]);
3669 +printk("%x|", ((u32*)tkey->key)[2]);
3670 +printk("%x|", ((u32*)tkey->key)[3]);
3671 +printk("%x|", ((u32*)tkey->key)[4]);
3672 +printk("%x|", ((u32*)tkey->key)[5]);
3673 +printk("%x|", ((u32*)tkey->key)[6]);
3674 +printk("%x\n", ((u32*)tkey->key)[7]);
3678 + if (!tkey->tx_phase1_done) {
3679 + tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
3681 + tkey->tx_phase1_done = 1;
3683 + tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
3686 + tkey->tx_phase1_done = 1;
3687 +#endif /*JOHN_TKIP*/
3689 + len = skb->len - hdr_len;
3690 + pos = skb_push(skb, 8);
3691 + memmove(pos, pos + 8, hdr_len);
3695 + *pos++ = Hi8(tkey->tx_iv16);
3696 + *pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F;
3697 + *pos++ = Lo8(tkey->tx_iv16);
3699 + *pos++ = rc4key[0];
3700 + *pos++ = rc4key[1];
3701 + *pos++ = rc4key[2];
3703 + *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */;
3704 + *pos++ = tkey->tx_iv32 & 0xff;
3705 + *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
3706 + *pos++ = (tkey->tx_iv32 >> 16) & 0xff;
3707 + *pos++ = (tkey->tx_iv32 >> 24) & 0xff;
3709 + icv = skb_put(skb, 4);
3710 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
3711 + crc = ~crc32_le(~0, pos, len);
3713 + crc = ~ether_crc_le(len, pos);
3716 + icv[1] = crc >> 8;
3717 + icv[2] = crc >> 16;
3718 + icv[3] = crc >> 24;
3719 + #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
3720 + crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
3721 + sg.page = virt_to_page(pos);
3722 + sg.offset = offset_in_page(pos);
3723 + sg.length = len + 4;
3724 + crypto_cipher_encrypt(tkey->tfm_arc4, &sg, &sg, len + 4);
3726 + crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
3727 + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
3728 + sg.page = virt_to_page(pos);
3729 + sg.offset = offset_in_page(pos);
3730 + sg.length = len + 4;
3732 + sg_init_one(&sg, pos, len+4);
3734 + ret= crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
3738 + if (tkey->tx_iv16 == 0) {
3739 + tkey->tx_phase1_done = 0;
3743 + #if((LINUX_VERSION_CODE <KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
3753 +static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
3755 + struct ieee80211_tkip_data *tkey = priv;
3756 + #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21)) ||(IN_OPENSUSE_SLED))
3757 + struct blkcipher_desc desc = {.tfm = tkey->rx_tfm_arc4};
3762 + struct ieee80211_hdr *hdr;
3766 + struct scatterlist sg;
3770 + if (skb->len < hdr_len + 8 + 4)
3773 + hdr = (struct ieee80211_hdr *) skb->data;
3774 + pos = skb->data + hdr_len;
3776 + if (!(keyidx & (1 << 5))) {
3777 + if (net_ratelimit()) {
3778 + printk(KERN_DEBUG "TKIP: received packet without ExtIV"
3779 + " flag from " MAC_FMT "\n", MAC_ARG(hdr->addr2));
3784 + if (tkey->key_idx != keyidx) {
3785 + printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
3786 + "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
3789 + if (!tkey->key_set) {
3790 + if (net_ratelimit()) {
3791 + printk(KERN_DEBUG "TKIP: received packet from " MAC_FMT
3792 + " with keyid=%d that does not have a configured"
3793 + " key\n", MAC_ARG(hdr->addr2), keyidx);
3797 + iv16 = (pos[0] << 8) | pos[2];
3798 + iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
3802 + if (iv32 < tkey->rx_iv32 ||
3803 + (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
3804 + if (net_ratelimit()) {
3805 + printk(KERN_DEBUG "TKIP: replay detected: STA=" MAC_FMT
3806 + " previous TSC %08x%04x received TSC "
3807 + "%08x%04x\n", MAC_ARG(hdr->addr2),
3808 + tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
3810 + tkey->dot11RSNAStatsTKIPReplays++;
3814 + if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
3815 + tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
3816 + tkey->rx_phase1_done = 1;
3818 + tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
3820 + plen = skb->len - hdr_len - 12;
3821 + #if((LINUX_VERSION_CODE <KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
3822 + crypto_cipher_setkey(tkey->tfm_arc4, rc4key, 16);
3823 + sg.page = virt_to_page(pos);
3824 + sg.offset = offset_in_page(pos);
3825 + sg.length = plen + 4;
3826 + crypto_cipher_decrypt(tkey->tfm_arc4, &sg, &sg, plen + 4);
3828 + crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
3829 + #if(LINUX_VERSION_CODE <KERNEL_VERSION(2,6,24))
3830 + sg.page = virt_to_page(pos);
3831 + sg.offset = offset_in_page(pos);
3832 + sg.length = plen + 4;
3834 + sg_init_one(&sg, pos, plen+4);
3836 + if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
3837 + if (net_ratelimit()) {
3838 + printk(KERN_DEBUG ": TKIP: failed to decrypt "
3839 + "received packet from " MAC_FMT "\n",
3840 + MAC_ARG(hdr->addr2));
3846 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
3847 + crc = ~crc32_le(~0, pos, plen);
3849 + crc = ~ether_crc_le(plen, pos);
3852 + icv[1] = crc >> 8;
3853 + icv[2] = crc >> 16;
3854 + icv[3] = crc >> 24;
3855 + if (memcmp(icv, pos + plen, 4) != 0) {
3856 + if (iv32 != tkey->rx_iv32) {
3857 + /* Previously cached Phase1 result was already lost, so
3858 + * it needs to be recalculated for the next packet. */
3859 + tkey->rx_phase1_done = 0;
3861 + if (net_ratelimit()) {
3862 + printk(KERN_DEBUG "TKIP: ICV error detected: STA="
3863 + MAC_FMT "\n", MAC_ARG(hdr->addr2));
3865 + tkey->dot11RSNAStatsTKIPICVErrors++;
3869 +#endif /* JOHN_TKIP */
3871 + /* Update real counters only after Michael MIC verification has
3873 + tkey->rx_iv32_new = iv32;
3874 + tkey->rx_iv16_new = iv16;
3876 + /* Remove IV and ICV */
3877 + memmove(skb->data + 8, skb->data, hdr_len);
3879 + skb_trim(skb, skb->len - 4);
3883 +if( ((u16*)skb->data)[0] & 0x4000){
3884 + printk("@@ rx decrypted skb->data");
3886 + for(i=0;i<skb->len;i++){
3887 + if( (i%24)==0 ) printk("\n");
3888 + printk("%2x ", ((u8*)skb->data)[i]);
3892 +#endif /*JOHN_DUMP*/
3896 +#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21)) && (!IN_OPENSUSE_SLED))
3897 +static int michael_mic(struct ieee80211_tkip_data *tkey, u8 *key, u8 *hdr,
3898 + u8 *data, size_t data_len, u8 *mic)
3900 + struct scatterlist sg[2];
3901 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
3902 + struct hash_desc desc;
3905 + if (tkey->tfm_michael == NULL) {
3906 + printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
3909 + sg[0].page = virt_to_page(hdr);
3910 + sg[0].offset = offset_in_page(hdr);
3911 + sg[0].length = 16;
3913 + sg[1].page = virt_to_page(data);
3914 + sg[1].offset = offset_in_page(data);
3915 + sg[1].length = data_len;
3917 + //crypto_digest_init(tkey->tfm_michael);
3918 + //crypto_digest_setkey(tkey->tfm_michael, key, 8);
3919 + //crypto_digest_update(tkey->tfm_michael, sg, 2);
3920 + //crypto_digest_final(tkey->tfm_michael, mic);
3923 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
3924 + crypto_digest_init(tkey->tfm_michael);
3925 + crypto_digest_setkey(tkey->tfm_michael, key, 8);
3926 + crypto_digest_update(tkey->tfm_michael, sg, 2);
3927 + crypto_digest_final(tkey->tfm_michael, mic);
3931 +if (crypto_hash_setkey(tkey->tfm_michael, key, 8))
3935 + desc.tfm = tkey->tfm_michael;
3937 + ret = crypto_hash_digest(&desc, sg, data_len + 16, mic);
3942 +static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
3943 + u8 * data, size_t data_len, u8 * mic)
3945 + struct hash_desc desc;
3946 + struct scatterlist sg[2];
3948 + if (tfm_michael == NULL) {
3949 + printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
3952 + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
3953 + sg[0].page = virt_to_page(hdr);
3954 + sg[0].offset = offset_in_page(hdr);
3955 + sg[0].length = 16;
3956 + sg[1].page = virt_to_page(data);
3957 + sg[1].offset = offset_in_page(data);
3958 + sg[1].length = data_len;
3960 + sg_init_table(sg, 2);
3961 + sg_set_buf(&sg[0], hdr, 16);
3962 + sg_set_buf(&sg[1], data, data_len);
3965 + if (crypto_hash_setkey(tfm_michael, key, 8))
3968 + desc.tfm = tfm_michael;
3970 + return crypto_hash_digest(&desc, sg, data_len + 16, mic);
3976 +static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
3978 + struct ieee80211_hdr *hdr11;
3980 + hdr11 = (struct ieee80211_hdr *) skb->data;
3981 + switch (le16_to_cpu(hdr11->frame_ctl) &
3982 + (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
3983 + case IEEE80211_FCTL_TODS:
3984 + memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
3985 + memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
3987 + case IEEE80211_FCTL_FROMDS:
3988 + memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
3989 + memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
3991 + case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
3992 + memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
3993 + memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
3996 + memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
3997 + memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
4001 + hdr[12] = 0; /* priority */
4003 + hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
4007 +static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv)
4009 + struct ieee80211_tkip_data *tkey = priv;
4011 + struct ieee80211_hdr *hdr;
4013 + hdr = (struct ieee80211_hdr *) skb->data;
4015 + if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
4016 + printk(KERN_DEBUG "Invalid packet for Michael MIC add "
4017 + "(tailroom=%d hdr_len=%d skb->len=%d)\n",
4018 + skb_tailroom(skb), hdr_len, skb->len);
4022 + michael_mic_hdr(skb, tkey->tx_hdr);
4024 + // { david, 2006.9.1
4025 + // fix the wpa process with wmm enabled.
4026 + if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
4027 + tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
4030 + pos = skb_put(skb, 8);
4031 + #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
4032 + if (michael_mic(tkey, &tkey->key[16], tkey->tx_hdr,
4033 + skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
4035 + if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
4036 + skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
4044 +#if WIRELESS_EXT >= 18
4045 +static void ieee80211_michael_mic_failure(struct net_device *dev,
4046 + struct ieee80211_hdr *hdr,
4049 + union iwreq_data wrqu;
4050 + struct iw_michaelmicfailure ev;
4052 + /* TODO: needed parameters: count, keyid, key type, TSC */
4053 + memset(&ev, 0, sizeof(ev));
4054 + ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
4055 + if (hdr->addr1[0] & 0x01)
4056 + ev.flags |= IW_MICFAILURE_GROUP;
4058 + ev.flags |= IW_MICFAILURE_PAIRWISE;
4059 + ev.src_addr.sa_family = ARPHRD_ETHER;
4060 + memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
4061 + memset(&wrqu, 0, sizeof(wrqu));
4062 + wrqu.data.length = sizeof(ev);
4063 + wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);
4065 +#elif WIRELESS_EXT >= 15
4066 +static void ieee80211_michael_mic_failure(struct net_device *dev,
4067 + struct ieee80211_hdr *hdr,
4070 + union iwreq_data wrqu;
4073 + /* TODO: needed parameters: count, keyid, key type, TSC */
4074 + sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr="
4075 + MAC_FMT ")", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni",
4076 + MAC_ARG(hdr->addr2));
4077 + memset(&wrqu, 0, sizeof(wrqu));
4078 + wrqu.data.length = strlen(buf);
4079 + wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf);
4081 +#else /* WIRELESS_EXT >= 15 */
4082 +static inline void ieee80211_michael_mic_failure(struct net_device *dev,
4083 + struct ieee80211_hdr *hdr,
4087 +#endif /* WIRELESS_EXT >= 15 */
4090 +static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
4091 + int hdr_len, void *priv)
4093 + struct ieee80211_tkip_data *tkey = priv;
4095 + struct ieee80211_hdr *hdr;
4097 + hdr = (struct ieee80211_hdr *) skb->data;
4099 + if (!tkey->key_set)
4102 + michael_mic_hdr(skb, tkey->rx_hdr);
4103 + // { david, 2006.9.1
4104 + // fix the wpa process with wmm enabled.
4105 + if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) {
4106 + tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
4109 + #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
4110 + if (michael_mic(tkey, &tkey->key[24], tkey->rx_hdr,
4111 + skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
4113 + if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
4114 + skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
4117 + if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
4118 + struct ieee80211_hdr *hdr;
4119 + hdr = (struct ieee80211_hdr *) skb->data;
4120 + printk(KERN_DEBUG "%s: Michael MIC verification failed for "
4121 + "MSDU from " MAC_FMT " keyidx=%d\n",
4122 + skb->dev ? skb->dev->name : "N/A", MAC_ARG(hdr->addr2),
4125 + ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
4126 + tkey->dot11RSNAStatsTKIPLocalMICFailures++;
4130 + /* Update TSC counters for RX now that the packet verification has
4132 + tkey->rx_iv32 = tkey->rx_iv32_new;
4133 + tkey->rx_iv16 = tkey->rx_iv16_new;
4135 + skb_trim(skb, skb->len - 8);
4141 +static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
4143 + struct ieee80211_tkip_data *tkey = priv;
4145 + #if ((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
4146 + struct crypto_tfm *tfm = tkey->tfm_michael;
4147 + struct crypto_tfm *tfm2 = tkey->tfm_arc4;
4149 + struct crypto_hash *tfm = tkey->tx_tfm_michael;
4150 + struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
4151 + struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
4152 + struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;
4155 + keyidx = tkey->key_idx;
4156 + memset(tkey, 0, sizeof(*tkey));
4157 + tkey->key_idx = keyidx;
4159 + #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
4160 + tkey->tfm_michael = tfm;
4161 + tkey->tfm_arc4 = tfm2;
4163 + tkey->tx_tfm_michael = tfm;
4164 + tkey->tx_tfm_arc4 = tfm2;
4165 + tkey->rx_tfm_michael = tfm3;
4166 + tkey->rx_tfm_arc4 = tfm4;
4169 + if (len == TKIP_KEY_LEN) {
4170 + memcpy(tkey->key, key, TKIP_KEY_LEN);
4171 + tkey->key_set = 1;
4172 + tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
4174 + tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
4175 + (seq[3] << 8) | seq[2];
4176 + tkey->rx_iv16 = (seq[1] << 8) | seq[0];
4178 + } else if (len == 0)
4179 + tkey->key_set = 0;
4187 +static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv)
4189 + struct ieee80211_tkip_data *tkey = priv;
4191 + if (len < TKIP_KEY_LEN)
4194 + if (!tkey->key_set)
4196 + memcpy(key, tkey->key, TKIP_KEY_LEN);
4199 + /* Return the sequence number of the last transmitted frame. */
4200 + u16 iv16 = tkey->tx_iv16;
4201 + u32 iv32 = tkey->tx_iv32;
4205 + seq[0] = tkey->tx_iv16;
4206 + seq[1] = tkey->tx_iv16 >> 8;
4207 + seq[2] = tkey->tx_iv32;
4208 + seq[3] = tkey->tx_iv32 >> 8;
4209 + seq[4] = tkey->tx_iv32 >> 16;
4210 + seq[5] = tkey->tx_iv32 >> 24;
4213 + return TKIP_KEY_LEN;
4217 +static char * ieee80211_tkip_print_stats(char *p, void *priv)
4219 + struct ieee80211_tkip_data *tkip = priv;
4220 + p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
4221 + "tx_pn=%02x%02x%02x%02x%02x%02x "
4222 + "rx_pn=%02x%02x%02x%02x%02x%02x "
4223 + "replays=%d icv_errors=%d local_mic_failures=%d\n",
4224 + tkip->key_idx, tkip->key_set,
4225 + (tkip->tx_iv32 >> 24) & 0xff,
4226 + (tkip->tx_iv32 >> 16) & 0xff,
4227 + (tkip->tx_iv32 >> 8) & 0xff,
4228 + tkip->tx_iv32 & 0xff,
4229 + (tkip->tx_iv16 >> 8) & 0xff,
4230 + tkip->tx_iv16 & 0xff,
4231 + (tkip->rx_iv32 >> 24) & 0xff,
4232 + (tkip->rx_iv32 >> 16) & 0xff,
4233 + (tkip->rx_iv32 >> 8) & 0xff,
4234 + tkip->rx_iv32 & 0xff,
4235 + (tkip->rx_iv16 >> 8) & 0xff,
4236 + tkip->rx_iv16 & 0xff,
4237 + tkip->dot11RSNAStatsTKIPReplays,
4238 + tkip->dot11RSNAStatsTKIPICVErrors,
4239 + tkip->dot11RSNAStatsTKIPLocalMICFailures);
4244 +static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
4246 + .init = ieee80211_tkip_init,
4247 + .deinit = ieee80211_tkip_deinit,
4248 + .encrypt_mpdu = ieee80211_tkip_encrypt,
4249 + .decrypt_mpdu = ieee80211_tkip_decrypt,
4250 + .encrypt_msdu = ieee80211_michael_mic_add,
4251 + .decrypt_msdu = ieee80211_michael_mic_verify,
4252 + .set_key = ieee80211_tkip_set_key,
4253 + .get_key = ieee80211_tkip_get_key,
4254 + .print_stats = ieee80211_tkip_print_stats,
4255 + .extra_prefix_len = 4 + 4, /* IV + ExtIV */
4256 + .extra_postfix_len = 8 + 4, /* MIC + ICV */
4257 + .owner = THIS_MODULE,
4261 +int ieee80211_crypto_tkip_init(void)
4263 + return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
4267 +void ieee80211_crypto_tkip_exit(void)
4269 + ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
4273 +void ieee80211_tkip_null(void)
4275 +// printk("============>%s()\n", __FUNCTION__);
4280 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
4281 +EXPORT_SYMBOL(ieee80211_tkip_null);
4283 +EXPORT_SYMBOL_NOVERS(ieee80211_tkip_null);
4288 +//module_init(ieee80211_crypto_tkip_init);
4289 +//module_exit(ieee80211_crypto_tkip_exit);
4291 +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c
4294 + * Host AP crypt: host-based WEP encryption implementation for Host AP driver
4296 + * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi>
4298 + * This program is free software; you can redistribute it and/or modify
4299 + * it under the terms of the GNU General Public License version 2 as
4300 + * published by the Free Software Foundation. See README and COPYING for
4304 +//#include <linux/config.h>
4305 +#include <linux/version.h>
4306 +#include <linux/module.h>
4307 +#include <linux/init.h>
4308 +#include <linux/slab.h>
4309 +#include <linux/random.h>
4310 +#include <linux/skbuff.h>
4311 +#include <asm/string.h>
4313 +#include "ieee80211.h"
4315 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
4316 +#include "rtl_crypto.h"
4318 +#include <linux/crypto.h>
4321 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
4322 + #include <asm/scatterlist.h>
4324 + #include <linux/scatterlist.h>
4326 +//#include <asm/scatterlist.h>
4327 +#include <linux/crc32.h>
4329 +MODULE_AUTHOR("Jouni Malinen");
4330 +MODULE_DESCRIPTION("Host AP crypt: WEP");
4331 +MODULE_LICENSE("GPL");
4333 +#ifdef OPENSUSE_SLED
4334 +#ifndef IN_OPENSUSE_SLED
4335 +#define IN_OPENSUSE_SLED 1
4340 +struct prism2_wep_data {
4342 +#define WEP_KEY_LEN 13
4343 + u8 key[WEP_KEY_LEN + 1];
4346 + #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
4347 + struct crypto_tfm *tfm;
4349 + struct crypto_blkcipher *tx_tfm;
4350 + struct crypto_blkcipher *rx_tfm;
4355 +static void * prism2_wep_init(int keyidx)
4357 + struct prism2_wep_data *priv;
4359 + priv = kmalloc(sizeof(*priv), GFP_ATOMIC);
4362 + memset(priv, 0, sizeof(*priv));
4363 + priv->key_idx = keyidx;
4364 + #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
4365 + priv->tfm = crypto_alloc_tfm("arc4", 0);
4366 + if (priv->tfm == NULL) {
4367 + printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
4368 + "crypto API arc4\n");
4372 + priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
4373 + if (IS_ERR(priv->tx_tfm)) {
4374 + printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
4375 + "crypto API arc4\n");
4376 + priv->tx_tfm = NULL;
4379 + priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
4380 + if (IS_ERR(priv->rx_tfm)) {
4381 + printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate "
4382 + "crypto API arc4\n");
4383 + priv->rx_tfm = NULL;
4388 + /* start WEP IV from a random value */
4389 + get_random_bytes(&priv->iv, 4);
4394 + //#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
4395 + #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
4398 + crypto_free_tfm(priv->tfm);
4404 + crypto_free_blkcipher(priv->tx_tfm);
4406 + crypto_free_blkcipher(priv->rx_tfm);
4414 +static void prism2_wep_deinit(void *priv)
4416 + struct prism2_wep_data *_priv = priv;
4417 + //#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
4418 + #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
4419 + if (_priv && _priv->tfm)
4420 + crypto_free_tfm(_priv->tfm);
4423 + if (_priv->tx_tfm)
4424 + crypto_free_blkcipher(_priv->tx_tfm);
4425 + if (_priv->rx_tfm)
4426 + crypto_free_blkcipher(_priv->rx_tfm);
4433 +/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
4434 + * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
4435 + * so the payload length increases with 8 bytes.
4437 + * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
4439 +static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
4441 + struct prism2_wep_data *wep = priv;
4442 +//#if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
4443 +#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))||(IN_OPENSUSE_SLED))
4444 + struct blkcipher_desc desc = {.tfm = wep->tx_tfm};
4447 + u8 key[WEP_KEY_LEN + 3];
4452 + struct scatterlist sg;
4454 + if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 ||
4455 + skb->len < hdr_len)
4458 + len = skb->len - hdr_len;
4459 + pos = skb_push(skb, 4);
4460 + memmove(pos, pos + 4, hdr_len);
4463 + klen = 3 + wep->key_len;
4467 + /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key
4468 + * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N)
4469 + * can be used to speedup attacks, so avoid using them. */
4470 + if ((wep->iv & 0xff00) == 0xff00) {
4471 + u8 B = (wep->iv >> 16) & 0xff;
4472 + if (B >= 3 && B < klen)
4473 + wep->iv += 0x0100;
4476 + /* Prepend 24-bit IV to RC4 key and TX frame */
4477 + *pos++ = key[0] = (wep->iv >> 16) & 0xff;
4478 + *pos++ = key[1] = (wep->iv >> 8) & 0xff;
4479 + *pos++ = key[2] = wep->iv & 0xff;
4480 + *pos++ = wep->key_idx << 6;
4482 + /* Copy rest of the WEP key (the secret part) */
4483 + memcpy(key + 3, wep->key, wep->key_len);
4486 + /* Append little-endian CRC32 and encrypt it to produce ICV */
4487 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
4488 + crc = ~crc32_le(~0, pos, len);
4490 + crc = ~ether_crc_le(len, pos);
4492 + icv = skb_put(skb, 4);
4494 + icv[1] = crc >> 8;
4495 + icv[2] = crc >> 16;
4496 + icv[3] = crc >> 24;
4498 + //#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
4499 + #if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
4500 + crypto_cipher_setkey(wep->tfm, key, klen);
4501 + sg.page = virt_to_page(pos);
4502 + sg.offset = offset_in_page(pos);
4503 + sg.length = len + 4;
4504 + crypto_cipher_encrypt(wep->tfm, &sg, &sg, len + 4);
4508 + crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
4509 + #if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
4510 + sg.page = virt_to_page(pos);
4511 + sg.offset = offset_in_page(pos);
4512 + sg.length = len + 4;
4514 + sg_init_one(&sg, pos, len+4);
4516 + return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
4518 +#endif /* JOHN_HWSEC */
4523 +/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of
4524 + * the frame: IV (4 bytes), encrypted payload (including SNAP header),
4525 + * ICV (4 bytes). len includes both IV and ICV.
4527 + * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on
4528 + * failure. If frame is OK, IV and ICV will be removed.
4530 +static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
4532 + struct prism2_wep_data *wep = priv;
4533 + //#if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
4534 + #if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))||(IN_OPENSUSE_SLED))
4535 + struct blkcipher_desc desc = {.tfm = wep->rx_tfm};
4538 + u8 key[WEP_KEY_LEN + 3];
4543 + struct scatterlist sg;
4545 + if (skb->len < hdr_len + 8)
4548 + pos = skb->data + hdr_len;
4552 + keyidx = *pos++ >> 6;
4553 + if (keyidx != wep->key_idx)
4556 + klen = 3 + wep->key_len;
4558 + /* Copy rest of the WEP key (the secret part) */
4559 + memcpy(key + 3, wep->key, wep->key_len);
4561 + /* Apply RC4 to data and compute CRC32 over decrypted data */
4562 + plen = skb->len - hdr_len - 8;
4564 +//#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))
4565 +#if((LINUX_VERSION_CODE < KERNEL_VERSION(2,6,21))&&(!IN_OPENSUSE_SLED))
4566 + crypto_cipher_setkey(wep->tfm, key, klen);
4567 + sg.page = virt_to_page(pos);
4568 + sg.offset = offset_in_page(pos);
4569 + sg.length = plen + 4;
4570 + crypto_cipher_decrypt(wep->tfm, &sg, &sg, plen + 4);
4572 + crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
4573 + #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))
4574 + sg.page = virt_to_page(pos);
4575 + sg.offset = offset_in_page(pos);
4576 + sg.length = plen + 4;
4578 + sg_init_one(&sg, pos, plen+4);
4580 + if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
4584 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
4585 + crc = ~crc32_le(~0, pos, plen);
4587 + crc = ~ether_crc_le(plen, pos);
4590 + icv[1] = crc >> 8;
4591 + icv[2] = crc >> 16;
4592 + icv[3] = crc >> 24;
4594 + if (memcmp(icv, pos + plen, 4) != 0) {
4595 + /* ICV mismatch - drop frame */
4598 +#endif /* JOHN_HWSEC */
4600 + /* Remove IV and ICV */
4601 + memmove(skb->data + 4, skb->data, hdr_len);
4603 + skb_trim(skb, skb->len - 4);
4608 +static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv)
4610 + struct prism2_wep_data *wep = priv;
4612 + if (len < 0 || len > WEP_KEY_LEN)
4615 + memcpy(wep->key, key, len);
4616 + wep->key_len = len;
4622 +static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv)
4624 + struct prism2_wep_data *wep = priv;
4626 + if (len < wep->key_len)
4629 + memcpy(key, wep->key, wep->key_len);
4631 + return wep->key_len;
4635 +static char * prism2_wep_print_stats(char *p, void *priv)
4637 + struct prism2_wep_data *wep = priv;
4638 + p += sprintf(p, "key[%d] alg=WEP len=%d\n",
4639 + wep->key_idx, wep->key_len);
4644 +static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
4646 + .init = prism2_wep_init,
4647 + .deinit = prism2_wep_deinit,
4648 + .encrypt_mpdu = prism2_wep_encrypt,
4649 + .decrypt_mpdu = prism2_wep_decrypt,
4650 + .encrypt_msdu = NULL,
4651 + .decrypt_msdu = NULL,
4652 + .set_key = prism2_wep_set_key,
4653 + .get_key = prism2_wep_get_key,
4654 + .print_stats = prism2_wep_print_stats,
4655 + .extra_prefix_len = 4, /* IV */
4656 + .extra_postfix_len = 4, /* ICV */
4657 + .owner = THIS_MODULE,
4661 +int ieee80211_crypto_wep_init(void)
4663 + return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
4667 +void ieee80211_crypto_wep_exit(void)
4669 + ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
4673 +void ieee80211_wep_null(void)
4675 +// printk("============>%s()\n", __FUNCTION__);
4679 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
4680 +EXPORT_SYMBOL(ieee80211_wep_null);
4682 +EXPORT_SYMBOL_NOVERS(ieee80211_wep_null);
4685 +//module_init(ieee80211_crypto_wep_init);
4686 +//module_exit(ieee80211_crypto_wep_exit);
4688 +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211.h
4691 + * Merged with mainline ieee80211.h in Aug 2004. Original ieee802_11
4692 + * remains copyright by the original authors
4694 + * Portions of the merged code are based on Host AP (software wireless
4695 + * LAN access point) driver for Intersil Prism2/2.5/3.
4697 + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
4698 + * <jkmaline@cc.hut.fi>
4699 + * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
4701 + * Adaption to a generic IEEE 802.11 stack by James Ketrenos
4702 + * <jketreno@linux.intel.com>
4703 + * Copyright (c) 2004, Intel Corporation
4705 + * Modified for Realtek's wi-fi cards by Andrea Merello
4706 + * <andreamrl@tiscali.it>
4708 + * This program is free software; you can redistribute it and/or modify
4709 + * it under the terms of the GNU General Public License version 2 as
4710 + * published by the Free Software Foundation. See README and COPYING for
4713 +#ifndef IEEE80211_H
4714 +#define IEEE80211_H
4715 +#include <linux/if_ether.h> /* ETH_ALEN */
4716 +#include <linux/kernel.h> /* ARRAY_SIZE */
4717 +#include <linux/version.h>
4718 +#include <linux/jiffies.h>
4719 +#include <linux/timer.h>
4720 +#include <linux/sched.h>
4722 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13))
4723 +#include <linux/wireless.h>
4739 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20))
4741 +typedef enum{false = 0, true} bool;
4744 +//#ifdef JOHN_HWSEC
4745 +#define KEY_TYPE_NA 0x0
4746 +#define KEY_TYPE_WEP40 0x1
4747 +#define KEY_TYPE_TKIP 0x2
4748 +#define KEY_TYPE_CCMP 0x4
4749 +#define KEY_TYPE_WEP104 0x5
4753 +#define aSifsTime 10
4755 +#define MGMT_QUEUE_NUM 5
4758 +#define IEEE_CMD_SET_WPA_PARAM 1
4759 +#define IEEE_CMD_SET_WPA_IE 2
4760 +#define IEEE_CMD_SET_ENCRYPTION 3
4761 +#define IEEE_CMD_MLME 4
4763 +#define IEEE_PARAM_WPA_ENABLED 1
4764 +#define IEEE_PARAM_TKIP_COUNTERMEASURES 2
4765 +#define IEEE_PARAM_DROP_UNENCRYPTED 3
4766 +#define IEEE_PARAM_PRIVACY_INVOKED 4
4767 +#define IEEE_PARAM_AUTH_ALGS 5
4768 +#define IEEE_PARAM_IEEE_802_1X 6
4769 +//It should consistent with the driver_XXX.c
4770 +// David, 2006.9.26
4771 +#define IEEE_PARAM_WPAX_SELECT 7
4772 +//Added for notify the encryption type selection
4773 +// David, 2006.9.26
4774 +#define IEEE_PROTO_WPA 1
4775 +#define IEEE_PROTO_RSN 2
4776 +//Added for notify the encryption type selection
4777 +// David, 2006.9.26
4778 +#define IEEE_WPAX_USEGROUP 0
4779 +#define IEEE_WPAX_WEP40 1
4780 +#define IEEE_WPAX_TKIP 2
4781 +#define IEEE_WPAX_WRAP 3
4782 +#define IEEE_WPAX_CCMP 4
4783 +#define IEEE_WPAX_WEP104 5
4785 +#define IEEE_KEY_MGMT_IEEE8021X 1
4786 +#define IEEE_KEY_MGMT_PSK 2
4790 +#define IEEE_MLME_STA_DEAUTH 1
4791 +#define IEEE_MLME_STA_DISASSOC 2
4794 +#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2
4795 +#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3
4796 +#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4
4797 +#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5
4798 +#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6
4799 +#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7
4802 +#define IEEE_CRYPT_ALG_NAME_LEN 16
4804 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,10))
4805 +#define ieee80211_wx_get_scan ieee80211_wx_get_scan_rtl
4806 +#define ieee80211_wx_set_encode ieee80211_wx_set_encode_rtl
4807 +#define ieee80211_wx_get_encode ieee80211_wx_get_encode_rtl
4808 +////////////////////////////////
4809 +// added for kernel conflict under FC5
4810 +#define ieee80211_wx_get_name ieee80211_wx_get_name_rtl
4811 +#define free_ieee80211 free_ieee80211_rtl
4812 +#define alloc_ieee80211 alloc_ieee80211_rtl
4813 +///////////////////////////////
4815 +//error in ubuntu2.6.22,so add these
4816 +#define ieee80211_wake_queue ieee80211_wake_queue_rtl
4817 +#define ieee80211_stop_queue ieee80211_stop_queue_rtl
4819 +#define ieee80211_rx ieee80211_rx_rtl
4821 +#define ieee80211_register_crypto_ops ieee80211_register_crypto_ops_rtl
4822 +#define ieee80211_unregister_crypto_ops ieee80211_unregister_crypto_ops_rtl
4823 +#define ieee80211_get_crypto_ops ieee80211_get_crypto_ops_rtl
4824 +#define ieee80211_crypt_deinit_entries ieee80211_crypt_deinit_entries_rtl
4825 +#define ieee80211_crypt_deinit_handler ieee80211_crypt_deinit_handler_rtl
4826 +#define ieee80211_crypt_delayed_deinit ieee80211_crypt_delayed_deinit_rtl
4828 +#define ieee80211_txb_free ieee80211_txb_free_rtl
4829 +#define ieee80211_wx_get_essid ieee80211_wx_get_essid_rtl
4830 +#define ieee80211_wx_set_essid ieee80211_wx_set_essid_rtl
4831 +#define ieee80211_wx_set_rate ieee80211_wx_set_rate_rtl
4832 +#define ieee80211_wx_get_rate ieee80211_wx_get_rate_rtl
4833 +#define ieee80211_wx_set_wap ieee80211_wx_set_wap_rtl
4834 +#define ieee80211_wx_get_wap ieee80211_wx_get_wap_rtl
4835 +#define ieee80211_wx_set_mode ieee80211_wx_set_mode_rtl
4836 +#define ieee80211_wx_get_mode ieee80211_wx_get_mode_rtl
4837 +#define ieee80211_wx_set_scan ieee80211_wx_set_scan_rtl
4838 +#define ieee80211_wx_get_freq ieee80211_wx_get_freq_rtl
4839 +#define ieee80211_wx_set_freq ieee80211_wx_set_freq_rtl
4840 +#define ieee80211_wx_set_rawtx ieee80211_wx_set_rawtx_rtl
4841 +#define ieee80211_wx_set_power ieee80211_wx_set_power_rtl
4842 +#define ieee80211_wx_get_power ieee80211_wx_get_power_rtl
4843 +#define ieee80211_wlan_frequencies ieee80211_wlan_frequencies_rtl
4844 +#define ieee80211_softmac_stop_protocol ieee80211_softmac_stop_protocol_rtl
4845 +#define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rtl
4846 +#define ieee80211_start_protocol ieee80211_start_protocol_rtl
4847 +#define ieee80211_stop_protocol ieee80211_stop_protocol_rtl
4848 +#define ieee80211_rx_mgt ieee80211_rx_mgt_rtl
4850 +#define ieee80211_wx_set_auth ieee80211_wx_set_auth_rtl
4852 +#define notify_wx_assoc_event notify_wx_assoc_event_rtl
4853 +#define ieee80211_stop_send_beacons ieee80211_stop_send_beacons_rtl
4854 +#define ieee80211_disassociate ieee80211_disassociate_rtl
4855 +#define ieee80211_start_scan ieee80211_start_scan_rtl
4857 +typedef struct ieee_param {
4859 + u8 sta_addr[ETH_ALEN];
4875 + u8 alg[IEEE_CRYPT_ALG_NAME_LEN];
4879 + u8 seq[8]; /* sequence counter (set: RX, get: TX) */
4888 +#if WIRELESS_EXT < 17
4889 +#define IW_QUAL_QUAL_INVALID 0x10
4890 +#define IW_QUAL_LEVEL_INVALID 0x20
4891 +#define IW_QUAL_NOISE_INVALID 0x40
4892 +#define IW_QUAL_QUAL_UPDATED 0x1
4893 +#define IW_QUAL_LEVEL_UPDATED 0x2
4894 +#define IW_QUAL_NOISE_UPDATED 0x4
4897 +// linux under 2.6.9 release may not support it, so modify it for common use
4898 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,9))
4899 +#define MSECS(t) (1000 * ((t) / HZ) + 1000 * ((t) % HZ) / HZ)
4900 +static inline unsigned long msleep_interruptible_rtl(unsigned int msecs)
4902 + unsigned long timeout = MSECS(msecs) + 1;
4905 + set_current_state(TASK_UNINTERRUPTIBLE);
4906 + timeout = schedule_timeout(timeout);
4911 +#define MSECS(t) msecs_to_jiffies(t)
4912 +#define msleep_interruptible_rtl msleep_interruptible
4915 +#define IEEE80211_DATA_LEN 2304
4916 +/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
4919 + The figure in section 7.1.2 suggests a body size of up to 2312
4920 + bytes is allowed, which is a bit confusing, I suspect this
4921 + represents the 2304 bytes of real data, plus a possible 8 bytes of
4922 + WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
4925 +#define IEEE80211_HLEN 30
4926 +#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
4928 +/* this is stolen and modified from the madwifi driver*/
4929 +#define IEEE80211_FC0_TYPE_MASK 0x0c
4930 +#define IEEE80211_FC0_TYPE_DATA 0x08
4931 +#define IEEE80211_FC0_SUBTYPE_MASK 0xB0
4932 +#define IEEE80211_FC0_SUBTYPE_QOS 0x80
4934 +#define IEEE80211_QOS_HAS_SEQ(fc) \
4935 + (((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \
4936 + (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
4938 +/* this is stolen from ipw2200 driver */
4939 +#define IEEE_IBSS_MAC_HASH_SIZE 31
4940 +struct ieee_ibss_seq {
4944 + unsigned long packet_time[17];
4945 + struct list_head list;
4948 +struct ieee80211_hdr {
4951 + u8 addr1[ETH_ALEN];
4952 + u8 addr2[ETH_ALEN];
4953 + u8 addr3[ETH_ALEN];
4955 + u8 addr4[ETH_ALEN];
4956 +} __attribute__ ((packed));
4958 +struct ieee80211_hdr_QOS {
4961 + u8 addr1[ETH_ALEN];
4962 + u8 addr2[ETH_ALEN];
4963 + u8 addr3[ETH_ALEN];
4965 + u8 addr4[ETH_ALEN];
4967 +} __attribute__ ((packed));
4969 +struct ieee80211_hdr_3addr {
4972 + u8 addr1[ETH_ALEN];
4973 + u8 addr2[ETH_ALEN];
4974 + u8 addr3[ETH_ALEN];
4976 +} __attribute__ ((packed));
4978 +struct ieee80211_hdr_3addr_QOS {
4981 + u8 addr1[ETH_ALEN];
4982 + u8 addr2[ETH_ALEN];
4983 + u8 addr3[ETH_ALEN];
4986 +} __attribute__ ((packed));
4993 + EAPOL_ENCAP_ASF_ALERT
4996 +static const char *eap_types[] = {
4997 + [EAP_PACKET] = "EAP-Packet",
4998 + [EAPOL_START] = "EAPOL-Start",
4999 + [EAPOL_LOGOFF] = "EAPOL-Logoff",
5000 + [EAPOL_KEY] = "EAPOL-Key",
5001 + [EAPOL_ENCAP_ASF_ALERT] = "EAPOL-Encap-ASF-Alert"
5004 +static inline const char *eap_get_type(int type)
5006 + return (type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
5015 +} __attribute__ ((packed));
5017 +#define IEEE80211_3ADDR_LEN 24
5018 +#define IEEE80211_4ADDR_LEN 30
5019 +#define IEEE80211_FCS_LEN 4
5021 +#define MIN_FRAG_THRESHOLD 256U
5022 +#define MAX_FRAG_THRESHOLD 2346U
5024 +/* Frame control field constants */
5025 +#define IEEE80211_FCTL_VERS 0x0002
5026 +#define IEEE80211_FCTL_FTYPE 0x000c
5027 +#define IEEE80211_FCTL_STYPE 0x00f0
5028 +#define IEEE80211_FCTL_TODS 0x0100
5029 +#define IEEE80211_FCTL_FROMDS 0x0200
5030 +#define IEEE80211_FCTL_DSTODS 0x0300 //added by david
5031 +#define IEEE80211_FCTL_MOREFRAGS 0x0400
5032 +#define IEEE80211_FCTL_RETRY 0x0800
5033 +#define IEEE80211_FCTL_PM 0x1000
5034 +#define IEEE80211_FCTL_MOREDATA 0x2000
5035 +#define IEEE80211_FCTL_WEP 0x4000
5036 +#define IEEE80211_FCTL_ORDER 0x8000
5038 +#define IEEE80211_FTYPE_MGMT 0x0000
5039 +#define IEEE80211_FTYPE_CTL 0x0004
5040 +#define IEEE80211_FTYPE_DATA 0x0008
5043 +#define IEEE80211_STYPE_ASSOC_REQ 0x0000
5044 +#define IEEE80211_STYPE_ASSOC_RESP 0x0010
5045 +#define IEEE80211_STYPE_REASSOC_REQ 0x0020
5046 +#define IEEE80211_STYPE_REASSOC_RESP 0x0030
5047 +#define IEEE80211_STYPE_PROBE_REQ 0x0040
5048 +#define IEEE80211_STYPE_PROBE_RESP 0x0050
5049 +#define IEEE80211_STYPE_BEACON 0x0080
5050 +#define IEEE80211_STYPE_ATIM 0x0090
5051 +#define IEEE80211_STYPE_DISASSOC 0x00A0
5052 +#define IEEE80211_STYPE_AUTH 0x00B0
5053 +#define IEEE80211_STYPE_DEAUTH 0x00C0
5054 +#define IEEE80211_STYPE_MANAGE_ACT 0x00D0
5057 +#define IEEE80211_STYPE_PSPOLL 0x00A0
5058 +#define IEEE80211_STYPE_RTS 0x00B0
5059 +#define IEEE80211_STYPE_CTS 0x00C0
5060 +#define IEEE80211_STYPE_ACK 0x00D0
5061 +#define IEEE80211_STYPE_CFEND 0x00E0
5062 +#define IEEE80211_STYPE_CFENDACK 0x00F0
5065 +#define IEEE80211_STYPE_DATA 0x0000
5066 +#define IEEE80211_STYPE_DATA_CFACK 0x0010
5067 +#define IEEE80211_STYPE_DATA_CFPOLL 0x0020
5068 +#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030
5069 +#define IEEE80211_STYPE_NULLFUNC 0x0040
5070 +#define IEEE80211_STYPE_CFACK 0x0050
5071 +#define IEEE80211_STYPE_CFPOLL 0x0060
5072 +#define IEEE80211_STYPE_CFACKPOLL 0x0070
5073 +#define IEEE80211_STYPE_QOS_DATA 0x0080 //added for WMM 2006/8/2
5074 +#define IEEE80211_STYPE_QOS_NULL 0x00C0
5077 +#define IEEE80211_SCTL_FRAG 0x000F
5078 +#define IEEE80211_SCTL_SEQ 0xFFF0
5083 +#ifdef CONFIG_IEEE80211_DEBUG
5084 +extern u32 ieee80211_debug_level;
5085 +#define IEEE80211_DEBUG(level, fmt, args...) \
5086 +do { if (ieee80211_debug_level & (level)) \
5087 + printk(KERN_DEBUG "ieee80211: %c %s " fmt, \
5088 + in_interrupt() ? 'I' : 'U', __FUNCTION__ , ## args); } while (0)
5090 +#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
5091 +#endif /* CONFIG_IEEE80211_DEBUG */
5094 + * To use the debug system;
5096 + * If you are defining a new debug classification, simply add it to the #define
5097 + * list here in the form of:
5099 + * #define IEEE80211_DL_xxxx VALUE
5101 + * shifting value to the left one bit from the previous entry. xxxx should be
5102 + * the name of the classification (for example, WEP)
5104 + * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your
5105 + * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want
5106 + * to send output to that classification.
5108 + * To add your debug level to the list of levels seen when you perform
5110 + * % cat /proc/net/ipw/debug_level
5112 + * you simply need to add your entry to the ipw_debug_levels array.
5114 + * If you do not see debug_level in /proc/net/ipw then you do not have
5115 + * CONFIG_IEEE80211_DEBUG defined in your kernel configuration
5119 +#define IEEE80211_DL_INFO (1<<0)
5120 +#define IEEE80211_DL_WX (1<<1)
5121 +#define IEEE80211_DL_SCAN (1<<2)
5122 +#define IEEE80211_DL_STATE (1<<3)
5123 +#define IEEE80211_DL_MGMT (1<<4)
5124 +#define IEEE80211_DL_FRAG (1<<5)
5125 +#define IEEE80211_DL_EAP (1<<6)
5126 +#define IEEE80211_DL_DROP (1<<7)
5128 +#define IEEE80211_DL_TX (1<<8)
5129 +#define IEEE80211_DL_RX (1<<9)
5131 +#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
5132 +#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
5133 +#define IEEE80211_DEBUG_INFO(f, a...) IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a)
5135 +#define IEEE80211_DEBUG_WX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a)
5136 +#define IEEE80211_DEBUG_SCAN(f, a...) IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a)
5137 +//#define IEEE_DEBUG_SCAN IEEE80211_WARNING
5138 +#define IEEE80211_DEBUG_STATE(f, a...) IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a)
5139 +#define IEEE80211_DEBUG_MGMT(f, a...) IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a)
5140 +#define IEEE80211_DEBUG_FRAG(f, a...) IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a)
5141 +#define IEEE80211_DEBUG_EAP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a)
5142 +#define IEEE80211_DEBUG_DROP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
5143 +#define IEEE80211_DEBUG_TX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
5144 +#define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
5145 +#include <linux/netdevice.h>
5146 +#include <linux/wireless.h>
5147 +#include <linux/if_arp.h> /* ARPHRD_ETHER */
5149 +#ifndef WIRELESS_SPY
5150 +#define WIRELESS_SPY // enable iwspy support
5152 +#include <net/iw_handler.h> // new driver API
5155 +#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
5156 +#endif /* ETH_P_PAE */
5158 +#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
5160 +#ifndef ETH_P_80211_RAW
5161 +#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
5164 +/* IEEE 802.11 defines */
5166 +#define P80211_OUI_LEN 3
5168 +struct ieee80211_snap_hdr {
5170 + u8 dsap; /* always 0xAA */
5171 + u8 ssap; /* always 0xAA */
5172 + u8 ctrl; /* always 0x03 */
5173 + u8 oui[P80211_OUI_LEN]; /* organizational universal id */
5175 +} __attribute__ ((packed));
5177 +#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr)
5179 +#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE)
5180 +#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE)
5182 +#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
5183 +#define WLAN_GET_SEQ_SEQ(seq) ((seq) & IEEE80211_SCTL_SEQ)
5185 +/* Authentication algorithms */
5186 +#define WLAN_AUTH_OPEN 0
5187 +#define WLAN_AUTH_SHARED_KEY 1
5189 +#define WLAN_AUTH_CHALLENGE_LEN 128
5191 +#define WLAN_CAPABILITY_BSS (1<<0)
5192 +#define WLAN_CAPABILITY_IBSS (1<<1)
5193 +#define WLAN_CAPABILITY_CF_POLLABLE (1<<2)
5194 +#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3)
5195 +#define WLAN_CAPABILITY_PRIVACY (1<<4)
5196 +#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5)
5197 +#define WLAN_CAPABILITY_PBCC (1<<6)
5198 +#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7)
5199 +#define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
5202 +#define WLAN_STATUS_SUCCESS 0
5203 +#define WLAN_STATUS_UNSPECIFIED_FAILURE 1
5204 +#define WLAN_STATUS_CAPS_UNSUPPORTED 10
5205 +#define WLAN_STATUS_REASSOC_NO_ASSOC 11
5206 +#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12
5207 +#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13
5208 +#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14
5209 +#define WLAN_STATUS_CHALLENGE_FAIL 15
5210 +#define WLAN_STATUS_AUTH_TIMEOUT 16
5211 +#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17
5212 +#define WLAN_STATUS_ASSOC_DENIED_RATES 18
5214 +#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19
5215 +#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20
5216 +#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21
5219 +#define WLAN_REASON_UNSPECIFIED 1
5220 +#define WLAN_REASON_PREV_AUTH_NOT_VALID 2
5221 +#define WLAN_REASON_DEAUTH_LEAVING 3
5222 +#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4
5223 +#define WLAN_REASON_DISASSOC_AP_BUSY 5
5224 +#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6
5225 +#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7
5226 +#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8
5227 +#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9
5230 +/* Information Element IDs */
5231 +#define WLAN_EID_SSID 0
5232 +#define WLAN_EID_SUPP_RATES 1
5233 +#define WLAN_EID_FH_PARAMS 2
5234 +#define WLAN_EID_DS_PARAMS 3
5235 +#define WLAN_EID_CF_PARAMS 4
5236 +#define WLAN_EID_TIM 5
5237 +#define WLAN_EID_IBSS_PARAMS 6
5238 +#define WLAN_EID_CHALLENGE 16
5239 +#define WLAN_EID_RSN 48
5240 +#define WLAN_EID_GENERIC 221
5242 +#define IEEE80211_MGMT_HDR_LEN 24
5243 +#define IEEE80211_DATA_HDR3_LEN 24
5244 +#define IEEE80211_DATA_HDR4_LEN 30
5247 +#define IEEE80211_STATMASK_SIGNAL (1<<0)
5248 +#define IEEE80211_STATMASK_RSSI (1<<1)
5249 +#define IEEE80211_STATMASK_NOISE (1<<2)
5250 +#define IEEE80211_STATMASK_RATE (1<<3)
5251 +#define IEEE80211_STATMASK_WEMASK 0x7
5254 +#define IEEE80211_CCK_MODULATION (1<<0)
5255 +#define IEEE80211_OFDM_MODULATION (1<<1)
5257 +#define IEEE80211_24GHZ_BAND (1<<0)
5258 +#define IEEE80211_52GHZ_BAND (1<<1)
5260 +#define IEEE80211_CCK_RATE_LEN 4
5261 +#define IEEE80211_CCK_RATE_1MB 0x02
5262 +#define IEEE80211_CCK_RATE_2MB 0x04
5263 +#define IEEE80211_CCK_RATE_5MB 0x0B
5264 +#define IEEE80211_CCK_RATE_11MB 0x16
5265 +#define IEEE80211_OFDM_RATE_LEN 8
5266 +#define IEEE80211_OFDM_RATE_6MB 0x0C
5267 +#define IEEE80211_OFDM_RATE_9MB 0x12
5268 +#define IEEE80211_OFDM_RATE_12MB 0x18
5269 +#define IEEE80211_OFDM_RATE_18MB 0x24
5270 +#define IEEE80211_OFDM_RATE_24MB 0x30
5271 +#define IEEE80211_OFDM_RATE_36MB 0x48
5272 +#define IEEE80211_OFDM_RATE_48MB 0x60
5273 +#define IEEE80211_OFDM_RATE_54MB 0x6C
5274 +#define IEEE80211_BASIC_RATE_MASK 0x80
5276 +#define IEEE80211_CCK_RATE_1MB_MASK (1<<0)
5277 +#define IEEE80211_CCK_RATE_2MB_MASK (1<<1)
5278 +#define IEEE80211_CCK_RATE_5MB_MASK (1<<2)
5279 +#define IEEE80211_CCK_RATE_11MB_MASK (1<<3)
5280 +#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4)
5281 +#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5)
5282 +#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6)
5283 +#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7)
5284 +#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8)
5285 +#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9)
5286 +#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10)
5287 +#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11)
5289 +#define IEEE80211_CCK_RATES_MASK 0x0000000F
5290 +#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \
5291 + IEEE80211_CCK_RATE_2MB_MASK)
5292 +#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \
5293 + IEEE80211_CCK_RATE_5MB_MASK | \
5294 + IEEE80211_CCK_RATE_11MB_MASK)
5296 +#define IEEE80211_OFDM_RATES_MASK 0x00000FF0
5297 +#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \
5298 + IEEE80211_OFDM_RATE_12MB_MASK | \
5299 + IEEE80211_OFDM_RATE_24MB_MASK)
5300 +#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \
5301 + IEEE80211_OFDM_RATE_9MB_MASK | \
5302 + IEEE80211_OFDM_RATE_18MB_MASK | \
5303 + IEEE80211_OFDM_RATE_36MB_MASK | \
5304 + IEEE80211_OFDM_RATE_48MB_MASK | \
5305 + IEEE80211_OFDM_RATE_54MB_MASK)
5306 +#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
5307 + IEEE80211_CCK_DEFAULT_RATES_MASK)
5309 +#define IEEE80211_NUM_OFDM_RATES 8
5310 +#define IEEE80211_NUM_CCK_RATES 4
5311 +#define IEEE80211_OFDM_SHIFT_MASK_A 4
5316 +/* NOTE: This data is for statistical purposes; not all hardware provides this
5317 + * information for frames received. Not setting these will not cause
5318 + * any adverse affects. */
5319 +struct ieee80211_rx_stats {
5321 + u8 signalstrength;
5325 + u16 rate; /* in 100 kbps */
5326 + u8 received_channel;
5334 +/* IEEE 802.11 requires that STA supports concurrent reception of at least
5335 + * three fragmented frames. This define can be increased to support more
5336 + * concurrent frames, but it should be noted that each entry can consume about
5337 + * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
5338 +#define IEEE80211_FRAG_CACHE_LEN 4
5340 +struct ieee80211_frag_entry {
5341 + unsigned long first_frag_time;
5343 + unsigned int last_frag;
5344 + struct sk_buff *skb;
5345 + u8 src_addr[ETH_ALEN];
5346 + u8 dst_addr[ETH_ALEN];
5349 +struct ieee80211_stats {
5350 + unsigned int tx_unicast_frames;
5351 + unsigned int tx_multicast_frames;
5352 + unsigned int tx_fragments;
5353 + unsigned int tx_unicast_octets;
5354 + unsigned int tx_multicast_octets;
5355 + unsigned int tx_deferred_transmissions;
5356 + unsigned int tx_single_retry_frames;
5357 + unsigned int tx_multiple_retry_frames;
5358 + unsigned int tx_retry_limit_exceeded;
5359 + unsigned int tx_discards;
5360 + unsigned int rx_unicast_frames;
5361 + unsigned int rx_multicast_frames;
5362 + unsigned int rx_fragments;
5363 + unsigned int rx_unicast_octets;
5364 + unsigned int rx_multicast_octets;
5365 + unsigned int rx_fcs_errors;
5366 + unsigned int rx_discards_no_buffer;
5367 + unsigned int tx_discards_wrong_sa;
5368 + unsigned int rx_discards_undecryptable;
5369 + unsigned int rx_message_in_msg_fragments;
5370 + unsigned int rx_message_in_bad_msg_fragments;
5373 +struct ieee80211_softmac_stats{
5374 + unsigned int rx_ass_ok;
5375 + unsigned int rx_ass_err;
5376 + unsigned int rx_probe_rq;
5377 + unsigned int tx_probe_rs;
5378 + unsigned int tx_beacons;
5379 + unsigned int rx_auth_rq;
5380 + unsigned int rx_auth_rs_ok;
5381 + unsigned int rx_auth_rs_err;
5382 + unsigned int tx_auth_rq;
5383 + unsigned int no_auth_rs;
5384 + unsigned int no_ass_rs;
5385 + unsigned int tx_ass_rq;
5386 + unsigned int rx_ass_rq;
5387 + unsigned int tx_probe_rq;
5388 + unsigned int reassoc;
5389 + unsigned int swtxstop;
5390 + unsigned int swtxawake;
5393 +struct ieee80211_device;
5395 +#include "ieee80211_crypt.h"
5397 +#define SEC_KEY_1 (1<<0)
5398 +#define SEC_KEY_2 (1<<1)
5399 +#define SEC_KEY_3 (1<<2)
5400 +#define SEC_KEY_4 (1<<3)
5401 +#define SEC_ACTIVE_KEY (1<<4)
5402 +#define SEC_AUTH_MODE (1<<5)
5403 +#define SEC_UNICAST_GROUP (1<<6)
5404 +#define SEC_LEVEL (1<<7)
5405 +#define SEC_ENABLED (1<<8)
5407 +#define SEC_LEVEL_0 0 /* None */
5408 +#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */
5409 +#define SEC_LEVEL_2 2 /* Level 1 + TKIP */
5410 +#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
5411 +#define SEC_LEVEL_3 4 /* Level 2 + CCMP */
5414 +#define WEP_KEY_LEN 13
5416 +#define WEP_KEY_LEN_MODIF 32
5418 +struct ieee80211_security {
5423 + unicast_uses_group:1;
5424 + u8 key_sizes[WEP_KEYS];
5425 + u8 keys[WEP_KEYS][WEP_KEY_LEN_MODIF];
5428 +} __attribute__ ((packed));
5433 + 802.11 data frame from AP
5435 + ,-------------------------------------------------------------------.
5436 +Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
5437 + |------|------|---------|---------|---------|------|---------|------|
5438 +Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs |
5439 + | | tion | (BSSID) | | | ence | data | |
5440 + `-------------------------------------------------------------------'
5442 +Total: 28-2340 bytes
5446 +struct ieee80211_header_data {
5455 +#define BEACON_PROBE_SSID_ID_POSITION 12
5457 +/* Management Frame Information Element Types */
5458 +#define MFIE_TYPE_SSID 0
5459 +#define MFIE_TYPE_RATES 1
5460 +#define MFIE_TYPE_FH_SET 2
5461 +#define MFIE_TYPE_DS_SET 3
5462 +#define MFIE_TYPE_CF_SET 4
5463 +#define MFIE_TYPE_TIM 5
5464 +#define MFIE_TYPE_IBSS_SET 6
5465 +#define MFIE_TYPE_COUNTRY 7 //+YJ,080625
5466 +#define MFIE_TYPE_CHALLENGE 16
5467 +#define MFIE_TYPE_ERP 42
5468 +#define MFIE_TYPE_RSN 48
5469 +#define MFIE_TYPE_RATES_EX 50
5470 +#define MFIE_TYPE_GENERIC 221
5472 +#ifdef ENABLE_DOT11D
5475 + COUNTRY_CODE_FCC = 0,
5476 + COUNTRY_CODE_IC = 1,
5477 + COUNTRY_CODE_ETSI = 2,
5478 + COUNTRY_CODE_SPAIN = 3,
5479 + COUNTRY_CODE_FRANCE = 4,
5480 + COUNTRY_CODE_MKK = 5,
5481 + COUNTRY_CODE_MKK1 = 6,
5482 + COUNTRY_CODE_ISRAEL = 7,
5483 + COUNTRY_CODE_TELEC = 8,
5484 + COUNTRY_CODE_GLOBAL_DOMAIN = 9,
5485 + COUNTRY_CODE_WORLD_WIDE_13_INDEX = 10
5486 +}country_code_type_t;
5489 +struct ieee80211_info_element_hdr {
5492 +} __attribute__ ((packed));
5494 +struct ieee80211_info_element {
5498 +} __attribute__ ((packed));
5501 + * These are the data types that can make up management packets
5503 + u16 auth_algorithm;
5504 + u16 auth_sequence;
5505 + u16 beacon_interval;
5507 + u8 current_ap[ETH_ALEN];
5508 + u16 listen_interval;
5510 + u16 association_id:14, reserved:2;
5511 + } __attribute__ ((packed));
5512 + u32 time_stamp[2];
5517 +#define IEEE80211_DEFAULT_TX_ESSID "Penguin"
5518 +#define IEEE80211_DEFAULT_BASIC_RATE 10
5520 +struct ieee80211_authentication {
5521 + struct ieee80211_header_data header;
5525 + //struct ieee80211_info_element_hdr info_element;
5526 +} __attribute__ ((packed));
5529 +struct ieee80211_probe_response {
5530 + struct ieee80211_header_data header;
5531 + u32 time_stamp[2];
5532 + u16 beacon_interval;
5534 + struct ieee80211_info_element info_element;
5535 +} __attribute__ ((packed));
5537 +struct ieee80211_probe_request {
5538 + struct ieee80211_header_data header;
5539 + /*struct ieee80211_info_element info_element;*/
5540 +} __attribute__ ((packed));
5542 +struct ieee80211_assoc_request_frame {
5543 + struct ieee80211_hdr_3addr header;
5545 + u16 listen_interval;
5546 + //u8 current_ap[ETH_ALEN];
5547 + struct ieee80211_info_element_hdr info_element;
5548 +} __attribute__ ((packed));
5550 +struct ieee80211_assoc_response_frame {
5551 + struct ieee80211_hdr_3addr header;
5555 + struct ieee80211_info_element info_element; /* supported rates */
5556 +} __attribute__ ((packed));
5558 +struct ieee80211_disassoc_frame{
5559 + struct ieee80211_hdr_3addr header;
5561 +}__attribute__ ((packed));
5563 +struct ieee80211_txb {
5569 + struct sk_buff *fragments[0];
5572 +struct ieee80211_wmm_ac_param {
5573 + u8 ac_aci_acm_aifsn;
5574 + u8 ac_ecwmin_ecwmax;
5575 + u16 ac_txop_limit;
5578 +struct ieee80211_wmm_ts_info {
5582 +} __attribute__ ((packed));
5584 +struct ieee80211_wmm_tspec_elem {
5585 + struct ieee80211_wmm_ts_info ts_info;
5586 + u16 norm_msdu_size;
5587 + u16 max_msdu_size;
5588 + u32 min_serv_inter;
5589 + u32 max_serv_inter;
5592 + u32 serv_start_time;
5593 + u32 min_data_rate;
5594 + u32 mean_data_rate;
5595 + u32 peak_data_rate;
5596 + u32 max_burst_size;
5599 + u16 surp_band_allow;
5601 +}__attribute__((packed));
5603 +enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame};
5604 +#define MAX_SP_Len (WMM_all_frame << 4)
5605 +#define IEEE80211_QOS_TID 0x0f
5606 +#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5)
5608 +/* SWEEP TABLE ENTRIES NUMBER*/
5609 +#define MAX_SWEEP_TAB_ENTRIES 42
5610 +#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7
5611 +/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs
5612 + * only use 8, and then use extended rates for the remaining supported
5613 + * rates. Other APs, however, stick all of their supported rates on the
5614 + * main rates information element... */
5615 +#define MAX_RATES_LENGTH ((u8)12)
5616 +#define MAX_RATES_EX_LENGTH ((u8)16)
5617 +#define MAX_NETWORK_COUNT 128
5618 +//#define MAX_CHANNEL_NUMBER 161
5619 +#define MAX_CHANNEL_NUMBER 165 //YJ,modified,080625
5620 +#define MAX_IE_LEN 0xFF //+YJ,080625
5622 +typedef struct _CHANNEL_LIST{
5623 + u8 Channel[MAX_CHANNEL_NUMBER + 1];
5625 +}CHANNEL_LIST, *PCHANNEL_LIST;
5627 +#define IEEE80211_SOFTMAC_SCAN_TIME 100//400
5630 +#define IEEE80211_WATCH_DOG_TIME 2000
5632 +//by amy for antenna
5633 +#define ANTENNA_DIVERSITY_TIMER_PERIOD 1000 // 1000 m
5634 +//by amy for antenna
5635 +#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2)
5637 +#define CRC_LENGTH 4U
5639 +#define MAX_WPA_IE_LEN 64
5641 +#define NETWORK_EMPTY_ESSID (1<<0)
5642 +#define NETWORK_HAS_OFDM (1<<1)
5643 +#define NETWORK_HAS_CCK (1<<2)
5645 +#define IEEE80211_DTIM_MBCAST 4
5646 +#define IEEE80211_DTIM_UCAST 2
5647 +#define IEEE80211_DTIM_VALID 1
5648 +#define IEEE80211_DTIM_INVALID 0
5650 +#define IEEE80211_PS_DISABLED 0
5651 +#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST
5652 +#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST
5653 +#define IEEE80211_PS_ENABLE IEEE80211_DTIM_VALID
5654 +//added by David for QoS 2006/6/30
5655 +//#define WMM_Hang_8187
5656 +#ifdef WMM_Hang_8187
5657 +#undef WMM_Hang_8187
5660 +#define WME_AC_BE 0x00
5661 +#define WME_AC_BK 0x01
5662 +#define WME_AC_VI 0x02
5663 +#define WME_AC_VO 0x03
5664 +#define WME_ACI_MASK 0x03
5665 +#define WME_AIFSN_MASK 0x03
5666 +#define WME_AC_PRAM_LEN 16
5668 +//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP
5669 +//#define UP2AC(up) ((up<3) ? ((up==0)?1:0) : (up>>1))
5670 +#define UP2AC(up) ( \
5671 + ((up) < 1) ? WME_AC_BE : \
5672 + ((up) < 3) ? WME_AC_BK : \
5673 + ((up) < 4) ? WME_AC_BE : \
5674 + ((up) < 6) ? WME_AC_VI : \
5676 +//AC Mapping to UP, using in Tx part for selecting the corresponding TX queue
5677 +#define AC2UP(_ac) ( \
5678 + ((_ac) == WME_AC_VO) ? 6 : \
5679 + ((_ac) == WME_AC_VI) ? 5 : \
5680 + ((_ac) == WME_AC_BK) ? 1 : \
5683 +#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */
5684 +struct ether_header {
5685 + u8 ether_dhost[ETHER_ADDR_LEN];
5686 + u8 ether_shost[ETHER_ADDR_LEN];
5688 +} __attribute__((packed));
5690 +#ifndef ETHERTYPE_PAE
5691 +#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */
5693 +#ifndef ETHERTYPE_IP
5694 +#define ETHERTYPE_IP 0x0800 /* IP protocol */
5697 +struct ieee80211_network {
5698 + /* These entries are used to identify a unique network */
5699 + u8 bssid[ETH_ALEN];
5701 + /* Ensure null-terminated for any debug msgs */
5702 + u8 ssid[IW_ESSID_MAX_SIZE + 1];
5705 + /* These are network statistics */
5706 + struct ieee80211_rx_stats stats;
5708 + u8 rates[MAX_RATES_LENGTH];
5710 + u8 rates_ex[MAX_RATES_EX_LENGTH];
5712 + unsigned long last_scanned;
5715 + u32 last_associate;
5716 + u32 time_stamp[2];
5717 + u16 beacon_interval;
5718 + u16 listen_interval;
5720 + u8 wpa_ie[MAX_WPA_IE_LEN];
5721 + size_t wpa_ie_len;
5722 + u8 rsn_ie[MAX_WPA_IE_LEN];
5723 + size_t rsn_ie_len;
5726 + u32 last_dtim_sta_time[2];
5727 + struct list_head list;
5730 + struct ieee80211_wmm_ac_param wmm_param[4];
5732 + u8 SignalStrength;
5734 + u8 HighestOperaRate;
5736 +#ifdef THOMAS_TURBO
5737 + u8 Turbo_Enable;//enable turbo mode, added by thomas
5739 +#ifdef ENABLE_DOT11D
5741 + u8 CountryIeBuf[MAX_IE_LEN];
5745 +enum ieee80211_state {
5747 + /* the card is not linked at all */
5748 + IEEE80211_NOLINK = 0,
5750 + /* IEEE80211_ASSOCIATING* are for BSS client mode
5751 + * the driver shall not perform RX filtering unless
5752 + * the state is LINKED.
5753 + * The driver shall just check for the state LINKED and
5754 + * defaults to NOLINK for ALL the other states (including
5755 + * LINKED_SCANNING)
5758 + /* the association procedure will start (wq scheduling)*/
5759 + IEEE80211_ASSOCIATING,
5760 + IEEE80211_ASSOCIATING_RETRY,
5762 + /* the association procedure is sending AUTH request*/
5763 + IEEE80211_ASSOCIATING_AUTHENTICATING,
5765 + /* the association procedure has successfully authentcated
5766 + * and is sending association request
5768 + IEEE80211_ASSOCIATING_AUTHENTICATED,
5770 + /* the link is ok. the card associated to a BSS or linked
5771 + * to a ibss cell or acting as an AP and creating the bss
5775 + /* same as LINKED, but the driver shall apply RX filter
5776 + * rules as we are in NO_LINK mode. As the card is still
5777 + * logically linked, but it is doing a syncro site survey
5778 + * then it will be back to LINKED state.
5780 + IEEE80211_LINKED_SCANNING,
5784 +#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
5785 +#define DEFAULT_FTS 2346
5786 +#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
5787 +#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5]
5790 +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,11))
5791 +extern inline int is_multicast_ether_addr(const u8 *addr)
5793 + return ((addr[0] != 0xff) && (0x01 & addr[0]));
5797 +#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,13))
5798 +extern inline int is_broadcast_ether_addr(const u8 *addr)
5800 + return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \
5801 + (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff));
5805 +#define CFG_IEEE80211_RESERVE_FCS (1<<0)
5806 +#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
5808 +typedef struct tx_pending_t{
5810 + struct ieee80211_txb *txb;
5814 +struct ieee80211_device {
5815 + struct net_device *dev;
5817 + /* Bookkeeping structures */
5818 + struct net_device_stats stats;
5819 + struct ieee80211_stats ieee_stats;
5820 + struct ieee80211_softmac_stats softmac_stats;
5822 + /* Probe / Beacon management */
5823 + struct list_head network_free_list;
5824 + struct list_head network_list;
5825 + struct ieee80211_network *networks;
5829 + int iw_mode; /* operating mode (IW_MODE_*) */
5832 + spinlock_t wpax_suitlist_lock;
5834 + int tx_headroom; /* Set to size of any additional room needed at front
5835 + * of allocated Tx SKBs */
5838 + /* WEP and other encryption related settings at the device level */
5839 + int open_wep; /* Set to 1 to allow unencrypted frames */
5841 + int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
5842 + * WEP key changes */
5844 + /* If the host performs {en,de}cryption, then set to 1 */
5847 + int ieee802_1x; /* is IEEE 802.1X used */
5851 + int drop_unencrypted;
5852 + int tkip_countermeasures;
5853 + int privacy_invoked;
5854 + size_t wpa_ie_len;
5857 + u8 ap_mac_addr[6];
5858 + u16 pairwise_key_type;
5859 + u16 broadcast_key_type;
5861 + struct list_head crypt_deinit_list;
5862 + struct ieee80211_crypt_data *crypt[WEP_KEYS];
5863 + int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
5864 + struct timer_list crypt_deinit_timer;
5866 + int bcrx_sta_key; /* use individual keys to override default keys even
5867 + * with RX of broad/multicast frames */
5869 + /* Fragmentation structures */
5870 + // each streaming contain a entry
5871 + struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN];
5872 + unsigned int frag_next_idx[17];
5873 + u16 fts; /* Fragmentation Threshold */
5875 + /* This stores infos for the current network.
5876 + * Either the network we are associated in INFRASTRUCTURE
5877 + * or the network that we are creating in MASTER mode.
5878 + * ad-hoc is a mixture ;-).
5879 + * Note that in infrastructure mode, even when not associated,
5880 + * fields bssid and essid may be valid (if wpa_set and essid_set
5881 + * are true) as thy carry the value set by the user via iwconfig
5883 + struct ieee80211_network current_network;
5886 + enum ieee80211_state state;
5889 + int mode; /* A, B, G */
5890 + int modulation; /* CCK, OFDM */
5891 + int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */
5892 + int abg_true; /* ABG flag */
5894 + /* used for forcing the ibss workqueue to terminate
5895 + * without wait for the syncro scan to terminate
5897 + short sync_scan_hurryup;
5899 +#ifdef ENABLE_DOT11D
5900 + void * pDot11dInfo;
5901 + bool bGlobalDomain;
5903 + // For Liteon Ch12~13 passive scan
5904 + u8 MinPassiveChnlNum;
5907 + /* map of allowed channels. 0 is dummy */
5908 + // FIXME: remeber to default to a basic channel plan depending of the PHY type
5909 + int channel_map[MAX_CHANNEL_NUMBER+1];
5912 + int rate; /* current rate */
5914 + //FIXME: pleace callback, see if redundant with softmac_features
5915 + short active_scan;
5917 + /* this contains flags for selectively enable softmac support */
5918 + u16 softmac_features;
5920 + /* if the sequence control field is not filled by HW */
5923 + /* association procedure transaction sequence number */
5924 + u16 associate_seq;
5926 + /* AID for RTXed association responses */
5929 + /* power save mode related*/
5933 + struct tasklet_struct ps_task;
5938 + /* used if IEEE_SOFTMAC_TX_QUEUE is set */
5941 + short proto_started;
5943 + struct semaphore wx_sem;
5944 + struct semaphore scan_sem;
5946 + spinlock_t mgmt_tx_lock;
5947 + spinlock_t beacon_lock;
5949 + short beacon_txing;
5954 + u8 wpax_type_set; //{added by David, 2006.9.28}
5955 + u32 wpax_type_notify; //{added by David, 2006.9.26}
5957 + /* QoS related flag */
5958 + char init_wmmparam_flag;
5960 + /* for discarding duplicated packets in IBSS */
5961 + struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE];
5963 + /* for discarding duplicated packets in BSS */
5964 + u16 last_rxseq_num[17]; /* rx seq previous per-tid */
5965 + u16 last_rxfrag_num[17];/* tx frag previous per-tid */
5966 + unsigned long last_packet_time[17];
5969 + unsigned long last_rx_ps_time;
5971 + /* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */
5972 + struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM];
5973 + int mgmt_queue_head;
5974 + int mgmt_queue_tail;
5977 + /* used if IEEE_SOFTMAC_TX_QUEUE is set */
5978 + struct tx_pending_t tx_pending;
5980 + /* used if IEEE_SOFTMAC_ASSOCIATE is set */
5981 + struct timer_list associate_timer;
5983 + /* used if IEEE_SOFTMAC_BEACONS is set */
5984 + struct timer_list beacon_timer;
5986 + struct work_struct associate_complete_wq;
5987 +// struct work_struct associate_retry_wq;
5988 + struct work_struct associate_procedure_wq;
5989 +// struct work_struct softmac_scan_wq;
5990 + struct work_struct wx_sync_scan_wq;
5991 + struct work_struct wmm_param_update_wq;
5992 + struct work_struct ps_request_tx_ack_wq;//for ps
5993 +// struct work_struct hw_wakeup_wq;
5994 +// struct work_struct hw_sleep_wq;
5995 +// struct work_struct watch_dog_wq;
5999 + u16 ListenInterval;
6000 + unsigned long NumRxDataInPeriod; //YJ,add,080828
6001 + unsigned long NumRxBcnInPeriod; //YJ,add,080828
6002 + unsigned long NumRxOkTotal;
6003 + unsigned long NumRxUnicast;//YJ,add,080828,for keep alive
6005 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
6006 + struct delayed_work softmac_scan_wq;
6007 + struct delayed_work associate_retry_wq;
6008 + struct delayed_work hw_wakeup_wq;
6009 + struct delayed_work hw_sleep_wq;//+by amy 080324
6010 + struct delayed_work watch_dog_wq;
6011 + struct delayed_work sw_antenna_wq;
6012 + struct delayed_work start_ibss_wq;
6013 +//by amy for rate adaptive 080312
6014 + struct delayed_work rate_adapter_wq;
6015 +//by amy for rate adaptive
6016 + struct delayed_work hw_dig_wq;
6017 + struct delayed_work tx_pw_wq;
6019 +//Added for RF power on power off by lizhaoming 080512
6020 + struct delayed_work GPIOChangeRFWorkItem;
6023 + struct work_struct start_ibss_wq;
6024 + struct work_struct softmac_scan_wq;
6025 + struct work_struct associate_retry_wq;
6026 + struct work_struct hw_wakeup_wq;
6027 + struct work_struct hw_sleep_wq;
6028 + struct work_struct watch_dog_wq;
6029 + struct work_struct sw_antenna_wq;
6030 +//by amy for rate adaptive 080312
6031 + struct work_struct rate_adapter_wq;
6032 +//by amy for rate adaptive
6033 + struct work_struct hw_dig_wq;
6034 + struct work_struct tx_pw_wq;
6036 +//Added for RF power on power off by lizhaoming 080512
6037 + struct work_struct GPIOChangeRFWorkItem;
6039 + struct workqueue_struct *wq;
6041 + /* Callback functions */
6042 + void (*set_security)(struct net_device *dev,
6043 + struct ieee80211_security *sec);
6045 + /* Used to TX data frame by using txb structs.
6046 + * this is not used if in the softmac_features
6047 + * is set the flag IEEE_SOFTMAC_TX_QUEUE
6049 + int (*hard_start_xmit)(struct ieee80211_txb *txb,
6050 + struct net_device *dev);
6052 + int (*reset_port)(struct net_device *dev);
6054 + /* Softmac-generated frames (mamagement) are TXed via this
6055 + * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
6056 + * not set. As some cards may have different HW queues that
6057 + * one might want to use for data and management frames
6058 + * the option to have two callbacks might be useful.
6059 + * This fucntion can't sleep.
6061 + int (*softmac_hard_start_xmit)(struct sk_buff *skb,
6062 + struct net_device *dev);
6064 + /* used instead of hard_start_xmit (not softmac_hard_start_xmit)
6065 + * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
6066 + * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
6067 + * then also management frames are sent via this callback.
6068 + * This function can't sleep.
6070 + void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
6071 + struct net_device *dev,int rate);
6073 + /* stops the HW queue for DATA frames. Useful to avoid
6074 + * waste time to TX data frame when we are reassociating
6075 + * This function can sleep.
6077 + void (*data_hard_stop)(struct net_device *dev);
6079 + /* OK this is complementar to data_poll_hard_stop */
6080 + void (*data_hard_resume)(struct net_device *dev);
6082 + /* ask to the driver to retune the radio .
6083 + * This function can sleep. the driver should ensure
6084 + * the radio has been swithced before return.
6086 + void (*set_chan)(struct net_device *dev,short ch);
6088 + /* These are not used if the ieee stack takes care of
6089 + * scanning (IEEE_SOFTMAC_SCAN feature set).
6090 + * In this case only the set_chan is used.
6092 + * The syncro version is similar to the start_scan but
6093 + * does not return until all channels has been scanned.
6094 + * this is called in user context and should sleep,
6095 + * it is called in a work_queue when swithcing to ad-hoc mode
6096 + * or in behalf of iwlist scan when the card is associated
6097 + * and root user ask for a scan.
6098 + * the fucntion stop_scan should stop both the syncro and
6099 + * background scanning and can sleep.
6100 + * The fucntion start_scan should initiate the background
6101 + * scanning and can't sleep.
6103 + void (*scan_syncro)(struct net_device *dev);
6104 + void (*start_scan)(struct net_device *dev);
6105 + void (*stop_scan)(struct net_device *dev);
6107 + /* indicate the driver that the link state is changed
6108 + * for example it may indicate the card is associated now.
6109 + * Driver might be interested in this to apply RX filter
6110 + * rules or simply light the LINK led
6112 + void (*link_change)(struct net_device *dev);
6114 + /* these two function indicates to the HW when to start
6115 + * and stop to send beacons. This is used when the
6116 + * IEEE_SOFTMAC_BEACONS is not set. For now the
6117 + * stop_send_bacons is NOT guaranteed to be called only
6118 + * after start_send_beacons.
6120 + void (*start_send_beacons) (struct net_device *dev);
6121 + void (*stop_send_beacons) (struct net_device *dev);
6123 + /* power save mode related */
6124 + void (*sta_wake_up) (struct net_device *dev);
6125 + void (*ps_request_tx_ack) (struct net_device *dev);
6126 + void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl);
6127 + short (*ps_is_queue_empty) (struct net_device *dev);
6130 + //void (*wmm_param_update) (struct net_device *dev, u8 *ac_param);
6131 + //void (*wmm_param_update) (struct ieee80211_device *ieee);
6133 + /* This must be the last item so that it points to the data
6134 + * allocated beyond this structure by alloc_ieee80211 */
6138 +#define IEEE_A (1<<0)
6139 +#define IEEE_B (1<<1)
6140 +#define IEEE_G (1<<2)
6141 +#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G)
6143 +/* Generate a 802.11 header */
6145 +/* Uses the channel change callback directly
6146 + * instead of [start/stop] scan callbacks
6148 +#define IEEE_SOFTMAC_SCAN (1<<2)
6150 +/* Perform authentication and association handshake */
6151 +#define IEEE_SOFTMAC_ASSOCIATE (1<<3)
6153 +/* Generate probe requests */
6154 +#define IEEE_SOFTMAC_PROBERQ (1<<4)
6156 +/* Generate respones to probe requests */
6157 +#define IEEE_SOFTMAC_PROBERS (1<<5)
6159 +/* The ieee802.11 stack will manages the netif queue
6160 + * wake/stop for the driver, taking care of 802.11
6161 + * fragmentation. See softmac.c for details. */
6162 +#define IEEE_SOFTMAC_TX_QUEUE (1<<7)
6164 +/* Uses only the softmac_data_hard_start_xmit
6165 + * even for TX management frames.
6167 +#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8)
6169 +/* Generate beacons. The stack will enqueue beacons
6172 +#define IEEE_SOFTMAC_BEACONS (1<<6)
6176 +static inline void *ieee80211_priv(struct net_device *dev)
6178 + return ((struct ieee80211_device *)netdev_priv(dev))->priv;
6181 +extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len)
6183 + /* Single white space is for Linksys APs */
6184 + if (essid_len == 1 && essid[0] == ' ')
6187 + /* Otherwise, if the entire essid is 0, we assume it is hidden */
6188 + while (essid_len) {
6190 + if (essid[essid_len] != '\0')
6197 +extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode)
6200 + * It is possible for both access points and our device to support
6201 + * combinations of modes, so as long as there is one valid combination
6202 + * of ap/device supported modes, then return success
6205 + if ((mode & IEEE_A) &&
6206 + (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
6207 + (ieee->freq_band & IEEE80211_52GHZ_BAND))
6210 + if ((mode & IEEE_G) &&
6211 + (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
6212 + (ieee->freq_band & IEEE80211_24GHZ_BAND))
6215 + if ((mode & IEEE_B) &&
6216 + (ieee->modulation & IEEE80211_CCK_MODULATION) &&
6217 + (ieee->freq_band & IEEE80211_24GHZ_BAND))
6223 +extern inline int ieee80211_get_hdrlen(u16 fc)
6227 + switch (WLAN_FC_GET_TYPE(fc)) {
6228 + case IEEE80211_FTYPE_DATA:
6229 + if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
6230 + hdrlen = 30; /* Addr4 */
6231 + if(IEEE80211_QOS_HAS_SEQ(fc))
6232 + hdrlen += 2; /* QOS ctrl*/
6234 + case IEEE80211_FTYPE_CTL:
6235 + switch (WLAN_FC_GET_STYPE(fc)) {
6236 + case IEEE80211_STYPE_CTS:
6237 + case IEEE80211_STYPE_ACK:
6253 +extern void free_ieee80211(struct net_device *dev);
6254 +extern struct net_device *alloc_ieee80211(int sizeof_priv);
6256 +extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
6258 +/* ieee80211_tx.c */
6260 +extern int ieee80211_encrypt_fragment(
6261 + struct ieee80211_device *ieee,
6262 + struct sk_buff *frag,
6265 +extern int ieee80211_xmit(struct sk_buff *skb,
6266 + struct net_device *dev);
6267 +extern void ieee80211_txb_free(struct ieee80211_txb *);
6270 +/* ieee80211_rx.c */
6271 +extern int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
6272 + struct ieee80211_rx_stats *rx_stats);
6273 +extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
6274 + struct ieee80211_hdr *header,
6275 + struct ieee80211_rx_stats *stats);
6277 +/* ieee80211_wx.c */
6278 +extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
6279 + struct iw_request_info *info,
6280 + union iwreq_data *wrqu, char *key);
6281 +extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
6282 + struct iw_request_info *info,
6283 + union iwreq_data *wrqu, char *key);
6284 +extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
6285 + struct iw_request_info *info,
6286 + union iwreq_data *wrqu, char *key);
6287 +extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
6288 + struct iw_request_info *info,
6289 + union iwreq_data* wrqu, char *extra);
6290 +int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
6291 + struct iw_request_info *info,
6292 + struct iw_param *data, char *extra);
6293 +int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
6294 + struct iw_request_info *info,
6295 + union iwreq_data *wrqu, char *extra);
6297 +int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len);
6298 +/* ieee80211_softmac.c */
6299 +extern short ieee80211_is_54g(struct ieee80211_network net);
6300 +extern short ieee80211_is_shortslot(struct ieee80211_network net);
6301 +extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
6302 + struct ieee80211_rx_stats *rx_stats, u16 type,
6304 +extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net);
6306 +extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee);
6307 +extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee);
6308 +extern void ieee80211_start_bss(struct ieee80211_device *ieee);
6309 +extern void ieee80211_start_master_bss(struct ieee80211_device *ieee);
6310 +extern void ieee80211_start_ibss(struct ieee80211_device *ieee);
6311 +extern void ieee80211_softmac_init(struct ieee80211_device *ieee);
6312 +extern void ieee80211_softmac_free(struct ieee80211_device *ieee);
6313 +extern void ieee80211_associate_abort(struct ieee80211_device *ieee);
6314 +extern void ieee80211_disassociate(struct ieee80211_device *ieee);
6315 +extern void ieee80211_stop_scan(struct ieee80211_device *ieee);
6316 +extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee);
6317 +extern void ieee80211_check_all_nets(struct ieee80211_device *ieee);
6318 +extern void ieee80211_start_protocol(struct ieee80211_device *ieee);
6319 +extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
6320 +extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
6321 +extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
6322 +extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
6323 +extern void ieee80211_wake_queue(struct ieee80211_device *ieee);
6324 +extern void ieee80211_stop_queue(struct ieee80211_device *ieee);
6325 +extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
6326 +extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
6327 +extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
6328 +extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p);
6329 +extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
6330 +extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success);
6331 +extern void SendDisassociation(struct ieee80211_device *ieee,u8* asSta,u8 asRsn);
6332 +extern void ieee80211_start_scan(struct ieee80211_device *ieee);
6334 +//Add for RF power on power off by lizhaoming 080512
6335 +extern void SendDisassociation(struct ieee80211_device *ieee,
6339 +/* ieee80211_crypt_ccmp&tkip&wep.c */
6340 +extern void ieee80211_tkip_null(void);
6341 +extern void ieee80211_wep_null(void);
6342 +extern void ieee80211_ccmp_null(void);
6343 +/* ieee80211_softmac_wx.c */
6345 +extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
6346 + struct iw_request_info *info,
6347 + union iwreq_data *wrqu, char *ext);
6349 +extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
6350 + struct iw_request_info *info,
6351 + union iwreq_data *awrq,
6354 +extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b);
6356 +extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
6357 + struct iw_request_info *info,
6358 + union iwreq_data *wrqu, char *extra);
6360 +extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
6361 + struct iw_request_info *info,
6362 + union iwreq_data *wrqu, char *extra);
6364 +extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
6365 + union iwreq_data *wrqu, char *b);
6367 +extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
6368 + union iwreq_data *wrqu, char *b);
6370 +extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
6371 + struct iw_request_info *a,
6372 + union iwreq_data *wrqu, char *extra);
6374 +extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
6375 + union iwreq_data *wrqu, char *b);
6377 +extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
6378 + union iwreq_data *wrqu, char *b);
6380 +extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
6381 + union iwreq_data *wrqu, char *b);
6382 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
6383 +extern void ieee80211_wx_sync_scan_wq(struct work_struct *work);
6385 + extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
6387 +//extern void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee);
6389 +extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
6390 + struct iw_request_info *info,
6391 + union iwreq_data *wrqu, char *extra);
6393 +extern int ieee80211_wx_get_name(struct ieee80211_device *ieee,
6394 + struct iw_request_info *info,
6395 + union iwreq_data *wrqu, char *extra);
6397 +extern int ieee80211_wx_set_power(struct ieee80211_device *ieee,
6398 + struct iw_request_info *info,
6399 + union iwreq_data *wrqu, char *extra);
6401 +extern int ieee80211_wx_get_power(struct ieee80211_device *ieee,
6402 + struct iw_request_info *info,
6403 + union iwreq_data *wrqu, char *extra);
6405 +extern void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee);
6407 +extern void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr);
6409 +extern const long ieee80211_wlan_frequencies[];
6411 +extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
6416 +extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
6418 + return ieee->scans;
6421 +static inline const char *escape_essid(const char *essid, u8 essid_len) {
6422 + static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
6423 + const char *s = essid;
6424 + char *d = escaped;
6426 + if (ieee80211_is_empty_essid(essid, essid_len)) {
6427 + memcpy(escaped, "<hidden>", sizeof("<hidden>"));
6431 + essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
6432 + while (essid_len--) {
6444 +#endif /* IEEE80211_H */
6446 +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c
6448 +/*******************************************************************************
6450 + Copyright(c) 2004 Intel Corporation. All rights reserved.
6452 + Portions of this file are based on the WEP enablement code provided by the
6453 + Host AP project hostap-drivers v0.1.3
6454 + Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
6455 + <jkmaline@cc.hut.fi>
6456 + Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
6458 + This program is free software; you can redistribute it and/or modify it
6459 + under the terms of version 2 of the GNU General Public License as
6460 + published by the Free Software Foundation.
6462 + This program is distributed in the hope that it will be useful, but WITHOUT
6463 + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6464 + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
6467 + You should have received a copy of the GNU General Public License along with
6468 + this program; if not, write to the Free Software Foundation, Inc., 59
6469 + Temple Place - Suite 330, Boston, MA 02111-1307, USA.
6471 + The full GNU General Public License is included in this distribution in the
6472 + file called LICENSE.
6474 + Contact Information:
6475 + James P. Ketrenos <ipw2100-admin@linux.intel.com>
6476 + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
6478 +*******************************************************************************/
6480 +#include <linux/compiler.h>
6481 +//#include <linux/config.h>
6482 +#include <linux/errno.h>
6483 +#include <linux/if_arp.h>
6484 +#include <linux/in6.h>
6485 +#include <linux/in.h>
6486 +#include <linux/ip.h>
6487 +#include <linux/kernel.h>
6488 +#include <linux/module.h>
6489 +#include <linux/netdevice.h>
6490 +#include <linux/pci.h>
6491 +#include <linux/proc_fs.h>
6492 +#include <linux/skbuff.h>
6493 +#include <linux/slab.h>
6494 +#include <linux/tcp.h>
6495 +#include <linux/types.h>
6496 +#include <linux/version.h>
6497 +#include <linux/wireless.h>
6498 +#include <linux/etherdevice.h>
6499 +#include <asm/uaccess.h>
6500 +#include <net/arp.h>
6502 +#include "ieee80211.h"
6504 +MODULE_DESCRIPTION("802.11 data/management/control stack");
6505 +MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
6506 +MODULE_LICENSE("GPL");
6508 +#define DRV_NAME "ieee80211"
6510 +static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
6512 + if (ieee->networks)
6515 + ieee->networks = kmalloc(
6516 + MAX_NETWORK_COUNT * sizeof(struct ieee80211_network),
6518 + if (!ieee->networks) {
6519 + printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
6524 + memset(ieee->networks, 0,
6525 + MAX_NETWORK_COUNT * sizeof(struct ieee80211_network));
6530 +static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
6532 + if (!ieee->networks)
6534 + kfree(ieee->networks);
6535 + ieee->networks = NULL;
6538 +static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
6542 + INIT_LIST_HEAD(&ieee->network_free_list);
6543 + INIT_LIST_HEAD(&ieee->network_list);
6544 + for (i = 0; i < MAX_NETWORK_COUNT; i++)
6545 + list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
6549 +struct net_device *alloc_ieee80211(int sizeof_priv)
6551 + struct ieee80211_device *ieee;
6552 + struct net_device *dev;
6555 + IEEE80211_DEBUG_INFO("Initializing...\n");
6557 + dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
6559 + IEEE80211_ERROR("Unable to network device.\n");
6562 + ieee = netdev_priv(dev);
6563 + dev->hard_start_xmit = ieee80211_xmit;
6567 + err = ieee80211_networks_allocate(ieee);
6569 + IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
6573 + ieee80211_networks_initialize(ieee);
6575 + /* Default fragmentation threshold is maximum payload size */
6576 + ieee->fts = DEFAULT_FTS;
6577 + ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
6578 + ieee->open_wep = 1;
6580 + /* Default to enabling full open WEP with host based encrypt/decrypt */
6581 + ieee->host_encrypt = 1;
6582 + ieee->host_decrypt = 1;
6583 + ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
6585 + INIT_LIST_HEAD(&ieee->crypt_deinit_list);
6586 + init_timer(&ieee->crypt_deinit_timer);
6587 + ieee->crypt_deinit_timer.data = (unsigned long)ieee;
6588 + ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
6590 + spin_lock_init(&ieee->lock);
6591 + spin_lock_init(&ieee->wpax_suitlist_lock);
6593 + ieee->wpax_type_set = 0;
6594 + ieee->wpa_enabled = 0;
6595 + ieee->tkip_countermeasures = 0;
6596 + ieee->drop_unencrypted = 0;
6597 + ieee->privacy_invoked = 0;
6598 + ieee->ieee802_1x = 1;
6601 + ieee80211_softmac_init(ieee);
6603 + for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
6604 + INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
6606 + for (i = 0; i < 17; i++) {
6607 + ieee->last_rxseq_num[i] = -1;
6608 + ieee->last_rxfrag_num[i] = -1;
6609 + ieee->last_packet_time[i] = 0;
6611 +//These function were added to load crypte module autoly
6612 + ieee80211_tkip_null();
6613 + ieee80211_wep_null();
6614 + ieee80211_ccmp_null();
6624 +void free_ieee80211(struct net_device *dev)
6626 + struct ieee80211_device *ieee = netdev_priv(dev);
6629 + struct list_head *p, *q;
6632 + ieee80211_softmac_free(ieee);
6633 + del_timer_sync(&ieee->crypt_deinit_timer);
6634 + ieee80211_crypt_deinit_entries(ieee, 1);
6636 + for (i = 0; i < WEP_KEYS; i++) {
6637 + struct ieee80211_crypt_data *crypt = ieee->crypt[i];
6640 + crypt->ops->deinit(crypt->priv);
6641 + module_put(crypt->ops->owner);
6644 + ieee->crypt[i] = NULL;
6648 + ieee80211_networks_free(ieee);
6650 + for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) {
6651 + list_for_each_safe(p, q, &ieee->ibss_mac_hash[i]) {
6652 + kfree(list_entry(p, struct ieee_ibss_seq, list));
6661 +#ifdef CONFIG_IEEE80211_DEBUG
6663 +static int debug = 0;
6664 +u32 ieee80211_debug_level = 0;
6665 +struct proc_dir_entry *ieee80211_proc = NULL;
6667 +static int show_debug_level(char *page, char **start, off_t offset,
6668 + int count, int *eof, void *data)
6670 + return snprintf(page, count, "0x%08X\n", ieee80211_debug_level);
6673 +static int store_debug_level(struct file *file, const char *buffer,
6674 + unsigned long count, void *data)
6676 + char buf[] = "0x00000000";
6677 + unsigned long len = min(sizeof(buf) - 1, (u32)count);
6678 + char *p = (char *)buf;
6679 + unsigned long val;
6681 + if (copy_from_user(buf, buffer, len))
6684 + if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
6686 + if (p[0] == 'x' || p[0] == 'X')
6688 + val = simple_strtoul(p, &p, 16);
6690 + val = simple_strtoul(p, &p, 10);
6692 + printk(KERN_INFO DRV_NAME
6693 + ": %s is not in hex or decimal form.\n", buf);
6695 + ieee80211_debug_level = val;
6697 + return strnlen(buf, count);
6700 +static int __init ieee80211_init(void)
6702 + struct proc_dir_entry *e;
6704 + ieee80211_debug_level = debug;
6705 + ieee80211_proc = create_proc_entry(DRV_NAME, S_IFDIR, proc_net);
6706 + if (ieee80211_proc == NULL) {
6707 + IEEE80211_ERROR("Unable to create " DRV_NAME
6708 + " proc directory\n");
6711 + e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR,
6714 + remove_proc_entry(DRV_NAME, proc_net);
6715 + ieee80211_proc = NULL;
6718 + e->read_proc = show_debug_level;
6719 + e->write_proc = store_debug_level;
6725 +static void __exit ieee80211_exit(void)
6727 + if (ieee80211_proc) {
6728 + remove_proc_entry("debug_level", ieee80211_proc);
6729 + remove_proc_entry(DRV_NAME, proc_net);
6730 + ieee80211_proc = NULL;
6734 +#include <linux/moduleparam.h>
6735 +module_param(debug, int, 0444);
6736 +MODULE_PARM_DESC(debug, "debug output mask");
6739 +module_exit(ieee80211_exit);
6740 +module_init(ieee80211_init);
6744 +EXPORT_SYMBOL(alloc_ieee80211);
6745 +EXPORT_SYMBOL(free_ieee80211);
6748 +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
6751 + * Original code based Host AP (software wireless LAN access point) driver
6752 + * for Intersil Prism2/2.5/3 - hostap.o module, common routines
6754 + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
6755 + * <jkmaline@cc.hut.fi>
6756 + * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
6757 + * Copyright (c) 2004, Intel Corporation
6759 + * This program is free software; you can redistribute it and/or modify
6760 + * it under the terms of the GNU General Public License version 2 as
6761 + * published by the Free Software Foundation. See README and COPYING for
6763 + ******************************************************************************
6765 + Few modifications for Realtek's Wi-Fi drivers by
6766 + Andrea Merello <andreamrl@tiscali.it>
6768 + A special thanks goes to Realtek for their support !
6770 +******************************************************************************/
6773 +#include <linux/compiler.h>
6774 +//#include <linux/config.h>
6775 +#include <linux/errno.h>
6776 +#include <linux/if_arp.h>
6777 +#include <linux/in6.h>
6778 +#include <linux/in.h>
6779 +#include <linux/ip.h>
6780 +#include <linux/kernel.h>
6781 +#include <linux/module.h>
6782 +#include <linux/netdevice.h>
6783 +#include <linux/pci.h>
6784 +#include <linux/proc_fs.h>
6785 +#include <linux/skbuff.h>
6786 +#include <linux/slab.h>
6787 +#include <linux/tcp.h>
6788 +#include <linux/types.h>
6789 +#include <linux/version.h>
6790 +#include <linux/wireless.h>
6791 +#include <linux/etherdevice.h>
6792 +#include <asm/uaccess.h>
6793 +#include <linux/ctype.h>
6795 +#include "ieee80211.h"
6796 +#ifdef ENABLE_DOT11D
6797 +#include "dot11d.h"
6799 +static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee,
6800 + struct sk_buff *skb,
6801 + struct ieee80211_rx_stats *rx_stats)
6803 + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
6804 + u16 fc = le16_to_cpu(hdr->frame_ctl);
6806 + skb->dev = ieee->dev;
6807 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
6808 + skb_reset_mac_header(skb);
6810 + skb->mac.raw = skb->data;
6812 + skb_pull(skb, ieee80211_get_hdrlen(fc));
6813 + skb->pkt_type = PACKET_OTHERHOST;
6814 + skb->protocol = __constant_htons(ETH_P_80211_RAW);
6815 + memset(skb->cb, 0, sizeof(skb->cb));
6820 +/* Called only as a tasklet (software IRQ) */
6821 +static struct ieee80211_frag_entry *
6822 +ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq,
6823 + unsigned int frag, u8 tid,u8 *src, u8 *dst)
6825 + struct ieee80211_frag_entry *entry;
6828 + for (i = 0; i < IEEE80211_FRAG_CACHE_LEN; i++) {
6829 + entry = &ieee->frag_cache[tid][i];
6830 + if (entry->skb != NULL &&
6831 + time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
6832 + IEEE80211_DEBUG_FRAG(
6833 + "expiring fragment cache entry "
6834 + "seq=%u last_frag=%u\n",
6835 + entry->seq, entry->last_frag);
6836 + dev_kfree_skb_any(entry->skb);
6837 + entry->skb = NULL;
6840 + if (entry->skb != NULL && entry->seq == seq &&
6841 + (entry->last_frag + 1 == frag || frag == -1) &&
6842 + memcmp(entry->src_addr, src, ETH_ALEN) == 0 &&
6843 + memcmp(entry->dst_addr, dst, ETH_ALEN) == 0)
6850 +/* Called only as a tasklet (software IRQ) */
6851 +static struct sk_buff *
6852 +ieee80211_frag_cache_get(struct ieee80211_device *ieee,
6853 + struct ieee80211_hdr *hdr)
6855 + struct sk_buff *skb = NULL;
6856 + u16 fc = le16_to_cpu(hdr->frame_ctl);
6857 + u16 sc = le16_to_cpu(hdr->seq_ctl);
6858 + unsigned int frag = WLAN_GET_SEQ_FRAG(sc);
6859 + unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
6860 + struct ieee80211_frag_entry *entry;
6861 + struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS;
6862 + struct ieee80211_hdr_QOS *hdr_4addr_QoS;
6865 +#ifdef _RTL8187_EXT_PATCH_
6866 + if(ieee->iw_mode == ieee->iw_ext_mode)
6868 + tid = (hdr->addr2[ETH_ALEN-2] ^ hdr->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID;
6872 + if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
6873 + hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)hdr;
6874 + tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
6877 + } else if (IEEE80211_QOS_HAS_SEQ(fc)) {
6878 + hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS *)hdr;
6879 + tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
6887 + /* Reserve enough space to fit maximum frame length */
6888 + skb = dev_alloc_skb(ieee->dev->mtu +
6889 + sizeof(struct ieee80211_hdr) +
6891 + 2 /* alignment */ +
6893 + ETH_ALEN /* WDS */ +
6894 + (IEEE80211_QOS_HAS_SEQ(fc)?2:0) /* QOS Control */);
6898 + entry = &ieee->frag_cache[tid][ieee->frag_next_idx[tid]];
6899 + ieee->frag_next_idx[tid]++;
6900 + if (ieee->frag_next_idx[tid] >= IEEE80211_FRAG_CACHE_LEN)
6901 + ieee->frag_next_idx[tid] = 0;
6903 + if (entry->skb != NULL)
6904 + dev_kfree_skb_any(entry->skb);
6906 + entry->first_frag_time = jiffies;
6908 + entry->last_frag = frag;
6910 + memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
6911 + memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
6913 + /* received a fragment of a frame for which the head fragment
6914 + * should have already been received */
6915 + entry = ieee80211_frag_cache_find(ieee, seq, frag, tid,hdr->addr2,
6917 + if (entry != NULL) {
6918 + entry->last_frag = frag;
6927 +/* Called only as a tasklet (software IRQ) */
6928 +static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
6929 + struct ieee80211_hdr *hdr)
6931 + u16 fc = le16_to_cpu(hdr->frame_ctl);
6932 + u16 sc = le16_to_cpu(hdr->seq_ctl);
6933 + unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
6934 + struct ieee80211_frag_entry *entry;
6935 + struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS;
6936 + struct ieee80211_hdr_QOS *hdr_4addr_QoS;
6939 +#ifdef _RTL8187_EXT_PATCH_
6940 + if(ieee->iw_mode == ieee->iw_ext_mode)
6942 + tid = (hdr->addr2[ETH_ALEN-2] ^ hdr->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID;
6946 + if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
6947 + hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)hdr;
6948 + tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
6951 + } else if (IEEE80211_QOS_HAS_SEQ(fc)) {
6952 + hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS *)hdr;
6953 + tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
6960 + entry = ieee80211_frag_cache_find(ieee, seq, -1, tid,hdr->addr2,
6963 + if (entry == NULL) {
6964 + IEEE80211_DEBUG_FRAG(
6965 + "could not invalidate fragment cache "
6966 + "entry (seq=%u)\n", seq);
6970 + entry->skb = NULL;
6976 +/* ieee80211_rx_frame_mgtmt
6978 + * Responsible for handling management control frames
6980 + * Called by ieee80211_rx */
6982 +ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
6983 + struct ieee80211_rx_stats *rx_stats, u16 type,
6986 + struct ieee80211_hdr *hdr;
6988 + // cheat the the hdr type
6989 + hdr = (struct ieee80211_hdr *)skb->data;
6991 + /* On the struct stats definition there is written that
6992 + * this is not mandatory.... but seems that the probe
6993 + * response parser uses it
6995 + rx_stats->len = skb->len;
6996 + ieee80211_rx_mgt(ieee,(struct ieee80211_hdr *)skb->data,rx_stats);
6998 + if((ieee->state == IEEE80211_LINKED)&&(memcmp(hdr->addr3,ieee->current_network.bssid,ETH_ALEN))) {
6999 + dev_kfree_skb_any(skb);
7003 + ieee80211_rx_frame_softmac(ieee, skb, rx_stats, type, stype);
7005 + dev_kfree_skb_any(skb);
7010 + if (ieee->iw_mode == IW_MODE_MASTER) {
7011 + printk(KERN_DEBUG "%s: Master mode not yet suppported.\n",
7015 + hostap_update_sta_ps(ieee, (struct hostap_ieee80211_hdr *)
7019 + if (ieee->hostapd && type == IEEE80211_TYPE_MGMT) {
7020 + if (stype == WLAN_FC_STYPE_BEACON &&
7021 + ieee->iw_mode == IW_MODE_MASTER) {
7022 + struct sk_buff *skb2;
7023 + /* Process beacon frames also in kernel driver to
7024 + * update STA(AP) table statistics */
7025 + skb2 = skb_clone(skb, GFP_ATOMIC);
7027 + hostap_rx(skb2->dev, skb2, rx_stats);
7030 + /* send management frames to the user space daemon for
7032 + ieee->apdevstats.rx_packets++;
7033 + ieee->apdevstats.rx_bytes += skb->len;
7034 + prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT);
7038 + if (ieee->iw_mode == IW_MODE_MASTER) {
7039 + if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) {
7040 + printk(KERN_DEBUG "%s: unknown management frame "
7041 + "(type=0x%02x, stype=0x%02x) dropped\n",
7042 + skb->dev->name, type, stype);
7046 + hostap_rx(skb->dev, skb, rx_stats);
7050 + printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame "
7051 + "received in non-Host AP mode\n", skb->dev->name);
7058 +/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
7059 +/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
7060 +static unsigned char rfc1042_header[] =
7061 +{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
7062 +/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
7063 +static unsigned char bridge_tunnel_header[] =
7064 +{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
7065 +/* No encapsulation header if EtherType < 0x600 (=length) */
7067 +/* Called by ieee80211_rx_frame_decrypt */
7068 +static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
7069 + struct sk_buff *skb, size_t hdrlen)
7071 + struct net_device *dev = ieee->dev;
7072 + u16 fc, ethertype;
7073 + struct ieee80211_hdr *hdr;
7076 + if (skb->len < 24)
7079 + hdr = (struct ieee80211_hdr *) skb->data;
7080 + fc = le16_to_cpu(hdr->frame_ctl);
7082 + /* check that the frame is unicast frame to us */
7083 + if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
7084 + IEEE80211_FCTL_TODS &&
7085 + memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&
7086 + memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
7087 + /* ToDS frame with own addr BSSID and DA */
7088 + } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
7089 + IEEE80211_FCTL_FROMDS &&
7090 + memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
7091 + /* FromDS frame with own addr as DA */
7095 + if (skb->len < 24 + 8)
7098 + /* check for port access entity Ethernet type */
7099 +// pos = skb->data + 24;
7100 + pos = skb->data + hdrlen;
7101 + ethertype = (pos[6] << 8) | pos[7];
7102 + if (ethertype == ETH_P_PAE)
7108 +/* Called only as a tasklet (software IRQ), by ieee80211_rx */
7110 +ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb,
7111 + struct ieee80211_crypt_data *crypt)
7113 + struct ieee80211_hdr *hdr;
7116 + if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
7119 + hdr = (struct ieee80211_hdr *) skb->data;
7120 +#ifdef _RTL8187_EXT_PATCH_
7121 + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen))
7123 + hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb);
7127 + hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
7129 +#ifdef CONFIG_IEEE80211_CRYPT_TKIP
7130 + if (ieee->tkip_countermeasures &&
7131 + strcmp(crypt->ops->name, "TKIP") == 0) {
7132 + if (net_ratelimit()) {
7133 + printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
7134 + "received packet from " MAC_FMT "\n",
7135 + ieee->dev->name, MAC_ARG(hdr->addr2));
7141 + atomic_inc(&crypt->refcnt);
7142 + res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
7143 + atomic_dec(&crypt->refcnt);
7145 + IEEE80211_DEBUG_DROP(
7146 + "decryption failed (SA=" MAC_FMT
7147 + ") res=%d\n", MAC_ARG(hdr->addr2), res);
7149 + IEEE80211_DEBUG_DROP("Decryption failed ICV "
7150 + "mismatch (key %d)\n",
7151 + skb->data[hdrlen + 3] >> 6);
7152 + ieee->ieee_stats.rx_discards_undecryptable++;
7160 +/* Called only as a tasklet (software IRQ), by ieee80211_rx */
7162 +ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *skb,
7163 + int keyidx, struct ieee80211_crypt_data *crypt)
7165 + struct ieee80211_hdr *hdr;
7168 + if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
7171 + hdr = (struct ieee80211_hdr *) skb->data;
7172 +#ifdef _RTL8187_EXT_PATCH_
7173 + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen))
7175 + hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb);
7179 + hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
7181 + atomic_inc(&crypt->refcnt);
7182 + res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
7183 + atomic_dec(&crypt->refcnt);
7185 + printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
7186 + " (SA=" MAC_FMT " keyidx=%d)\n",
7187 + ieee->dev->name, MAC_ARG(hdr->addr2), keyidx);
7195 +/* this function is stolen from ipw2200 driver*/
7196 +#define IEEE_PACKET_RETRY_TIME (5*HZ)
7197 +static int is_duplicate_packet(struct ieee80211_device *ieee,
7198 + struct ieee80211_hdr *header)
7200 + u16 fc = le16_to_cpu(header->frame_ctl);
7201 + u16 sc = le16_to_cpu(header->seq_ctl);
7202 + u16 seq = WLAN_GET_SEQ_SEQ(sc);
7203 + u16 frag = WLAN_GET_SEQ_FRAG(sc);
7204 + u16 *last_seq, *last_frag;
7205 + unsigned long *last_time;
7206 + struct ieee80211_hdr_3addr_QOS *hdr_3addr_QoS;
7207 + struct ieee80211_hdr_QOS *hdr_4addr_QoS;
7210 +#ifdef _RTL8187_EXT_PATCH_
7211 + if(ieee->iw_mode == ieee->iw_ext_mode)
7213 + tid = (header->addr2[ETH_ALEN-2] ^ header->addr2[ETH_ALEN-1]) & IEEE80211_QOS_TID;
7218 + if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) {
7219 + hdr_4addr_QoS = (struct ieee80211_hdr_QOS *)header;
7220 + tid = le16_to_cpu(hdr_4addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
7223 + } else if(IEEE80211_QOS_HAS_SEQ(fc)) { //QoS
7224 + hdr_3addr_QoS = (struct ieee80211_hdr_3addr_QOS*)header;
7225 + tid = le16_to_cpu(hdr_3addr_QoS->QOS_ctl) & IEEE80211_QOS_TID;
7228 + } else { // no QoS
7231 + switch (ieee->iw_mode) {
7232 + case IW_MODE_ADHOC:
7234 + struct list_head *p;
7235 + struct ieee_ibss_seq *entry = NULL;
7236 + u8 *mac = header->addr2;
7237 + int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE;
7238 + //for (pos = (head)->next; pos != (head); pos = pos->next)
7239 + __list_for_each(p, &ieee->ibss_mac_hash[index]) {
7240 + entry = list_entry(p, struct ieee_ibss_seq, list);
7241 + if (!memcmp(entry->mac, mac, ETH_ALEN))
7244 + // if (memcmp(entry->mac, mac, ETH_ALEN)){
7245 + if (p == &ieee->ibss_mac_hash[index]) {
7246 + entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC);
7248 + printk(KERN_WARNING "Cannot malloc new mac entry\n");
7251 + memcpy(entry->mac, mac, ETH_ALEN);
7252 + entry->seq_num[tid] = seq;
7253 + entry->frag_num[tid] = frag;
7254 + entry->packet_time[tid] = jiffies;
7255 + list_add(&entry->list, &ieee->ibss_mac_hash[index]);
7258 + last_seq = &entry->seq_num[tid];
7259 + last_frag = &entry->frag_num[tid];
7260 + last_time = &entry->packet_time[tid];
7264 + case IW_MODE_INFRA:
7265 + last_seq = &ieee->last_rxseq_num[tid];
7266 + last_frag = &ieee->last_rxfrag_num[tid];
7267 + last_time = &ieee->last_packet_time[tid];
7271 +#ifdef _RTL8187_EXT_PATCH_
7272 + if(ieee->iw_mode == ieee->iw_ext_mode)
7274 + last_seq = &ieee->last_rxseq_num[tid];
7275 + last_frag = &ieee->last_rxfrag_num[tid];
7276 + last_time = &ieee->last_packet_time[tid];
7285 +// printk(KERN_WARNING ":)))))))))))%x %x %x, fc(%x)\n", tid, *last_seq, seq, header->frame_ctl);
7287 + if ((*last_seq == seq) &&
7288 + time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) {
7289 + if (*last_frag == frag){
7290 + //printk(KERN_WARNING "[1] go drop!\n");
7294 + if (*last_frag + 1 != frag)
7295 + /* out-of-order fragment */
7296 + //printk(KERN_WARNING "[2] go drop!\n");
7301 + *last_frag = frag;
7302 + *last_time = jiffies;
7306 +// BUG_ON(!(fc & IEEE80211_FCTL_RETRY));
7307 +// printk("DUP\n");
7313 +/* All received frames are sent to this function. @skb contains the frame in
7314 + * IEEE 802.11 format, i.e., in the format it was sent over air.
7315 + * This function is called only as a tasklet (software IRQ). */
7316 +int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
7317 + struct ieee80211_rx_stats *rx_stats)
7319 + struct net_device *dev = ieee->dev;
7320 + //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
7321 + struct ieee80211_hdr *hdr;
7322 + //struct ieee80211_hdr_3addr_QOS *hdr;
7325 + u16 fc, type, stype, sc;
7326 + struct net_device_stats *stats;
7327 + unsigned int frag;
7331 + struct net_device *wds = NULL;
7332 + struct sk_buff *skb2 = NULL;
7333 + struct net_device *wds = NULL;
7334 + int frame_authorized = 0;
7335 + int from_assoc_ap = 0;
7338 +// u16 QOS_ctl = 0;
7341 + u8 bssid[ETH_ALEN];
7342 + struct ieee80211_crypt_data *crypt = NULL;
7345 + //Added for mesh by Lawrence.
7346 +#ifdef _RTL8187_EXT_PATCH_
7350 + // cheat the the hdr type
7351 + hdr = (struct ieee80211_hdr *)skb->data;
7352 + stats = &ieee->stats;
7354 + if (skb->len < 10) {
7355 + printk(KERN_INFO "%s: SKB length < 10\n",
7360 + fc = le16_to_cpu(hdr->frame_ctl);
7361 + type = WLAN_FC_GET_TYPE(fc);
7362 + stype = WLAN_FC_GET_STYPE(fc);
7363 + sc = le16_to_cpu(hdr->seq_ctl);
7365 + frag = WLAN_GET_SEQ_FRAG(sc);
7367 +//YJ,add,080828,for keep alive
7368 + if((fc & IEEE80211_FCTL_TODS) != IEEE80211_FCTL_TODS)
7370 + if(!memcmp(hdr->addr1,dev->dev_addr, ETH_ALEN))
7372 + ieee->NumRxUnicast++;
7377 + if(!memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN))
7379 + ieee->NumRxUnicast++;
7382 +//YJ,add,080828,for keep alive,end
7384 +#ifdef _RTL8187_EXT_PATCH_
7385 + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_rx_frame_get_hdrlen))
7387 + hdrlen = ieee->ext_patch_ieee80211_rx_frame_get_hdrlen(ieee, skb);
7388 + if(skb->len < hdrlen)
7393 + hdrlen = ieee80211_get_hdrlen(fc);
7396 +#if WIRELESS_EXT > 15
7397 + /* Put this code here so that we avoid duplicating it in all
7398 + * Rx paths. - Jean II */
7399 +#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
7400 + /* If spy monitoring on */
7401 + if (iface->spy_data.spy_number > 0) {
7402 + struct iw_quality wstats;
7403 + wstats.level = rx_stats->signal;
7404 + wstats.noise = rx_stats->noise;
7405 + wstats.updated = 6; /* No qual value */
7406 + /* Update spy records */
7407 + wireless_spy_update(dev, hdr->addr2, &wstats);
7409 +#endif /* IW_WIRELESS_SPY */
7410 +#endif /* WIRELESS_EXT > 15 */
7411 + hostap_update_rx_stats(local->ap, hdr, rx_stats);
7414 +#if WIRELESS_EXT > 15
7415 + if (ieee->iw_mode == IW_MODE_MONITOR) {
7416 + ieee80211_monitor_rx(ieee, skb, rx_stats);
7417 + stats->rx_packets++;
7418 + stats->rx_bytes += skb->len;
7422 + if (ieee->host_decrypt) {
7424 + if (skb->len >= hdrlen + 3)
7425 + idx = skb->data[hdrlen + 3] >> 6;
7426 + crypt = ieee->crypt[idx];
7430 + /* Use station specific key to override default keys if the
7431 + * receiver address is a unicast address ("individual RA"). If
7432 + * bcrx_sta_key parameter is set, station specific key is used
7433 + * even with broad/multicast targets (this is against IEEE
7434 + * 802.11, but makes it easier to use different keys with
7435 + * stations that do not support WEP key mapping). */
7437 + if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key)
7438 + (void) hostap_handle_sta_crypto(local, hdr, &crypt,
7442 + /* allow NULL decrypt to indicate an station specific override
7443 + * for default encryption */
7444 + if (crypt && (crypt->ops == NULL ||
7445 + crypt->ops->decrypt_mpdu == NULL))
7448 + if (!crypt && (fc & IEEE80211_FCTL_WEP)) {
7449 + /* This seems to be triggered by some (multicast?)
7450 + * frames from other than current BSS, so just drop the
7451 + * frames silently instead of filling system log with
7452 + * these reports. */
7453 + IEEE80211_DEBUG_DROP("Decryption failed (not set)"
7454 + " (SA=" MAC_FMT ")\n",
7455 + MAC_ARG(hdr->addr2));
7456 + ieee->ieee_stats.rx_discards_undecryptable++;
7461 + if (skb->len < IEEE80211_DATA_HDR3_LEN)
7464 +#ifdef _RTL8187_EXT_PATCH_
7465 + if( ieee->iw_mode == ieee->iw_ext_mode && ieee->ext_patch_ieee80211_rx_mgt_update_expire )
7466 + ieee->ext_patch_ieee80211_rx_mgt_update_expire( ieee, skb );
7469 + // if QoS enabled, should check the sequence for each of the AC
7470 + if (is_duplicate_packet(ieee, hdr))
7474 + if (type == IEEE80211_FTYPE_MGMT) {
7477 + if ( stype == IEEE80211_STYPE_AUTH &&
7478 + fc & IEEE80211_FCTL_WEP && ieee->host_decrypt &&
7479 + (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0)
7481 + printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
7482 + "from " MAC_FMT "\n", dev->name,
7483 + MAC_ARG(hdr->addr2));
7484 + /* TODO: could inform hostapd about this so that it
7485 + * could send auth failure report */
7491 + if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
7496 +#ifdef _RTL8187_EXT_PATCH_
7497 + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_on_rx)
7499 + if(ieee->ext_patch_ieee80211_rx_on_rx(ieee, skb, rx_stats, type, stype)==0)
7506 + /* Data frame - extract src/dst addresses */
7507 + switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
7508 + case IEEE80211_FCTL_FROMDS:
7509 + memcpy(dst, hdr->addr1, ETH_ALEN);
7510 + memcpy(src, hdr->addr3, ETH_ALEN);
7511 + memcpy(bssid,hdr->addr2,ETH_ALEN);
7513 + case IEEE80211_FCTL_TODS:
7514 + memcpy(dst, hdr->addr3, ETH_ALEN);
7515 + memcpy(src, hdr->addr2, ETH_ALEN);
7516 + memcpy(bssid,hdr->addr1,ETH_ALEN);
7518 + case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
7519 + if (skb->len < IEEE80211_DATA_HDR4_LEN)
7521 + memcpy(dst, hdr->addr3, ETH_ALEN);
7522 + memcpy(src, hdr->addr4, ETH_ALEN);
7523 + memcpy(bssid, ieee->current_network.bssid, ETH_ALEN);
7526 + memcpy(dst, hdr->addr1, ETH_ALEN);
7527 + memcpy(src, hdr->addr2, ETH_ALEN);
7528 + memcpy(bssid,hdr->addr3,ETH_ALEN);
7533 + if (hostap_rx_frame_wds(ieee, hdr, fc, &wds))
7536 + skb->dev = dev = wds;
7537 + stats = hostap_get_stats(dev);
7540 + if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
7541 + (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS &&
7543 + memcmp(hdr->addr2, ieee->assoc_ap_addr, ETH_ALEN) == 0) {
7544 + /* Frame from BSSID of the AP for which we are a client */
7545 + skb->dev = dev = ieee->stadev;
7546 + stats = hostap_get_stats(dev);
7547 + from_assoc_ap = 1;
7551 + dev->last_rx = jiffies;
7554 + if ((ieee->iw_mode == IW_MODE_MASTER ||
7555 + ieee->iw_mode == IW_MODE_REPEAT) &&
7557 + switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats,
7559 + case AP_RX_CONTINUE_NOT_AUTHORIZED:
7560 + frame_authorized = 0;
7562 + case AP_RX_CONTINUE:
7563 + frame_authorized = 1;
7573 +#ifdef _RTL8187_EXT_PATCH_
7574 + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_is_valid_framectl)
7576 + if(ieee->ext_patch_ieee80211_rx_is_valid_framectl(ieee, fc, type, stype)==0)
7581 + /* Nullfunc frames may have PS-bit set, so they must be passed to
7582 + * hostap_handle_sta_rx() before being dropped here. */
7583 + if (stype != IEEE80211_STYPE_DATA &&
7584 + stype != IEEE80211_STYPE_DATA_CFACK &&
7585 + stype != IEEE80211_STYPE_DATA_CFPOLL &&
7586 + stype != IEEE80211_STYPE_DATA_CFACKPOLL&&
7587 + stype != IEEE80211_STYPE_QOS_DATA//add by David,2006.8.4
7589 + if (stype != IEEE80211_STYPE_NULLFUNC)
7590 + IEEE80211_DEBUG_DROP(
7591 + "RX: dropped data frame "
7592 + "with no data (type=0x%02x, "
7593 + "subtype=0x%02x, len=%d)\n",
7594 + type, stype, skb->len);
7597 + if(memcmp(bssid,ieee->current_network.bssid,ETH_ALEN)) {
7601 + ieee->NumRxDataInPeriod++;
7602 + ieee->NumRxOkTotal++;
7603 + /* skb: hdr + (possibly fragmented, possibly encrypted) payload */
7605 + if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
7606 + (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
7609 + hdr = (struct ieee80211_hdr *) skb->data;
7611 + /* skb: hdr + (possibly fragmented) plaintext payload */
7612 + // PR: FIXME: hostap has additional conditions in the "if" below:
7613 + // ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
7614 + if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) {
7616 + struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
7617 + IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
7620 + IEEE80211_DEBUG(IEEE80211_DL_RX | IEEE80211_DL_FRAG,
7621 + "Rx cannot get skb from fragment "
7622 + "cache (morefrag=%d seq=%u frag=%u)\n",
7623 + (fc & IEEE80211_FCTL_MOREFRAGS) != 0,
7624 + WLAN_GET_SEQ_SEQ(sc), frag);
7631 + if (frag_skb->tail + flen > frag_skb->end) {
7632 + printk(KERN_WARNING "%s: host decrypted and "
7633 + "reassembled frame did not fit skb\n",
7635 + ieee80211_frag_cache_invalidate(ieee, hdr);
7640 + /* copy first fragment (including full headers) into
7641 + * beginning of the fragment cache skb */
7642 + memcpy(skb_put(frag_skb, flen), skb->data, flen);
7644 + /* append frame payload to the end of the fragment
7646 + memcpy(skb_put(frag_skb, flen), skb->data + hdrlen,
7649 + dev_kfree_skb_any(skb);
7652 + if (fc & IEEE80211_FCTL_MOREFRAGS) {
7653 + /* more fragments expected - leave the skb in fragment
7654 + * cache for now; it will be delivered to upper layers
7655 + * after all fragments have been received */
7659 + /* this was the last fragment and the frame will be
7660 + * delivered, so remove skb from fragment cache */
7662 + hdr = (struct ieee80211_hdr *) skb->data;
7663 + ieee80211_frag_cache_invalidate(ieee, hdr);
7666 + /* skb: hdr + (possible reassembled) full MSDU payload; possibly still
7667 + * encrypted/authenticated */
7668 + if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
7669 + ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
7672 + hdr = (struct ieee80211_hdr *) skb->data;
7673 + if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) {
7674 + if (/*ieee->ieee802_1x &&*/
7675 + ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
7677 +#ifdef CONFIG_IEEE80211_DEBUG
7678 + /* pass unencrypted EAPOL frames even if encryption is
7680 + struct eapol *eap = (struct eapol *)(skb->data +
7682 + IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
7683 + eap_get_type(eap->type));
7686 + IEEE80211_DEBUG_DROP(
7687 + "encryption configured, but RX "
7688 + "frame not encrypted (SA=" MAC_FMT ")\n",
7689 + MAC_ARG(hdr->addr2));
7694 +#ifdef CONFIG_IEEE80211_DEBUG
7695 + if (crypt && !(fc & IEEE80211_FCTL_WEP) &&
7696 + ieee80211_is_eapol_frame(ieee, skb)) {
7697 + struct eapol *eap = (struct eapol *)(skb->data +
7699 + IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
7700 + eap_get_type(eap->type));
7704 + if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep &&
7705 + !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
7706 + IEEE80211_DEBUG_DROP(
7707 + "dropped unencrypted RX data "
7708 + "frame from " MAC_FMT
7709 + " (drop_unencrypted=1)\n",
7710 + MAC_ARG(hdr->addr2));
7714 + if(ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
7715 + printk(KERN_WARNING "RX: IEEE802.1X EPAOL frame!\n");
7718 + /* skb: hdr + (possible reassembled) full plaintext payload */
7719 + payload = skb->data + hdrlen;
7720 + ethertype = (payload[6] << 8) | payload[7];
7723 + /* If IEEE 802.1X is used, check whether the port is authorized to send
7724 + * the received frame. */
7725 + if (ieee->ieee802_1x && ieee->iw_mode == IW_MODE_MASTER) {
7726 + if (ethertype == ETH_P_PAE) {
7727 + printk(KERN_DEBUG "%s: RX: IEEE 802.1X frame\n",
7729 + if (ieee->hostapd && ieee->apdev) {
7730 + /* Send IEEE 802.1X frames to the user
7731 + * space daemon for processing */
7732 + prism2_rx_80211(ieee->apdev, skb, rx_stats,
7734 + ieee->apdevstats.rx_packets++;
7735 + ieee->apdevstats.rx_bytes += skb->len;
7738 + } else if (!frame_authorized) {
7739 + printk(KERN_DEBUG "%s: dropped frame from "
7740 + "unauthorized port (IEEE 802.1X): "
7741 + "ethertype=0x%04x\n",
7742 + dev->name, ethertype);
7748 +#ifdef _RTL8187_EXT_PATCH_
7749 + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_process_dataframe)
7751 + //Added for mesh rx interrupt.
7752 + //spin_lock_irqsave(&ieee->lock,flags);
7753 + status = ieee->ext_patch_ieee80211_rx_process_dataframe(ieee, skb, rx_stats);
7754 + //spin_unlock_irqrestore(&ieee->lock,flags);
7757 +// if(ieee->ext_patch_ieee80211_rx_process_dataframe(ieee, skb, rx_stats))
7764 + /* convert hdr + possible LLC headers into Ethernet header */
7765 + if (skb->len - hdrlen >= 8 &&
7766 + ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
7767 + ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
7768 + memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
7769 + /* remove RFC1042 or Bridge-Tunnel encapsulation and
7770 + * replace EtherType */
7771 + skb_pull(skb, hdrlen + SNAP_SIZE);
7772 + memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
7773 + memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
7776 + /* Leave Ethernet header part of hdr and full payload */
7777 + skb_pull(skb, hdrlen);
7778 + len = htons(skb->len);
7779 + memcpy(skb_push(skb, 2), &len, 2);
7780 + memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
7781 + memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
7785 + if (wds && ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
7786 + IEEE80211_FCTL_TODS) &&
7787 + skb->len >= ETH_HLEN + ETH_ALEN) {
7788 + /* Non-standard frame: get addr4 from its bogus location after
7790 + memcpy(skb->data + ETH_ALEN,
7791 + skb->data + skb->len - ETH_ALEN, ETH_ALEN);
7792 + skb_trim(skb, skb->len - ETH_ALEN);
7796 + stats->rx_packets++;
7797 + stats->rx_bytes += skb->len;
7800 + if (ieee->iw_mode == IW_MODE_MASTER && !wds &&
7801 + ieee->ap->bridge_packets) {
7802 + if (dst[0] & 0x01) {
7803 + /* copy multicast frame both to the higher layers and
7804 + * to the wireless media */
7805 + ieee->ap->bridged_multicast++;
7806 + skb2 = skb_clone(skb, GFP_ATOMIC);
7808 + printk(KERN_DEBUG "%s: skb_clone failed for "
7809 + "multicast frame\n", dev->name);
7810 + } else if (hostap_is_sta_assoc(ieee->ap, dst)) {
7811 + /* send frame directly to the associated STA using
7812 + * wireless media and not passing to higher layers */
7813 + ieee->ap->bridged_unicast++;
7819 + if (skb2 != NULL) {
7820 + /* send to wireless media */
7821 + skb2->protocol = __constant_htons(ETH_P_802_3);
7822 + skb2->mac.raw = skb2->nh.raw = skb2->data;
7823 + /* skb2->nh.raw = skb2->data + ETH_HLEN; */
7825 + dev_queue_xmit(skb2);
7830 + skb->protocol = eth_type_trans(skb, dev);
7831 + memset(skb->cb, 0, sizeof(skb->cb));
7833 + skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
7834 + ieee->last_rx_ps_time = jiffies;
7841 + hostap_handle_sta_release(sta);
7846 + stats->rx_dropped++;
7848 + /* Returning 0 indicates to caller that we have not handled the SKB--
7849 + * so it is still allocated and can be used again by underlying
7850 + * hardware as a DMA target */
7854 +#ifdef _RTL8187_EXT_PATCH_
7855 +int ieee_ext_skb_p80211_to_ether(struct sk_buff *skb, int hdrlen, u8 *dst, u8 *src)
7860 + /* skb: hdr + (possible reassembled) full plaintext payload */
7861 + payload = skb->data + hdrlen;
7862 + ethertype = (payload[6] << 8) | payload[7];
7864 + /* convert hdr + possible LLC headers into Ethernet header */
7865 + if (skb->len - hdrlen >= 8 &&
7866 + ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
7867 + ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
7868 + memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
7869 + /* remove RFC1042 or Bridge-Tunnel encapsulation and
7870 + * replace EtherType */
7871 + skb_pull(skb, hdrlen + SNAP_SIZE);
7872 + memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
7873 + memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
7876 + /* Leave Ethernet header part of hdr and full payload */
7877 + skb_pull(skb, hdrlen);
7878 + len = htons(skb->len);
7879 + memcpy(skb_push(skb, 2), &len, 2);
7880 + memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
7881 + memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
7886 +#endif // _RTL8187_EXT_PATCH_
7889 +#define MGMT_FRAME_FIXED_PART_LENGTH 0x24
7891 +static inline int ieee80211_is_ofdm_rate(u8 rate)
7893 + switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
7894 + case IEEE80211_OFDM_RATE_6MB:
7895 + case IEEE80211_OFDM_RATE_9MB:
7896 + case IEEE80211_OFDM_RATE_12MB:
7897 + case IEEE80211_OFDM_RATE_18MB:
7898 + case IEEE80211_OFDM_RATE_24MB:
7899 + case IEEE80211_OFDM_RATE_36MB:
7900 + case IEEE80211_OFDM_RATE_48MB:
7901 + case IEEE80211_OFDM_RATE_54MB:
7907 +static inline int ieee80211_SignalStrengthTranslate(
7913 + // Step 1. Scale mapping.
7914 + if(CurrSS >= 71 && CurrSS <= 100)
7916 + RetSS = 90 + ((CurrSS - 70) / 3);
7918 + else if(CurrSS >= 41 && CurrSS <= 70)
7920 + RetSS = 78 + ((CurrSS - 40) / 3);
7922 + else if(CurrSS >= 31 && CurrSS <= 40)
7924 + RetSS = 66 + (CurrSS - 30);
7926 + else if(CurrSS >= 21 && CurrSS <= 30)
7928 + RetSS = 54 + (CurrSS - 20);
7930 + else if(CurrSS >= 5 && CurrSS <= 20)
7932 + RetSS = 42 + (((CurrSS - 5) * 2) / 3);
7934 + else if(CurrSS == 4)
7938 + else if(CurrSS == 3)
7942 + else if(CurrSS == 2)
7946 + else if(CurrSS == 1)
7954 + //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
7956 + // Step 2. Smoothing.
7958 + //RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
7963 +#ifdef ENABLE_DOT11D
7964 +static inline void ieee80211_extract_country_ie(
7965 + struct ieee80211_device *ieee,
7966 + struct ieee80211_info_element *info_element,
7967 + struct ieee80211_network *network,
7973 + u8 * p = (u8*)info_element->data;
7974 + printk("-----------------------\n");
7975 + printk("%s Country IE:", network->ssid);
7976 + for(i=0; i<info_element->len; i++)
7977 + printk("\t%2.2x", *(p+i));
7978 + printk("\n-----------------------\n");
7980 + if(IS_DOT11D_ENABLE(ieee))
7982 + if(info_element->len!= 0)
7984 + memcpy(network->CountryIeBuf, info_element->data, info_element->len);
7985 + network->CountryIeLen = info_element->len;
7987 + if(!IS_COUNTRY_IE_VALID(ieee))
7989 + Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data);
7994 + // 070305, rcnjko: I update country IE watch dog here because
7995 + // some AP (e.g. Cisco 1242) don't include country IE in their
7996 + // probe response frame.
7998 + if(IS_EQUAL_CIE_SRC(ieee, addr2) )
8000 + UPDATE_CIE_WATCHDOG(ieee);
8008 +ieee80211_TranslateToDbm(
8009 + unsigned char SignalStrengthIndex // 0-100 index.
8012 + unsigned char SignalPower; // in dBm.
8014 + // Translate to dBm (x=0.5y-95).
8015 + SignalPower = (int)SignalStrengthIndex * 7 / 10;
8016 + SignalPower -= 95;
8018 + return SignalPower;
8020 +inline int ieee80211_network_init(
8021 + struct ieee80211_device *ieee,
8022 + struct ieee80211_probe_response *beacon,
8023 + struct ieee80211_network *network,
8024 + struct ieee80211_rx_stats *stats)
8026 +#ifdef CONFIG_IEEE80211_DEBUG
8027 + char rates_str[64];
8030 + struct ieee80211_info_element *info_element;
8034 + u8 curRate = 0,hOpRate = 0,curRate_ex = 0;
8036 + /* Pull out fixed field data */
8037 + memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
8038 + network->capability = beacon->capability;
8039 + network->last_scanned = jiffies;
8040 + network->time_stamp[0] = beacon->time_stamp[0];
8041 + network->time_stamp[1] = beacon->time_stamp[1];
8042 + network->beacon_interval = beacon->beacon_interval;
8043 + /* Where to pull this? beacon->listen_interval;*/
8044 + network->listen_interval = 0x0A;
8045 + network->rates_len = network->rates_ex_len = 0;
8046 + network->last_associate = 0;
8047 + network->ssid_len = 0;
8048 + network->flags = 0;
8049 + network->atim_window = 0;
8050 + network->QoS_Enable = 0;
8052 + network->HighestOperaRate = 0;
8054 +#ifdef THOMAS_TURBO
8055 + network->Turbo_Enable = 0;
8057 +#ifdef ENABLE_DOT11D
8058 + network->CountryIeLen = 0;
8059 + memset(network->CountryIeBuf, 0, MAX_IE_LEN);
8062 + if (stats->freq == IEEE80211_52GHZ_BAND) {
8063 + /* for A band (No DS info) */
8064 + network->channel = stats->received_channel;
8066 + network->flags |= NETWORK_HAS_CCK;
8068 + network->wpa_ie_len = 0;
8069 + network->rsn_ie_len = 0;
8071 + info_element = &beacon->info_element;
8072 + left = stats->len - ((void *)info_element - (void *)beacon);
8073 + while (left >= sizeof(struct ieee80211_info_element_hdr)) {
8074 + if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
8075 + IEEE80211_DEBUG_SCAN("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%d left=%d.\n",
8076 + info_element->len + sizeof(struct ieee80211_info_element),
8081 + switch (info_element->id) {
8082 + case MFIE_TYPE_SSID:
8083 + if (ieee80211_is_empty_essid(info_element->data,
8084 + info_element->len)) {
8085 + network->flags |= NETWORK_EMPTY_ESSID;
8089 + network->ssid_len = min(info_element->len,
8090 + (u8)IW_ESSID_MAX_SIZE);
8091 + memcpy(network->ssid, info_element->data, network->ssid_len);
8092 + if (network->ssid_len < IW_ESSID_MAX_SIZE)
8093 + memset(network->ssid + network->ssid_len, 0,
8094 + IW_ESSID_MAX_SIZE - network->ssid_len);
8096 + IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n",
8097 + network->ssid, network->ssid_len);
8100 + case MFIE_TYPE_RATES:
8101 +#ifdef CONFIG_IEEE80211_DEBUG
8104 + network->rates_len = min(info_element->len, MAX_RATES_LENGTH);
8105 + for (i = 0; i < network->rates_len; i++) {
8106 + network->rates[i] = info_element->data[i];
8107 + curRate = network->rates[i] & 0x7f;
8108 + if( hOpRate < curRate )
8109 + hOpRate = curRate;
8110 +#ifdef CONFIG_IEEE80211_DEBUG
8111 + p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
8113 + if (ieee80211_is_ofdm_rate(info_element->data[i])) {
8114 + network->flags |= NETWORK_HAS_OFDM;
8115 + if (info_element->data[i] &
8116 + IEEE80211_BASIC_RATE_MASK)
8122 + IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES: '%s' (%d)\n",
8123 + rates_str, network->rates_len);
8126 + case MFIE_TYPE_RATES_EX:
8127 +#ifdef CONFIG_IEEE80211_DEBUG
8130 + network->rates_ex_len = min(info_element->len, MAX_RATES_EX_LENGTH);
8131 + for (i = 0; i < network->rates_ex_len; i++) {
8132 + network->rates_ex[i] = info_element->data[i];
8133 + curRate_ex = network->rates_ex[i] & 0x7f;
8134 + if( hOpRate < curRate_ex )
8135 + hOpRate = curRate_ex;
8136 +#ifdef CONFIG_IEEE80211_DEBUG
8137 + p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
8139 + if (ieee80211_is_ofdm_rate(info_element->data[i])) {
8140 + network->flags |= NETWORK_HAS_OFDM;
8141 + if (info_element->data[i] &
8142 + IEEE80211_BASIC_RATE_MASK)
8148 + IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
8149 + rates_str, network->rates_ex_len);
8152 + case MFIE_TYPE_DS_SET:
8153 + IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n",
8154 + info_element->data[0]);
8155 + if (stats->freq == IEEE80211_24GHZ_BAND)
8156 + network->channel = info_element->data[0];
8159 + case MFIE_TYPE_FH_SET:
8160 + IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n");
8163 + case MFIE_TYPE_CF_SET:
8164 + IEEE80211_DEBUG_SCAN("MFIE_TYPE_CF_SET: ignored\n");
8167 + case MFIE_TYPE_TIM:
8169 + if(info_element->len < 4)
8172 + network->dtim_period = info_element->data[1];
8174 + if(ieee->state != IEEE80211_LINKED)
8177 + network->last_dtim_sta_time[0] = stats->mac_time[0];
8179 + network->last_dtim_sta_time[0] = jiffies;
8181 + network->last_dtim_sta_time[1] = stats->mac_time[1];
8183 + network->dtim_data = IEEE80211_DTIM_VALID;
8185 + if(info_element->data[0] != 0)
8188 + if(info_element->data[2] & 1)
8189 + network->dtim_data |= IEEE80211_DTIM_MBCAST;
8191 + offset = (info_element->data[2] >> 1)*2;
8193 + //printk("offset1:%x aid:%x\n",offset, ieee->assoc_id);
8195 + /* add and modified for ps 2008.1.22 */
8196 + if(ieee->assoc_id < 8*offset ||
8197 + ieee->assoc_id > 8*(offset + info_element->len -3)) {
8201 + offset = (ieee->assoc_id/8) - offset;// + ((aid % 8)? 0 : 1) ;
8203 + // printk("offset:%x data:%x, ucast:%d\n", offset,
8204 + // info_element->data[3+offset] ,
8205 + // info_element->data[3+offset] & (1<<(ieee->assoc_id%8)));
8207 + if(info_element->data[3+offset] & (1<<(ieee->assoc_id%8))) {
8208 + network->dtim_data |= IEEE80211_DTIM_UCAST;
8212 + case MFIE_TYPE_IBSS_SET:
8213 + IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: ignored\n");
8216 + case MFIE_TYPE_CHALLENGE:
8217 + IEEE80211_DEBUG_SCAN("MFIE_TYPE_CHALLENGE: ignored\n");
8220 + case MFIE_TYPE_GENERIC:
8222 + IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n",
8223 + info_element->len);
8224 + if (info_element->len >= 4 &&
8225 + info_element->data[0] == 0x00 &&
8226 + info_element->data[1] == 0x50 &&
8227 + info_element->data[2] == 0xf2 &&
8228 + info_element->data[3] == 0x01) {
8229 + network->wpa_ie_len = min(info_element->len + 2,
8231 + memcpy(network->wpa_ie, info_element,
8232 + network->wpa_ie_len);
8235 +#ifdef THOMAS_TURBO
8236 + if (info_element->len == 7 &&
8237 + info_element->data[0] == 0x00 &&
8238 + info_element->data[1] == 0xe0 &&
8239 + info_element->data[2] == 0x4c &&
8240 + info_element->data[3] == 0x01 &&
8241 + info_element->data[4] == 0x02) {
8242 + network->Turbo_Enable = 1;
8245 + if (1 == stats->nic_type) {//nic 87
8249 + if (info_element->len >= 5 &&
8250 + info_element->data[0] == 0x00 &&
8251 + info_element->data[1] == 0x50 &&
8252 + info_element->data[2] == 0xf2 &&
8253 + info_element->data[3] == 0x02 &&
8254 + info_element->data[4] == 0x00) {
8255 + //printk(KERN_WARNING "wmm info updated: %x\n", info_element->data[6]);
8256 + //WMM Information Element
8257 + network->wmm_info = info_element->data[6];
8258 + network->QoS_Enable = 1;
8261 + if (info_element->len >= 8 &&
8262 + info_element->data[0] == 0x00 &&
8263 + info_element->data[1] == 0x50 &&
8264 + info_element->data[2] == 0xf2 &&
8265 + info_element->data[3] == 0x02 &&
8266 + info_element->data[4] == 0x01) {
8267 + // Not care about version at present.
8268 + //WMM Information Element
8269 + //printk(KERN_WARNING "wmm info¶m updated: %x\n", info_element->data[6]);
8270 + network->wmm_info = info_element->data[6];
8271 + //WMM Parameter Element
8272 + memcpy(network->wmm_param, (u8 *)(info_element->data + 8),(info_element->len - 8));
8273 + network->QoS_Enable = 1;
8277 + case MFIE_TYPE_RSN:
8278 + IEEE80211_DEBUG_SCAN("MFIE_TYPE_RSN: %d bytes\n",
8279 + info_element->len);
8280 + network->rsn_ie_len = min(info_element->len + 2,
8282 + memcpy(network->rsn_ie, info_element,
8283 + network->rsn_ie_len);
8285 +#ifdef ENABLE_DOT11D
8286 + case MFIE_TYPE_COUNTRY:
8287 + IEEE80211_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n",
8288 + info_element->len);
8289 +// printk("=====>Receive <%s> Country IE\n",network->ssid);
8290 + ieee80211_extract_country_ie(ieee, info_element, network, beacon->header.addr2);
8294 + IEEE80211_DEBUG_SCAN("unsupported IE %d\n",
8295 + info_element->id);
8299 + left -= sizeof(struct ieee80211_info_element_hdr) +
8300 + info_element->len;
8301 + info_element = (struct ieee80211_info_element *)
8302 + &info_element->data[info_element->len];
8305 + network->HighestOperaRate = hOpRate;
8307 + network->mode = 0;
8308 + if (stats->freq == IEEE80211_52GHZ_BAND)
8309 + network->mode = IEEE_A;
8311 + if (network->flags & NETWORK_HAS_OFDM)
8312 + network->mode |= IEEE_G;
8313 + if (network->flags & NETWORK_HAS_CCK)
8314 + network->mode |= IEEE_B;
8317 + if (network->mode == 0) {
8318 + IEEE80211_DEBUG_SCAN("Filtered out '%s (" MAC_FMT ")' "
8320 + escape_essid(network->ssid,
8321 + network->ssid_len),
8322 + MAC_ARG(network->bssid));
8326 + if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
8327 + network->flags |= NETWORK_EMPTY_ESSID;
8329 + stats->signal = ieee80211_SignalStrengthTranslate(stats->signal);
8331 + stats->signal = ieee80211_TranslateToDbm(stats->signalstrength);
8332 + //stats->noise = stats->signal - stats->noise;
8333 + stats->noise = ieee80211_TranslateToDbm(100 - stats->signalstrength) - 25;
8334 + memcpy(&network->stats, stats, sizeof(network->stats));
8339 +static inline int is_same_network(struct ieee80211_network *src,
8340 + struct ieee80211_network *dst,
8341 + struct ieee80211_device * ieee)
8343 + /* A network is only a duplicate if the channel, BSSID, ESSID
8344 + * and the capability field (in particular IBSS and BSS) all match.
8345 + * We treat all <hidden> with the same BSSID and channel
8346 + * as one network */
8347 + return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod,080819,for hidden ap
8348 + //((src->ssid_len == dst->ssid_len) &&
8349 + (src->channel == dst->channel) &&
8350 + !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
8351 + (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod,080819,for hidden ap
8352 + //!memcmp(src->ssid, dst->ssid, src->ssid_len) &&
8353 + ((src->capability & WLAN_CAPABILITY_IBSS) ==
8354 + (dst->capability & WLAN_CAPABILITY_IBSS)) &&
8355 + ((src->capability & WLAN_CAPABILITY_BSS) ==
8356 + (dst->capability & WLAN_CAPABILITY_BSS)));
8359 +inline void update_network(struct ieee80211_network *dst,
8360 + struct ieee80211_network *src)
8362 + unsigned char quality = src->stats.signalstrength;
8363 + unsigned char signal = 0;
8364 + unsigned char noise = 0;
8365 + if(dst->stats.signalstrength > 0) {
8366 + quality = (dst->stats.signalstrength * 5 + src->stats.signalstrength + 5)/6;
8368 + signal = ieee80211_TranslateToDbm(quality);
8369 + //noise = signal - src->stats.noise;
8370 + if(dst->stats.noise > 0)
8371 + noise = (dst->stats.noise * 5 + src->stats.noise)/6;
8372 + //if(strcmp(dst->ssid, "linksys_lzm000") == 0)
8373 +// printk("ssid:%s, quality:%d, signal:%d\n", dst->ssid, quality, signal);
8374 + memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
8375 + dst->stats.signalstrength = quality;
8376 + dst->stats.signal = signal;
8377 +// printk("==================>stats.signal is %d\n",dst->stats.signal);
8378 + dst->stats.noise = noise;
8381 + dst->capability = src->capability;
8382 + memcpy(dst->rates, src->rates, src->rates_len);
8383 + dst->rates_len = src->rates_len;
8384 + memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
8385 + dst->rates_ex_len = src->rates_ex_len;
8386 + dst->HighestOperaRate= src->HighestOperaRate;
8387 + //printk("==========>in %s: src->ssid is %s,chan is %d\n",__FUNCTION__,src->ssid,src->channel);
8389 + //YJ,add,080819,for hidden ap
8390 + if(src->ssid_len > 0)
8392 + //if(src->ssid_len == 13)
8393 + // printk("=====================>>>>>>>> Dst ssid: %s Src ssid: %s\n", dst->ssid, src->ssid);
8394 + memset(dst->ssid, 0, dst->ssid_len);
8395 + dst->ssid_len = src->ssid_len;
8396 + memcpy(dst->ssid, src->ssid, src->ssid_len);
8398 + //YJ,add,080819,for hidden ap,end
8400 + dst->channel = src->channel;
8401 + dst->mode = src->mode;
8402 + dst->flags = src->flags;
8403 + dst->time_stamp[0] = src->time_stamp[0];
8404 + dst->time_stamp[1] = src->time_stamp[1];
8406 + dst->beacon_interval = src->beacon_interval;
8407 + dst->listen_interval = src->listen_interval;
8408 + dst->atim_window = src->atim_window;
8409 + dst->dtim_period = src->dtim_period;
8410 + dst->dtim_data = src->dtim_data;
8411 + dst->last_dtim_sta_time[0] = src->last_dtim_sta_time[0];
8412 + dst->last_dtim_sta_time[1] = src->last_dtim_sta_time[1];
8413 +// printk("update:%s, dtim_period:%x, dtim_data:%x\n", src->ssid, src->dtim_period, src->dtim_data);
8414 + memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
8415 + dst->wpa_ie_len = src->wpa_ie_len;
8416 + memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);
8417 + dst->rsn_ie_len = src->rsn_ie_len;
8419 + dst->last_scanned = jiffies;
8420 + /* dst->last_associate is not overwritten */
8421 +// disable QoS process now, added by David 2006/7/25
8423 + dst->wmm_info = src->wmm_info; //sure to exist in beacon or probe response frame.
8425 + if((dst->wmm_info^src->wmm_info)&0x0f) {//Param Set Count change, update Parameter
8426 + memcpy(dst->wmm_param, src->wmm_param, IEEE80211_AC_PRAM_LEN);
8429 + if(src->wmm_param[0].ac_aci_acm_aifsn|| \
8430 + src->wmm_param[1].ac_aci_acm_aifsn|| \
8431 + src->wmm_param[2].ac_aci_acm_aifsn|| \
8432 + src->wmm_param[1].ac_aci_acm_aifsn) {
8433 + memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN);
8435 + dst->QoS_Enable = src->QoS_Enable;
8437 + dst->QoS_Enable = 1;//for Rtl8187 simulation
8439 + dst->SignalStrength = src->SignalStrength;
8440 +#ifdef THOMAS_TURBO
8441 + dst->Turbo_Enable = src->Turbo_Enable;
8443 +#ifdef ENABLE_DOT11D
8444 + dst->CountryIeLen = src->CountryIeLen;
8445 + memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen);
8450 +inline void ieee80211_process_probe_response(
8451 + struct ieee80211_device *ieee,
8452 + struct ieee80211_probe_response *beacon,
8453 + struct ieee80211_rx_stats *stats)
8455 + struct ieee80211_network network;
8456 + struct ieee80211_network *target;
8457 + struct ieee80211_network *oldest = NULL;
8458 +#ifdef CONFIG_IEEE80211_DEBUG
8459 + struct ieee80211_info_element *info_element = &beacon->info_element;
8461 + unsigned long flags;
8464 + u8 is_beacon = (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_BEACON)? 1:0; //YJ,add,080819,for hidden ap
8466 + memset(&network, 0, sizeof(struct ieee80211_network));
8468 +#ifdef _RTL8187_EXT_PATCH_
8469 + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_process_probe_response_1) {
8470 + ieee->ext_patch_ieee80211_process_probe_response_1(ieee, beacon, stats);
8475 + IEEE80211_DEBUG_SCAN(
8476 + "'%s' (" MAC_FMT "): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
8477 + escape_essid(info_element->data, info_element->len),
8478 + MAC_ARG(beacon->header.addr3),
8479 + (beacon->capability & (1<<0xf)) ? '1' : '0',
8480 + (beacon->capability & (1<<0xe)) ? '1' : '0',
8481 + (beacon->capability & (1<<0xd)) ? '1' : '0',
8482 + (beacon->capability & (1<<0xc)) ? '1' : '0',
8483 + (beacon->capability & (1<<0xb)) ? '1' : '0',
8484 + (beacon->capability & (1<<0xa)) ? '1' : '0',
8485 + (beacon->capability & (1<<0x9)) ? '1' : '0',
8486 + (beacon->capability & (1<<0x8)) ? '1' : '0',
8487 + (beacon->capability & (1<<0x7)) ? '1' : '0',
8488 + (beacon->capability & (1<<0x6)) ? '1' : '0',
8489 + (beacon->capability & (1<<0x5)) ? '1' : '0',
8490 + (beacon->capability & (1<<0x4)) ? '1' : '0',
8491 + (beacon->capability & (1<<0x3)) ? '1' : '0',
8492 + (beacon->capability & (1<<0x2)) ? '1' : '0',
8493 + (beacon->capability & (1<<0x1)) ? '1' : '0',
8494 + (beacon->capability & (1<<0x0)) ? '1' : '0');
8496 + if(strcmp(escape_essid(beacon->info_element.data, beacon->info_element.len), "rtl_softap") == 0)
8498 + if(WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_BEACON)
8500 + u32 i = 0, len = stats->len;
8501 + u8 * p = (u8*)beacon;
8502 + printk("-----------------------\n");
8503 + printk("rtl_softap Beacon:");
8504 + for(i=0; i<len; i++)
8505 + printk("\t%2.2x", *(p+i));
8506 + printk("\n-----------------------\n");
8510 + if (ieee80211_network_init(ieee, beacon, &network, stats)) {
8511 + IEEE80211_DEBUG_SCAN("Dropped '%s' (" MAC_FMT ") via %s.\n",
8512 + escape_essid(info_element->data,
8513 + info_element->len),
8514 + MAC_ARG(beacon->header.addr3),
8515 + WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
8516 + IEEE80211_STYPE_PROBE_RESP ?
8517 + "PROBE RESPONSE" : "BEACON");
8521 +#ifdef ENABLE_DOT11D
8522 + // For Asus EeePc request,
8523 + // (1) if wireless adapter receive get any 802.11d country code in AP beacon,
8524 + // wireless adapter should follow the country code.
8525 + // (2) If there is no any country code in beacon,
8526 + // then wireless adapter should do active scan from ch1~11 and
8527 + // passive scan from ch12~14
8528 + if(ieee->bGlobalDomain)
8530 + if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP)
8532 + // Case 1: Country code
8533 + if(IS_COUNTRY_IE_VALID(ieee) )
8535 + if( !IsLegalChannel(ieee, network.channel) )
8537 + printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network.channel);
8541 + // Case 2: No any country code.
8544 + // Filter over channel ch12~14
8545 + if(network.channel > 11)
8547 + printk("GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network.channel);
8554 + // Case 1: Country code
8555 + if(IS_COUNTRY_IE_VALID(ieee) )
8557 + if( !IsLegalChannel(ieee, network.channel) )
8559 + printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n",network.channel);
8563 + // Case 2: No any country code.
8566 + // Filter over channel ch12~14
8567 + if(network.channel > 14)
8569 + printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n",network.channel);
8576 + /* The network parsed correctly -- so now we scan our known networks
8577 + * to see if we can find it in our list.
8579 + * NOTE: This search is definitely not optimized. Once its doing
8580 + * the "right thing" we'll optimize it for efficiency if
8583 + /* Search for this entry in the list and update it if it is
8584 + * already there. */
8586 + spin_lock_irqsave(&ieee->lock, flags);
8588 + if(is_same_network(&ieee->current_network, &network, ieee)) {
8589 + wmm_info = ieee->current_network.wmm_info;
8590 + //YJ,add,080819,for hidden ap
8591 + if(is_beacon == 0)
8592 + network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & ieee->current_network.flags);
8593 + else if(ieee->state == IEEE80211_LINKED)
8594 + ieee->NumRxBcnInPeriod++;
8595 + //YJ,add,080819,for hidden ap,end
8596 + //printk("====>network.ssid=%s cur_ssid=%s\n", network.ssid, ieee->current_network.ssid);
8597 + update_network(&ieee->current_network, &network);
8600 + list_for_each_entry(target, &ieee->network_list, list) {
8601 + if (is_same_network(target, &network, ieee))
8603 + if ((oldest == NULL) ||
8604 + (target->last_scanned < oldest->last_scanned))
8608 + /* If we didn't find a match, then get a new network slot to initialize
8609 + * with this beacon's information */
8610 + if (&target->list == &ieee->network_list) {
8611 + if (list_empty(&ieee->network_free_list)) {
8612 + /* If there are no more slots, expire the oldest */
8613 + list_del(&oldest->list);
8615 + IEEE80211_DEBUG_SCAN("Expired '%s' (" MAC_FMT ") from "
8616 + "network list.\n",
8617 + escape_essid(target->ssid,
8618 + target->ssid_len),
8619 + MAC_ARG(target->bssid));
8621 + /* Otherwise just pull from the free list */
8622 + target = list_entry(ieee->network_free_list.next,
8623 + struct ieee80211_network, list);
8624 + list_del(ieee->network_free_list.next);
8628 +#ifdef CONFIG_IEEE80211_DEBUG
8629 + IEEE80211_DEBUG_SCAN("Adding '%s' (" MAC_FMT ") via %s.\n",
8630 + escape_essid(network.ssid,
8631 + network.ssid_len),
8632 + MAC_ARG(network.bssid),
8633 + WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
8634 + IEEE80211_STYPE_PROBE_RESP ?
8635 + "PROBE RESPONSE" : "BEACON");
8638 +#ifdef _RTL8187_EXT_PATCH_
8639 + network.ext_entry = target->ext_entry;
8641 + memcpy(target, &network, sizeof(*target));
8642 + list_add_tail(&target->list, &ieee->network_list);
8643 + if(ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)
8644 + ieee80211_softmac_new_net(ieee,&network);
8646 + IEEE80211_DEBUG_SCAN("Updating '%s' (" MAC_FMT ") via %s.\n",
8647 + escape_essid(target->ssid,
8648 + target->ssid_len),
8649 + MAC_ARG(target->bssid),
8650 + WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
8651 + IEEE80211_STYPE_PROBE_RESP ?
8652 + "PROBE RESPONSE" : "BEACON");
8654 + /* we have an entry and we are going to update it. But this entry may
8655 + * be already expired. In this case we do the same as we found a new
8656 + * net and call the new_net handler
8658 + renew = !time_after(target->last_scanned + ieee->scan_age, jiffies);
8659 + //YJ,add,080819,for hidden ap
8660 + if(is_beacon == 0)
8661 + network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & target->flags);
8662 + //if(strncmp(network.ssid, "linksys-c",9) == 0)
8663 + // printk("====>2 network.ssid=%s FLAG=%d target.ssid=%s FLAG=%d\n", network.ssid, network.flags, target->ssid, target->flags);
8664 + if(((network.flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \
8665 + && (((network.ssid_len > 0) && (strncmp(target->ssid, network.ssid, network.ssid_len)))\
8666 + ||((ieee->current_network.ssid_len == network.ssid_len)&&(strncmp(ieee->current_network.ssid, network.ssid, network.ssid_len) == 0)&&(ieee->state == IEEE80211_NOLINK))))
8668 + //YJ,add,080819,for hidden ap,end
8669 + update_network(target, &network);
8670 + if(renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE))
8671 + ieee80211_softmac_new_net(ieee,&network);
8674 + spin_unlock_irqrestore(&ieee->lock, flags);
8677 +void ieee80211_rx_mgt(struct ieee80211_device *ieee,
8678 + struct ieee80211_hdr *header,
8679 + struct ieee80211_rx_stats *stats)
8681 + switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
8683 + case IEEE80211_STYPE_BEACON:
8684 + IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
8685 + WLAN_FC_GET_STYPE(header->frame_ctl));
8686 + IEEE80211_DEBUG_SCAN("Beacon\n");
8687 + ieee80211_process_probe_response(
8688 + ieee, (struct ieee80211_probe_response *)header, stats);
8691 + case IEEE80211_STYPE_PROBE_RESP:
8692 + IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
8693 + WLAN_FC_GET_STYPE(header->frame_ctl));
8694 + IEEE80211_DEBUG_SCAN("Probe response\n");
8695 + ieee80211_process_probe_response(
8696 + ieee, (struct ieee80211_probe_response *)header, stats);
8699 +#ifdef _RTL8187_EXT_PATCH_
8700 + case IEEE80211_STYPE_PROBE_REQ:
8701 + IEEE80211_DEBUG_MGMT("received PROBE REQUEST (%d)\n",
8702 + WLAN_FC_GET_STYPE(header->frame_ctl));
8703 + IEEE80211_DEBUG_SCAN("Probe request\n");
8705 + if( ieee->iw_mode == ieee->iw_ext_mode && ieee->ext_patch_ieee80211_rx_mgt_on_probe_req )
8706 + ieee->ext_patch_ieee80211_rx_mgt_on_probe_req( ieee, (struct ieee80211_probe_request *)header, stats);
8708 +#endif // _RTL8187_EXT_PATCH_
8714 +EXPORT_SYMBOL(ieee80211_rx_mgt);
8715 +EXPORT_SYMBOL(ieee80211_rx);
8716 +EXPORT_SYMBOL(ieee80211_network_init);
8717 +#ifdef _RTL8187_EXT_PATCH_
8718 +EXPORT_SYMBOL(ieee_ext_skb_p80211_to_ether);
8722 +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
8724 +/* IEEE 802.11 SoftMAC layer
8725 + * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
8727 + * Mostly extracted from the rtl8180-sa2400 driver for the
8728 + * in-kernel generic ieee802.11 stack.
8730 + * Few lines might be stolen from other part of the ieee80211
8731 + * stack. Copyright who own it's copyright
8733 + * WPA code stolen from the ipw2200 driver.
8734 + * Copyright who own it's copyright.
8736 + * released under the GPL
8740 +#include "ieee80211.h"
8742 +#include <linux/random.h>
8743 +#include <linux/delay.h>
8744 +#include <linux/version.h>
8745 +#include <asm/uaccess.h>
8747 +#ifdef ENABLE_DOT11D
8748 +#include "dot11d.h"
8750 +u8 rsn_authen_cipher_suite[16][4] = {
8751 + {0x00,0x0F,0xAC,0x00}, //Use group key, //Reserved
8752 + {0x00,0x0F,0xAC,0x01}, //WEP-40 //RSNA default
8753 + {0x00,0x0F,0xAC,0x02}, //TKIP //NONE //{used just as default}
8754 + {0x00,0x0F,0xAC,0x03}, //WRAP-historical
8755 + {0x00,0x0F,0xAC,0x04}, //CCMP
8756 + {0x00,0x0F,0xAC,0x05}, //WEP-104
8759 +short ieee80211_is_54g(struct ieee80211_network net)
8761 + return ((net.rates_ex_len > 0) || (net.rates_len > 4));
8764 +short ieee80211_is_shortslot(struct ieee80211_network net)
8766 + return (net.capability & WLAN_CAPABILITY_SHORT_SLOT);
8769 +/* returns the total length needed for pleacing the RATE MFIE
8770 + * tag and the EXTENDED RATE MFIE tag if needed.
8771 + * It encludes two bytes per tag for the tag itself and its len
8773 +unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee)
8775 + unsigned int rate_len = 0;
8777 + if (ieee->modulation & IEEE80211_CCK_MODULATION)
8778 + rate_len = IEEE80211_CCK_RATE_LEN + 2;
8780 + if (ieee->modulation & IEEE80211_OFDM_MODULATION)
8782 + rate_len += IEEE80211_OFDM_RATE_LEN + 2;
8787 +/* pleace the MFIE rate, tag to the memory (double) poined.
8788 + * Then it updates the pointer so that
8789 + * it points after the new MFIE tag added.
8791 +void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p)
8795 + if (ieee->modulation & IEEE80211_CCK_MODULATION){
8796 + *tag++ = MFIE_TYPE_RATES;
8798 + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
8799 + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
8800 + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
8801 + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
8804 + /* We may add an option for custom rates that specific HW might support */
8808 +void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p)
8812 + if (ieee->modulation & IEEE80211_OFDM_MODULATION){
8814 + *tag++ = MFIE_TYPE_RATES_EX;
8816 + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
8817 + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
8818 + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
8819 + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
8820 + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
8821 + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
8822 + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
8823 + *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
8827 + /* We may add an option for custom rates that specific HW might support */
8832 +void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) {
8835 + *tag++ = MFIE_TYPE_GENERIC; //0
8843 +#ifdef SUPPORT_USPD
8844 + if(ieee->current_network.wmm_info & 0x80) {
8845 + *tag++ = 0x0f|MAX_SP_Len;
8847 + *tag++ = MAX_SP_Len;
8850 + *tag++ = MAX_SP_Len;
8855 +#ifdef THOMAS_TURBO
8856 +void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) {
8859 + *tag++ = MFIE_TYPE_GENERIC; //0
8870 + printk(KERN_ALERT "This is enable turbo mode IE process\n");
8874 +void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
8877 + nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM;
8880 + * if the queue is full but we have newer frames then
8881 + * just overwrites the oldest.
8883 + * if (nh == ieee->mgmt_queue_tail)
8886 + ieee->mgmt_queue_head = nh;
8887 + ieee->mgmt_queue_ring[nh] = skb;
8892 +struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
8894 + struct sk_buff *ret;
8896 + if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
8899 + ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
8901 + ieee->mgmt_queue_tail =
8902 + (ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM;
8907 +void init_mgmt_queue(struct ieee80211_device *ieee)
8909 + ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
8913 +void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
8915 +inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
8917 + unsigned long flags;
8918 + short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
8919 + struct ieee80211_hdr_3addr *header=
8920 + (struct ieee80211_hdr_3addr *) skb->data;
8923 + spin_lock_irqsave(&ieee->lock, flags);
8925 + /* called with 2nd param 0, no mgmt lock required */
8926 + ieee80211_sta_wakeup(ieee,0);
8929 + if(ieee->queue_stop){
8931 + enqueue_mgmt(ieee,skb);
8933 + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
8935 + if (ieee->seq_ctrl[0] == 0xFFF)
8936 + ieee->seq_ctrl[0] = 0;
8938 + ieee->seq_ctrl[0]++;
8940 + /* avoid watchdog triggers */
8941 + ieee->dev->trans_start = jiffies;
8942 + ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
8945 + spin_unlock_irqrestore(&ieee->lock, flags);
8947 + spin_unlock_irqrestore(&ieee->lock, flags);
8948 + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
8950 + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
8952 + if (ieee->seq_ctrl[0] == 0xFFF)
8953 + ieee->seq_ctrl[0] = 0;
8955 + ieee->seq_ctrl[0]++;
8957 + /* avoid watchdog triggers */
8958 + ieee->dev->trans_start = jiffies;
8959 + ieee->softmac_hard_start_xmit(skb,ieee->dev);
8961 + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
8966 +inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee)
8969 + short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
8970 + struct ieee80211_hdr_3addr *header =
8971 + (struct ieee80211_hdr_3addr *) skb->data;
8976 + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
8978 + if (ieee->seq_ctrl[0] == 0xFFF)
8979 + ieee->seq_ctrl[0] = 0;
8981 + ieee->seq_ctrl[0]++;
8983 + /* avoid watchdog triggers */
8984 + ieee->dev->trans_start = jiffies;
8985 + ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
8989 + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
8991 + if (ieee->seq_ctrl[0] == 0xFFF)
8992 + ieee->seq_ctrl[0] = 0;
8994 + ieee->seq_ctrl[0]++;
8996 + /* avoid watchdog triggers */
8997 + ieee->dev->trans_start = jiffies;
8998 + ieee->softmac_hard_start_xmit(skb,ieee->dev);
9001 +// dev_kfree_skb_any(skb);//edit by thomas
9003 +//by amy for power save
9004 +inline struct sk_buff *ieee80211_disassociate_skb(
9005 + struct ieee80211_network *beacon,
9006 + struct ieee80211_device *ieee,
9009 + struct sk_buff *skb;
9010 + struct ieee80211_disassoc_frame *disass;
9012 + skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc_frame));
9016 + disass = (struct ieee80211_disassoc_frame *) skb_put(skb,sizeof(struct ieee80211_disassoc_frame));
9017 + disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
9018 + disass->header.duration_id = 0;
9020 + memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
9021 + memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
9022 + memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
9024 + disass->reasoncode = asRsn;
9028 +SendDisassociation(
9029 + struct ieee80211_device *ieee,
9034 + struct ieee80211_network *beacon = &ieee->current_network;
9035 + struct sk_buff *skb;
9036 + skb = ieee80211_disassociate_skb(beacon,ieee,asRsn);
9038 + softmac_mgmt_xmit(skb, ieee);
9039 + //dev_kfree_skb_any(skb);//edit by thomas
9043 +//by amy for power save
9044 +inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
9046 + unsigned int len,rate_len;
9048 + struct sk_buff *skb;
9049 + struct ieee80211_probe_request *req;
9051 +#ifdef _RTL8187_EXT_PATCH_
9052 + short extMore = 0;
9053 + if(ieee->ext_patch_ieee80211_probe_req_1)
9054 + extMore = ieee->ext_patch_ieee80211_probe_req_1(ieee);
9057 + len = ieee->current_network.ssid_len;
9059 + rate_len = ieee80211_MFIE_rate_len(ieee);
9061 +#ifdef _RTL8187_EXT_PATCH_
9064 + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
9065 + 2 + len + rate_len);
9066 +#ifdef _RTL8187_EXT_PATCH_
9068 + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
9069 + 2 + len + rate_len+128); // MESHID + CAP
9075 + req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
9076 + req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
9077 + req->header.duration_id = 0; //FIXME: is this OK ?
9079 + memset(req->header.addr1, 0xff, ETH_ALEN);
9080 + memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
9081 + memset(req->header.addr3, 0xff, ETH_ALEN);
9083 + tag = (u8 *) skb_put(skb,len+2+rate_len);
9085 + *tag++ = MFIE_TYPE_SSID;
9087 + memcpy(tag, ieee->current_network.ssid, len);
9089 + ieee80211_MFIE_Brate(ieee,&tag);
9090 + ieee80211_MFIE_Grate(ieee,&tag);
9092 +#ifdef _RTL8187_EXT_PATCH_
9094 + ieee->ext_patch_ieee80211_probe_req_2(ieee, skb, tag);
9099 +struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
9101 +//#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
9102 +//void ext_ieee80211_send_beacon_wq(struct work_struct *work)
9104 +// struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ext_send_beacon_wq);
9106 +void ext_ieee80211_send_beacon_wq(struct ieee80211_device *ieee)
9110 + struct sk_buff *skb;
9112 + //unsigned long flags;
9114 + skb = ieee80211_get_beacon_(ieee);
9117 + softmac_mgmt_xmit(skb, ieee);
9118 + ieee->softmac_stats.tx_beacons++;
9119 + dev_kfree_skb_any(skb);//edit by thomas
9123 + //printk(KERN_WARNING "[1] beacon sending!\n");
9124 + ieee->beacon_timer.expires = jiffies +
9125 + (MSECS( ieee->current_network.beacon_interval -5));
9127 + //spin_lock_irqsave(&ieee->beacon_lock,flags);
9128 + if(ieee->beacon_txing)
9129 + add_timer(&ieee->beacon_timer);
9130 + //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
9133 +void ieee80211_send_beacon(struct ieee80211_device *ieee)
9135 + struct sk_buff *skb;
9137 + //unsigned long flags;
9139 + skb = ieee80211_get_beacon_(ieee);
9142 + softmac_mgmt_xmit(skb, ieee);
9143 + ieee->softmac_stats.tx_beacons++;
9144 + dev_kfree_skb_any(skb);//edit by thomas
9147 + //printk(KERN_WARNING "[1] beacon sending!\n");
9148 + ieee->beacon_timer.expires = jiffies +
9149 + (MSECS( ieee->current_network.beacon_interval -5));
9151 + //spin_lock_irqsave(&ieee->beacon_lock,flags);
9152 + if(ieee->beacon_txing)
9153 + add_timer(&ieee->beacon_timer);
9154 + //spin_unlock_irqrestore(&ieee->beacon_lock,flags);
9158 +void ieee80211_send_beacon_cb(unsigned long _ieee)
9160 + struct ieee80211_device *ieee =
9161 + (struct ieee80211_device *) _ieee;
9162 + unsigned long flags;
9164 + spin_lock_irqsave(&ieee->beacon_lock, flags);
9165 + ieee80211_send_beacon(ieee);
9166 + spin_unlock_irqrestore(&ieee->beacon_lock, flags);
9169 +#ifdef _RTL8187_EXT_PATCH_
9171 +inline struct sk_buff *ieee80211_probe_req_with_SSID(struct ieee80211_device *ieee, char *ssid, int len_ssid)
9173 + unsigned int len,rate_len;
9175 + struct sk_buff *skb;
9176 + struct ieee80211_probe_request *req;
9178 +#ifdef _RTL8187_EXT_PATCH_
9179 + short extMore = 0;
9180 + if(ieee->ext_patch_ieee80211_probe_req_1)
9181 + extMore = ieee->ext_patch_ieee80211_probe_req_1(ieee);
9186 + rate_len = ieee80211_MFIE_rate_len(ieee);
9188 +#ifdef _RTL8187_EXT_PATCH_
9191 + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
9192 + 2 + len + rate_len);
9193 +#ifdef _RTL8187_EXT_PATCH_
9195 + skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
9196 + 2 + len + rate_len+128); // MESHID + CAP
9202 + req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request));
9203 + req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
9204 + req->header.duration_id = 0; //FIXME: is this OK ?
9206 + memset(req->header.addr1, 0xff, ETH_ALEN);
9207 + memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
9208 + memset(req->header.addr3, 0xff, ETH_ALEN);
9210 + tag = (u8 *) skb_put(skb,len+2+rate_len);
9212 + *tag++ = MFIE_TYPE_SSID;
9216 + memcpy(tag, ssid, len);
9220 + ieee80211_MFIE_Brate(ieee,&tag);
9221 + ieee80211_MFIE_Grate(ieee,&tag);
9223 +#ifdef _RTL8187_EXT_PATCH_
9225 + ieee->ext_patch_ieee80211_probe_req_2(ieee, skb, tag);
9230 +#endif // _RTL8187_EXT_PATCH_
9233 +void ieee80211_send_probe(struct ieee80211_device *ieee)
9235 + struct sk_buff *skb;
9237 +#ifdef _RTL8187_EXT_PATCH_
9238 + if(ieee->iw_mode == ieee->iw_ext_mode)
9239 + skb = ieee80211_probe_req_with_SSID(ieee, NULL, 0);
9242 + skb = ieee80211_probe_req(ieee);
9244 + softmac_mgmt_xmit(skb, ieee);
9245 + ieee->softmac_stats.tx_probe_rq++;
9246 + //dev_kfree_skb_any(skb);//edit by thomas
9250 +void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
9252 + if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)){
9253 + ieee80211_send_probe(ieee);
9254 + ieee80211_send_probe(ieee);
9258 +/* this performs syncro scan blocking the caller until all channels
9259 + * in the allowed channel map has been checked.
9261 +void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
9264 +#ifdef ENABLE_DOT11D
9265 + u8 channel_map[MAX_CHANNEL_NUMBER+1];
9266 + memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
9268 + down(&ieee->scan_sem);
9269 +// printk("==================> Sync scan\n");
9270 +// dump_chnl_map(channel_map);
9277 + if (ch > MAX_CHANNEL_NUMBER)
9278 + goto out; /* scan completed */
9280 +#ifdef ENABLE_DOT11D
9281 + }while(!channel_map[ch]);
9283 + }while(!ieee->channel_map[ch]);
9285 + /* this fuction can be called in two situations
9286 + * 1- We have switched to ad-hoc mode and we are
9287 + * performing a complete syncro scan before conclude
9288 + * there are no interesting cell and to create a
9289 + * new one. In this case the link state is
9290 + * IEEE80211_NOLINK until we found an interesting cell.
9291 + * If so the ieee8021_new_net, called by the RX path
9292 + * will set the state to IEEE80211_LINKED, so we stop
9294 + * 2- We are linked and the root uses run iwlist scan.
9295 + * So we switch to IEEE80211_LINKED_SCANNING to remember
9296 + * that we are still logically linked (not interested in
9297 + * new network events, despite for updating the net list,
9298 + * but we are temporarly 'unlinked' as the driver shall
9299 + * not filter RX frames and the channel is changing.
9300 + * So the only situation in witch are interested is to check
9301 + * if the state become LINKED because of the #1 situation
9304 + if (ieee->state == IEEE80211_LINKED)
9307 + ieee->set_chan(ieee->dev, ch);
9308 +// printk("=====>channel=%d ",ch);
9309 +#ifdef ENABLE_DOT11D
9310 + if(channel_map[ch] == 1)
9313 +// printk("====send probe request\n");
9314 + ieee80211_send_probe_requests(ieee);
9316 + /* this prevent excessive time wait when we
9317 + * need to wait for a syncro scan to end..
9319 + if (ieee->sync_scan_hurryup)
9323 + msleep_interruptible_rtl(IEEE80211_SOFTMAC_SCAN_TIME);
9327 + ieee->sync_scan_hurryup = 0;
9328 + up(&ieee->scan_sem);
9329 +#ifdef ENABLE_DOT11D
9330 + if(IS_DOT11D_ENABLE(ieee))
9331 + DOT11D_ScanComplete(ieee);
9335 +void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee)
9338 + unsigned int watch_dog = 0;
9339 +#ifdef ENABLE_DOT11D
9340 + u8 channel_map[MAX_CHANNEL_NUMBER+1];
9341 + memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
9343 + down(&ieee->scan_sem);
9344 + ch = ieee->current_network.channel;
9345 +// if(ieee->sync_scan_hurryup)
9348 +// printk("stop scan sync\n");
9351 +// printk("=======hh===============>ips scan\n");
9354 + /* this fuction can be called in two situations
9355 + * 1- We have switched to ad-hoc mode and we are
9356 + * performing a complete syncro scan before conclude
9357 + * there are no interesting cell and to create a
9358 + * new one. In this case the link state is
9359 + * IEEE80211_NOLINK until we found an interesting cell.
9360 + * If so the ieee8021_new_net, called by the RX path
9361 + * will set the state to IEEE80211_LINKED, so we stop
9363 + * 2- We are linked and the root uses run iwlist scan.
9364 + * So we switch to IEEE80211_LINKED_SCANNING to remember
9365 + * that we are still logically linked (not interested in
9366 + * new network events, despite for updating the net list,
9367 + * but we are temporarly 'unlinked' as the driver shall
9368 + * not filter RX frames and the channel is changing.
9369 + * So the only situation in witch are interested is to check
9370 + * if the state become LINKED because of the #1 situation
9372 + if (ieee->state == IEEE80211_LINKED)
9376 +#ifdef ENABLE_DOT11D
9377 + if(channel_map[ieee->current_network.channel] > 0)
9380 + ieee->set_chan(ieee->dev, ieee->current_network.channel);
9381 +// printk("======>channel=%d ",ieee->current_network.channel);
9383 +#ifdef ENABLE_DOT11D
9384 + if(channel_map[ieee->current_network.channel] == 1)
9387 +// printk("====send probe request\n");
9388 + ieee80211_send_probe_requests(ieee);
9390 + /* this prevent excessive time wait when we
9391 + * need to wait for a syncro scan to end..
9393 +// if (ieee->sync_scan_hurryup)
9396 + msleep_interruptible_rtl(IEEE80211_SOFTMAC_SCAN_TIME);
9399 + if (watch_dog++ >= MAX_CHANNEL_NUMBER)
9400 + // if (++watch_dog >= 15);//MAX_CHANNEL_NUMBER) //YJ,modified,080630
9401 + goto out; /* scan completed */
9403 + ieee->current_network.channel = (ieee->current_network.channel + 1)%MAX_CHANNEL_NUMBER;
9404 +#ifdef ENABLE_DOT11D
9405 + }while(!channel_map[ieee->current_network.channel]);
9407 + }while(!ieee->channel_map[ieee->current_network.channel]);
9411 + //ieee->sync_scan_hurryup = 0;
9412 + //ieee->set_chan(ieee->dev, ch);
9413 + //ieee->current_network.channel = ch;
9414 + ieee->actscanning = false;
9415 + up(&ieee->scan_sem);
9416 +#ifdef ENABLE_DOT11D
9417 + if(IS_DOT11D_ENABLE(ieee))
9418 + DOT11D_ScanComplete(ieee);
9424 +/* called both by wq with ieee->lock held */
9425 +void ieee80211_softmac_scan(struct ieee80211_device *ieee)
9427 + short watchdog = 0;
9430 + ieee->current_network.channel =
9431 + (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
9432 + if (watchdog++ > MAX_CHANNEL_NUMBER)
9433 + return; /* no good chans */
9435 + }while(!ieee->channel_map[ieee->current_network.channel]);
9438 + schedule_work(&ieee->softmac_scan_wq);
9442 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
9443 +void ieee80211_softmac_scan_wq(struct work_struct *work)
9445 + struct delayed_work *dwork = container_of(work, struct delayed_work, work);
9446 + struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
9448 +void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee)
9451 + static short watchdog = 0;
9452 +#ifdef ENABLE_DOT11D
9453 + u8 channel_map[MAX_CHANNEL_NUMBER+1];
9454 + memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
9456 +// printk("ieee80211_softmac_scan_wq ENABLE_IPS\n");
9457 +// printk("in %s\n",__FUNCTION__);
9458 + down(&ieee->scan_sem);
9461 + ieee->current_network.channel =
9462 + (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
9463 + if (watchdog++ > MAX_CHANNEL_NUMBER)
9464 + goto out; /* no good chans */
9466 +#ifdef ENABLE_DOT11D
9467 + }while(!channel_map[ieee->current_network.channel]);
9469 + }while(!ieee->channel_map[ieee->current_network.channel]);
9472 + //printk("current_network.channel:%d\n", ieee->current_network.channel);
9473 + if (ieee->scanning == 0 )
9475 + printk("error out, scanning = 0\n");
9478 + ieee->set_chan(ieee->dev, ieee->current_network.channel);
9479 +#ifdef ENABLE_DOT11D
9480 + if(channel_map[ieee->current_network.channel] == 1)
9482 + ieee80211_send_probe_requests(ieee);
9484 + queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
9485 + up(&ieee->scan_sem);
9488 + ieee->actscanning = false;
9490 + ieee->scanning = 0;
9491 + up(&ieee->scan_sem);
9493 +#ifdef ENABLE_DOT11D
9494 + if(IS_DOT11D_ENABLE(ieee))
9495 + DOT11D_ScanComplete(ieee);
9500 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
9501 +void ieee80211_softmac_scan_wq(struct work_struct *work)
9503 + struct delayed_work *dwork = container_of(work, struct delayed_work, work);
9504 + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, softmac_scan_wq);
9506 +void ieee80211_softmac_scan_wq(struct ieee80211_device *ieee)
9510 + short watchdog = 0;
9511 +#ifdef ENABLE_DOT11D
9512 + u8 channel_map[MAX_CHANNEL_NUMBER+1];
9513 + memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
9515 +// printk("enter scan wq,watchdog is %d\n",watchdog);
9516 + down(&ieee->scan_sem);
9519 + ieee->current_network.channel =
9520 + (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
9521 + if (watchdog++ > MAX_CHANNEL_NUMBER)
9522 + goto out; /* no good chans */
9524 +#ifdef ENABLE_DOT11D
9525 + }while(!channel_map[ieee->current_network.channel]);
9527 + }while(!ieee->channel_map[ieee->current_network.channel]);
9530 +// printk("current_network.channel:%d\n", ieee->current_network.channel);
9531 + if (ieee->scanning == 0 )
9533 + printk("error out, scanning = 0\n");
9536 + ieee->set_chan(ieee->dev, ieee->current_network.channel);
9537 +#ifdef ENABLE_DOT11D
9538 + if(channel_map[ieee->current_network.channel] == 1)
9540 + ieee80211_send_probe_requests(ieee);
9542 + queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
9544 + up(&ieee->scan_sem);
9545 +#ifdef ENABLE_DOT11D
9546 + if(IS_DOT11D_ENABLE(ieee))
9547 + DOT11D_ScanComplete(ieee);
9552 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
9553 +void ieee80211_softmac_scan_cb(unsigned long _dev)
9555 + unsigned long flags;
9556 + struct ieee80211_device *ieee = (struct ieee80211_device *)_dev;
9558 + spin_lock_irqsave(&ieee->lock, flags);
9559 + ieee80211_softmac_scan(ieee);
9560 + spin_unlock_irqrestore(&ieee->lock, flags);
9565 +void ieee80211_beacons_start(struct ieee80211_device *ieee)
9567 + unsigned long flags;
9569 + spin_lock_irqsave(&ieee->beacon_lock,flags);
9571 + ieee->beacon_txing = 1;
9572 + ieee80211_send_beacon(ieee);
9574 + spin_unlock_irqrestore(&ieee->beacon_lock,flags);
9577 +void ieee80211_beacons_stop(struct ieee80211_device *ieee)
9579 + unsigned long flags;
9581 + spin_lock_irqsave(&ieee->beacon_lock,flags);
9583 + ieee->beacon_txing = 0;
9584 + del_timer_sync(&ieee->beacon_timer);
9586 + spin_unlock_irqrestore(&ieee->beacon_lock,flags);
9591 +void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
9593 + if(ieee->stop_send_beacons)
9594 + ieee->stop_send_beacons(ieee->dev);
9595 + if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
9596 + ieee80211_beacons_stop(ieee);
9600 +void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
9602 + if(ieee->start_send_beacons)
9603 + ieee->start_send_beacons(ieee->dev);
9604 + if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
9605 + ieee80211_beacons_start(ieee);
9609 +void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
9611 +// unsigned long flags;
9613 + //ieee->sync_scan_hurryup = 1;
9615 + down(&ieee->scan_sem);
9616 +// spin_lock_irqsave(&ieee->lock, flags);
9618 + if (ieee->scanning == 1){
9619 + ieee->scanning = 0;
9620 + //del_timer_sync(&ieee->scan_timer);
9621 + cancel_delayed_work(&ieee->softmac_scan_wq);
9624 +// spin_unlock_irqrestore(&ieee->lock, flags);
9625 + up(&ieee->scan_sem);
9628 +void ieee80211_stop_scan(struct ieee80211_device *ieee)
9630 + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
9631 + ieee80211_softmac_stop_scan(ieee);
9633 + ieee->stop_scan(ieee->dev);
9636 +/* called with ieee->lock held */
9637 +void ieee80211_start_scan(struct ieee80211_device *ieee)
9639 +#ifdef ENABLE_DOT11D
9640 + if(IS_DOT11D_ENABLE(ieee) )
9642 + if(IS_COUNTRY_IE_VALID(ieee))
9644 + RESET_CIE_WATCHDOG(ieee);
9648 + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){
9649 + if (ieee->scanning == 0)
9651 + ieee->scanning = 1;
9652 + //ieee80211_softmac_scan(ieee);
9653 + // queue_work(ieee->wq, &ieee->softmac_scan_wq);
9654 + //care this,1203,2007,by lawrence
9656 + queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq,0);
9660 + ieee->start_scan(ieee->dev);
9664 +/* called with wx_sem held */
9665 +void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
9667 +#ifdef ENABLE_DOT11D
9668 + if(IS_DOT11D_ENABLE(ieee) )
9670 + if(IS_COUNTRY_IE_VALID(ieee))
9672 + RESET_CIE_WATCHDOG(ieee);
9676 + ieee->sync_scan_hurryup = 0;
9678 + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
9679 + ieee80211_softmac_scan_syncro(ieee);
9681 + ieee->scan_syncro(ieee->dev);
9685 +inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon,
9686 + struct ieee80211_device *ieee, int challengelen)
9688 + struct sk_buff *skb;
9689 + struct ieee80211_authentication *auth;
9691 + skb = dev_alloc_skb(sizeof(struct ieee80211_authentication) + challengelen);
9693 + if (!skb) return NULL;
9695 + auth = (struct ieee80211_authentication *)
9696 + skb_put(skb, sizeof(struct ieee80211_authentication));
9698 + auth->header.frame_ctl = IEEE80211_STYPE_AUTH;
9699 + if (challengelen) auth->header.frame_ctl |= IEEE80211_FCTL_WEP;
9701 + auth->header.duration_id = 0x013a; //FIXME
9703 + memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN);
9704 + memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
9705 + memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
9707 + auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
9709 + auth->transaction = cpu_to_le16(ieee->associate_seq);
9710 + ieee->associate_seq++;
9712 + auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
9718 +static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest)
9722 + struct ieee80211_probe_response *beacon_buf;
9723 + struct sk_buff *skb;
9725 + int atim_len,erp_len;
9726 + struct ieee80211_crypt_data* crypt;
9728 + char *ssid = ieee->current_network.ssid;
9729 + int ssid_len = ieee->current_network.ssid_len;
9730 + int rate_len = ieee->current_network.rates_len+2;
9731 + int rate_ex_len = ieee->current_network.rates_ex_len;
9732 + int wpa_ie_len = ieee->wpa_ie_len;
9733 + if(rate_ex_len > 0) rate_ex_len+=2;
9735 + if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
9740 + if(ieee80211_is_54g(ieee->current_network))
9745 + beacon_size = sizeof(struct ieee80211_probe_response)+
9754 + skb = dev_alloc_skb(beacon_size);
9759 + beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, beacon_size);
9761 + memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
9762 + memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
9763 + memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
9765 + beacon_buf->header.duration_id = 0; //FIXME
9766 + beacon_buf->beacon_interval =
9767 + cpu_to_le16(ieee->current_network.beacon_interval);
9768 + beacon_buf->capability =
9769 + cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
9771 + if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
9772 + cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));
9774 + crypt = ieee->crypt[ieee->tx_keyidx];
9776 + encrypt = ieee->host_encrypt && crypt && crypt->ops &&
9777 + ((0 == strcmp(crypt->ops->name, "WEP")) || wpa_ie_len);
9780 + beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
9783 + beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
9785 + beacon_buf->info_element.id = MFIE_TYPE_SSID;
9786 + beacon_buf->info_element.len = ssid_len;
9788 + tag = (u8*) beacon_buf->info_element.data;
9790 + memcpy(tag, ssid, ssid_len);
9794 + *(tag++) = MFIE_TYPE_RATES;
9795 + *(tag++) = rate_len-2;
9796 + memcpy(tag,ieee->current_network.rates,rate_len-2);
9799 + *(tag++) = MFIE_TYPE_DS_SET;
9801 + *(tag++) = ieee->current_network.channel;
9804 + *(tag++) = MFIE_TYPE_IBSS_SET;
9806 + *((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window);
9811 + *(tag++) = MFIE_TYPE_ERP;
9817 + *(tag++) = MFIE_TYPE_RATES_EX;
9818 + *(tag++) = rate_ex_len-2;
9819 + memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2);
9820 + tag+=rate_ex_len-2;
9825 + if (ieee->iw_mode == IW_MODE_ADHOC)
9826 + {//as Windows will set pairwise key same as the group key which is not allowed in Linux, so set this for IOT issue. WB 2008.07.07
9827 + memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
9830 + memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
9833 + skb->dev = ieee->dev;
9836 +#ifdef _RTL8187_EXT_PATCH_
9837 +struct sk_buff* ieee80211_ext_probe_resp_by_net(struct ieee80211_device *ieee, u8 *dest, struct ieee80211_network *net)
9841 + struct ieee80211_probe_response *beacon_buf;
9842 + struct sk_buff *skb;
9844 + int atim_len,erp_len;
9845 + struct ieee80211_crypt_data* crypt;
9846 + u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
9847 + int wpa_ie_len = ieee->wpa_ie_len;
9848 + char *ssid = net->ssid;
9849 + int ssid_len = net->ssid_len;
9851 + int rate_len = ieee->current_network.rates_len+2;
9852 + int rate_ex_len = ieee->current_network.rates_ex_len;
9853 + if(rate_ex_len > 0) rate_ex_len+=2;
9855 + if( ieee->meshScanMode&4)
9856 + ieee->current_network.channel = ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee);
9857 + if( ieee->meshScanMode&6)
9860 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
9861 + queue_work(ieee->wq, &ieee->ext_stop_scan_wq);
9863 + schedule_task(&ieee->ext_stop_scan_wq);
9866 + if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS) // use current_network here
9871 + if(ieee80211_is_54g(*net))
9876 + beacon_size = sizeof(struct ieee80211_probe_response)+
9884 + skb = dev_alloc_skb(beacon_size+196);
9889 + beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, beacon_size);
9891 + memcpy (beacon_buf->header.addr1, dest,ETH_ALEN);
9892 + memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
9893 + memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
9895 + beacon_buf->header.duration_id = 0; //FIXME
9897 + beacon_buf->beacon_interval =
9898 + cpu_to_le16(ieee->current_network.beacon_interval); // use current_network here
9899 + beacon_buf->capability =
9900 + cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
9902 + if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
9903 + cpu_to_le16((beacon_buf->capability |= WLAN_CAPABILITY_SHORT_SLOT));
9905 + crypt = ieee->crypt[ieee->tx_keyidx];
9907 + encrypt = ieee->host_encrypt && crypt && crypt->ops &&
9908 + ((0 == strcmp(crypt->ops->name, "WEP"))||wpa_ie_len);
9911 + beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
9914 + beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
9916 + beacon_buf->info_element.id = MFIE_TYPE_SSID;
9917 + beacon_buf->info_element.len = ssid_len;
9919 + tag = (u8*) beacon_buf->info_element.data;
9921 + // brocad cast / probe rsp
9922 + if(memcmp(dest, broadcast_addr, ETH_ALEN ))
9923 + memcpy(tag, ssid, ssid_len);
9929 +//get_bssrate_set(priv, _SUPPORTEDRATES_IE_, &pbssrate, &bssrate_len);
9930 +//pbuf = set_ie(pbuf, _SUPPORTEDRATES_IE_, bssrate_len, pbssrate, &frlen);
9932 + *(tag++) = MFIE_TYPE_RATES;
9933 + *(tag++) = rate_len-2;
9934 + memcpy(tag,ieee->current_network.rates,rate_len-2);
9937 + *(tag++) = MFIE_TYPE_DS_SET;
9939 + *(tag++) = ieee->current_network.channel; // use current_network here
9943 + *(tag++) = MFIE_TYPE_IBSS_SET;
9945 + *((u16*)(tag)) = cpu_to_le16(ieee->current_network.atim_window); // use current_network here
9950 + *(tag++) = MFIE_TYPE_ERP;
9956 + *(tag++) = MFIE_TYPE_RATES_EX;
9957 + *(tag++) = rate_ex_len-2;
9958 + memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2);
9959 + tag+=rate_ex_len-2;
9962 + memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
9964 + skb->dev = ieee->dev;
9967 +#endif // _RTL8187_EXT_PATCH_
9969 +struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest)
9971 + struct sk_buff *skb;
9974 + struct ieee80211_crypt_data* crypt;
9975 + struct ieee80211_assoc_response_frame *assoc;
9978 + unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
9979 + int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len;
9981 + skb = dev_alloc_skb(len);
9986 + assoc = (struct ieee80211_assoc_response_frame *)
9987 + skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
9989 + assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
9990 + memcpy(assoc->header.addr1, dest,ETH_ALEN);
9991 + memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
9992 + memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
9993 + assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
9994 + WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
9997 + if(ieee->short_slot)
9998 + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
10000 + if (ieee->host_encrypt)
10001 + crypt = ieee->crypt[ieee->tx_keyidx];
10002 + else crypt = NULL;
10004 + encrypt = ( crypt && crypt->ops);
10007 + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
10009 + assoc->status = 0;
10010 + assoc->aid = cpu_to_le16(ieee->assoc_id);
10011 + if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
10012 + else ieee->assoc_id++;
10014 + tag = (u8*) skb_put(skb, rate_len);
10016 + ieee80211_MFIE_Brate(ieee, &tag);
10017 + ieee80211_MFIE_Grate(ieee, &tag);
10022 +struct sk_buff* ieee80211_auth_resp(struct ieee80211_device *ieee,int status, u8 *dest)
10024 + struct sk_buff *skb;
10025 + struct ieee80211_authentication *auth;
10027 + skb = dev_alloc_skb(sizeof(struct ieee80211_authentication)+1);
10032 + skb->len = sizeof(struct ieee80211_authentication);
10034 + auth = (struct ieee80211_authentication *)skb->data;
10036 + auth->status = cpu_to_le16(status);
10037 + auth->transaction = cpu_to_le16(2);
10038 + auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
10040 +#ifdef _RTL8187_EXT_PATCH_
10041 + if(ieee->iw_mode == ieee->iw_ext_mode)
10042 + memcpy(auth->header.addr3, dest, ETH_ALEN);
10044 + memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
10046 + memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
10047 + memcpy(auth->header.addr1, dest, ETH_ALEN);
10048 + auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
10054 +struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr)
10056 + struct sk_buff *skb;
10057 + struct ieee80211_hdr_3addr* hdr;
10059 + skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr));
10064 + hdr = (struct ieee80211_hdr_3addr*)skb_put(skb,sizeof(struct ieee80211_hdr_3addr));
10066 + memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
10067 + memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
10068 + memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
10070 + hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
10071 + IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
10072 + (pwr ? IEEE80211_FCTL_PM:0));
10080 +void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest)
10082 + struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
10085 + softmac_mgmt_xmit(buf, ieee);
10086 + dev_kfree_skb_any(buf);//edit by thomas
10091 +void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8* dest)
10093 + struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
10096 + softmac_mgmt_xmit(buf, ieee);
10097 + dev_kfree_skb_any(buf);//edit by thomas
10102 +void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
10105 + struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
10108 + softmac_mgmt_xmit(buf, ieee);
10109 + dev_kfree_skb_any(buf);//edit by thomas
10114 +inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee)
10116 + struct sk_buff *skb;
10117 + //unsigned long flags;
10119 + struct ieee80211_assoc_request_frame *hdr;
10121 + //short info_addr = 0;
10123 + //u16 suite_count = 0;
10124 + //u8 suit_select = 0;
10125 + unsigned int wpa_len = beacon->wpa_ie_len;
10126 + //struct net_device *dev = ieee->dev;
10127 + //union iwreq_data wrqu;
10131 + // for testing purpose
10132 + unsigned int rsn_len = beacon->rsn_ie_len;
10134 + unsigned int rsn_len = beacon->rsn_ie_len - 4;
10136 + unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
10137 + unsigned int wmm_info_len = beacon->QoS_Enable?9:0;
10138 +#ifdef THOMAS_TURBO
10139 + unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
10142 + u8 encry_proto = ieee->wpax_type_notify & 0xff;
10143 + //u8 pairwise_type = (ieee->wpax_type_notify >> 8) & 0xff;
10144 + //u8 authen_type = (ieee->wpax_type_notify >> 16) & 0xff;
10148 + //[0] Notify type of encryption: WPA/WPA2
10149 + //[1] pair wise type
10150 + //[2] authen type
10151 + if(ieee->wpax_type_set) {
10152 + if (IEEE_PROTO_WPA == encry_proto) {
10154 + } else if (IEEE_PROTO_RSN == encry_proto) {
10158 +#ifdef THOMAS_TURBO
10159 + len = sizeof(struct ieee80211_assoc_request_frame)+
10160 + + beacon->ssid_len//essid tagged val
10161 + + rate_len//rates tagged val
10165 + + turbo_info_len;
10167 + len = sizeof(struct ieee80211_assoc_request_frame)+
10168 + + beacon->ssid_len//essid tagged val
10169 + + rate_len//rates tagged val
10175 +#ifdef _RTL8187_EXT_PATCH_
10176 + if(ieee->iw_mode == ieee->iw_ext_mode)
10177 + skb = dev_alloc_skb(len+256); // stanley
10180 + skb = dev_alloc_skb(len);
10185 + hdr = (struct ieee80211_assoc_request_frame *)
10186 + skb_put(skb, sizeof(struct ieee80211_assoc_request_frame));
10189 + hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ;
10190 + hdr->header.duration_id= 37; //FIXME
10191 + memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
10192 + memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
10193 + memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
10194 + memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John
10196 + hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
10197 + if (beacon->capability & WLAN_CAPABILITY_PRIVACY )
10198 + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
10199 + if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
10200 + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
10202 + if(ieee->short_slot)
10203 + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
10205 +#ifdef _RTL8187_EXT_PATCH_
10206 + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_association_req_1)
10207 + ieee->ext_patch_ieee80211_association_req_1(hdr);
10210 + hdr->listen_interval = 0xa; //FIXME
10212 + hdr->info_element.id = MFIE_TYPE_SSID;
10214 + hdr->info_element.len = beacon->ssid_len;
10215 + tag = skb_put(skb, beacon->ssid_len);
10216 + memcpy(tag, beacon->ssid, beacon->ssid_len);
10218 + tag = skb_put(skb, rate_len);
10220 + ieee80211_MFIE_Brate(ieee, &tag);
10221 + ieee80211_MFIE_Grate(ieee, &tag);
10223 + //add rsn==0 condition for ap's mix security mode(wpa+wpa2), john2007.8.9
10224 + //choose AES encryption as default algorithm while using mixed mode
10226 + if(rsn_len == 0){
10228 + tag = skb_put(skb,wpa_len);
10233 + //{add by david. 2006.8.31
10234 + //fix linksys compatibility bug
10236 + if(wpa_len > 24) {//22+2, mean include the capability
10237 + beacon->wpa_ie[wpa_len - 2] = 0;
10239 + //multicast cipher OUI
10240 + if( beacon->wpa_ie[11]==0x2 ){ //0x0050f202 is the oui of tkip
10241 + ieee->broadcast_key_type = KEY_TYPE_TKIP;
10243 + else if( beacon->wpa_ie[11]==0x4 ){//0x0050f204 is the oui of ccmp
10244 + ieee->broadcast_key_type = KEY_TYPE_CCMP;
10246 + //unicast cipher OUI
10247 + if( beacon->wpa_ie[14]==0
10248 + && beacon->wpa_ie[15]==0x50
10249 + && beacon->wpa_ie[16]==0xf2
10250 + && beacon->wpa_ie[17]==0x2 ){ //0x0050f202 is the oui of tkip
10251 + ieee->pairwise_key_type = KEY_TYPE_TKIP;
10254 + else if( beacon->wpa_ie[14]==0
10255 + && beacon->wpa_ie[15]==0x50
10256 + && beacon->wpa_ie[16]==0xf2
10257 + && beacon->wpa_ie[17]==0x4 ){//0x0050f204 is the oui of ccmp
10258 + ieee->pairwise_key_type = KEY_TYPE_CCMP;
10260 + //indicate the wpa_ie content to WPA_SUPPLICANT
10261 + buff = kmalloc(IW_CUSTOM_MAX, GFP_ATOMIC);
10262 + memset(buff, 0, IW_CUSTOM_MAX);
10264 + p += sprintf(p, "ASSOCINFO(ReqIEs=");
10265 + for(i=0;i<wpa_len;i++){
10266 + p += sprintf(p, "%02x", beacon->wpa_ie[i]);
10268 + p += sprintf(p, ")");
10269 + memset(&wrqu, 0, sizeof(wrqu) );
10270 + wrqu.data.length = p - buff;
10272 + wireless_send_event(dev, IWEVCUSTOM, &wrqu, buff);
10273 + memcpy(tag,beacon->wpa_ie,wpa_len);
10278 + if(rsn_len > 22) {
10280 + if( beacon->rsn_ie[4]==0x0 &&
10281 + beacon->rsn_ie[5]==0xf &&
10282 + beacon->rsn_ie[6]==0xac){
10284 + switch(beacon->rsn_ie[7]){
10286 + ieee->broadcast_key_type = KEY_TYPE_WEP40;
10289 + ieee->broadcast_key_type = KEY_TYPE_TKIP;
10292 + ieee->broadcast_key_type = KEY_TYPE_CCMP;
10295 + ieee->broadcast_key_type = KEY_TYPE_WEP104;
10298 + printk("fault suite type in RSN broadcast key\n");
10303 + if( beacon->rsn_ie[10]==0x0 &&
10304 + beacon->rsn_ie[11]==0xf &&
10305 + beacon->rsn_ie[12]==0xac){
10306 + if(beacon->rsn_ie[8]==1){//not mixed mode
10307 + switch(beacon->rsn_ie[13]){
10309 + ieee->pairwise_key_type = KEY_TYPE_TKIP;
10312 + ieee->pairwise_key_type = KEY_TYPE_CCMP;
10315 + printk("fault suite type in RSN pairwise key\n");
10319 + else if(beacon->rsn_ie[8]==2){//mixed mode
10320 + ieee->pairwise_key_type = KEY_TYPE_CCMP;
10326 + tag = skb_put(skb,22);
10327 + memcpy(tag,(beacon->rsn_ie + info_addr),8);
10332 + spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
10333 + for (i = 0; i < 2; i++) {
10337 + suite_count = beacon->rsn_ie[info_addr] + \
10338 + (beacon->rsn_ie[info_addr + 1] << 8);
10340 + if(1 == suite_count) {
10341 + memcpy(tag,(beacon->rsn_ie + info_addr),4);
10344 + // if the wpax_type_notify has been set by the application,
10345 + // just use it, otherwise just use the default one.
10346 + if(ieee->wpax_type_set) {
10347 + suit_select = ((0 == i) ? pairwise_type:authen_type)&0x0f ;
10348 + memcpy(tag,rsn_authen_cipher_suite[suit_select],4);
10350 + //default set as ccmp, or none authentication
10352 + memcpy(tag,rsn_authen_cipher_suite[4],4);
10354 + memcpy(tag,rsn_authen_cipher_suite[2],4);
10359 + info_addr += (suite_count * 4);
10363 + spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
10366 + tag[1] = beacon->rsn_ie[info_addr+1];
10369 + tag = skb_put(skb,rsn_len);
10373 + if( beacon->rsn_ie[4]==0x0 &&
10374 + beacon->rsn_ie[5]==0xf &&
10375 + beacon->rsn_ie[6]==0xac){
10376 + switch(beacon->rsn_ie[7]){
10378 + ieee->broadcast_key_type = KEY_TYPE_WEP40;
10381 + ieee->broadcast_key_type = KEY_TYPE_TKIP;
10384 + ieee->broadcast_key_type = KEY_TYPE_CCMP;
10387 + ieee->broadcast_key_type = KEY_TYPE_WEP104;
10390 + printk("fault suite type in RSN broadcast key\n");
10394 + if( beacon->rsn_ie[10]==0x0 &&
10395 + beacon->rsn_ie[11]==0xf &&
10396 + beacon->rsn_ie[12]==0xac){
10397 + if(beacon->rsn_ie[8]==1){//not mixed mode
10398 + switch(beacon->rsn_ie[13]){
10400 + ieee->pairwise_key_type = KEY_TYPE_TKIP;
10403 + ieee->pairwise_key_type = KEY_TYPE_CCMP;
10406 + printk("fault suite type in RSN pairwise key\n");
10411 + else if(beacon->rsn_ie[8]==2){//mixed mode
10412 + ieee->pairwise_key_type = KEY_TYPE_CCMP;
10417 + beacon->rsn_ie[rsn_len - 2] = 0;
10418 + memcpy(tag,beacon->rsn_ie,rsn_len);
10422 + tag = skb_put(skb,ieee->wpa_ie_len);
10423 + memcpy(tag,ieee->wpa_ie,ieee->wpa_ie_len);
10425 + tag = skb_put(skb,wmm_info_len);
10426 + if(wmm_info_len) {
10427 + ieee80211_WMM_Info(ieee, &tag);
10429 +#ifdef THOMAS_TURBO
10430 + tag = skb_put(skb,turbo_info_len);
10431 + if(turbo_info_len) {
10432 + ieee80211_TURBO_Info(ieee, &tag);
10436 +#ifdef _RTL8187_EXT_PATCH_
10437 + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_association_req_2)
10438 + ieee->ext_patch_ieee80211_association_req_2(ieee, beacon, skb);
10444 +void ieee80211_associate_abort(struct ieee80211_device *ieee)
10447 + unsigned long flags;
10448 + spin_lock_irqsave(&ieee->lock, flags);
10450 + ieee->associate_seq++;
10452 + /* don't scan, and avoid to have the RX path possibily
10453 + * try again to associate. Even do not react to AUTH or
10454 + * ASSOC response. Just wait for the retry wq to be scheduled.
10455 + * Here we will check if there are good nets to associate
10456 + * with, so we retry or just get back to NO_LINK and scanning
10458 + if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){
10459 + IEEE80211_DEBUG_MGMT("Authentication failed\n");
10460 + ieee->softmac_stats.no_auth_rs++;
10462 + IEEE80211_DEBUG_MGMT("Association failed\n");
10463 + ieee->softmac_stats.no_ass_rs++;
10466 + ieee->state = IEEE80211_ASSOCIATING_RETRY;
10468 + queue_delayed_work(ieee->wq, &ieee->associate_retry_wq,IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
10470 + spin_unlock_irqrestore(&ieee->lock, flags);
10473 +void ieee80211_associate_abort_cb(unsigned long dev)
10475 + ieee80211_associate_abort((struct ieee80211_device *) dev);
10479 +void ieee80211_associate_step1(struct ieee80211_device *ieee)
10481 + struct ieee80211_network *beacon = &ieee->current_network;
10482 + struct sk_buff *skb;
10484 + IEEE80211_DEBUG_MGMT("Stopping scan\n");
10485 + ieee->softmac_stats.tx_auth_rq++;
10486 + skb=ieee80211_authentication_req(beacon, ieee, 0);
10487 +#ifdef _RTL8187_EXT_PATCH_
10488 + if(ieee->iw_mode == ieee->iw_ext_mode ) {
10490 + softmac_mgmt_xmit(skb, ieee);
10496 + ieee80211_associate_abort(ieee);
10499 + ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ;
10500 + IEEE80211_DEBUG_MGMT("Sending authentication request\n");
10501 + //printk("---Sending authentication request\n");
10502 + softmac_mgmt_xmit(skb, ieee);
10503 + //BUGON when you try to add_timer twice, using mod_timer may be better, john0709
10504 + if(!timer_pending(&ieee->associate_timer)){
10505 + ieee->associate_timer.expires = jiffies + (HZ / 2);
10506 + add_timer(&ieee->associate_timer);
10508 + //If call dev_kfree_skb_any,a warning will ocur....
10509 + //KERNEL: assertion (!atomic_read(&skb->users)) failed at net/core/dev.c (1708)
10510 + //So ... 1204 by lawrence.
10511 + //printk("\nIn %s,line %d call kfree skb.",__FUNCTION__,__LINE__);
10512 + //dev_kfree_skb_any(skb);//edit by thomas
10516 +void ieee80211_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen)
10519 + struct sk_buff *skb;
10520 + struct ieee80211_network *beacon = &ieee->current_network;
10521 +// int hlen = sizeof(struct ieee80211_authentication);
10522 + del_timer_sync(&ieee->associate_timer);
10523 + ieee->associate_seq++;
10524 + ieee->softmac_stats.tx_auth_rq++;
10526 + skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
10528 + ieee80211_associate_abort(ieee);
10530 + c = skb_put(skb, chlen+2);
10531 + *(c++) = MFIE_TYPE_CHALLENGE;
10533 + memcpy(c, challenge, chlen);
10535 + IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
10537 + ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr ));
10539 + softmac_mgmt_xmit(skb, ieee);
10540 + if (!timer_pending(&ieee->associate_timer)){
10541 + //printk("=========>add timer again, to crash\n");
10542 + ieee->associate_timer.expires = jiffies + (HZ / 2);
10543 + add_timer(&ieee->associate_timer);
10545 + dev_kfree_skb_any(skb);//edit by thomas
10547 + kfree(challenge);
10550 +#ifdef _RTL8187_EXT_PATCH_
10552 +// based on ieee80211_assoc_resp
10553 +struct sk_buff* ieee80211_assoc_resp_by_net(struct ieee80211_device *ieee, u8 *dest, unsigned short status, struct ieee80211_network *pstat, int pkt_type)
10555 + struct sk_buff *skb;
10558 + struct ieee80211_crypt_data* crypt;
10559 + struct ieee80211_assoc_response_frame *assoc;
10562 + unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
10563 + int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len;
10565 + if(ieee->iw_mode == ieee->iw_ext_mode)
10566 + skb = dev_alloc_skb(len+256); // stanley
10568 + skb = dev_alloc_skb(len);
10573 + assoc = (struct ieee80211_assoc_response_frame *)
10574 + skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
10576 + assoc->header.frame_ctl = cpu_to_le16(pkt_type);
10578 + memcpy(assoc->header.addr1, dest,ETH_ALEN);
10579 + memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
10580 + memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
10581 + assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
10582 + WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
10584 + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_assoc_resp_by_net_1)
10585 + ieee->ext_patch_ieee80211_assoc_resp_by_net_1(assoc);
10587 + if(ieee->short_slot)
10588 + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
10590 + if (ieee->host_encrypt)
10591 + crypt = ieee->crypt[ieee->tx_keyidx];
10592 + else crypt = NULL;
10594 + encrypt = ( crypt && crypt->ops);
10597 + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
10599 + assoc->status = 0;
10600 + assoc->aid = cpu_to_le16(ieee->assoc_id);
10601 + if (ieee->assoc_id == 0x2007) ieee->assoc_id=0;
10602 + else ieee->assoc_id++;
10604 + assoc->info_element.id = 230; // Stanley, an unused id (just a hot fix)
10605 + assoc->info_element.len = 0;
10607 + tag = (u8*) skb_put(skb, rate_len);
10609 + ieee80211_MFIE_Brate(ieee, &tag);
10610 + ieee80211_MFIE_Grate(ieee, &tag);
10612 + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_assoc_resp_by_net_2)
10613 + ieee->ext_patch_ieee80211_assoc_resp_by_net_2(ieee, pstat, pkt_type, skb);
10618 +// based on ieee80211_resp_to_assoc_rq
10619 +void ieee80211_ext_issue_assoc_rsp(struct ieee80211_device *ieee, u8 *dest, unsigned short status, struct ieee80211_network *pstat, int pkt_type)
10621 + struct sk_buff *buf = ieee80211_assoc_resp_by_net(ieee, dest, status, pstat, pkt_type);
10624 + softmac_mgmt_xmit(buf, ieee);
10627 +// based on ieee80211_associate_step2
10628 +void ieee80211_ext_issue_assoc_req(struct ieee80211_device *ieee, struct ieee80211_network *pstat)
10631 + struct sk_buff* skb;
10633 + // printk("@@@@@ ieee80211_ext_issue_assoc_req on channel: %d\n", ieee->current_network.channel);
10635 + ieee->softmac_stats.tx_ass_rq++;
10636 + skb=ieee80211_association_req(pstat, ieee);
10638 + softmac_mgmt_xmit(skb, ieee);
10641 +void ieee80211_ext_issue_disassoc(struct ieee80211_device *ieee, struct ieee80211_network *pstat, int reason, unsigned char extReason)
10644 + // printk("@@@@@ ieee80211_ext_issue_disassoc\n");
10647 +#endif // _RTL8187_EXT_PATCH_
10649 +void ieee80211_associate_step2(struct ieee80211_device *ieee)
10651 + struct sk_buff* skb;
10652 + struct ieee80211_network *beacon = &ieee->current_network;
10654 + del_timer_sync(&ieee->associate_timer);
10656 + IEEE80211_DEBUG_MGMT("Sending association request\n");
10657 + ieee->softmac_stats.tx_ass_rq++;
10658 + skb=ieee80211_association_req(beacon, ieee);
10660 + ieee80211_associate_abort(ieee);
10662 + softmac_mgmt_xmit(skb, ieee);
10663 + if (!timer_pending(&ieee->associate_timer)){
10664 + ieee->associate_timer.expires = jiffies + (HZ / 2);
10665 + add_timer(&ieee->associate_timer);
10667 + //dev_kfree_skb_any(skb);//edit by thomas
10671 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
10672 +void ieee80211_associate_complete_wq(struct work_struct *work)
10674 + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
10676 +void ieee80211_associate_complete_wq(struct ieee80211_device *ieee)
10679 + printk(KERN_INFO "Associated successfully\n");
10680 + if(ieee80211_is_54g(ieee->current_network) &&
10681 + (ieee->modulation & IEEE80211_OFDM_MODULATION)){
10683 + ieee->rate = 540;
10684 + printk(KERN_INFO"Using G rates\n");
10686 + ieee->rate = 110;
10687 + printk(KERN_INFO"Using B rates\n");
10689 + ieee->link_change(ieee->dev);
10690 + notify_wx_assoc_event(ieee);
10691 + if (ieee->data_hard_resume)
10692 + ieee->data_hard_resume(ieee->dev);
10693 + netif_carrier_on(ieee->dev);
10696 +void ieee80211_associate_complete(struct ieee80211_device *ieee)
10699 + del_timer_sync(&ieee->associate_timer);
10701 + for(i = 0; i < 6; i++) {
10702 + //ieee->seq_ctrl[i] = 0;
10704 + ieee->state = IEEE80211_LINKED;
10705 + IEEE80211_DEBUG_MGMT("Successfully associated\n");
10707 + queue_work(ieee->wq, &ieee->associate_complete_wq);
10710 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
10711 +void ieee80211_associate_procedure_wq(struct work_struct *work)
10713 + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
10715 +void ieee80211_associate_procedure_wq(struct ieee80211_device *ieee)
10718 + ieee->sync_scan_hurryup = 1;
10719 + down(&ieee->wx_sem);
10721 + if (ieee->data_hard_stop)
10722 + ieee->data_hard_stop(ieee->dev);
10724 + ieee80211_stop_scan(ieee);
10725 + ieee->set_chan(ieee->dev, ieee->current_network.channel);
10727 + ieee->associate_seq = 1;
10728 + ieee80211_associate_step1(ieee);
10730 + up(&ieee->wx_sem);
10732 +#ifdef _RTL8187_EXT_PATCH_
10733 +// based on ieee80211_associate_procedure_wq
10735 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
10736 +void ieee80211_ext_stop_scan_wq(struct work_struct *work)
10738 + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ext_stop_scan_wq);
10740 +void ieee80211_ext_stop_scan_wq(struct ieee80211_device *ieee)
10743 + if (ieee->scanning == 0)
10745 + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel
10746 + && ( ieee->current_network.channel == ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee) ) )
10750 + ieee->sync_scan_hurryup = 1;
10752 + down(&ieee->wx_sem);
10754 + // printk("@@@@@@@@@@ ieee80211_ext_stop_scan_wq\n");
10755 + if (ieee->data_hard_stop)
10756 + ieee->data_hard_stop(ieee->dev);
10758 + ieee80211_stop_scan(ieee);
10761 + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel)
10762 + ieee->set_chan(ieee->dev, ieee->ext_patch_ieee80211_ext_stop_scan_wq_set_channel(ieee));
10764 + ieee->set_chan(ieee->dev, ieee->current_network.channel);
10766 + up(&ieee->wx_sem);
10770 +void ieee80211_ext_send_11s_beacon(struct ieee80211_device *ieee)
10772 + #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
10773 + queue_work(ieee->wq, &ieee->ext_send_beacon_wq);
10775 + schedule_task(&ieee->ext_send_beacon_wq);
10780 +#endif // _RTL8187_EXT_PATCH_
10782 +inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net)
10784 + u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
10785 + int tmp_ssid_len = 0;
10787 + short apset,ssidset,ssidbroad,apmatch,ssidmatch;
10789 + /* we are interested in new new only if we are not associated
10790 + * and we are not associating / authenticating
10792 + if (ieee->state != IEEE80211_NOLINK)
10795 + if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
10798 + if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
10802 + if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC){
10803 + /* if the user specified the AP MAC, we need also the essid
10804 + * This could be obtained by beacons or, if the network does not
10805 + * broadcast it, it can be put manually.
10807 + apset = ieee->wap_set;//(memcmp(ieee->current_network.bssid, zero,ETH_ALEN)!=0 );
10808 + ssidset = ieee->ssid_set;//ieee->current_network.ssid[0] != '\0';
10809 + ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0');
10810 + apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0);
10812 + if(ieee->current_network.ssid_len != net->ssid_len)
10815 + ssidmatch = (0==strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
10817 + //printk("cur: %s, %d, net:%s, %d\n", ieee->current_network.ssid, ieee->current_network.ssid_len, net->ssid, net->ssid_len);
10818 + //printk("apset=%d apmatch=%d ssidset=%d ssidbroad=%d ssidmatch=%d\n",apset,apmatch,ssidset,ssidbroad,ssidmatch);
10820 + if ( /* if the user set the AP check if match.
10821 + * if the network does not broadcast essid we check the user supplyed ANY essid
10822 + * if the network does broadcast and the user does not set essid it is OK
10823 + * if the network does broadcast and the user did set essid chech if essid match
10825 + ( apset && apmatch &&
10826 + ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) ||
10827 + /* if the ap is not set, check that the user set the bssid
10828 + * and the network does bradcast and that those two bssid matches
10830 + (!apset && ssidset && ssidbroad && ssidmatch)
10834 + /* if the essid is hidden replace it with the
10835 + * essid provided by the user.
10838 + strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
10839 + tmp_ssid_len = ieee->current_network.ssid_len;
10841 + memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
10844 + strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
10845 + ieee->current_network.ssid_len = tmp_ssid_len;
10847 + printk(KERN_INFO"Linking with %s: channel is %d\n",ieee->current_network.ssid,ieee->current_network.channel);
10849 + if (ieee->iw_mode == IW_MODE_INFRA){
10850 + ieee->state = IEEE80211_ASSOCIATING;
10851 + ieee->beinretry = false;
10852 + queue_work(ieee->wq, &ieee->associate_procedure_wq);
10854 + if(ieee80211_is_54g(ieee->current_network) &&
10855 + (ieee->modulation & IEEE80211_OFDM_MODULATION)){
10856 + ieee->rate = 540;
10857 + printk(KERN_INFO"Using G rates\n");
10859 + ieee->rate = 110;
10860 + printk(KERN_INFO"Using B rates\n");
10862 + ieee->state = IEEE80211_LINKED;
10863 + ieee->beinretry = false;
10871 +void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
10873 + unsigned long flags;
10874 + struct ieee80211_network *target;
10876 + spin_lock_irqsave(&ieee->lock, flags);
10877 + list_for_each_entry(target, &ieee->network_list, list) {
10879 + /* if the state become different that NOLINK means
10880 + * we had found what we are searching for
10883 + if (ieee->state != IEEE80211_NOLINK)
10886 + if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
10887 + ieee80211_softmac_new_net(ieee, target);
10890 + spin_unlock_irqrestore(&ieee->lock, flags);
10895 +static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen)
10897 + struct ieee80211_authentication *a;
10899 + if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
10900 + IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len);
10903 + *challenge = NULL;
10904 + a = (struct ieee80211_authentication*) skb->data;
10905 + if(skb->len > (sizeof(struct ieee80211_authentication) +3)){
10906 + t = skb->data + sizeof(struct ieee80211_authentication);
10908 + if(*(t++) == MFIE_TYPE_CHALLENGE){
10910 + *challenge = (u8*)kmalloc(*chlen, GFP_ATOMIC);
10911 + memcpy(*challenge, t, *chlen);
10915 + return cpu_to_le16(a->status);
10920 +int auth_rq_parse(struct sk_buff *skb,u8* dest)
10922 + struct ieee80211_authentication *a;
10924 + if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){
10925 + IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len);
10928 + a = (struct ieee80211_authentication*) skb->data;
10930 + memcpy(dest,a->header.addr2, ETH_ALEN);
10932 + if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
10933 + return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
10935 + return WLAN_STATUS_SUCCESS;
10938 +static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src)
10945 + struct ieee80211_hdr_3addr *header =
10946 + (struct ieee80211_hdr_3addr *) skb->data;
10948 + if (skb->len < sizeof (struct ieee80211_hdr_3addr ))
10949 + return -1; /* corrupted */
10951 + memcpy(src,header->addr2, ETH_ALEN);
10953 + skbend = (u8*)skb->data + skb->len;
10955 + tag = skb->data + sizeof (struct ieee80211_hdr_3addr );
10957 + while (tag+1 < skbend){
10960 + ssidlen = *(tag+1);
10963 + tag++; /* point to the len field */
10964 + tag = tag + *(tag); /* point to the last data byte of the tag */
10965 + tag++; /* point to the next tag */
10968 + //IEEE80211DMESG("Card MAC address is "MACSTR, MAC2STR(src));
10969 + if (ssidlen == 0) return 1;
10971 + if (!ssid) return 1; /* ssid not found in tagged param */
10972 + return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
10976 +int assoc_rq_parse(struct sk_buff *skb,u8* dest)
10978 + struct ieee80211_assoc_request_frame *a;
10980 + if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
10981 + sizeof(struct ieee80211_info_element))) {
10983 + IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len);
10987 + a = (struct ieee80211_assoc_request_frame*) skb->data;
10989 + memcpy(dest,a->header.addr2,ETH_ALEN);
10994 +static inline u16 assoc_parse(struct sk_buff *skb, int *aid)
10996 + struct ieee80211_assoc_response_frame *a;
10997 + if (skb->len < sizeof(struct ieee80211_assoc_response_frame)){
10998 + IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
11002 + a = (struct ieee80211_assoc_response_frame*) skb->data;
11003 + *aid = le16_to_cpu(a->aid) & 0x3fff;
11004 + return le16_to_cpu(a->status);
11007 +static inline void
11008 +ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
11010 + u8 dest[ETH_ALEN];
11012 + //IEEE80211DMESG("Rx probe");
11013 + ieee->softmac_stats.rx_probe_rq++;
11014 + //DMESG("Dest is "MACSTR, MAC2STR(dest));
11015 + if (probe_rq_parse(ieee, skb, dest)){
11016 + //IEEE80211DMESG("Was for me!");
11017 + ieee->softmac_stats.tx_probe_rs++;
11018 + ieee80211_resp_to_probe(ieee, dest);
11023 +ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
11025 + u8 dest[ETH_ALEN];
11027 + //IEEE80211DMESG("Rx probe");
11028 + ieee->softmac_stats.rx_auth_rq++;
11030 + if ((status = auth_rq_parse(skb, dest))!= -1){
11031 + ieee80211_resp_to_auth(ieee, status, dest);
11033 + //DMESG("Dest is "MACSTR, MAC2STR(dest));
11038 +ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
11041 + u8 dest[ETH_ALEN];
11042 + //unsigned long flags;
11044 + ieee->softmac_stats.rx_ass_rq++;
11045 + if (assoc_rq_parse(skb,dest) != -1){
11046 + ieee80211_resp_to_assoc_rq(ieee, dest);
11049 + printk(KERN_INFO"New client associated: "MAC_FMT"\n", MAC_ARG(dest));
11052 + spin_lock_irqsave(&ieee->lock,flags);
11053 + add_associate(ieee,dest);
11054 + spin_unlock_irqrestore(&ieee->lock,flags);
11060 +void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
11063 + struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
11066 + softmac_ps_mgmt_xmit(buf, ieee);
11071 +short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l)
11074 + int timeout = ieee->ps_timeout;
11079 + /*if(ieee->ps == IEEE80211_PS_DISABLED ||
11080 + ieee->iw_mode != IW_MODE_INFRA ||
11081 + ieee->state != IEEE80211_LINKED)
11085 + dtim = ieee->current_network.dtim_data;
11086 + //printk("DTIM\n");
11088 + if(!(dtim & IEEE80211_DTIM_VALID))
11091 + timeout = ieee->current_network.beacon_interval;
11093 + //printk("VALID\n");
11094 + ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
11096 + if(dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST)& ieee->ps))
11099 + if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
11102 + if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
11105 + if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) &&
11106 + (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
11110 + *time_l = ieee->current_network.last_dtim_sta_time[0]
11111 + + (ieee->current_network.beacon_interval
11112 + * ieee->current_network.dtim_period) * 1000;
11116 + *time_l = ieee->current_network.last_dtim_sta_time[0]
11117 + + MSECS((ieee->current_network.beacon_interval));
11118 + //* ieee->current_network.dtim_period));
11119 + //printk("beacon_interval:%x, dtim_period:%x, totol to Msecs:%x, HZ:%x\n", ieee->current_network.beacon_interval, ieee->current_network.dtim_period, MSECS(((ieee->current_network.beacon_interval * ieee->current_network.dtim_period))), HZ);
11124 + *time_h = ieee->current_network.last_dtim_sta_time[1];
11125 + if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
11134 +inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
11140 + unsigned long flags,flags2;
11142 + spin_lock_irqsave(&ieee->lock, flags);
11144 + if((ieee->ps == IEEE80211_PS_DISABLED ||
11146 + ieee->iw_mode != IW_MODE_INFRA ||
11147 + ieee->state != IEEE80211_LINKED)){
11149 + //#warning CHECK_LOCK_HERE
11150 + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
11152 + ieee80211_sta_wakeup(ieee, 1);
11154 + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
11157 + sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl);
11158 +// printk("===>%s,%d[2 wake, 1 sleep, 0 do nothing], ieee->sta_sleep = %d\n",__FUNCTION__, sleep,ieee->sta_sleep);
11159 + /* 2 wake, 1 sleep, 0 do nothing */
11165 + if(ieee->sta_sleep == 1)
11166 + ieee->enter_sleep_state(ieee->dev,th,tl);
11168 + else if(ieee->sta_sleep == 0){
11169 + // printk("send null 1\n");
11170 + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
11172 + if(ieee->ps_is_queue_empty(ieee->dev)){
11175 + ieee->sta_sleep = 2;
11177 + ieee->ps_request_tx_ack(ieee->dev);
11179 + ieee80211_sta_ps_send_null_frame(ieee,1);
11181 + ieee->ps_th = th;
11182 + ieee->ps_tl = tl;
11184 + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
11189 + }else if(sleep == 2){
11190 +//#warning CHECK_LOCK_HERE
11191 + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
11193 + // printk("send wakeup packet\n");
11194 + ieee80211_sta_wakeup(ieee,1);
11196 + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
11200 + spin_unlock_irqrestore(&ieee->lock, flags);
11204 +void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
11206 + if(ieee->sta_sleep == 0){
11208 + // printk("Warning: driver is probably failing to report TX ps error\n");
11209 + ieee->ps_request_tx_ack(ieee->dev);
11210 + ieee80211_sta_ps_send_null_frame(ieee, 0);
11216 + if(ieee->sta_sleep == 1)
11217 + ieee->sta_wake_up(ieee->dev);
11219 + ieee->sta_sleep = 0;
11222 + ieee->ps_request_tx_ack(ieee->dev);
11223 + ieee80211_sta_ps_send_null_frame(ieee, 0);
11227 +void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
11229 + unsigned long flags,flags2;
11231 + spin_lock_irqsave(&ieee->lock, flags);
11232 + if(ieee->sta_sleep == 2){
11233 + /* Null frame with PS bit set */
11236 + // printk("==================> %s::enter sleep state\n",__FUNCTION__);
11237 + ieee->sta_sleep = 1;
11238 + ieee->enter_sleep_state(ieee->dev,ieee->ps_th,ieee->ps_tl);
11240 + /* if the card report not success we can't be sure the AP
11241 + * has not RXed so we can't assume the AP believe us awake
11244 + /* 21112005 - tx again null without PS bit if lost */
11247 + if((ieee->sta_sleep == 0) && !success){
11248 + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
11249 + ieee80211_sta_ps_send_null_frame(ieee, 0);
11250 + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
11253 + spin_unlock_irqrestore(&ieee->lock, flags);
11257 +ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
11258 + struct ieee80211_rx_stats *rx_stats, u16 type,
11261 + struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data;
11263 + u8* challenge=NULL;
11266 + struct ieee80211_assoc_response_frame *assoc_resp;
11267 + struct ieee80211_info_element *info_element;
11269 + if(!ieee->proto_started)
11272 + if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
11273 + ieee->iw_mode == IW_MODE_INFRA &&
11274 + ieee->state == IEEE80211_LINKED))
11276 + tasklet_schedule(&ieee->ps_task);
11278 + if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP &&
11279 + WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON)
11280 + ieee->last_rx_ps_time = jiffies;
11282 + switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
11284 + case IEEE80211_STYPE_ASSOC_RESP:
11285 + case IEEE80211_STYPE_REASSOC_RESP:
11287 + IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
11288 + WLAN_FC_GET_STYPE(header->frame_ctl));
11289 + if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
11290 + ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
11291 + ieee->iw_mode == IW_MODE_INFRA){
11292 + if (0 == (errcode=assoc_parse(skb, &aid))){
11295 + ieee->state=IEEE80211_LINKED;
11296 + ieee->assoc_id = aid;
11297 + ieee->softmac_stats.rx_ass_ok++;
11299 + //printk(KERN_WARNING "nic_type = %s", (rx_stats->nic_type == 1)?"rtl8187":"rtl8187B");
11300 + if(1 == rx_stats->nic_type) //card type is 8187
11302 + goto associate_complete;
11304 + assoc_resp = (struct ieee80211_assoc_response_frame*)skb->data;
11305 + info_element = &assoc_resp->info_element;
11306 + left = skb->len - ((void*)info_element - (void*)assoc_resp);
11308 + while (left >= sizeof(struct ieee80211_info_element_hdr)) {
11309 + if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
11310 + printk(KERN_WARNING "[re]associate reeponse error!");
11313 + switch (info_element->id) {
11314 + case MFIE_TYPE_GENERIC:
11315 + IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n", info_element->len);
11316 + if (info_element->len >= 8 &&
11317 + info_element->data[0] == 0x00 &&
11318 + info_element->data[1] == 0x50 &&
11319 + info_element->data[2] == 0xf2 &&
11320 + info_element->data[3] == 0x02 &&
11321 + info_element->data[4] == 0x01) {
11322 + // Not care about version at present.
11323 + //WMM Parameter Element
11324 + memcpy(ieee->current_network.wmm_param,(u8*)(info_element->data\
11325 + + 8),(info_element->len - 8));
11327 + if (((ieee->current_network.wmm_info^info_element->data[6])& \
11328 + 0x0f)||(!ieee->init_wmmparam_flag)) {
11329 + //refresh paramete element for current network
11330 + // update the register parameter for hardware
11331 + ieee->init_wmmparam_flag = 1;
11332 + queue_work(ieee->wq, &ieee->wmm_param_update_wq);
11335 + //update info_element for current network
11336 + ieee->current_network.wmm_info = info_element->data[6];
11340 + //nothing to do at present!!!
11344 + left -= sizeof(struct ieee80211_info_element_hdr) +
11345 + info_element->len;
11346 + info_element = (struct ieee80211_info_element *)
11347 + &info_element->data[info_element->len];
11349 + if(!ieee->init_wmmparam_flag) //legacy AP, reset the AC_xx_param register
11351 + queue_work(ieee->wq,&ieee->wmm_param_update_wq);
11352 + ieee->init_wmmparam_flag = 1;//indicate AC_xx_param upated since last associate
11354 +associate_complete:
11355 + ieee80211_associate_complete(ieee);
11357 + ieee->softmac_stats.rx_ass_err++;
11358 + IEEE80211_DEBUG_MGMT(
11359 + "Association response status code 0x%x\n",
11361 + ieee80211_associate_abort(ieee);
11364 +#ifdef _RTL8187_EXT_PATCH_
11365 + else if ((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp)
11367 + ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_rsp(ieee, skb);
11372 + case IEEE80211_STYPE_ASSOC_REQ:
11373 + case IEEE80211_STYPE_REASSOC_REQ:
11375 + if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
11376 + ieee->iw_mode == IW_MODE_MASTER)
11378 + ieee80211_rx_assoc_rq(ieee, skb);
11379 +#ifdef _RTL8187_EXT_PATCH_
11380 + else if ((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req)
11382 + ieee->ext_patch_ieee80211_rx_frame_softmac_on_assoc_req(ieee, skb);
11387 + case IEEE80211_STYPE_AUTH:
11389 +#ifdef _RTL8187_EXT_PATCH_
11390 +printk("IEEE80211_STYPE_AUTH\n");
11391 + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_auth)
11392 + if( ieee->ext_patch_ieee80211_rx_frame_softmac_on_auth(ieee, skb, rx_stats) );
11394 + if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){
11395 + if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING &&
11396 + ieee->iw_mode == IW_MODE_INFRA){
11398 + IEEE80211_DEBUG_MGMT("Received authentication response");
11400 + if (0 == (errcode=auth_parse(skb, &challenge, &chlen))){
11401 + if(ieee->open_wep || !challenge){
11402 + ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
11403 + ieee->softmac_stats.rx_auth_rs_ok++;
11405 + ieee80211_associate_step2(ieee);
11407 + ieee80211_auth_challenge(ieee, challenge, chlen);
11410 + ieee->softmac_stats.rx_auth_rs_err++;
11411 + IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode);
11412 + ieee80211_associate_abort(ieee);
11415 + }else if (ieee->iw_mode == IW_MODE_MASTER){
11416 + ieee80211_rx_auth_rq(ieee, skb);
11421 + case IEEE80211_STYPE_PROBE_REQ:
11423 + if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
11424 + ((ieee->iw_mode == IW_MODE_ADHOC ||
11425 + ieee->iw_mode == IW_MODE_MASTER) &&
11426 + ieee->state == IEEE80211_LINKED))
11428 + ieee80211_rx_probe_rq(ieee, skb);
11431 + case IEEE80211_STYPE_DISASSOC:
11432 + case IEEE80211_STYPE_DEAUTH:
11433 +#ifdef _RTL8187_EXT_PATCH_
11434 +printk("IEEE80211_STYPE_DEAUTH\n");
11435 + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_rx_frame_softmac_on_deauth)
11436 + if( ieee->ext_patch_ieee80211_rx_frame_softmac_on_deauth(ieee, skb, rx_stats) ) ;
11438 + /* FIXME for now repeat all the association procedure
11439 + * both for disassociation and deauthentication
11441 + if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
11442 + (ieee->state == IEEE80211_LINKED) &&
11443 + (ieee->iw_mode == IW_MODE_INFRA) &&
11444 + (!memcmp(header->addr2,ieee->current_network.bssid,ETH_ALEN))){
11445 + ieee->state = IEEE80211_ASSOCIATING;
11446 + ieee->softmac_stats.reassoc++;
11448 + //notify_wx_assoc_event(ieee); //YJ,del,080828, do not notify os here
11449 + queue_work(ieee->wq, &ieee->associate_procedure_wq);
11459 + //dev_kfree_skb_any(skb);
11465 +/* following are for a simplier TX queue management.
11466 + * Instead of using netif_[stop/wake]_queue the driver
11467 + * will uses these two function (plus a reset one), that
11468 + * will internally uses the kernel netif_* and takes
11469 + * care of the ieee802.11 fragmentation.
11470 + * So the driver receives a fragment per time and might
11471 + * call the stop function when it want without take care
11472 + * to have enought room to TX an entire packet.
11473 + * This might be useful if each fragment need it's own
11474 + * descriptor, thus just keep a total free memory > than
11475 + * the max fragmentation treshold is not enought.. If the
11476 + * ieee802.11 stack passed a TXB struct then you needed
11477 + * to keep N free descriptors where
11478 + * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
11479 + * In this way you need just one and the 802.11 stack
11480 + * will take care of buffering fragments and pass them to
11481 + * to the driver later, when it wakes the queue.
11484 +void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee)
11488 + unsigned long flags;
11490 +#ifdef _RTL8187_EXT_PATCH_
11491 + int rate = ieee->rate;
11494 + spin_lock_irqsave(&ieee->lock,flags);
11496 + if(ieee->queue_stop){
11497 + IEEE80211DMESG("EE: IEEE hard_start_xmit invoked when kernel queue should be stopped");
11498 + netif_stop_queue(ieee->dev);
11499 + ieee->ieee_stats.swtxstop++;
11500 + //dev_kfree_skb_any(skb);
11505 + ieee->stats.tx_bytes+=skb->len;
11508 + txb=ieee80211_skb_to_txb(ieee,skb);
11512 + IEEE80211DMESG("WW: IEEE stack failed to provide txb");
11513 + //dev_kfree_skb_any(skb);
11519 +#ifdef _RTL8187_EXT_PATCH_
11520 + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_ieee80211_softmac_xmit_get_rate && txb->nr_frags)
11522 + rate = ieee->ext_patch_ieee80211_softmac_xmit_get_rate(ieee, txb->fragments[0]);
11525 + /* called with 2nd parm 0, no tx mgmt lock required */
11526 + ieee80211_sta_wakeup(ieee,0);
11528 + for(i = 0; i < txb->nr_frags; i++) {
11530 + if (ieee->queue_stop){
11531 + ieee->tx_pending.txb = txb;
11532 + ieee->tx_pending.frag = i;
11535 + ieee->softmac_data_hard_start_xmit(
11536 + txb->fragments[i],
11537 +#ifdef _RTL8187_EXT_PATCH_
11538 + ieee->dev, rate);
11540 + ieee->dev,ieee->rate);
11542 + //(i+1)<txb->nr_frags);
11543 + ieee->stats.tx_packets++;
11544 + ieee->stats.tx_bytes += txb->fragments[i]->len;
11545 + ieee->dev->trans_start = jiffies;
11549 + ieee80211_txb_free(txb);
11552 + spin_unlock_irqrestore(&ieee->lock,flags);
11556 +/* called with ieee->lock acquired */
11557 +void ieee80211_resume_tx(struct ieee80211_device *ieee)
11560 + for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
11562 + if (ieee->queue_stop){
11563 + ieee->tx_pending.frag = i;
11567 + ieee->softmac_data_hard_start_xmit(
11568 + ieee->tx_pending.txb->fragments[i],
11569 + ieee->dev,ieee->rate);
11570 + //(i+1)<ieee->tx_pending.txb->nr_frags);
11571 + ieee->stats.tx_packets++;
11572 + ieee->dev->trans_start = jiffies;
11577 + ieee80211_txb_free(ieee->tx_pending.txb);
11578 + ieee->tx_pending.txb = NULL;
11582 +void ieee80211_reset_queue(struct ieee80211_device *ieee)
11584 + unsigned long flags;
11586 + spin_lock_irqsave(&ieee->lock,flags);
11587 + init_mgmt_queue(ieee);
11588 + if (ieee->tx_pending.txb){
11589 + ieee80211_txb_free(ieee->tx_pending.txb);
11590 + ieee->tx_pending.txb = NULL;
11592 + ieee->queue_stop = 0;
11593 + spin_unlock_irqrestore(&ieee->lock,flags);
11597 +void ieee80211_wake_queue(struct ieee80211_device *ieee)
11600 + unsigned long flags;
11601 + struct sk_buff *skb;
11602 + struct ieee80211_hdr_3addr *header;
11604 + spin_lock_irqsave(&ieee->lock,flags);
11605 + if (! ieee->queue_stop) goto exit;
11607 + ieee->queue_stop = 0;
11609 + if(ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE){
11610 + while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){
11612 + header = (struct ieee80211_hdr_3addr *) skb->data;
11614 + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
11616 + if (ieee->seq_ctrl[0] == 0xFFF)
11617 + ieee->seq_ctrl[0] = 0;
11619 + ieee->seq_ctrl[0]++;
11621 + //printk(KERN_ALERT "ieee80211_wake_queue \n");
11622 + ieee->softmac_data_hard_start_xmit(skb,ieee->dev,ieee->basic_rate);
11623 + dev_kfree_skb_any(skb);//edit by thomas
11626 + if (!ieee->queue_stop && ieee->tx_pending.txb)
11627 + ieee80211_resume_tx(ieee);
11629 + if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)){
11630 + ieee->softmac_stats.swtxawake++;
11631 + netif_wake_queue(ieee->dev);
11635 + spin_unlock_irqrestore(&ieee->lock,flags);
11639 +void ieee80211_stop_queue(struct ieee80211_device *ieee)
11641 + //unsigned long flags;
11642 + //spin_lock_irqsave(&ieee->lock,flags);
11644 + if (! netif_queue_stopped(ieee->dev)){
11645 + netif_stop_queue(ieee->dev);
11646 + ieee->softmac_stats.swtxstop++;
11648 + ieee->queue_stop = 1;
11649 + //spin_unlock_irqrestore(&ieee->lock,flags);
11654 +inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
11657 + get_random_bytes(ieee->current_network.bssid, ETH_ALEN);
11659 + /* an IBSS cell address must have the two less significant
11660 + * bits of the first byte = 2
11662 + ieee->current_network.bssid[0] &= ~0x01;
11663 + ieee->current_network.bssid[0] |= 0x02;
11666 +/* called in user context only */
11667 +void ieee80211_start_master_bss(struct ieee80211_device *ieee)
11669 + ieee->assoc_id = 1;
11671 + if (ieee->current_network.ssid_len == 0){
11672 + strncpy(ieee->current_network.ssid,
11673 + IEEE80211_DEFAULT_TX_ESSID,
11674 + IW_ESSID_MAX_SIZE);
11676 + ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
11677 + ieee->ssid_set = 1;
11680 + memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
11682 + ieee->set_chan(ieee->dev, ieee->current_network.channel);
11683 + ieee->state = IEEE80211_LINKED;
11684 + ieee->link_change(ieee->dev);
11685 + notify_wx_assoc_event(ieee);
11687 + if (ieee->data_hard_resume)
11688 + ieee->data_hard_resume(ieee->dev);
11690 + netif_carrier_on(ieee->dev);
11693 +void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
11695 + if(ieee->raw_tx){
11697 + if (ieee->data_hard_resume)
11698 + ieee->data_hard_resume(ieee->dev);
11700 + netif_carrier_on(ieee->dev);
11703 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
11704 +void ieee80211_start_ibss_wq(struct work_struct *work)
11706 + struct delayed_work *dwork = container_of(work, struct delayed_work, work);
11707 + struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
11709 +void ieee80211_start_ibss_wq(struct ieee80211_device *ieee)
11713 + /* iwconfig mode ad-hoc will schedule this and return
11714 + * on the other hand this will block further iwconfig SET
11715 + * operations because of the wx_sem hold.
11716 + * Anyway some most set operations set a flag to speed-up
11717 + * (abort) this wq (when syncro scanning) before sleeping
11718 + * on the semaphore
11721 + down(&ieee->wx_sem);
11724 + if (ieee->current_network.ssid_len == 0){
11725 + strcpy(ieee->current_network.ssid,IEEE80211_DEFAULT_TX_ESSID);
11726 + ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
11727 + ieee->ssid_set = 1;
11730 + /* check if we have this cell in our network list */
11731 + ieee80211_softmac_check_all_nets(ieee);
11733 +#ifdef ENABLE_DOT11D
11734 + if(ieee->state == IEEE80211_NOLINK)
11735 + ieee->current_network.channel = 10;
11737 + /* if not then the state is not linked. Maybe the user swithced to
11738 + * ad-hoc mode just after being in monitor mode, or just after
11739 + * being very few time in managed mode (so the card have had no
11740 + * time to scan all the chans..) or we have just run up the iface
11741 + * after setting ad-hoc mode. So we have to give another try..
11742 + * Here, in ibss mode, should be safe to do this without extra care
11743 + * (in bss mode we had to make sure no-one tryed to associate when
11744 + * we had just checked the ieee->state and we was going to start the
11745 + * scan) beacause in ibss mode the ieee80211_new_net function, when
11746 + * finds a good net, just set the ieee->state to IEEE80211_LINKED,
11747 + * so, at worst, we waste a bit of time to initiate an unneeded syncro
11748 + * scan, that will stop at the first round because it sees the state
11751 + if (ieee->state == IEEE80211_NOLINK)
11752 + ieee80211_start_scan_syncro(ieee);
11754 + /* the network definitively is not here.. create a new cell */
11755 + if (ieee->state == IEEE80211_NOLINK){
11756 + printk("creating new IBSS cell\n");
11757 + if(!ieee->wap_set)
11758 + ieee80211_randomize_cell(ieee);
11760 + if(ieee->modulation & IEEE80211_CCK_MODULATION){
11762 + ieee->current_network.rates_len = 4;
11764 + ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
11765 + ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
11766 + ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
11767 + ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
11770 + ieee->current_network.rates_len = 0;
11772 + if(ieee->modulation & IEEE80211_OFDM_MODULATION){
11773 + ieee->current_network.rates_ex_len = 8;
11775 + ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
11776 + ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
11777 + ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
11778 + ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
11779 + ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
11780 + ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
11781 + ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
11782 + ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
11784 + ieee->rate = 540;
11786 + ieee->current_network.rates_ex_len = 0;
11787 + ieee->rate = 110;
11790 + // By default, WMM function will be disabled in IBSS mode
11791 + ieee->current_network.QoS_Enable = 0;
11793 + ieee->current_network.atim_window = 0;
11794 + ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
11795 + if(ieee->short_slot)
11796 + ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
11800 + ieee->state = IEEE80211_LINKED;
11801 + ieee->set_chan(ieee->dev, ieee->current_network.channel);
11802 + ieee->link_change(ieee->dev);
11804 + notify_wx_assoc_event(ieee);
11806 + ieee80211_start_send_beacons(ieee);
11807 + printk(KERN_WARNING "after sending beacon packet!\n");
11809 + if (ieee->data_hard_resume)
11810 + ieee->data_hard_resume(ieee->dev);
11812 + netif_carrier_on(ieee->dev);
11814 + up(&ieee->wx_sem);
11816 +inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
11818 + queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 100);
11821 +/* this is called only in user context, with wx_sem held */
11822 +void ieee80211_start_bss(struct ieee80211_device *ieee)
11824 + unsigned long flags;
11825 +#ifdef ENABLE_DOT11D
11827 + // Ref: 802.11d 11.1.3.3
11828 + // STA shall not start a BSS unless properly formed Beacon frame including a Country IE.
11830 + if(IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee))
11832 + if(! ieee->bGlobalDomain)
11838 + /* check if we have already found the net we
11839 + * are interested in (if any).
11840 + * if not (we are disassociated and we are not
11841 + * in associating / authenticating phase) start the background scanning.
11843 + ieee80211_softmac_check_all_nets(ieee);
11845 + /* ensure no-one start an associating process (thus setting
11846 + * the ieee->state to ieee80211_ASSOCIATING) while we
11847 + * have just cheked it and we are going to enable scan.
11848 + * The ieee80211_new_net function is always called with
11849 + * lock held (from both ieee80211_softmac_check_all_nets and
11850 + * the rx path), so we cannot be in the middle of such function
11852 + spin_lock_irqsave(&ieee->lock, flags);
11854 +//#ifdef ENABLE_IPS
11855 +// printk("start bss ENABLE_IPS\n");
11857 + if (ieee->state == IEEE80211_NOLINK){
11858 + ieee->actscanning = true;
11859 + ieee80211_start_scan(ieee);
11862 + spin_unlock_irqrestore(&ieee->lock, flags);
11865 +/* called only in userspace context */
11866 +void ieee80211_disassociate(struct ieee80211_device *ieee)
11868 + netif_carrier_off(ieee->dev);
11870 + if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
11871 + ieee80211_reset_queue(ieee);
11873 + if (ieee->data_hard_stop)
11874 + ieee->data_hard_stop(ieee->dev);
11876 +#ifdef ENABLE_DOT11D
11877 + if(IS_DOT11D_ENABLE(ieee))
11878 + Dot11d_Reset(ieee);
11880 + ieee->state = IEEE80211_NOLINK;
11881 + ieee->link_change(ieee->dev);
11882 + notify_wx_assoc_event(ieee);
11885 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
11886 +void ieee80211_associate_retry_wq(struct work_struct *work)
11888 + struct delayed_work *dwork = container_of(work, struct delayed_work, work);
11889 + struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
11891 +void ieee80211_associate_retry_wq(struct ieee80211_device *ieee)
11894 + unsigned long flags;
11895 + down(&ieee->wx_sem);
11896 + if(!ieee->proto_started)
11898 + if(ieee->state != IEEE80211_ASSOCIATING_RETRY)
11900 + /* until we do not set the state to IEEE80211_NOLINK
11901 + * there are no possibility to have someone else trying
11902 + * to start an association procdure (we get here with
11903 + * ieee->state = IEEE80211_ASSOCIATING).
11904 + * When we set the state to IEEE80211_NOLINK it is possible
11905 + * that the RX path run an attempt to associate, but
11906 + * both ieee80211_softmac_check_all_nets and the
11907 + * RX path works with ieee->lock held so there are no
11908 + * problems. If we are still disassociated then start a scan.
11909 + * the lock here is necessary to ensure no one try to start
11910 + * an association procedure when we have just checked the
11911 + * state and we are going to start the scan.
11913 + ieee->state = IEEE80211_NOLINK;
11914 + ieee->beinretry = true;
11915 + ieee80211_softmac_check_all_nets(ieee);
11917 + spin_lock_irqsave(&ieee->lock, flags);
11919 + if(ieee->state == IEEE80211_NOLINK){
11920 + ieee->beinretry = false;
11921 + ieee->actscanning = true;
11922 + ieee80211_start_scan(ieee);
11924 + //YJ,add,080828, notify os here
11925 + if(ieee->state == IEEE80211_NOLINK)
11927 + notify_wx_assoc_event(ieee);
11929 + //YJ,add,080828,end
11930 + spin_unlock_irqrestore(&ieee->lock, flags);
11933 + up(&ieee->wx_sem);
11936 +struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
11938 + u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff};
11940 + struct sk_buff *skb = NULL;
11941 + struct ieee80211_probe_response *b;
11944 +#ifdef _RTL8187_EXT_PATCH_
11945 + if((ieee->iw_mode == ieee->iw_ext_mode) && ieee->ext_patch_get_beacon_get_probersp )
11946 + skb = ieee->ext_patch_get_beacon_get_probersp(ieee, broadcast_addr, &(ieee->current_network));
11948 + skb = ieee80211_probe_resp(ieee, broadcast_addr);
11950 + skb = ieee80211_probe_resp(ieee, broadcast_addr);
11956 + b = (struct ieee80211_probe_response *) skb->data;
11957 + b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
11963 +struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
11965 + struct sk_buff *skb;
11966 + struct ieee80211_probe_response *b;
11968 + skb = ieee80211_get_beacon_(ieee);
11972 + b = (struct ieee80211_probe_response *) skb->data;
11973 + b->header.seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
11975 + if (ieee->seq_ctrl[0] == 0xFFF)
11976 + ieee->seq_ctrl[0] = 0;
11978 + ieee->seq_ctrl[0]++;
11983 +void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
11985 + ieee->sync_scan_hurryup = 1;
11986 + down(&ieee->wx_sem);
11987 + ieee80211_stop_protocol(ieee);
11988 + up(&ieee->wx_sem);
11992 +void ieee80211_stop_protocol(struct ieee80211_device *ieee)
11994 + if (!ieee->proto_started)
11997 + ieee->proto_started = 0;
11999 +#ifdef _RTL8187_EXT_PATCH_
12000 + if(ieee->ext_patch_ieee80211_stop_protocol)
12001 + ieee->ext_patch_ieee80211_stop_protocol(ieee);
12002 +//if call queue_delayed_work,can call this,or do nothing..
12003 +//edit by lawrence,20071118
12004 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
12005 +// cancel_delayed_work(&ieee->ext_stop_scan_wq);
12006 +// cancel_delayed_work(&ieee->ext_send_beacon_wq);
12008 +#endif // _RTL8187_EXT_PATCH_
12010 + ieee80211_stop_send_beacons(ieee);
12011 + if((ieee->iw_mode == IW_MODE_INFRA)&&(ieee->state == IEEE80211_LINKED)) {
12012 + SendDisassociation(ieee,NULL,WLAN_REASON_DISASSOC_STA_HAS_LEFT);
12014 + del_timer_sync(&ieee->associate_timer);
12015 + cancel_delayed_work(&ieee->associate_retry_wq);
12016 + cancel_delayed_work(&ieee->start_ibss_wq);
12017 + ieee80211_stop_scan(ieee);
12019 + ieee80211_disassociate(ieee);
12022 +void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
12024 + ieee->sync_scan_hurryup = 0;
12025 + down(&ieee->wx_sem);
12026 + ieee80211_start_protocol(ieee);
12027 + up(&ieee->wx_sem);
12030 +void ieee80211_start_protocol(struct ieee80211_device *ieee)
12035 + if (ieee->proto_started)
12038 + ieee->proto_started = 1;
12040 + if (ieee->current_network.channel == 0){
12043 + if (ch > MAX_CHANNEL_NUMBER)
12044 + return; /* no channel found */
12046 +#ifdef ENABLE_DOT11D
12047 + }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]);
12049 + }while(!ieee->channel_map[ch]);
12052 + ieee->current_network.channel = ch;
12055 + if (ieee->current_network.beacon_interval == 0)
12056 + ieee->current_network.beacon_interval = 100;
12057 + ieee->set_chan(ieee->dev,ieee->current_network.channel);
12059 + for(i = 0; i < 17; i++) {
12060 + ieee->last_rxseq_num[i] = -1;
12061 + ieee->last_rxfrag_num[i] = -1;
12062 + ieee->last_packet_time[i] = 0;
12065 + ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers.
12068 + /* if the user set the MAC of the ad-hoc cell and then
12069 + * switch to managed mode, shall we make sure that association
12070 + * attempts does not fail just because the user provide the essid
12071 + * and the nic is still checking for the AP MAC ??
12073 + switch (ieee->iw_mode) {
12074 + case IW_MODE_AUTO:
12075 + ieee->iw_mode = IW_MODE_INFRA;
12076 + //not set break here intentionly
12077 + case IW_MODE_INFRA:
12078 + ieee80211_start_bss(ieee);
12081 + case IW_MODE_ADHOC:
12082 + ieee80211_start_ibss(ieee);
12085 + case IW_MODE_MASTER:
12086 + ieee80211_start_master_bss(ieee);
12089 + case IW_MODE_MONITOR:
12090 + ieee80211_start_monitor_mode(ieee);
12094 +#ifdef _RTL8187_EXT_PATCH_
12095 + if((ieee->iw_mode == ieee->iw_ext_mode) &&\
12096 + ieee->ext_patch_ieee80211_start_protocol &&\
12097 + ieee->ext_patch_ieee80211_start_protocol(ieee)) {
12098 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
12099 + queue_work(ieee->wq, &ieee->ext_stop_scan_wq);
12101 + // By default, WMM function will be disabled in
12102 + // EXTENSION mode
12103 + ieee->current_network.QoS_Enable = 0;
12105 + if(ieee->modulation & IEEE80211_CCK_MODULATION){
12106 + ieee->current_network.rates_len = 4;
12107 + ieee->current_network.rates[0] = \
12108 + IEEE80211_BASIC_RATE_MASK | \
12109 + IEEE80211_CCK_RATE_1MB;
12110 + ieee->current_network.rates[1] = \
12111 + IEEE80211_BASIC_RATE_MASK |\
12112 + IEEE80211_CCK_RATE_2MB;
12113 + ieee->current_network.rates[2] = \
12114 + IEEE80211_BASIC_RATE_MASK |\
12115 + IEEE80211_CCK_RATE_5MB;
12116 + ieee->current_network.rates[3] = \
12117 + IEEE80211_BASIC_RATE_MASK |\
12118 + IEEE80211_CCK_RATE_11MB;
12120 + ieee->current_network.rates_len = 0;
12122 + if(ieee->modulation & IEEE80211_OFDM_MODULATION){
12123 + ieee->current_network.rates_ex_len = 8;
12124 + ieee->current_network.rates_ex[0] = \
12125 + IEEE80211_BASIC_RATE_MASK |\
12126 + IEEE80211_OFDM_RATE_6MB;
12127 + ieee->current_network.rates_ex[1] = \
12128 + IEEE80211_BASIC_RATE_MASK |\
12129 + IEEE80211_OFDM_RATE_9MB;
12130 + ieee->current_network.rates_ex[2] = \
12131 + IEEE80211_BASIC_RATE_MASK |\
12132 + IEEE80211_OFDM_RATE_12MB;
12133 + ieee->current_network.rates_ex[3] = \
12134 + IEEE80211_BASIC_RATE_MASK | \
12135 + IEEE80211_OFDM_RATE_18MB;
12136 + ieee->current_network.rates_ex[4] =\
12137 + IEEE80211_BASIC_RATE_MASK |\
12138 + IEEE80211_OFDM_RATE_24MB;
12139 + ieee->current_network.rates_ex[5] =\
12140 + IEEE80211_BASIC_RATE_MASK |\
12141 + IEEE80211_OFDM_RATE_36MB;
12142 + ieee->current_network.rates_ex[6] = \
12143 + IEEE80211_BASIC_RATE_MASK |\
12144 + IEEE80211_OFDM_RATE_48MB;
12145 + ieee->current_network.rates_ex[7] =\
12146 + IEEE80211_BASIC_RATE_MASK |\
12147 + IEEE80211_OFDM_RATE_54MB;
12148 + ieee->rate = 540;
12150 + ieee->current_network.rates_ex_len = 0;
12151 + ieee->rate = 110;
12155 + spin_lock_irqsave(&ieee->lock, flags);
12156 + if (ieee->state == IEEE80211_NOLINK)
12157 + ieee80211_start_scan(ieee);
12158 + // ieee->set_chan(ieee->dev, 8);
12160 + spin_unlock_irqrestore(&ieee->lock, flags);
12162 + memcpy(ieee->current_network.bssid, ieee->dev->dev_addr,\
12164 + ieee->link_change(ieee->dev);
12165 + notify_wx_assoc_event(ieee);
12167 + if (ieee->data_hard_resume)
12168 + ieee->data_hard_resume(ieee->dev);
12170 + netif_carrier_on(ieee->dev);
12172 + ieee->iw_mode = IW_MODE_INFRA;
12173 + ieee80211_start_bss(ieee);
12176 + ieee->iw_mode = IW_MODE_INFRA;
12177 + ieee80211_start_bss(ieee);
12185 +#define DRV_NAME "Ieee80211"
12186 +void ieee80211_softmac_init(struct ieee80211_device *ieee)
12189 + memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
12191 + ieee->state = IEEE80211_NOLINK;
12192 + ieee->sync_scan_hurryup = 0;
12193 + for(i = 0; i < 5; i++) {
12194 + ieee->seq_ctrl[i] = 0;
12197 + ieee->assoc_id = 0;
12198 + ieee->queue_stop = 0;
12199 + ieee->scanning = 0;
12200 + ieee->softmac_features = 0; //so IEEE2100-like driver are happy
12201 + ieee->wap_set = 0;
12202 + ieee->ssid_set = 0;
12203 + ieee->proto_started = 0;
12204 + ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
12206 +//#ifdef ENABLE_LPS
12207 + ieee->ps = IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST;
12209 +// ieee->ps = IEEE80211_PS_DISABLED;
12211 + ieee->sta_sleep = 0;
12213 + ieee->bInactivePs = false;
12214 + ieee->actscanning = false;
12215 + ieee->ListenInterval = 2;
12216 + ieee->NumRxDataInPeriod = 0; //YJ,add,080828
12217 + ieee->NumRxBcnInPeriod = 0; //YJ,add,080828
12218 + ieee->NumRxOkTotal = 0;//+by amy 080312
12219 + ieee->NumRxUnicast = 0;//YJ,add,080828,for keep alive
12220 + ieee->beinretry = false;
12221 + ieee->bHwRadioOff = false;
12223 +#ifdef _RTL8187_EXT_PATCH_
12224 + ieee->iw_ext_mode = 999;
12227 + init_mgmt_queue(ieee);
12229 + init_timer(&ieee->scan_timer);
12230 + ieee->scan_timer.data = (unsigned long)ieee;
12231 + ieee->scan_timer.function = ieee80211_softmac_scan_cb;
12233 + ieee->tx_pending.txb = NULL;
12235 + init_timer(&ieee->associate_timer);
12236 + ieee->associate_timer.data = (unsigned long)ieee;
12237 + ieee->associate_timer.function = ieee80211_associate_abort_cb;
12239 + init_timer(&ieee->beacon_timer);
12240 + ieee->beacon_timer.data = (unsigned long) ieee;
12241 + ieee->beacon_timer.function = ieee80211_send_beacon_cb;
12243 +#ifdef PF_SYNCTHREAD
12244 + ieee->wq = create_workqueue(DRV_NAME,0);
12246 + ieee->wq = create_workqueue(DRV_NAME);
12248 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)//added by lawrence,070702
12249 + INIT_DELAYED_WORK(&ieee->start_ibss_wq,(void*) ieee80211_start_ibss_wq);
12250 + INIT_WORK(&ieee->associate_complete_wq,(void*) ieee80211_associate_complete_wq);
12251 + INIT_WORK(&ieee->associate_procedure_wq,(void*) ieee80211_associate_procedure_wq);
12252 + INIT_DELAYED_WORK(&ieee->softmac_scan_wq,(void*) ieee80211_softmac_scan_wq);
12253 + INIT_DELAYED_WORK(&ieee->associate_retry_wq,(void*) ieee80211_associate_retry_wq);
12254 + INIT_WORK(&ieee->wx_sync_scan_wq,(void*) ieee80211_wx_sync_scan_wq);
12255 +// INIT_WORK(&ieee->watch_dog_wq,(void*) ieee80211_watch_dog_wq);
12256 +//added by lawrence,20071118
12257 +#ifdef _RTL8187_EXT_PATCH_
12258 + INIT_WORK(&ieee->ext_stop_scan_wq,(void*) ieee80211_ext_stop_scan_wq);
12259 + //INIT_WORK(&ieee->ext_send_beacon_wq,(void*) ieee80211_beacons_start,ieee);
12260 + INIT_WORK(&ieee->ext_send_beacon_wq,(void*) ext_ieee80211_send_beacon_wq);
12261 +#endif //_RTL8187_EXT_PATCH_
12263 + INIT_WORK(&ieee->start_ibss_wq,(void*) ieee80211_start_ibss_wq,ieee);
12264 + INIT_WORK(&ieee->associate_retry_wq,(void*) ieee80211_associate_retry_wq,ieee);
12265 + INIT_WORK(&ieee->associate_complete_wq,(void*) ieee80211_associate_complete_wq,ieee);
12266 + INIT_WORK(&ieee->associate_procedure_wq,(void*) ieee80211_associate_procedure_wq,ieee);
12267 + INIT_WORK(&ieee->softmac_scan_wq,(void*) ieee80211_softmac_scan_wq,ieee);
12268 + INIT_WORK(&ieee->wx_sync_scan_wq,(void*) ieee80211_wx_sync_scan_wq,ieee);
12269 +// INIT_WORK(&ieee->watch_dog_wq,(void*) ieee80211_watch_dog_wq,ieee);
12270 +#ifdef _RTL8187_EXT_PATCH_
12271 + INIT_WORK(&ieee->ext_stop_scan_wq,(void*) ieee80211_ext_stop_scan_wq,ieee);
12272 + //INIT_WORK(&ieee->ext_send_beacon_wq,(void*) ieee80211_beacons_start,ieee);
12273 + INIT_WORK(&ieee->ext_send_beacon_wq,(void*) ext_ieee80211_send_beacon_wq,ieee);
12276 + sema_init(&ieee->wx_sem, 1);
12277 + sema_init(&ieee->scan_sem, 1);
12279 + spin_lock_init(&ieee->mgmt_tx_lock);
12280 + spin_lock_init(&ieee->beacon_lock);
12282 + tasklet_init(&ieee->ps_task,
12283 + (void(*)(unsigned long)) ieee80211_sta_ps,
12284 + (unsigned long)ieee);
12285 +#ifdef ENABLE_DOT11D
12286 + ieee->pDot11dInfo = kmalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
12290 +void ieee80211_softmac_free(struct ieee80211_device *ieee)
12292 + down(&ieee->wx_sem);
12294 + del_timer_sync(&ieee->associate_timer);
12295 + cancel_delayed_work(&ieee->associate_retry_wq);
12298 + //add for RF power on power of by lizhaoming 080512
12299 + cancel_delayed_work(&ieee->GPIOChangeRFWorkItem);
12301 +#ifdef _RTL8187_EXT_PATCH_
12302 + cancel_delayed_work(&ieee->ext_stop_scan_wq);
12303 + cancel_delayed_work(&ieee->ext_send_beacon_wq);
12305 + destroy_workqueue(ieee->wq);
12306 +#ifdef ENABLE_DOT11D
12307 + if(NULL != ieee->pDot11dInfo)
12308 + kfree(ieee->pDot11dInfo);
12310 + up(&ieee->wx_sem);
12313 +/********************************************************
12314 + * Start of WPA code. *
12315 + * this is stolen from the ipw2200 driver *
12316 + ********************************************************/
12319 +static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
12321 + /* This is called when wpa_supplicant loads and closes the driver
12323 + printk("%s WPA\n",value ? "enabling" : "disabling");
12324 + ieee->wpa_enabled = value;
12329 +void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int wpa_ie_len)
12331 + /* make sure WPA is enabled */
12332 + ieee80211_wpa_enable(ieee, 1);
12334 + ieee80211_disassociate(ieee);
12338 +static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason)
12343 + switch (command) {
12344 + case IEEE_MLME_STA_DEAUTH:
12345 + // silently ignore
12348 + case IEEE_MLME_STA_DISASSOC:
12349 + ieee80211_disassociate(ieee);
12353 + printk("Unknown MLME request: %d\n", command);
12354 + ret = -EOPNOTSUPP;
12361 +static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
12362 + struct ieee_param *param, int plen)
12366 + if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
12367 + (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
12370 + if (param->u.wpa_ie.len) {
12371 + buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
12375 + memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
12376 + kfree(ieee->wpa_ie);
12377 + ieee->wpa_ie = buf;
12378 + ieee->wpa_ie_len = param->u.wpa_ie.len;
12380 + kfree(ieee->wpa_ie);
12381 + ieee->wpa_ie = NULL;
12382 + ieee->wpa_ie_len = 0;
12385 + ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
12389 +#define AUTH_ALG_OPEN_SYSTEM 0x1
12390 +#define AUTH_ALG_SHARED_KEY 0x2
12392 +static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
12395 + struct ieee80211_security sec = {
12396 + .flags = SEC_AUTH_MODE,
12400 + if (value & AUTH_ALG_SHARED_KEY) {
12401 + sec.auth_mode = WLAN_AUTH_SHARED_KEY;
12402 + ieee->open_wep = 0;
12404 + sec.auth_mode = WLAN_AUTH_OPEN;
12405 + ieee->open_wep = 1;
12408 + if (ieee->set_security)
12409 + ieee->set_security(ieee->dev, &sec);
12411 + ret = -EOPNOTSUPP;
12416 +static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value)
12419 + unsigned long flags;
12422 + case IEEE_PARAM_WPA_ENABLED:
12423 + ret = ieee80211_wpa_enable(ieee, value);
12426 + case IEEE_PARAM_TKIP_COUNTERMEASURES:
12427 + ieee->tkip_countermeasures=value;
12430 + case IEEE_PARAM_DROP_UNENCRYPTED: {
12433 + * wpa_supplicant calls set_wpa_enabled when the driver
12434 + * is loaded and unloaded, regardless of if WPA is being
12435 + * used. No other calls are made which can be used to
12436 + * determine if encryption will be used or not prior to
12437 + * association being expected. If encryption is not being
12438 + * used, drop_unencrypted is set to false, else true -- we
12439 + * can use this to determine if the CAP_PRIVACY_ON bit should
12442 + struct ieee80211_security sec = {
12443 + .flags = SEC_ENABLED,
12444 + .enabled = value,
12446 + ieee->drop_unencrypted = value;
12447 + /* We only change SEC_LEVEL for open mode. Others
12448 + * are set by ipw_wpa_set_encryption.
12451 + sec.flags |= SEC_LEVEL;
12452 + sec.level = SEC_LEVEL_0;
12455 + sec.flags |= SEC_LEVEL;
12456 + sec.level = SEC_LEVEL_1;
12458 + if (ieee->set_security)
12459 + ieee->set_security(ieee->dev, &sec);
12463 + case IEEE_PARAM_PRIVACY_INVOKED:
12464 + ieee->privacy_invoked=value;
12467 + case IEEE_PARAM_AUTH_ALGS:
12468 + ret = ieee80211_wpa_set_auth_algs(ieee, value);
12471 + case IEEE_PARAM_IEEE_802_1X:
12472 + ieee->ieee802_1x=value;
12474 + case IEEE_PARAM_WPAX_SELECT:
12475 + // added for WPA2 mixed mode
12476 + //printk(KERN_WARNING "------------------------>wpax value = %x\n", value);
12477 + spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
12478 + ieee->wpax_type_set = 1;
12479 + ieee->wpax_type_notify = value;
12480 + spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
12484 + printk("Unknown WPA param: %d\n",name);
12485 + ret = -EOPNOTSUPP;
12491 +/* implementation borrowed from hostap driver */
12493 +static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
12494 + struct ieee_param *param, int param_len)
12498 + struct ieee80211_crypto_ops *ops;
12499 + struct ieee80211_crypt_data **crypt;
12501 + struct ieee80211_security sec = {
12505 + param->u.crypt.err = 0;
12506 + param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
12509 + (int) ((char *) param->u.crypt.key - (char *) param) +
12510 + param->u.crypt.key_len) {
12511 + printk("Len mismatch %d, %d\n", param_len,
12512 + param->u.crypt.key_len);
12515 + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
12516 + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
12517 + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
12518 + if (param->u.crypt.idx >= WEP_KEYS)
12520 + crypt = &ieee->crypt[param->u.crypt.idx];
12525 + if (strcmp(param->u.crypt.alg, "none") == 0) {
12529 + //sec.encrypt = 0;
12530 + sec.level = SEC_LEVEL_0;
12531 + sec.flags |= SEC_ENABLED | SEC_LEVEL;
12532 + ieee80211_crypt_delayed_deinit(ieee, crypt);
12538 +// sec.encrypt = 1;
12539 + sec.flags |= SEC_ENABLED;
12541 + /* IPW HW cannot build TKIP MIC, host decryption still needed. */
12542 + if (!(ieee->host_encrypt || ieee->host_decrypt) &&
12543 + strcmp(param->u.crypt.alg, "TKIP"))
12544 + goto skip_host_crypt;
12546 + ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
12547 + if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
12548 + request_module("ieee80211_crypt_wep");
12549 + ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
12550 + } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
12551 + request_module("ieee80211_crypt_tkip");
12552 + ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
12553 + } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
12554 + request_module("ieee80211_crypt_ccmp");
12555 + ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
12557 + if (ops == NULL) {
12558 + printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
12559 + param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
12564 + if (*crypt == NULL || (*crypt)->ops != ops) {
12565 + struct ieee80211_crypt_data *new_crypt;
12567 + ieee80211_crypt_delayed_deinit(ieee, crypt);
12569 + new_crypt = (struct ieee80211_crypt_data *)
12570 + kmalloc(sizeof(*new_crypt), GFP_KERNEL);
12571 + if (new_crypt == NULL) {
12575 + memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
12576 + new_crypt->ops = ops;
12577 + if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
12578 + new_crypt->priv =
12579 + new_crypt->ops->init(param->u.crypt.idx);
12581 + if (new_crypt->priv == NULL) {
12582 + kfree(new_crypt);
12583 + param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
12588 + *crypt = new_crypt;
12591 + if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
12592 + (*crypt)->ops->set_key(param->u.crypt.key,
12593 + param->u.crypt.key_len, param->u.crypt.seq,
12594 + (*crypt)->priv) < 0) {
12595 + printk("key setting failed\n");
12596 + param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
12602 + if (param->u.crypt.set_tx) {
12603 + ieee->tx_keyidx = param->u.crypt.idx;
12604 + sec.active_key = param->u.crypt.idx;
12605 + sec.flags |= SEC_ACTIVE_KEY;
12607 + sec.flags &= ~SEC_ACTIVE_KEY;
12609 + if (param->u.crypt.alg != NULL) {
12610 + memcpy(sec.keys[param->u.crypt.idx],
12611 + param->u.crypt.key,
12612 + param->u.crypt.key_len);
12613 + sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
12614 + sec.flags |= (1 << param->u.crypt.idx);
12616 + if (strcmp(param->u.crypt.alg, "WEP") == 0) {
12617 + sec.flags |= SEC_LEVEL;
12618 + sec.level = SEC_LEVEL_1;
12619 + } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
12620 + sec.flags |= SEC_LEVEL;
12621 + sec.level = SEC_LEVEL_2;
12622 + } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
12623 + sec.flags |= SEC_LEVEL;
12624 + sec.level = SEC_LEVEL_3;
12628 + if (ieee->set_security)
12629 + ieee->set_security(ieee->dev, &sec);
12631 + /* Do not reset port if card is in Managed mode since resetting will
12632 + * generate new IEEE 802.11 authentication which may end up in looping
12633 + * with IEEE 802.1X. If your hardware requires a reset after WEP
12634 + * configuration (for example... Prism2), implement the reset_port in
12635 + * the callbacks structures used to initialize the 802.11 stack. */
12636 + if (ieee->reset_on_keychange &&
12637 + ieee->iw_mode != IW_MODE_INFRA &&
12638 + ieee->reset_port &&
12639 + ieee->reset_port(ieee->dev)) {
12640 + printk("reset_port failed\n");
12641 + param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
12648 +int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p)
12650 + struct ieee_param *param;
12653 + down(&ieee->wx_sem);
12654 + //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
12656 + if (p->length < sizeof(struct ieee_param) || !p->pointer){
12661 + param = (struct ieee_param *)kmalloc(p->length, GFP_KERNEL);
12662 + if (param == NULL){
12666 + if (copy_from_user(param, p->pointer, p->length)) {
12672 + switch (param->cmd) {
12674 + case IEEE_CMD_SET_WPA_PARAM:
12675 + ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
12676 + param->u.wpa_param.value);
12679 + case IEEE_CMD_SET_WPA_IE:
12680 + ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
12683 + case IEEE_CMD_SET_ENCRYPTION:
12684 + ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
12687 + case IEEE_CMD_MLME:
12688 + ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
12689 + param->u.mlme.reason_code);
12693 + printk("Unknown WPA supplicant request: %d\n",param->cmd);
12694 + ret = -EOPNOTSUPP;
12698 + if (ret == 0 && copy_to_user(p->pointer, param, p->length))
12703 + up(&ieee->wx_sem);
12708 +void notify_wx_assoc_event(struct ieee80211_device *ieee)
12710 + union iwreq_data wrqu;
12711 + wrqu.ap_addr.sa_family = ARPHRD_ETHER;
12712 + if (ieee->state == IEEE80211_LINKED)
12713 + memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
12715 + memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
12716 + wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
12721 +EXPORT_SYMBOL(ieee80211_get_beacon);
12722 +EXPORT_SYMBOL(ieee80211_wake_queue);
12723 +EXPORT_SYMBOL(ieee80211_stop_queue);
12724 +EXPORT_SYMBOL(ieee80211_reset_queue);
12725 +EXPORT_SYMBOL(ieee80211_softmac_stop_protocol);
12726 +EXPORT_SYMBOL(ieee80211_softmac_start_protocol);
12727 +EXPORT_SYMBOL(ieee80211_is_shortslot);
12728 +EXPORT_SYMBOL(ieee80211_is_54g);
12729 +EXPORT_SYMBOL(ieee80211_wpa_supplicant_ioctl);
12730 +EXPORT_SYMBOL(ieee80211_ps_tx_ack);
12731 +EXPORT_SYMBOL(ieee80211_start_protocol);
12732 +EXPORT_SYMBOL(ieee80211_stop_protocol);
12733 +EXPORT_SYMBOL(notify_wx_assoc_event);
12734 +EXPORT_SYMBOL(ieee80211_stop_send_beacons);
12735 +EXPORT_SYMBOL(SendDisassociation);
12736 +EXPORT_SYMBOL(ieee80211_disassociate);
12737 +EXPORT_SYMBOL(ieee80211_start_scan);
12738 +EXPORT_SYMBOL(ieee80211_softmac_ips_scan_syncro);
12739 +#ifdef _RTL8187_EXT_PATCH_
12740 +EXPORT_SYMBOL(ieee80211_ext_issue_assoc_req);
12741 +EXPORT_SYMBOL(ieee80211_ext_issue_disassoc);
12742 +EXPORT_SYMBOL(ieee80211_ext_issue_assoc_rsp);
12743 +EXPORT_SYMBOL(softmac_mgmt_xmit);
12744 +EXPORT_SYMBOL(ieee80211_ext_probe_resp_by_net);
12745 +EXPORT_SYMBOL(ieee80211_start_scan);
12746 +EXPORT_SYMBOL(ieee80211_stop_scan);
12747 +EXPORT_SYMBOL(ieee80211_ext_send_11s_beacon);
12748 +EXPORT_SYMBOL(ieee80211_rx_auth_rq);
12749 +EXPORT_SYMBOL(ieee80211_associate_step1);
12750 +#endif // _RTL8187_EXT_PATCH_
12751 +EXPORT_SYMBOL(ieee80211_sta_ps_send_null_frame);
12754 +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c
12756 +/* IEEE 802.11 SoftMAC layer
12757 + * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
12759 + * Mostly extracted from the rtl8180-sa2400 driver for the
12760 + * in-kernel generic ieee802.11 stack.
12762 + * Some pieces of code might be stolen from ipw2100 driver
12763 + * copyright of who own it's copyright ;-)
12765 + * PS wx handler mostly stolen from hostap, copyright who
12766 + * own it's copyright ;-)
12768 + * released under the GPL
12772 +#include "ieee80211.h"
12774 +/* FIXME: add A freqs */
12776 +const long ieee80211_wlan_frequencies[] = {
12777 + 2412, 2417, 2422, 2427,
12778 + 2432, 2437, 2442, 2447,
12779 + 2452, 2457, 2462, 2467,
12784 +int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a,
12785 + union iwreq_data *wrqu, char *b)
12788 + struct iw_freq *fwrq = & wrqu->freq;
12789 +// printk("in %s\n",__FUNCTION__);
12790 + down(&ieee->wx_sem);
12792 + if(ieee->iw_mode == IW_MODE_INFRA){
12793 + ret = -EOPNOTSUPP;
12797 + /* if setting by freq convert to channel */
12798 + if (fwrq->e == 1) {
12799 + if ((fwrq->m >= (int) 2.412e8 &&
12800 + fwrq->m <= (int) 2.487e8)) {
12801 + int f = fwrq->m / 100000;
12804 + while ((c < 14) && (f != ieee80211_wlan_frequencies[c]))
12807 + /* hack to fall through */
12813 + if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1 ){
12814 + ret = -EOPNOTSUPP;
12817 + }else { /* Set the channel */
12820 + ieee->current_network.channel = fwrq->m;
12821 + ieee->set_chan(ieee->dev, ieee->current_network.channel);
12823 + if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
12824 + if(ieee->state == IEEE80211_LINKED){
12826 + ieee80211_stop_send_beacons(ieee);
12827 + ieee80211_start_send_beacons(ieee);
12833 + up(&ieee->wx_sem);
12838 +int ieee80211_wx_get_freq(struct ieee80211_device *ieee,
12839 + struct iw_request_info *a,
12840 + union iwreq_data *wrqu, char *b)
12842 + struct iw_freq *fwrq = & wrqu->freq;
12844 + if (ieee->current_network.channel == 0)
12847 + fwrq->m = ieee->current_network.channel;
12853 +int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
12854 + struct iw_request_info *info,
12855 + union iwreq_data *wrqu, char *extra)
12857 + unsigned long flags;
12859 + wrqu->ap_addr.sa_family = ARPHRD_ETHER;
12861 + if (ieee->iw_mode == IW_MODE_MONITOR)
12864 + /* We want avoid to give to the user inconsistent infos*/
12865 + spin_lock_irqsave(&ieee->lock, flags);
12867 + if (ieee->state != IEEE80211_LINKED &&
12868 + ieee->state != IEEE80211_LINKED_SCANNING &&
12869 + ieee->wap_set == 0)
12871 + memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
12873 + memcpy(wrqu->ap_addr.sa_data,
12874 + ieee->current_network.bssid, ETH_ALEN);
12876 + spin_unlock_irqrestore(&ieee->lock, flags);
12882 +int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
12883 + struct iw_request_info *info,
12884 + union iwreq_data *awrq,
12889 + u8 zero[] = {0,0,0,0,0,0};
12890 + unsigned long flags;
12892 + short ifup = ieee->proto_started;//dev->flags & IFF_UP;
12893 + struct sockaddr *temp = (struct sockaddr *)awrq;
12895 + //printk("=======Set WAP:");
12896 + ieee->sync_scan_hurryup = 1;
12898 + down(&ieee->wx_sem);
12899 + /* use ifconfig hw ether */
12900 + if (ieee->iw_mode == IW_MODE_MASTER){
12905 + if (temp->sa_family != ARPHRD_ETHER){
12911 + ieee80211_stop_protocol(ieee);
12913 + /* just to avoid to give inconsistent infos in the
12914 + * get wx method. not really needed otherwise
12916 + spin_lock_irqsave(&ieee->lock, flags);
12918 + memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN);
12919 + ieee->wap_set = memcmp(temp->sa_data, zero,ETH_ALEN)!=0;
12920 + //printk(" %x:%x:%x:%x:%x:%x\n", ieee->current_network.bssid[0],ieee->current_network.bssid[1],ieee->current_network.bssid[2],ieee->current_network.bssid[3],ieee->current_network.bssid[4],ieee->current_network.bssid[5]);
12922 + spin_unlock_irqrestore(&ieee->lock, flags);
12925 + ieee80211_start_protocol(ieee);
12928 + up(&ieee->wx_sem);
12932 + int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b)
12935 + unsigned long flags;
12937 + if (ieee->iw_mode == IW_MODE_MONITOR)
12940 + /* We want avoid to give to the user inconsistent infos*/
12941 + spin_lock_irqsave(&ieee->lock, flags);
12943 + if (ieee->current_network.ssid[0] == '\0' ||
12944 + ieee->current_network.ssid_len == 0){
12949 + if (ieee->state != IEEE80211_LINKED &&
12950 + ieee->state != IEEE80211_LINKED_SCANNING &&
12951 + ieee->ssid_set == 0){
12955 + len = ieee->current_network.ssid_len;
12956 + wrqu->essid.length = len;
12957 + strncpy(b,ieee->current_network.ssid,len);
12958 + wrqu->essid.flags = 1;
12961 + spin_unlock_irqrestore(&ieee->lock, flags);
12967 +int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
12968 + struct iw_request_info *info,
12969 + union iwreq_data *wrqu, char *extra)
12972 + u32 target_rate = wrqu->bitrate.value;
12974 + //added by lizhaoming for auto mode
12975 + if(target_rate == -1){
12976 + ieee->rate = 110;
12978 + ieee->rate = target_rate/100000;
12980 + //FIXME: we might want to limit rate also in management protocols.
12986 +int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
12987 + struct iw_request_info *info,
12988 + union iwreq_data *wrqu, char *extra)
12991 + wrqu->bitrate.value = ieee->rate * 100000;
12996 +int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
12997 + union iwreq_data *wrqu, char *b)
13000 + ieee->sync_scan_hurryup = 1;
13002 + down(&ieee->wx_sem);
13004 + if (wrqu->mode == ieee->iw_mode)
13007 + if (wrqu->mode == IW_MODE_MONITOR){
13009 + ieee->dev->type = ARPHRD_IEEE80211;
13011 + ieee->dev->type = ARPHRD_ETHER;
13014 + if (!ieee->proto_started){
13015 + ieee->iw_mode = wrqu->mode;
13017 + ieee80211_stop_protocol(ieee);
13018 + ieee->iw_mode = wrqu->mode;
13019 + ieee80211_start_protocol(ieee);
13023 + up(&ieee->wx_sem);
13028 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
13029 +void ieee80211_wx_sync_scan_wq(struct work_struct *work)
13031 + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq);
13033 +void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee)
13036 +//void ieee80211_wx_sync_scan_wq(struct ieee80211_device *ieee)
13040 + chan = ieee->current_network.channel;
13042 + netif_carrier_off(ieee->dev);
13044 + if (ieee->data_hard_stop)
13045 + ieee->data_hard_stop(ieee->dev);
13047 + ieee80211_stop_send_beacons(ieee);
13049 + ieee->state = IEEE80211_LINKED_SCANNING;
13050 + ieee->link_change(ieee->dev);
13052 + ieee80211_start_scan_syncro(ieee);
13054 + ieee->set_chan(ieee->dev, chan);
13056 + ieee->state = IEEE80211_LINKED;
13057 + ieee->link_change(ieee->dev);
13059 + if (ieee->data_hard_resume)
13060 + ieee->data_hard_resume(ieee->dev);
13062 + if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
13063 + ieee80211_start_send_beacons(ieee);
13065 + netif_carrier_on(ieee->dev);
13067 + //YJ,add,080828, In prevent of lossing ping packet during scanning
13068 + //ieee80211_sta_ps_send_null_frame(ieee, false);
13069 + //YJ,add,080828,end
13071 + up(&ieee->wx_sem);
13075 +int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a,
13076 + union iwreq_data *wrqu, char *b)
13080 + down(&ieee->wx_sem);
13082 + if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)){
13087 + //In prevent of lossing ping packet during scanning
13088 + //ieee80211_sta_ps_send_null_frame(ieee, true);
13089 + //YJ,add,080828,end
13091 + if ( ieee->state == IEEE80211_LINKED){
13092 + queue_work(ieee->wq, &ieee->wx_sync_scan_wq);
13093 + /* intentionally forget to up sem */
13098 + up(&ieee->wx_sem);
13102 +int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
13103 + struct iw_request_info *a,
13104 + union iwreq_data *wrqu, char *extra)
13108 + short proto_started;
13109 + unsigned long flags;
13111 + ieee->sync_scan_hurryup = 1;
13113 + down(&ieee->wx_sem);
13115 + proto_started = ieee->proto_started;
13117 + if (wrqu->essid.length > IW_ESSID_MAX_SIZE){
13122 + if (ieee->iw_mode == IW_MODE_MONITOR){
13127 + if(proto_started)
13128 + ieee80211_stop_protocol(ieee);
13130 + /* this is just to be sure that the GET wx callback
13131 + * has consisten infos. not needed otherwise
13133 + spin_lock_irqsave(&ieee->lock, flags);
13135 + if (wrqu->essid.flags && wrqu->essid.length) {
13136 +//YJ,modified,080819
13137 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
13138 + len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE;
13140 + len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length) : IW_ESSID_MAX_SIZE;
13142 + memset(ieee->current_network.ssid, 0, ieee->current_network.ssid_len); //YJ,add,080819
13143 + strncpy(ieee->current_network.ssid, extra, len);
13144 + ieee->current_network.ssid_len = len;
13145 + ieee->ssid_set = 1;
13146 +//YJ,modified,080819,end
13148 + //YJ,add,080819,for hidden ap
13150 + memset(ieee->current_network.bssid, 0, ETH_ALEN);
13151 + ieee->current_network.capability = 0;
13153 + //YJ,add,080819,for hidden ap,end
13156 + ieee->ssid_set = 0;
13157 + ieee->current_network.ssid[0] = '\0';
13158 + ieee->current_network.ssid_len = 0;
13160 + //printk("==========set essid %s!\n",ieee->current_network.ssid);
13161 + spin_unlock_irqrestore(&ieee->lock, flags);
13163 + if (proto_started)
13164 + ieee80211_start_protocol(ieee);
13166 + up(&ieee->wx_sem);
13170 + int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a,
13171 + union iwreq_data *wrqu, char *b)
13174 + wrqu->mode = ieee->iw_mode;
13178 + int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
13179 + struct iw_request_info *info,
13180 + union iwreq_data *wrqu, char *extra)
13183 + int *parms = (int *)extra;
13184 + int enable = (parms[0] > 0);
13185 + short prev = ieee->raw_tx;
13187 + down(&ieee->wx_sem);
13190 + ieee->raw_tx = 1;
13192 + ieee->raw_tx = 0;
13194 + printk(KERN_INFO"raw TX is %s\n",
13195 + ieee->raw_tx ? "enabled" : "disabled");
13197 + if(ieee->iw_mode == IW_MODE_MONITOR)
13199 + if(prev == 0 && ieee->raw_tx){
13200 + if (ieee->data_hard_resume)
13201 + ieee->data_hard_resume(ieee->dev);
13203 + netif_carrier_on(ieee->dev);
13206 + if(prev && ieee->raw_tx == 1)
13207 + netif_carrier_off(ieee->dev);
13210 + up(&ieee->wx_sem);
13215 +int ieee80211_wx_get_name(struct ieee80211_device *ieee,
13216 + struct iw_request_info *info,
13217 + union iwreq_data *wrqu, char *extra)
13219 + strcpy(wrqu->name, "802.11");
13220 + if(ieee->modulation & IEEE80211_CCK_MODULATION){
13221 + strcat(wrqu->name, "b");
13222 + if(ieee->modulation & IEEE80211_OFDM_MODULATION)
13223 + strcat(wrqu->name, "/g");
13224 + }else if(ieee->modulation & IEEE80211_OFDM_MODULATION)
13225 + strcat(wrqu->name, "g");
13227 + if((ieee->state == IEEE80211_LINKED) ||
13228 + (ieee->state == IEEE80211_LINKED_SCANNING))
13229 + strcat(wrqu->name," linked");
13230 + else if(ieee->state != IEEE80211_NOLINK)
13231 + strcat(wrqu->name," link..");
13238 +/* this is mostly stolen from hostap */
13239 +int ieee80211_wx_set_power(struct ieee80211_device *ieee,
13240 + struct iw_request_info *info,
13241 + union iwreq_data *wrqu, char *extra)
13246 + (!ieee->sta_wake_up) ||
13247 + (!ieee->ps_request_tx_ack) ||
13248 + (!ieee->enter_sleep_state) ||
13249 + (!ieee->ps_is_queue_empty)){
13251 + printk("ERROR. PS mode is tryied to be use but\
13252 +driver missed a callback\n\n");
13257 + down(&ieee->wx_sem);
13259 + if (wrqu->power.disabled){
13260 + ieee->ps = IEEE80211_PS_DISABLED;
13264 + switch (wrqu->power.flags & IW_POWER_MODE) {
13265 + case IW_POWER_UNICAST_R:
13266 + ieee->ps = IEEE80211_PS_UNICAST;
13269 + case IW_POWER_ALL_R:
13270 + ieee->ps = IEEE80211_PS_UNICAST | IEEE80211_PS_MBCAST;
13273 + case IW_POWER_ON:
13274 + ieee->ps = IEEE80211_PS_DISABLED;
13282 + if (wrqu->power.flags & IW_POWER_TIMEOUT) {
13284 + ieee->ps_timeout = wrqu->power.value / 1000;
13285 + printk("Timeout %d\n",ieee->ps_timeout);
13288 + if (wrqu->power.flags & IW_POWER_PERIOD) {
13290 + ret = -EOPNOTSUPP;
13292 + //wrq->value / 1024;
13296 + up(&ieee->wx_sem);
13301 +/* this is stolen from hostap */
13302 +int ieee80211_wx_get_power(struct ieee80211_device *ieee,
13303 + struct iw_request_info *info,
13304 + union iwreq_data *wrqu, char *extra)
13308 + down(&ieee->wx_sem);
13310 + if(ieee->ps == IEEE80211_PS_DISABLED){
13311 + wrqu->power.disabled = 1;
13315 + wrqu->power.disabled = 0;
13317 +// if ((wrqu->power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
13318 + wrqu->power.flags = IW_POWER_TIMEOUT;
13319 + wrqu->power.value = ieee->ps_timeout * 1000;
13321 +// ret = -EOPNOTSUPP;
13323 + //wrqu->power.flags = IW_POWER_PERIOD;
13324 + //wrqu->power.value = ieee->current_network.dtim_period *
13325 + // ieee->current_network.beacon_interval * 1024;
13329 + if (ieee->ps & IEEE80211_PS_MBCAST)
13330 + wrqu->power.flags |= IW_POWER_ALL_R;
13332 + wrqu->power.flags |= IW_POWER_UNICAST_R;
13335 + up(&ieee->wx_sem);
13341 +EXPORT_SYMBOL(ieee80211_wx_get_essid);
13342 +EXPORT_SYMBOL(ieee80211_wx_set_essid);
13343 +EXPORT_SYMBOL(ieee80211_wx_set_rate);
13344 +EXPORT_SYMBOL(ieee80211_wx_get_rate);
13345 +EXPORT_SYMBOL(ieee80211_wx_set_wap);
13346 +EXPORT_SYMBOL(ieee80211_wx_get_wap);
13347 +EXPORT_SYMBOL(ieee80211_wx_set_mode);
13348 +EXPORT_SYMBOL(ieee80211_wx_get_mode);
13349 +EXPORT_SYMBOL(ieee80211_wx_set_scan);
13350 +EXPORT_SYMBOL(ieee80211_wx_get_freq);
13351 +EXPORT_SYMBOL(ieee80211_wx_set_freq);
13352 +EXPORT_SYMBOL(ieee80211_wx_set_rawtx);
13353 +EXPORT_SYMBOL(ieee80211_wx_get_name);
13354 +EXPORT_SYMBOL(ieee80211_wx_set_power);
13355 +EXPORT_SYMBOL(ieee80211_wx_get_power);
13356 +EXPORT_SYMBOL(ieee80211_wlan_frequencies);
13359 +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
13361 +/******************************************************************************
13363 + Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
13365 + This program is free software; you can redistribute it and/or modify it
13366 + under the terms of version 2 of the GNU General Public License as
13367 + published by the Free Software Foundation.
13369 + This program is distributed in the hope that it will be useful, but WITHOUT
13370 + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13371 + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13374 + You should have received a copy of the GNU General Public License along with
13375 + this program; if not, write to the Free Software Foundation, Inc., 59
13376 + Temple Place - Suite 330, Boston, MA 02111-1307, USA.
13378 + The full GNU General Public License is included in this distribution in the
13379 + file called LICENSE.
13381 + Contact Information:
13382 + James P. Ketrenos <ipw2100-admin@linux.intel.com>
13383 + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
13385 +******************************************************************************
13387 + Few modifications for Realtek's Wi-Fi drivers by
13388 + Andrea Merello <andreamrl@tiscali.it>
13390 + A special thanks goes to Realtek for their support !
13392 +******************************************************************************/
13394 +#include <linux/compiler.h>
13395 +//#include <linux/config.h>
13396 +#include <linux/errno.h>
13397 +#include <linux/if_arp.h>
13398 +#include <linux/in6.h>
13399 +#include <linux/in.h>
13400 +#include <linux/ip.h>
13401 +#include <linux/kernel.h>
13402 +#include <linux/module.h>
13403 +#include <linux/netdevice.h>
13404 +#include <linux/pci.h>
13405 +#include <linux/proc_fs.h>
13406 +#include <linux/skbuff.h>
13407 +#include <linux/slab.h>
13408 +#include <linux/tcp.h>
13409 +#include <linux/types.h>
13410 +#include <linux/version.h>
13411 +#include <linux/wireless.h>
13412 +#include <linux/etherdevice.h>
13413 +#include <asm/uaccess.h>
13414 +#include <linux/if_vlan.h>
13416 +#include "ieee80211.h"
13425 +802.11 frame_contorl for data frames - 2 bytes
13426 + ,-----------------------------------------------------------------------------------------.
13427 +bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e |
13428 + |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
13429 +val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x |
13430 + |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
13431 +desc | ^-ver-^ | ^type-^ | ^-----subtype-----^ | to |from |more |retry| pwr |more |wep |
13432 + | | | x=0 data,x=1 data+ack | DS | DS |frag | | mgm |data | |
13433 + '-----------------------------------------------------------------------------------------'
13436 +802.11 Data Frame |
13437 + ,--------- 'ctrl' expands to >-----------'
13439 + ,--'---,-------------------------------------------------------------.
13440 +Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
13441 + |------|------|---------|---------|---------|------|---------|------|
13442 +Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs |
13443 + | | tion | (BSSID) | | | ence | data | |
13444 + `--------------------------------------------------| |------'
13445 +Total: 28 non-data bytes `----.----'
13447 + .- 'Frame data' expands to <---------------------------'
13450 + ,---------------------------------------------------.
13451 +Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 |
13452 + |------|------|---------|----------|------|---------|
13453 +Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP |
13454 + | DSAP | SSAP | | | | Packet |
13455 + | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | |
13456 + `-----------------------------------------| |
13457 +Total: 8 non-data bytes `----.----'
13459 + .- 'IP Packet' expands, if WEP enabled, to <--'
13462 + ,-----------------------.
13463 +Bytes | 4 | 0-2296 | 4 |
13464 + |-----|-----------|-----|
13465 +Desc. | IV | Encrypted | ICV |
13466 + | | IP Packet | |
13467 + `-----------------------'
13468 +Total: 8 non-data bytes
13471 +802.3 Ethernet Data Frame
13473 + ,-----------------------------------------.
13474 +Bytes | 6 | 6 | 2 | Variable | 4 |
13475 + |-------|-------|------|-----------|------|
13476 +Desc. | Dest. | Source| Type | IP Packet | fcs |
13477 + | MAC | MAC | | | |
13478 + `-----------------------------------------'
13479 +Total: 18 non-data bytes
13481 +In the event that fragmentation is required, the incoming payload is split into
13482 +N parts of size ieee->fts. The first fragment contains the SNAP header and the
13483 +remaining packets are just data.
13485 +If encryption is enabled, each fragment payload size is reduced by enough space
13486 +to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
13487 +So if you have 1500 bytes of payload with ieee->fts set to 500 without
13488 +encryption it will take 3 frames. With WEP it will take 4 frames as the
13489 +payload of each frame is reduced to 492 bytes.
13491 +* SKB visualization
13495 +* | ETHERNET HEADER ,-<-- PAYLOAD
13496 +* | | 14 bytes from skb->data
13497 +* | 2 bytes for Type --> ,T. | (sizeof ethhdr)
13499 +* |,-Dest.--. ,--Src.---. | | |
13500 +* | 6 bytes| | 6 bytes | | | |
13502 +* 0 | v 1 | v | v 2
13503 +* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
13506 +* | | | | `T' <---- 2 bytes for Type
13508 +* | | '---SNAP--' <-------- 6 bytes for SNAP
13510 +* `-IV--' <-------------------- 4 bytes for IV (WEP)
13516 +static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
13517 +static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
13519 +static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
13521 + struct ieee80211_snap_hdr *snap;
13524 + snap = (struct ieee80211_snap_hdr *)data;
13525 + snap->dsap = 0xaa;
13526 + snap->ssap = 0xaa;
13527 + snap->ctrl = 0x03;
13529 + if (h_proto == 0x8137 || h_proto == 0x80f3)
13530 + oui = P802_1H_OUI;
13532 + oui = RFC1042_OUI;
13533 + snap->oui[0] = oui[0];
13534 + snap->oui[1] = oui[1];
13535 + snap->oui[2] = oui[2];
13537 + *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
13539 + return SNAP_SIZE + sizeof(u16);
13542 +int ieee80211_encrypt_fragment(
13543 + struct ieee80211_device *ieee,
13544 + struct sk_buff *frag,
13547 + struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx];
13550 + /*added to care about null crypt condition, to solve that system hangs when shared keys error*/
13551 + if (!crypt || !crypt->ops)
13554 +#ifdef CONFIG_IEEE80211_CRYPT_TKIP
13555 + struct ieee80211_hdr *header;
13557 + if (ieee->tkip_countermeasures &&
13558 + crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
13559 + header = (struct ieee80211_hdr *) frag->data;
13560 + if (net_ratelimit()) {
13561 + printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
13562 + "TX packet to " MAC_FMT "\n",
13563 + ieee->dev->name, MAC_ARG(header->addr1));
13568 + /* To encrypt, frame format is:
13569 + * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */
13571 + // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption.
13572 + /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
13573 + * call both MSDU and MPDU encryption functions from here. */
13574 + atomic_inc(&crypt->refcnt);
13576 + if (crypt->ops->encrypt_msdu)
13577 + res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
13578 + if (res == 0 && crypt->ops->encrypt_mpdu)
13579 + res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
13581 + atomic_dec(&crypt->refcnt);
13583 + printk(KERN_INFO "%s: Encryption failed: len=%d.\n",
13584 + ieee->dev->name, frag->len);
13585 + ieee->ieee_stats.tx_discards++;
13593 +void ieee80211_txb_free(struct ieee80211_txb *txb) {
13595 + if (unlikely(!txb))
13597 + for (i = 0; i < txb->nr_frags; i++)
13598 + if (txb->fragments[i])
13599 + dev_kfree_skb_any(txb->fragments[i]);
13603 +struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
13606 + struct ieee80211_txb *txb;
13609 + sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags),
13614 + memset(txb, 0, sizeof(struct ieee80211_txb));
13615 + txb->nr_frags = nr_frags;
13616 + txb->frag_size = txb_size;
13618 + for (i = 0; i < nr_frags; i++) {
13619 + txb->fragments[i] = dev_alloc_skb(txb_size);
13620 + if (unlikely(!txb->fragments[i])) {
13625 + if (unlikely(i != nr_frags)) {
13627 + dev_kfree_skb_any(txb->fragments[i--]);
13634 +// Classify the to-be send data packet
13635 +// Need to acquire the sent queue index.
13637 +ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network)
13639 + struct ether_header *eh = (struct ether_header*)skb->data;
13640 + unsigned int wme_UP = 0;
13642 + if(!network->QoS_Enable) {
13643 + skb->priority = 0;
13647 + if(eh->ether_type == __constant_htons(ETHERTYPE_IP)) {
13648 + const struct iphdr *ih = (struct iphdr*)(skb->data + \
13649 + sizeof(struct ether_header));
13650 + wme_UP = (ih->tos >> 5)&0x07;
13651 + } else if (vlan_tx_tag_present(skb)) {//vtag packet
13652 +#ifndef VLAN_PRI_SHIFT
13653 +#define VLAN_PRI_SHIFT 13 /* Shift to find VLAN user priority */
13654 +#define VLAN_PRI_MASK 7 /* Mask for user priority bits in VLAN */
13656 + u32 tag = vlan_tx_tag_get(skb);
13657 + wme_UP = (tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK;
13658 + } else if(ETH_P_PAE == ntohs(((struct ethhdr *)skb->data)->h_proto)) {
13659 + //printk(KERN_WARNING "type = normal packet\n");
13663 + skb->priority = wme_UP;
13667 +#ifdef _RTL8187_EXT_PATCH_
13668 +// based on part of ieee80211_xmit. Mainly allocate txb. ieee->lock is held
13669 +struct ieee80211_txb *ieee80211_ext_alloc_txb(struct sk_buff *skb, struct net_device *dev, struct ieee80211_hdr_3addr *header, int hdr_len, u8 isQoS, u16 *pQOS_ctl, int isEncrypt, struct ieee80211_crypt_data* crypt)
13671 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
13672 + struct ieee80211_device *ieee = netdev_priv(dev);
13674 + struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
13676 + struct ieee80211_txb *txb = NULL;
13677 + struct ieee80211_hdr_3addr *frag_hdr;
13678 + int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
13680 + int bytes, QOS_ctl;
13681 + struct sk_buff *skb_frag;
13683 + ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
13685 + /* Advance the SKB to the start of the payload */
13686 + skb_pull(skb, sizeof(struct ethhdr));
13688 + /* Determine total amount of storage required for TXB packets */
13689 + bytes = skb->len + SNAP_SIZE + sizeof(u16);
13691 + /* Determine fragmentation size based on destination (multicast
13692 + * and broadcast are not fragmented) */
13693 + // if (is_multicast_ether_addr(dest) ||
13694 + // is_broadcast_ether_addr(dest)) {
13695 + if (is_multicast_ether_addr(header->addr1) ||
13696 + is_broadcast_ether_addr(header->addr1)) {
13697 + frag_size = MAX_FRAG_THRESHOLD;
13698 + QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
13701 + //printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size);
13702 + frag_size = ieee->fts;//default:392
13707 + QOS_ctl |= skb->priority; //set in the ieee80211_classify
13708 + *pQOS_ctl = cpu_to_le16(QOS_ctl);
13710 + //printk(KERN_WARNING "header size = %d, QOS_ctl = %x\n", hdr_len,QOS_ctl);
13711 + /* Determine amount of payload per fragment. Regardless of if
13712 + * this stack is providing the full 802.11 header, one will
13713 + * eventually be affixed to this fragment -- so we must account for
13714 + * it when determining the amount of payload space. */
13715 + //bytes_per_frag = frag_size - (IEEE80211_3ADDR_LEN + (ieee->current_network->QoS_Enable ? 2:0));
13716 + bytes_per_frag = frag_size - hdr_len;
13717 + if (ieee->config &
13718 + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
13719 + bytes_per_frag -= IEEE80211_FCS_LEN;
13721 + /* Each fragment may need to have room for encryptiong pre/postfix */
13723 + bytes_per_frag -= crypt->ops->extra_prefix_len +
13724 + crypt->ops->extra_postfix_len;
13726 + /* Number of fragments is the total bytes_per_frag /
13727 + * payload_per_fragment */
13728 + nr_frags = bytes / bytes_per_frag;
13729 + bytes_last_frag = bytes % bytes_per_frag;
13730 + if (bytes_last_frag)
13733 + bytes_last_frag = bytes_per_frag;
13735 + /* When we allocate the TXB we allocate enough space for the reserve
13736 + * and full fragment bytes (bytes_per_frag doesn't include prefix,
13737 + * postfix, header, FCS, etc.) */
13738 + txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
13739 + if (unlikely(!txb)) {
13740 + printk(KERN_WARNING "%s: Could not allocate TXB\n",
13741 + ieee->dev->name);
13744 + txb->encrypted = isEncrypt;
13745 + txb->payload_size = bytes;
13747 + for (i = 0; i < nr_frags; i++) {
13748 + skb_frag = txb->fragments[i];
13749 + skb_frag->priority = UP2AC(skb->priority);
13751 + skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
13753 + frag_hdr = (struct ieee80211_hdr_3addr *)skb_put(skb_frag, hdr_len);
13754 + memcpy(frag_hdr, (void *)header, hdr_len);
13756 + /* If this is not the last fragment, then add the MOREFRAGS
13757 + * bit to the frame control */
13758 + if (i != nr_frags - 1) {
13759 + frag_hdr->frame_ctl = cpu_to_le16(
13760 + header->frame_ctl | IEEE80211_FCTL_MOREFRAGS);
13761 + bytes = bytes_per_frag;
13764 + /* The last fragment takes the remaining length */
13765 + bytes = bytes_last_frag;
13768 + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
13769 + //frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl<<4 | i);
13772 + /* Put a SNAP header on the first fragment */
13774 + ieee80211_put_snap(
13775 + skb_put(skb_frag, SNAP_SIZE + sizeof(u16)), ether_type);
13776 + bytes -= SNAP_SIZE + sizeof(u16);
13779 + memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
13781 + /* Advance the SKB... */
13782 + skb_pull(skb, bytes);
13784 + /* Encryption routine will move the header forward in order
13785 + * to insert the IV between the header and the payload */
13787 + ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
13788 + if (ieee->config &
13789 + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
13790 + skb_put(skb_frag, 4);
13792 + // Advance sequence number in data frame.
13793 + //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
13794 + if (ieee->seq_ctrl[0] == 0xFFF)
13795 + ieee->seq_ctrl[0] = 0;
13797 + ieee->seq_ctrl[0]++;
13798 + // stanley, just for debug
13802 + for(j=0;j<nr_frags;j++)
13805 + struct sk_buff *skb = txb->fragments[j];
13806 + printk("send(%d): ", j);
13807 + for (i=0;i<skb->len;i++)
13808 + printk("%02X ", skb->data[i]&0xff);
13818 +// based on part of ieee80211_xmit. Mainly allocate txb. ieee->lock is held
13819 +// Assume no encryption, no FCS computing
13820 +struct ieee80211_txb *ieee80211_ext_reuse_txb(struct sk_buff *skb, struct net_device *dev, struct ieee80211_hdr_3addr *header, int hdr_len, u8 isQoS, u16 *pQOS_ctl, int isEncrypt, struct ieee80211_crypt_data* crypt)
13822 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
13823 + struct ieee80211_device *ieee = netdev_priv(dev);
13825 + struct ieee80211_device *ieee = (struct ieee80211_device *)dev->priv;
13827 + struct ieee80211_txb *txb = NULL;
13828 + struct ieee80211_hdr_3addr *frag_hdr;
13830 + int bytes, QOS_ctl;
13832 + ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
13834 + /* Advance the SKB to the start of the payload */
13835 + skb_pull(skb, sizeof(struct ethhdr));
13837 + /* Determine total amount of storage required for TXB packets */
13838 + bytes = skb->len + SNAP_SIZE + sizeof(u16);
13840 + if (is_multicast_ether_addr(header->addr1) ||
13841 + is_broadcast_ether_addr(header->addr1)) {
13842 + QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
13849 + QOS_ctl |= skb->priority; //set in the ieee80211_classify
13850 + *pQOS_ctl = cpu_to_le16(QOS_ctl);
13853 + txb = kmalloc( sizeof(struct ieee80211_txb) + sizeof(u8*), GFP_ATOMIC );
13854 + if (unlikely(!txb)) {
13855 + printk(KERN_WARNING "%s: Could not allocate TXB\n",
13856 + ieee->dev->name);
13860 + txb->nr_frags = 1;
13861 + txb->frag_size = bytes;
13862 + txb->encrypted = isEncrypt;
13863 + txb->payload_size = bytes;
13865 + txb->fragments[0] = skb;
13866 + ieee80211_put_snap(
13867 + skb_push(skb, SNAP_SIZE + sizeof(u16)), ether_type);
13868 + frag_hdr = (struct ieee80211_hdr_3addr *)skb_push(skb, hdr_len);
13869 + memcpy(frag_hdr, (void *)header, hdr_len);
13870 + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | 0);
13871 + skb->priority = UP2AC(skb->priority);
13873 + // Advance sequence number in data frame.
13874 + //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
13875 + if (ieee->seq_ctrl[0] == 0xFFF)
13876 + ieee->seq_ctrl[0] = 0;
13878 + ieee->seq_ctrl[0]++;
13883 +#endif // _RTL8187_EXT_PATCH_
13885 +/* SKBs are added to the ieee->tx_queue. */
13886 +int ieee80211_xmit(struct sk_buff *skb,
13887 + struct net_device *dev)
13889 + struct ieee80211_device *ieee = netdev_priv(dev);
13890 + struct ieee80211_txb *txb = NULL;
13891 + struct ieee80211_hdr_3addr_QOS *frag_hdr;
13892 + int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
13893 + unsigned long flags;
13894 + struct net_device_stats *stats = &ieee->stats;
13895 + int ether_type, encrypt;
13896 + int bytes, fc, QOS_ctl, hdr_len;
13897 + struct sk_buff *skb_frag;
13898 + //struct ieee80211_hdr header = { /* Ensure zero initialized */
13899 + // .duration_id = 0,
13902 + struct ieee80211_hdr_3addr_QOS header = { /* Ensure zero initialized */
13903 + .duration_id = 0,
13907 + u8 dest[ETH_ALEN], src[ETH_ALEN];
13909 + struct ieee80211_crypt_data* crypt;
13911 + //printk(KERN_WARNING "upper layer packet!\n");
13912 + spin_lock_irqsave(&ieee->lock, flags);
13914 + /* If there is no driver handler to take the TXB, dont' bother
13915 + * creating it... */
13916 + if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))||
13917 + ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
13918 + printk(KERN_WARNING "%s: No xmit handler.\n",
13919 + ieee->dev->name);
13923 + ieee80211_classify(skb,&ieee->current_network);
13924 + if(likely(ieee->raw_tx == 0)){
13926 + if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
13927 + printk(KERN_WARNING "%s: skb too small (%d).\n",
13928 + ieee->dev->name, skb->len);
13933 +#ifdef _RTL8187_EXT_PATCH_
13934 + // note, skb->priority which was set by ieee80211_classify, and used by physical tx
13935 + if((ieee->iw_mode == ieee->iw_ext_mode) && (ieee->ext_patch_ieee80211_xmit))
13937 + txb = ieee->ext_patch_ieee80211_xmit(skb, dev);
13942 + ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
13944 + crypt = ieee->crypt[ieee->tx_keyidx];
13946 + encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
13947 + ieee->host_encrypt && crypt && crypt->ops;
13949 + if (!encrypt && ieee->ieee802_1x &&
13950 + ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
13951 + stats->tx_dropped++;
13955 + #ifdef CONFIG_IEEE80211_DEBUG
13956 + if (crypt && !encrypt && ether_type == ETH_P_PAE) {
13957 + struct eapol *eap = (struct eapol *)(skb->data +
13958 + sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
13959 + IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
13960 + eap_get_type(eap->type));
13964 + /* Save source and destination addresses */
13965 + memcpy(&dest, skb->data, ETH_ALEN);
13966 + memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
13968 + /* Advance the SKB to the start of the payload */
13969 + skb_pull(skb, sizeof(struct ethhdr));
13971 + /* Determine total amount of storage required for TXB packets */
13972 + bytes = skb->len + SNAP_SIZE + sizeof(u16);
13974 + if(ieee->current_network.QoS_Enable) {
13976 + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA |
13977 + IEEE80211_FCTL_WEP;
13979 + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA;
13983 + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
13984 + IEEE80211_FCTL_WEP;
13986 + fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
13989 + if (ieee->iw_mode == IW_MODE_INFRA) {
13990 + fc |= IEEE80211_FCTL_TODS;
13991 + /* To DS: Addr1 = BSSID, Addr2 = SA,
13993 + memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
13994 + memcpy(&header.addr2, &src, ETH_ALEN);
13995 + memcpy(&header.addr3, &dest, ETH_ALEN);
13996 + } else if (ieee->iw_mode == IW_MODE_ADHOC) {
13997 + /* not From/To DS: Addr1 = DA, Addr2 = SA,
13999 + memcpy(&header.addr1, dest, ETH_ALEN);
14000 + memcpy(&header.addr2, src, ETH_ALEN);
14001 + memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
14003 + // printk(KERN_WARNING "essid MAC address is "MAC_FMT, MAC_ARG(&header.addr1));
14004 + header.frame_ctl = cpu_to_le16(fc);
14005 + //hdr_len = IEEE80211_3ADDR_LEN;
14007 + /* Determine fragmentation size based on destination (multicast
14008 + * and broadcast are not fragmented) */
14009 +// if (is_multicast_ether_addr(dest) ||
14010 +// is_broadcast_ether_addr(dest)) {
14011 + if (is_multicast_ether_addr(header.addr1) ||
14012 + is_broadcast_ether_addr(header.addr1)) {
14013 + frag_size = MAX_FRAG_THRESHOLD;
14014 + QOS_ctl = QOS_CTL_NOTCONTAIN_ACK;
14017 + //printk(KERN_WARNING "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&frag_size = %d\n", frag_size);
14018 + frag_size = ieee->fts;//default:392
14022 + if (ieee->current_network.QoS_Enable) {
14023 + hdr_len = IEEE80211_3ADDR_LEN + 2;
14024 + QOS_ctl |= skb->priority; //set in the ieee80211_classify
14025 + header.QOS_ctl = cpu_to_le16(QOS_ctl);
14027 + hdr_len = IEEE80211_3ADDR_LEN;
14029 + //printk(KERN_WARNING "header size = %d, QOS_ctl = %x\n", hdr_len,QOS_ctl);
14030 + /* Determine amount of payload per fragment. Regardless of if
14031 + * this stack is providing the full 802.11 header, one will
14032 + * eventually be affixed to this fragment -- so we must account for
14033 + * it when determining the amount of payload space. */
14034 + //bytes_per_frag = frag_size - (IEEE80211_3ADDR_LEN + (ieee->current_network->QoS_Enable ? 2:0));
14035 + bytes_per_frag = frag_size - hdr_len;
14036 + if (ieee->config &
14037 + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
14038 + bytes_per_frag -= IEEE80211_FCS_LEN;
14040 + /* Each fragment may need to have room for encryptiong pre/postfix */
14042 + bytes_per_frag -= crypt->ops->extra_prefix_len +
14043 + crypt->ops->extra_postfix_len;
14045 + /* Number of fragments is the total bytes_per_frag /
14046 + * payload_per_fragment */
14047 + nr_frags = bytes / bytes_per_frag;
14048 + bytes_last_frag = bytes % bytes_per_frag;
14049 + if (bytes_last_frag)
14052 + bytes_last_frag = bytes_per_frag;
14054 + /* When we allocate the TXB we allocate enough space for the reserve
14055 + * and full fragment bytes (bytes_per_frag doesn't include prefix,
14056 + * postfix, header, FCS, etc.) */
14057 + txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
14058 + if (unlikely(!txb)) {
14059 + printk(KERN_WARNING "%s: Could not allocate TXB\n",
14060 + ieee->dev->name);
14063 + txb->encrypted = encrypt;
14064 + txb->payload_size = bytes;
14066 + for (i = 0; i < nr_frags; i++) {
14067 + skb_frag = txb->fragments[i];
14068 + skb_frag->priority = UP2AC(skb->priority);
14070 + skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
14072 + frag_hdr = (struct ieee80211_hdr_3addr_QOS *)skb_put(skb_frag, hdr_len);
14073 + memcpy(frag_hdr, &header, hdr_len);
14075 + /* If this is not the last fragment, then add the MOREFRAGS
14076 + * bit to the frame control */
14077 + if (i != nr_frags - 1) {
14078 + frag_hdr->frame_ctl = cpu_to_le16(
14079 + fc | IEEE80211_FCTL_MOREFRAGS);
14080 + bytes = bytes_per_frag;
14083 + /* The last fragment takes the remaining length */
14084 + bytes = bytes_last_frag;
14086 + if(ieee->current_network.QoS_Enable) {
14087 + // add 1 only indicate to corresponding seq number control 2006/7/12
14088 + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
14089 + //printk(KERN_WARNING "skb->priority = %d,", skb->priority);
14090 + //printk(KERN_WARNING "type:%d: seq = %d\n",UP2AC(skb->priority),ieee->seq_ctrl[UP2AC(skb->priority)+1]);
14092 + frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i);
14094 + //frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl<<4 | i);
14097 + /* Put a SNAP header on the first fragment */
14099 + ieee80211_put_snap(
14100 + skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
14102 + bytes -= SNAP_SIZE + sizeof(u16);
14105 + memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
14107 + /* Advance the SKB... */
14108 + skb_pull(skb, bytes);
14110 + /* Encryption routine will move the header forward in order
14111 + * to insert the IV between the header and the payload */
14113 + ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
14114 + if (ieee->config &
14115 + (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
14116 + skb_put(skb_frag, 4);
14118 + // Advance sequence number in data frame.
14119 + //printk(KERN_WARNING "QoS Enalbed? %s\n", ieee->current_network.QoS_Enable?"Y":"N");
14120 + if (ieee->current_network.QoS_Enable) {
14121 + if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
14122 + ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
14124 + ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
14126 + if (ieee->seq_ctrl[0] == 0xFFF)
14127 + ieee->seq_ctrl[0] = 0;
14129 + ieee->seq_ctrl[0]++;
14133 + if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
14134 + printk(KERN_WARNING "%s: skb too small (%d).\n",
14135 + ieee->dev->name, skb->len);
14139 + txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
14141 + printk(KERN_WARNING "%s: Could not allocate TXB\n",
14142 + ieee->dev->name);
14146 + txb->encrypted = 0;
14147 + txb->payload_size = skb->len;
14148 + memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len);
14152 + spin_unlock_irqrestore(&ieee->lock, flags);
14153 +#ifdef _RTL8187_EXT_PATCH_
14154 + // Sometimes, extension mode can reuse skb (by txb->fragments[0])
14155 + if( ! ((ieee->iw_mode == ieee->iw_ext_mode) && txb && (txb->fragments[0] == skb)) )
14157 + dev_kfree_skb_any(skb);
14159 + if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){
14160 + ieee80211_softmac_xmit(txb, ieee);
14162 + if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
14163 + stats->tx_packets++;
14164 + stats->tx_bytes += txb->payload_size;
14167 + ieee80211_txb_free(txb);
14174 + spin_unlock_irqrestore(&ieee->lock, flags);
14175 + netif_stop_queue(dev);
14176 + stats->tx_errors++;
14182 +EXPORT_SYMBOL(ieee80211_txb_free);
14183 +#ifdef _RTL8187_EXT_PATCH_
14184 +EXPORT_SYMBOL(ieee80211_alloc_txb);
14185 +EXPORT_SYMBOL(ieee80211_ext_alloc_txb);
14186 +EXPORT_SYMBOL(ieee80211_ext_reuse_txb);
14187 +#endif // _RTL8187_EXT_PATCH_
14190 +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
14192 +/******************************************************************************
14194 + Copyright(c) 2004 Intel Corporation. All rights reserved.
14196 + Portions of this file are based on the WEP enablement code provided by the
14197 + Host AP project hostap-drivers v0.1.3
14198 + Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
14199 + <jkmaline@cc.hut.fi>
14200 + Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
14202 + This program is free software; you can redistribute it and/or modify it
14203 + under the terms of version 2 of the GNU General Public License as
14204 + published by the Free Software Foundation.
14206 + This program is distributed in the hope that it will be useful, but WITHOUT
14207 + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14208 + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14211 + You should have received a copy of the GNU General Public License along with
14212 + this program; if not, write to the Free Software Foundation, Inc., 59
14213 + Temple Place - Suite 330, Boston, MA 02111-1307, USA.
14215 + The full GNU General Public License is included in this distribution in the
14216 + file called LICENSE.
14218 + Contact Information:
14219 + James P. Ketrenos <ipw2100-admin@linux.intel.com>
14220 + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
14222 +******************************************************************************/
14223 +#include <linux/wireless.h>
14224 +#include <linux/version.h>
14225 +#include <linux/kmod.h>
14226 +#include <linux/module.h>
14228 +#include "ieee80211.h"
14229 +static const char *ieee80211_modes[] = {
14230 + "?", "a", "b", "ab", "g", "ag", "bg", "abg"
14233 +#ifdef FEDORACORE_9
14234 +#define IN_FEDORACORE_9 1
14236 +#define IN_FEDORACORE_9 0
14239 +#define MAX_CUSTOM_LEN 64
14240 +static inline char *rtl818x_translate_scan(struct ieee80211_device *ieee,
14241 + char *start, char *stop,
14242 + struct ieee80211_network *network,
14243 + struct iw_request_info *info)
14245 + char custom[MAX_CUSTOM_LEN];
14247 + struct iw_event iwe;
14249 + u8 max_rate, rate;
14251 + /* First entry *MUST* be the AP MAC address */
14252 + iwe.cmd = SIOCGIWAP;
14253 + iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
14254 + memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
14255 +#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
14256 + start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
14258 + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
14261 + /* Remaining entries will be displayed in the order we provide them */
14263 + /* Add the ESSID */
14264 + iwe.cmd = SIOCGIWESSID;
14265 + iwe.u.data.flags = 1;
14266 + //YJ,modified,080903,for hidden ap
14267 + //if (network->flags & NETWORK_EMPTY_ESSID) {
14268 + if (network->ssid_len == 0) {
14269 + //YJ,modified,080903,end
14270 + iwe.u.data.length = sizeof("<hidden>");
14271 +#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
14272 + start = iwe_stream_add_point(info, start, stop, &iwe, "<hidden>");
14274 + start = iwe_stream_add_point(start, stop, &iwe, "<hidden>");
14277 + iwe.u.data.length = min(network->ssid_len, (u8)32);
14278 +#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
14279 + start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
14281 + start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
14284 + //printk("ESSID: %s\n",network->ssid);
14285 + /* Add the protocol name */
14286 + iwe.cmd = SIOCGIWNAME;
14287 + snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s", ieee80211_modes[network->mode]);
14288 +#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
14289 + start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
14291 + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_CHAR_LEN);
14295 + iwe.cmd = SIOCGIWMODE;
14296 + if (network->capability &
14297 + (WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) {
14298 + if (network->capability & WLAN_CAPABILITY_BSS)
14299 + iwe.u.mode = IW_MODE_MASTER;
14301 + iwe.u.mode = IW_MODE_ADHOC;
14303 +#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
14304 + start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
14306 + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN);
14310 + /* Add frequency/channel */
14311 + iwe.cmd = SIOCGIWFREQ;
14312 +/* iwe.u.freq.m = ieee80211_frequency(network->channel, network->mode);
14313 + iwe.u.freq.e = 3; */
14314 + iwe.u.freq.m = network->channel;
14315 + iwe.u.freq.e = 0;
14316 + iwe.u.freq.i = 0;
14317 +#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
14318 + start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
14320 + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
14323 + /* Add encryption capability */
14324 + iwe.cmd = SIOCGIWENCODE;
14325 + if (network->capability & WLAN_CAPABILITY_PRIVACY)
14326 + iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
14328 + iwe.u.data.flags = IW_ENCODE_DISABLED;
14329 + iwe.u.data.length = 0;
14330 +#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
14331 + start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
14333 + start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
14336 + /* Add basic and extended rates */
14339 + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
14340 + for (i = 0, j = 0; i < network->rates_len; ) {
14341 + if (j < network->rates_ex_len &&
14342 + ((network->rates_ex[j] & 0x7F) <
14343 + (network->rates[i] & 0x7F)))
14344 + rate = network->rates_ex[j++] & 0x7F;
14346 + rate = network->rates[i++] & 0x7F;
14347 + if (rate > max_rate)
14349 + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
14350 + "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
14352 + for (; j < network->rates_ex_len; j++) {
14353 + rate = network->rates_ex[j] & 0x7F;
14354 + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
14355 + "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
14356 + if (rate > max_rate)
14360 + iwe.cmd = SIOCGIWRATE;
14361 + iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
14362 + iwe.u.bitrate.value = max_rate * 500000;
14363 +#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
14364 + start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN);
14366 + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_PARAM_LEN);
14369 + iwe.cmd = IWEVCUSTOM;
14370 + iwe.u.data.length = p - custom;
14371 + if (iwe.u.data.length)
14372 +#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
14373 + start = iwe_stream_add_point(info, start, stop, &iwe, custom);
14375 + start = iwe_stream_add_point(start, stop, &iwe, custom);
14378 + /* Add quality statistics */
14379 + /* TODO: Fix these values... */
14380 + if (network->stats.signal == 0 || network->stats.rssi == 0)
14381 + printk("========>signal:%d, rssi:%d\n", network->stats.signal, network->stats.rssi);
14382 + iwe.cmd = IWEVQUAL;
14383 +// printk("SIGNAL: %d,RSSI: %d,NOISE: %d\n",network->stats.signal,network->stats.rssi,network->stats.noise);
14384 + iwe.u.qual.qual = network->stats.signalstrength;
14385 + iwe.u.qual.level = network->stats.signal;
14386 + iwe.u.qual.noise = network->stats.noise;
14387 + iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK;
14388 + if (!(network->stats.mask & IEEE80211_STATMASK_RSSI))
14389 + iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
14390 + if (!(network->stats.mask & IEEE80211_STATMASK_NOISE))
14391 + iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
14392 + if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
14393 + iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
14394 + iwe.u.qual.updated = 7;
14395 +#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
14396 + start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
14398 + start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
14401 + iwe.cmd = IWEVCUSTOM;
14404 + iwe.u.data.length = p - custom;
14405 + if (iwe.u.data.length)
14406 +#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
14407 + start = iwe_stream_add_point(info, start, stop, &iwe, custom);
14409 + start = iwe_stream_add_point(start, stop, &iwe, custom);
14413 + if (ieee->wpa_enabled && network->wpa_ie_len){
14414 + char buf[MAX_WPA_IE_LEN * 2 + 30];
14415 + // printk("WPA IE\n");
14417 + p += sprintf(p, "wpa_ie=");
14418 + for (i = 0; i < network->wpa_ie_len; i++) {
14419 + p += sprintf(p, "%02x", network->wpa_ie[i]);
14422 + memset(&iwe, 0, sizeof(iwe));
14423 + iwe.cmd = IWEVCUSTOM;
14424 + iwe.u.data.length = strlen(buf);
14425 +#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
14426 + start = iwe_stream_add_point(info, start, stop, &iwe, buf);
14428 + start = iwe_stream_add_point(start, stop, &iwe, buf);
14432 + if (ieee->wpa_enabled && network->rsn_ie_len){
14433 + char buf[MAX_WPA_IE_LEN * 2 + 30];
14436 + p += sprintf(p, "rsn_ie=");
14437 + for (i = 0; i < network->rsn_ie_len; i++) {
14438 + p += sprintf(p, "%02x", network->rsn_ie[i]);
14443 + memset(&iwe, 0, sizeof(iwe));
14444 + if (network->wpa_ie_len) {
14445 + // printk("wpa_ie_len:%d\n", network->wpa_ie_len);
14446 + char buf[MAX_WPA_IE_LEN];
14447 + memcpy(buf, network->wpa_ie, network->wpa_ie_len);
14448 + iwe.cmd = IWEVGENIE;
14449 + iwe.u.data.length = network->wpa_ie_len;
14450 +#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
14451 + start = iwe_stream_add_point(info, start, stop, &iwe, buf);
14453 + start = iwe_stream_add_point(start, stop, &iwe, buf);
14457 + memset(&iwe, 0, sizeof(iwe));
14458 + if (network->rsn_ie_len) {
14459 + // printk("=====>rsn_ie_len:\n", network->rsn_ie_len);
14463 + for (i=0; i<network->rsn_ie_len; i++);
14464 + printk("%2x ", network->rsn_ie[i]);
14468 + char buf[MAX_WPA_IE_LEN];
14469 + memcpy(buf, network->rsn_ie, network->rsn_ie_len);
14470 + iwe.cmd = IWEVGENIE;
14471 + iwe.u.data.length = network->rsn_ie_len;
14472 +#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
14473 + start = iwe_stream_add_point(info, start, stop, &iwe, buf);
14475 + start = iwe_stream_add_point(start, stop, &iwe, buf);
14481 + /* Add EXTRA: Age to display seconds since last beacon/probe response
14482 + * for given network. */
14483 + iwe.cmd = IWEVCUSTOM;
14485 + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
14486 + " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100));
14487 + iwe.u.data.length = p - custom;
14488 + if (iwe.u.data.length)
14489 +#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))||IN_FEDORACORE_9)
14490 + start = iwe_stream_add_point(info, start, stop, &iwe, custom);
14492 + start = iwe_stream_add_point(start, stop, &iwe, custom);
14498 +int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
14499 + struct iw_request_info *info,
14500 + union iwreq_data *wrqu, char *extra)
14502 + struct ieee80211_network *network;
14503 + unsigned long flags;
14505 + char *ev = extra;
14506 + char *stop = ev + wrqu->data.length;//IW_SCAN_MAX_DATA;
14507 + //char *stop = ev + IW_SCAN_MAX_DATA;
14510 + IEEE80211_DEBUG_WX("Getting scan\n");
14511 + down(&ieee->wx_sem);
14512 + spin_lock_irqsave(&ieee->lock, flags);
14514 + if(!ieee->bHwRadioOff)
14516 + list_for_each_entry(network, &ieee->network_list, list) {
14519 + if((stop-ev)<200)
14524 + if (ieee->scan_age == 0 ||
14525 + time_after(network->last_scanned + ieee->scan_age, jiffies))
14527 + ev = rtl818x_translate_scan(ieee, ev, stop, network, info);
14530 + IEEE80211_DEBUG_SCAN(
14531 + "Not showing network '%s ("
14532 + MAC_FMT ")' due to age (%lums).\n",
14533 + escape_essid(network->ssid,
14534 + network->ssid_len),
14535 + MAC_ARG(network->bssid),
14536 + (jiffies - network->last_scanned) / (HZ / 100));
14539 + spin_unlock_irqrestore(&ieee->lock, flags);
14540 + up(&ieee->wx_sem);
14541 + wrqu->data.length = ev - extra;
14542 + wrqu->data.flags = 0;
14543 + IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
14548 +int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
14549 + struct iw_request_info *info,
14550 + union iwreq_data *wrqu, char *keybuf)
14552 + struct iw_point *erq = &(wrqu->encoding);
14553 + struct net_device *dev = ieee->dev;
14554 + struct ieee80211_security sec = {
14557 + int i, key, key_provided, len;
14558 + struct ieee80211_crypt_data **crypt;
14560 + IEEE80211_DEBUG_WX("SET_ENCODE\n");
14562 + key = erq->flags & IW_ENCODE_INDEX;
14564 + if (key > WEP_KEYS)
14567 + key_provided = 1;
14569 + key_provided = 0;
14570 + key = ieee->tx_keyidx;
14573 + IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
14574 + "provided" : "default");
14576 + crypt = &ieee->crypt[key];
14578 + if (erq->flags & IW_ENCODE_DISABLED) {
14579 + if (key_provided && *crypt) {
14580 + IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
14582 + ieee80211_crypt_delayed_deinit(ieee, crypt);
14584 + IEEE80211_DEBUG_WX("Disabling encryption.\n");
14586 + /* Check all the keys to see if any are still configured,
14587 + * and if no key index was provided, de-init them all */
14588 + for (i = 0; i < WEP_KEYS; i++) {
14589 + if (ieee->crypt[i] != NULL) {
14590 + if (key_provided)
14592 + ieee80211_crypt_delayed_deinit(
14593 + ieee, &ieee->crypt[i]);
14597 + if (i == WEP_KEYS) {
14599 + sec.level = SEC_LEVEL_0;
14600 + sec.flags |= SEC_ENABLED | SEC_LEVEL;
14609 + sec.flags |= SEC_ENABLED;
14611 + if (*crypt != NULL && (*crypt)->ops != NULL &&
14612 + strcmp((*crypt)->ops->name, "WEP") != 0) {
14613 + /* changing to use WEP; deinit previously used algorithm
14615 + ieee80211_crypt_delayed_deinit(ieee, crypt);
14618 + if (*crypt == NULL) {
14619 + struct ieee80211_crypt_data *new_crypt;
14621 + /* take WEP into use */
14622 + new_crypt = kmalloc(sizeof(struct ieee80211_crypt_data),
14624 + if (new_crypt == NULL)
14626 + memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
14627 + new_crypt->ops = ieee80211_get_crypto_ops("WEP");
14628 + if (!new_crypt->ops) {
14629 + request_module("ieee80211_crypt_wep");
14630 + new_crypt->ops = ieee80211_get_crypto_ops("WEP");
14633 + if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
14634 + new_crypt->priv = new_crypt->ops->init(key);
14636 + if (!new_crypt->ops || !new_crypt->priv) {
14637 + kfree(new_crypt);
14638 + new_crypt = NULL;
14640 + printk(KERN_WARNING "%s: could not initialize WEP: "
14641 + "load module ieee80211_crypt_wep\n",
14643 + return -EOPNOTSUPP;
14645 + *crypt = new_crypt;
14648 + /* If a new key was provided, set it up */
14649 + if (erq->length > 0) {
14650 + len = erq->length <= 5 ? 5 : 13;
14651 + memcpy(sec.keys[key], keybuf, erq->length);
14652 + if (len > erq->length)
14653 + memset(sec.keys[key] + erq->length, 0,
14654 + len - erq->length);
14655 + IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
14656 + key, escape_essid(sec.keys[key], len),
14657 + erq->length, len);
14658 + sec.key_sizes[key] = len;
14659 + (*crypt)->ops->set_key(sec.keys[key], len, NULL,
14661 + sec.flags |= (1 << key);
14662 + /* This ensures a key will be activated if no key is
14663 + * explicitely set */
14664 + if (key == sec.active_key)
14665 + sec.flags |= SEC_ACTIVE_KEY;
14666 + ieee->tx_keyidx = key;//by wb 080312
14668 + len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
14669 + NULL, (*crypt)->priv);
14671 + /* Set a default key of all 0 */
14672 + IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
14674 + memset(sec.keys[key], 0, 13);
14675 + (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
14677 + sec.key_sizes[key] = 13;
14678 + sec.flags |= (1 << key);
14681 + /* No key data - just set the default TX key index */
14682 + if (key_provided) {
14683 + IEEE80211_DEBUG_WX(
14684 + "Setting key %d to default Tx key.\n", key);
14685 + ieee->tx_keyidx = key;
14686 + sec.active_key = key;
14687 + sec.flags |= SEC_ACTIVE_KEY;
14692 + ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
14693 + sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
14694 + sec.flags |= SEC_AUTH_MODE;
14695 + IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
14696 + "OPEN" : "SHARED KEY");
14698 + /* For now we just support WEP, so only set that security level...
14699 + * TODO: When WPA is added this is one place that needs to change */
14700 + sec.flags |= SEC_LEVEL;
14701 + sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
14703 + if (ieee->set_security)
14704 + ieee->set_security(dev, &sec);
14706 + /* Do not reset port if card is in Managed mode since resetting will
14707 + * generate new IEEE 802.11 authentication which may end up in looping
14708 + * with IEEE 802.1X. If your hardware requires a reset after WEP
14709 + * configuration (for example... Prism2), implement the reset_port in
14710 + * the callbacks structures used to initialize the 802.11 stack. */
14711 + if (ieee->reset_on_keychange &&
14712 + ieee->iw_mode != IW_MODE_INFRA &&
14713 + ieee->reset_port && ieee->reset_port(dev)) {
14714 + printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);
14720 +int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
14721 + struct iw_request_info *info,
14722 + union iwreq_data *wrqu, char *keybuf)
14724 + struct iw_point *erq = &(wrqu->encoding);
14726 + struct ieee80211_crypt_data *crypt;
14728 + IEEE80211_DEBUG_WX("GET_ENCODE\n");
14730 + if(ieee->iw_mode == IW_MODE_MONITOR)
14733 + key = erq->flags & IW_ENCODE_INDEX;
14735 + if (key > WEP_KEYS)
14739 + key = ieee->tx_keyidx;
14741 + crypt = ieee->crypt[key];
14742 + erq->flags = key + 1;
14744 + if (crypt == NULL || crypt->ops == NULL) {
14746 + erq->flags |= IW_ENCODE_DISABLED;
14750 + if (strcmp(crypt->ops->name, "WEP") != 0) {
14751 + /* only WEP is supported with wireless extensions, so just
14752 + * report that encryption is used */
14754 + erq->flags |= IW_ENCODE_ENABLED;
14758 + len = crypt->ops->get_key(keybuf, WEP_KEY_LEN, NULL, crypt->priv);
14759 + erq->length = (len >= 0 ? len : 0);
14761 + erq->flags |= IW_ENCODE_ENABLED;
14763 + if (ieee->open_wep)
14764 + erq->flags |= IW_ENCODE_OPEN;
14766 + erq->flags |= IW_ENCODE_RESTRICTED;
14771 +int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
14772 + struct iw_request_info *info,
14773 + union iwreq_data *wrqu, char *extra)
14775 + struct net_device *dev = ieee->dev;
14776 + struct iw_point *encoding = &wrqu->encoding;
14777 + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
14778 + int i, idx, ret = 0;
14779 + int group_key = 0;
14780 + const char *alg, *module;
14781 + struct ieee80211_crypto_ops *ops;
14782 + struct ieee80211_crypt_data **crypt;
14784 + struct ieee80211_security sec = {
14787 + //printk("======>encoding flag:%x,ext flag:%x, ext alg:%d\n", encoding->flags,ext->ext_flags, ext->alg);
14788 + idx = encoding->flags & IW_ENCODE_INDEX;
14790 + if (idx < 1 || idx > WEP_KEYS)
14794 + idx = ieee->tx_keyidx;
14796 + if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
14797 + crypt = &ieee->crypt[idx];
14800 + /* some Cisco APs use idx>0 for unicast in dynamic WEP */
14801 + //printk("not group key, flags:%x, ext->alg:%d\n", ext->ext_flags, ext->alg);
14802 + if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
14804 + if (ieee->iw_mode == IW_MODE_INFRA)
14805 + crypt = &ieee->crypt[idx];
14810 + sec.flags |= SEC_ENABLED;// | SEC_ENCRYPT;
14811 + if ((encoding->flags & IW_ENCODE_DISABLED) ||
14812 + ext->alg == IW_ENCODE_ALG_NONE) {
14814 + ieee80211_crypt_delayed_deinit(ieee, crypt);
14816 + for (i = 0; i < WEP_KEYS; i++)
14817 + if (ieee->crypt[i] != NULL)
14820 + if (i == WEP_KEYS) {
14822 + // sec.encrypt = 0;
14823 + sec.level = SEC_LEVEL_0;
14824 + sec.flags |= SEC_LEVEL;
14826 + //printk("disabled: flag:%x\n", encoding->flags);
14831 + // sec.encrypt = 1;
14833 + if (group_key ? !ieee->host_mc_decrypt :
14834 + !(ieee->host_encrypt || ieee->host_decrypt ||
14835 + ieee->host_encrypt_msdu))
14836 + goto skip_host_crypt;
14838 + switch (ext->alg) {
14839 + case IW_ENCODE_ALG_WEP:
14841 + module = "ieee80211_crypt_wep";
14843 + case IW_ENCODE_ALG_TKIP:
14845 + module = "ieee80211_crypt_tkip";
14847 + case IW_ENCODE_ALG_CCMP:
14849 + module = "ieee80211_crypt_ccmp";
14852 + IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
14853 + dev->name, ext->alg);
14857 +// printk("8-09-08-9=====>%s, alg name:%s\n",__FUNCTION__, alg);
14859 + ops = ieee80211_get_crypto_ops(alg);
14860 + if (ops == NULL) {
14861 + request_module(module);
14862 + ops = ieee80211_get_crypto_ops(alg);
14864 + if (ops == NULL) {
14865 + IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
14866 + dev->name, ext->alg);
14867 + printk("========>unknown crypto alg %d\n", ext->alg);
14872 + if (*crypt == NULL || (*crypt)->ops != ops) {
14873 + struct ieee80211_crypt_data *new_crypt;
14875 + ieee80211_crypt_delayed_deinit(ieee, crypt);
14877 + new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
14878 + if (new_crypt == NULL) {
14882 + new_crypt->ops = ops;
14883 + if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
14884 + new_crypt->priv = new_crypt->ops->init(idx);
14885 + if (new_crypt->priv == NULL) {
14886 + kfree(new_crypt);
14890 + *crypt = new_crypt;
14894 + if (ext->key_len > 0 && (*crypt)->ops->set_key &&
14895 + (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
14896 + (*crypt)->priv) < 0) {
14897 + IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
14898 + printk("key setting failed\n");
14903 + //skip_host_crypt:
14904 + //printk("skip_host_crypt:ext_flags:%x\n", ext->ext_flags);
14905 + if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
14906 + ieee->tx_keyidx = idx;
14907 + sec.active_key = idx;
14908 + sec.flags |= SEC_ACTIVE_KEY;
14911 + if (ext->alg != IW_ENCODE_ALG_NONE) {
14912 + memcpy(sec.keys[idx], ext->key, ext->key_len);
14913 + sec.key_sizes[idx] = ext->key_len;
14914 + sec.flags |= (1 << idx);
14915 + if (ext->alg == IW_ENCODE_ALG_WEP) {
14916 + // sec.encode_alg[idx] = SEC_ALG_WEP;
14917 + sec.flags |= SEC_LEVEL;
14918 + sec.level = SEC_LEVEL_1;
14919 + } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
14920 + // sec.encode_alg[idx] = SEC_ALG_TKIP;
14921 + sec.flags |= SEC_LEVEL;
14922 + sec.level = SEC_LEVEL_2;
14923 + } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
14924 + // sec.encode_alg[idx] = SEC_ALG_CCMP;
14925 + sec.flags |= SEC_LEVEL;
14926 + sec.level = SEC_LEVEL_3;
14928 + /* Don't set sec level for group keys. */
14930 + sec.flags &= ~SEC_LEVEL;
14934 + if (ieee->set_security)
14935 + ieee->set_security(ieee->dev, &sec);
14937 + if (ieee->reset_on_keychange &&
14938 + ieee->iw_mode != IW_MODE_INFRA &&
14939 + ieee->reset_port && ieee->reset_port(dev)) {
14940 + IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
14946 +int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
14947 + struct iw_request_info *info,
14948 + union iwreq_data *wrqu, char *extra)
14950 + struct iw_mlme *mlme = (struct iw_mlme *) extra;
14951 +// printk("\ndkgadfslkdjgalskdf===============>%s(), cmd:%x\n", __FUNCTION__, mlme->cmd);
14953 + switch (mlme->cmd) {
14954 + case IW_MLME_DEAUTH:
14955 + case IW_MLME_DISASSOC:
14956 + // printk("disassoc now\n");
14957 + ieee80211_disassociate(ieee);
14960 + return -EOPNOTSUPP;
14966 +int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
14967 + struct iw_request_info *info,
14968 + struct iw_param *data, char *extra)
14971 + struct ieee80211_security sec = {
14972 + .flags = SEC_AUTH_MODE,
14975 + //printk("set auth:flag:%x, data value:%x\n", data->flags, data->value);
14976 + switch (data->flags & IW_AUTH_INDEX) {
14977 + case IW_AUTH_WPA_VERSION:
14978 + /*need to support wpa2 here*/
14979 + //printk("wpa version:%x\n", data->value);
14981 + case IW_AUTH_CIPHER_PAIRWISE:
14982 + case IW_AUTH_CIPHER_GROUP:
14983 + case IW_AUTH_KEY_MGMT:
14985 + * * Host AP driver does not use these parameters and allows
14986 + * * wpa_supplicant to control them internally.
14989 + case IW_AUTH_TKIP_COUNTERMEASURES:
14990 + ieee->tkip_countermeasures = data->value;
14992 + case IW_AUTH_DROP_UNENCRYPTED:
14993 + ieee->drop_unencrypted = data->value;
14996 + case IW_AUTH_80211_AUTH_ALG:
14997 + ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM)?1:0;
14998 + //printk("open_wep:%d\n", ieee->open_wep);
15002 + case IW_AUTH_WPA_ENABLED:
15003 + ieee->wpa_enabled = (data->value)?1:0;
15004 + //printk("enalbe wpa:%d\n", ieee->wpa_enabled);
15008 + case IW_AUTH_RX_UNENCRYPTED_EAPOL:
15009 + ieee->ieee802_1x = data->value;
15011 + case IW_AUTH_PRIVACY_INVOKED:
15012 + ieee->privacy_invoked = data->value;
15015 + return -EOPNOTSUPP;
15021 +int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
15024 + printk("====>%s()\n", __FUNCTION__);
15027 + for (i=0; i<len; i++)
15028 + printk("%2x ", ie[i]&0xff);
15034 + if (len>MAX_WPA_IE_LEN || (len && ie == NULL))
15036 + printk("return error out, len:%d\n", len);
15042 + if (len != ie[1]+2){
15043 + printk("len:%d, ie:%d\n", len, ie[1]);
15046 + buf = kmalloc(len, GFP_KERNEL);
15049 + memcpy(buf, ie, len);
15050 + kfree(ieee->wpa_ie);
15051 + ieee->wpa_ie = buf;
15052 + ieee->wpa_ie_len = len;
15055 + if (ieee->wpa_ie)
15056 + kfree(ieee->wpa_ie);
15057 + ieee->wpa_ie = NULL;
15058 + ieee->wpa_ie_len = 0;
15060 +// printk("<=====out %s()\n", __FUNCTION__);
15068 +EXPORT_SYMBOL(ieee80211_wx_set_gen_ie);
15069 +EXPORT_SYMBOL(ieee80211_wx_set_mlme);
15070 +EXPORT_SYMBOL(ieee80211_wx_set_auth);
15071 +EXPORT_SYMBOL(ieee80211_wx_set_encode_ext);
15072 +EXPORT_SYMBOL(ieee80211_wx_get_scan);
15073 +EXPORT_SYMBOL(ieee80211_wx_set_encode);
15074 +EXPORT_SYMBOL(ieee80211_wx_get_encode);
15077 +++ b/drivers/staging/rtl8187se/ieee80211/internal.h
15080 + * Cryptographic API.
15082 + * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
15084 + * This program is free software; you can redistribute it and/or modify it
15085 + * under the terms of the GNU General Public License as published by the Free
15086 + * Software Foundation; either version 2 of the License, or (at your option)
15087 + * any later version.
15090 +#ifndef _CRYPTO_INTERNAL_H
15091 +#define _CRYPTO_INTERNAL_H
15094 +//#include <linux/crypto.h>
15095 +#include "rtl_crypto.h"
15096 +#include <linux/mm.h>
15097 +#include <linux/highmem.h>
15098 +#include <linux/init.h>
15099 +#include <asm/hardirq.h>
15100 +#include <asm/softirq.h>
15101 +#include <asm/kmap_types.h>
15103 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,20))
15104 +#define list_for_each_entry(pos, head, member) \
15105 + for (pos = list_entry((head)->next, typeof(*pos), member), \
15106 + prefetch(pos->member.next); \
15107 + &pos->member != (head); \
15108 + pos = list_entry(pos->member.next, typeof(*pos), member), \
15109 + prefetch(pos->member.next))
15111 +static inline void cond_resched(void)
15113 + if (need_resched()) {
15114 + set_current_state(TASK_RUNNING);
15120 +extern enum km_type crypto_km_types[];
15122 +static inline enum km_type crypto_kmap_type(int out)
15124 + return crypto_km_types[(in_softirq() ? 2 : 0) + out];
15127 +static inline void *crypto_kmap(struct page *page, int out)
15129 + return kmap_atomic(page, crypto_kmap_type(out));
15132 +static inline void crypto_kunmap(void *vaddr, int out)
15134 + kunmap_atomic(vaddr, crypto_kmap_type(out));
15137 +static inline void crypto_yield(struct crypto_tfm *tfm)
15139 + if (!in_softirq())
15143 +static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm)
15145 + return (void *)&tfm[1];
15148 +struct crypto_alg *crypto_alg_lookup(const char *name);
15150 +#ifdef CONFIG_KMOD
15151 +void crypto_alg_autoload(const char *name);
15152 +struct crypto_alg *crypto_alg_mod_lookup(const char *name);
15154 +static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name)
15156 + return crypto_alg_lookup(name);
15160 +#ifdef CONFIG_CRYPTO_HMAC
15161 +int crypto_alloc_hmac_block(struct crypto_tfm *tfm);
15162 +void crypto_free_hmac_block(struct crypto_tfm *tfm);
15164 +static inline int crypto_alloc_hmac_block(struct crypto_tfm *tfm)
15169 +static inline void crypto_free_hmac_block(struct crypto_tfm *tfm)
15173 +#ifdef CONFIG_PROC_FS
15174 +void __init crypto_init_proc(void);
15176 +static inline void crypto_init_proc(void)
15180 +int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags);
15181 +int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags);
15182 +int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags);
15184 +int crypto_init_digest_ops(struct crypto_tfm *tfm);
15185 +int crypto_init_cipher_ops(struct crypto_tfm *tfm);
15186 +int crypto_init_compress_ops(struct crypto_tfm *tfm);
15188 +void crypto_exit_digest_ops(struct crypto_tfm *tfm);
15189 +void crypto_exit_cipher_ops(struct crypto_tfm *tfm);
15190 +void crypto_exit_compress_ops(struct crypto_tfm *tfm);
15192 +#endif /* _CRYPTO_INTERNAL_H */
15195 +++ b/drivers/staging/rtl8187se/ieee80211/rtl_crypto.h
15198 + * Scatterlist Cryptographic API.
15200 + * Copyright (c) 2002 James Morris <jmorris@intercode.com.au>
15201 + * Copyright (c) 2002 David S. Miller (davem@redhat.com)
15203 + * Portions derived from Cryptoapi, by Alexander Kjeldaas <astor@fast.no>
15204 + * and Nettle, by Niels Mé°ˆler.
15206 + * This program is free software; you can redistribute it and/or modify it
15207 + * under the terms of the GNU General Public License as published by the Free
15208 + * Software Foundation; either version 2 of the License, or (at your option)
15209 + * any later version.
15212 +#ifndef _LINUX_CRYPTO_H
15213 +#define _LINUX_CRYPTO_H
15215 +#include <linux/module.h>
15216 +#include <linux/kernel.h>
15217 +#include <linux/types.h>
15218 +#include <linux/list.h>
15219 +#include <linux/string.h>
15220 +#include <asm/page.h>
15221 +#include <asm/errno.h>
15223 +#define crypto_register_alg crypto_register_alg_rtl
15224 +#define crypto_unregister_alg crypto_unregister_alg_rtl
15225 +#define crypto_alloc_tfm crypto_alloc_tfm_rtl
15226 +#define crypto_free_tfm crypto_free_tfm_rtl
15227 +#define crypto_alg_available crypto_alg_available_rtl
15230 + * Algorithm masks and types.
15232 +#define CRYPTO_ALG_TYPE_MASK 0x000000ff
15233 +#define CRYPTO_ALG_TYPE_CIPHER 0x00000001
15234 +#define CRYPTO_ALG_TYPE_DIGEST 0x00000002
15235 +#define CRYPTO_ALG_TYPE_COMPRESS 0x00000004
15238 + * Transform masks and values (for crt_flags).
15240 +#define CRYPTO_TFM_MODE_MASK 0x000000ff
15241 +#define CRYPTO_TFM_REQ_MASK 0x000fff00
15242 +#define CRYPTO_TFM_RES_MASK 0xfff00000
15244 +#define CRYPTO_TFM_MODE_ECB 0x00000001
15245 +#define CRYPTO_TFM_MODE_CBC 0x00000002
15246 +#define CRYPTO_TFM_MODE_CFB 0x00000004
15247 +#define CRYPTO_TFM_MODE_CTR 0x00000008
15249 +#define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100
15250 +#define CRYPTO_TFM_RES_WEAK_KEY 0x00100000
15251 +#define CRYPTO_TFM_RES_BAD_KEY_LEN 0x00200000
15252 +#define CRYPTO_TFM_RES_BAD_KEY_SCHED 0x00400000
15253 +#define CRYPTO_TFM_RES_BAD_BLOCK_LEN 0x00800000
15254 +#define CRYPTO_TFM_RES_BAD_FLAGS 0x01000000
15257 + * Miscellaneous stuff.
15259 +#define CRYPTO_UNSPEC 0
15260 +#define CRYPTO_MAX_ALG_NAME 64
15262 +struct scatterlist;
15265 + * Algorithms: modular crypto algorithm implementations, managed
15266 + * via crypto_register_alg() and crypto_unregister_alg().
15268 +struct cipher_alg {
15269 + unsigned int cia_min_keysize;
15270 + unsigned int cia_max_keysize;
15271 + int (*cia_setkey)(void *ctx, const u8 *key,
15272 + unsigned int keylen, u32 *flags);
15273 + void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src);
15274 + void (*cia_decrypt)(void *ctx, u8 *dst, const u8 *src);
15277 +struct digest_alg {
15278 + unsigned int dia_digestsize;
15279 + void (*dia_init)(void *ctx);
15280 + void (*dia_update)(void *ctx, const u8 *data, unsigned int len);
15281 + void (*dia_final)(void *ctx, u8 *out);
15282 + int (*dia_setkey)(void *ctx, const u8 *key,
15283 + unsigned int keylen, u32 *flags);
15286 +struct compress_alg {
15287 + int (*coa_init)(void *ctx);
15288 + void (*coa_exit)(void *ctx);
15289 + int (*coa_compress)(void *ctx, const u8 *src, unsigned int slen,
15290 + u8 *dst, unsigned int *dlen);
15291 + int (*coa_decompress)(void *ctx, const u8 *src, unsigned int slen,
15292 + u8 *dst, unsigned int *dlen);
15295 +#define cra_cipher cra_u.cipher
15296 +#define cra_digest cra_u.digest
15297 +#define cra_compress cra_u.compress
15299 +struct crypto_alg {
15300 + struct list_head cra_list;
15302 + unsigned int cra_blocksize;
15303 + unsigned int cra_ctxsize;
15304 + const char cra_name[CRYPTO_MAX_ALG_NAME];
15307 + struct cipher_alg cipher;
15308 + struct digest_alg digest;
15309 + struct compress_alg compress;
15312 + struct module *cra_module;
15316 + * Algorithm registration interface.
15318 +int crypto_register_alg(struct crypto_alg *alg);
15319 +int crypto_unregister_alg(struct crypto_alg *alg);
15322 + * Algorithm query interface.
15324 +int crypto_alg_available(const char *name, u32 flags);
15327 + * Transforms: user-instantiated objects which encapsulate algorithms
15328 + * and core processing logic. Managed via crypto_alloc_tfm() and
15329 + * crypto_free_tfm(), as well as the various helpers below.
15331 +struct crypto_tfm;
15333 +struct cipher_tfm {
15335 + unsigned int cit_ivsize;
15337 + int (*cit_setkey)(struct crypto_tfm *tfm,
15338 + const u8 *key, unsigned int keylen);
15339 + int (*cit_encrypt)(struct crypto_tfm *tfm,
15340 + struct scatterlist *dst,
15341 + struct scatterlist *src,
15342 + unsigned int nbytes);
15343 + int (*cit_encrypt_iv)(struct crypto_tfm *tfm,
15344 + struct scatterlist *dst,
15345 + struct scatterlist *src,
15346 + unsigned int nbytes, u8 *iv);
15347 + int (*cit_decrypt)(struct crypto_tfm *tfm,
15348 + struct scatterlist *dst,
15349 + struct scatterlist *src,
15350 + unsigned int nbytes);
15351 + int (*cit_decrypt_iv)(struct crypto_tfm *tfm,
15352 + struct scatterlist *dst,
15353 + struct scatterlist *src,
15354 + unsigned int nbytes, u8 *iv);
15355 + void (*cit_xor_block)(u8 *dst, const u8 *src);
15358 +struct digest_tfm {
15359 + void (*dit_init)(struct crypto_tfm *tfm);
15360 + void (*dit_update)(struct crypto_tfm *tfm,
15361 + struct scatterlist *sg, unsigned int nsg);
15362 + void (*dit_final)(struct crypto_tfm *tfm, u8 *out);
15363 + void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg,
15364 + unsigned int nsg, u8 *out);
15365 + int (*dit_setkey)(struct crypto_tfm *tfm,
15366 + const u8 *key, unsigned int keylen);
15367 +#ifdef CONFIG_CRYPTO_HMAC
15368 + void *dit_hmac_block;
15372 +struct compress_tfm {
15373 + int (*cot_compress)(struct crypto_tfm *tfm,
15374 + const u8 *src, unsigned int slen,
15375 + u8 *dst, unsigned int *dlen);
15376 + int (*cot_decompress)(struct crypto_tfm *tfm,
15377 + const u8 *src, unsigned int slen,
15378 + u8 *dst, unsigned int *dlen);
15381 +#define crt_cipher crt_u.cipher
15382 +#define crt_digest crt_u.digest
15383 +#define crt_compress crt_u.compress
15385 +struct crypto_tfm {
15390 + struct cipher_tfm cipher;
15391 + struct digest_tfm digest;
15392 + struct compress_tfm compress;
15395 + struct crypto_alg *__crt_alg;
15399 + * Transform user interface.
15403 + * crypto_alloc_tfm() will first attempt to locate an already loaded algorithm.
15404 + * If that fails and the kernel supports dynamically loadable modules, it
15405 + * will then attempt to load a module of the same name or alias. A refcount
15406 + * is grabbed on the algorithm which is then associated with the new transform.
15408 + * crypto_free_tfm() frees up the transform and any associated resources,
15409 + * then drops the refcount on the associated algorithm.
15411 +struct crypto_tfm *crypto_alloc_tfm(const char *alg_name, u32 tfm_flags);
15412 +void crypto_free_tfm(struct crypto_tfm *tfm);
15415 + * Transform helpers which query the underlying algorithm.
15417 +static inline const char *crypto_tfm_alg_name(struct crypto_tfm *tfm)
15419 + return tfm->__crt_alg->cra_name;
15422 +static inline const char *crypto_tfm_alg_modname(struct crypto_tfm *tfm)
15424 + struct crypto_alg *alg = tfm->__crt_alg;
15426 + if (alg->cra_module)
15427 + return alg->cra_module->name;
15432 +static inline u32 crypto_tfm_alg_type(struct crypto_tfm *tfm)
15434 + return tfm->__crt_alg->cra_flags & CRYPTO_ALG_TYPE_MASK;
15437 +static inline unsigned int crypto_tfm_alg_min_keysize(struct crypto_tfm *tfm)
15439 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
15440 + return tfm->__crt_alg->cra_cipher.cia_min_keysize;
15443 +static inline unsigned int crypto_tfm_alg_max_keysize(struct crypto_tfm *tfm)
15445 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
15446 + return tfm->__crt_alg->cra_cipher.cia_max_keysize;
15449 +static inline unsigned int crypto_tfm_alg_ivsize(struct crypto_tfm *tfm)
15451 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
15452 + return tfm->crt_cipher.cit_ivsize;
15455 +static inline unsigned int crypto_tfm_alg_blocksize(struct crypto_tfm *tfm)
15457 + return tfm->__crt_alg->cra_blocksize;
15460 +static inline unsigned int crypto_tfm_alg_digestsize(struct crypto_tfm *tfm)
15462 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
15463 + return tfm->__crt_alg->cra_digest.dia_digestsize;
15469 +static inline void crypto_digest_init(struct crypto_tfm *tfm)
15471 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
15472 + tfm->crt_digest.dit_init(tfm);
15475 +static inline void crypto_digest_update(struct crypto_tfm *tfm,
15476 + struct scatterlist *sg,
15477 + unsigned int nsg)
15479 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
15480 + tfm->crt_digest.dit_update(tfm, sg, nsg);
15483 +static inline void crypto_digest_final(struct crypto_tfm *tfm, u8 *out)
15485 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
15486 + tfm->crt_digest.dit_final(tfm, out);
15489 +static inline void crypto_digest_digest(struct crypto_tfm *tfm,
15490 + struct scatterlist *sg,
15491 + unsigned int nsg, u8 *out)
15493 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
15494 + tfm->crt_digest.dit_digest(tfm, sg, nsg, out);
15497 +static inline int crypto_digest_setkey(struct crypto_tfm *tfm,
15498 + const u8 *key, unsigned int keylen)
15500 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST);
15501 + if (tfm->crt_digest.dit_setkey == NULL)
15503 + return tfm->crt_digest.dit_setkey(tfm, key, keylen);
15506 +static inline int crypto_cipher_setkey(struct crypto_tfm *tfm,
15507 + const u8 *key, unsigned int keylen)
15509 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
15510 + return tfm->crt_cipher.cit_setkey(tfm, key, keylen);
15513 +static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm,
15514 + struct scatterlist *dst,
15515 + struct scatterlist *src,
15516 + unsigned int nbytes)
15518 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
15519 + return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes);
15522 +static inline int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm,
15523 + struct scatterlist *dst,
15524 + struct scatterlist *src,
15525 + unsigned int nbytes, u8 *iv)
15527 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
15528 + BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB);
15529 + return tfm->crt_cipher.cit_encrypt_iv(tfm, dst, src, nbytes, iv);
15532 +static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm,
15533 + struct scatterlist *dst,
15534 + struct scatterlist *src,
15535 + unsigned int nbytes)
15537 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
15538 + return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes);
15541 +static inline int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm,
15542 + struct scatterlist *dst,
15543 + struct scatterlist *src,
15544 + unsigned int nbytes, u8 *iv)
15546 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
15547 + BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB);
15548 + return tfm->crt_cipher.cit_decrypt_iv(tfm, dst, src, nbytes, iv);
15551 +static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm,
15552 + const u8 *src, unsigned int len)
15554 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
15555 + memcpy(tfm->crt_cipher.cit_iv, src, len);
15558 +static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm,
15559 + u8 *dst, unsigned int len)
15561 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER);
15562 + memcpy(dst, tfm->crt_cipher.cit_iv, len);
15565 +static inline int crypto_comp_compress(struct crypto_tfm *tfm,
15566 + const u8 *src, unsigned int slen,
15567 + u8 *dst, unsigned int *dlen)
15569 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
15570 + return tfm->crt_compress.cot_compress(tfm, src, slen, dst, dlen);
15573 +static inline int crypto_comp_decompress(struct crypto_tfm *tfm,
15574 + const u8 *src, unsigned int slen,
15575 + u8 *dst, unsigned int *dlen)
15577 + BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS);
15578 + return tfm->crt_compress.cot_decompress(tfm, src, slen, dst, dlen);
15584 +#ifdef CONFIG_CRYPTO_HMAC
15585 +void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen);
15586 +void crypto_hmac_update(struct crypto_tfm *tfm,
15587 + struct scatterlist *sg, unsigned int nsg);
15588 +void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key,
15589 + unsigned int *keylen, u8 *out);
15590 +void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen,
15591 + struct scatterlist *sg, unsigned int nsg, u8 *out);
15592 +#endif /* CONFIG_CRYPTO_HMAC */
15594 +#endif /* _LINUX_CRYPTO_H */
15597 +++ b/drivers/staging/rtl8187se/Kconfig
15600 + tristate "RealTek RTL8187SE Wireless LAN NIC driver"
15605 +++ b/drivers/staging/rtl8187se/Makefile
15608 +#EXTRA_CFLAGS += -DCONFIG_IEEE80211_NOWEP=y
15609 +#EXTRA_CFLAGS += -DCONFIG_RTL8180_IOMAP
15610 +#EXTRA_CFLAGS += -std=gnu89
15611 +#EXTRA_CFLAGS += -O2
15613 +EXTRA_CFLAGS += -DTHOMAS_TURBO
15614 +#CFLAGS += -DCONFIG_RTL8185B
15615 +#CFLAGS += -DCONFIG_RTL818x_S
15617 +#added for EeePC testing
15618 +EXTRA_CFLAGS += -DENABLE_IPS
15619 +EXTRA_CFLAGS += -DSW_ANTE
15620 +EXTRA_CFLAGS += -DTX_TRACK
15621 +EXTRA_CFLAGS += -DHIGH_POWER
15622 +EXTRA_CFLAGS += -DSW_DIG
15623 +EXTRA_CFLAGS += -DRATE_ADAPT
15624 +EXTRA_CFLAGS += -DCONFIG_RTL8180_PM
15627 +EXTRA_CFLAGS += -DENABLE_DOT11D
15629 +#enable it for legacy power save, disable it for leisure power save
15630 +EXTRA_CFLAGS += -DENABLE_LPS
15633 +#EXTRA_CFLAGS += -mhard-float -DCONFIG_FORCE_HARD_FLOAT=y
15635 +rtl8187se-objs := \
15640 + r8180_max2820.o \
15642 + r8180_rtl8225.o \
15643 + r8180_rtl8255.o \
15644 + r8180_rtl8225z2.o \
15648 + ieee80211/dot11d.o \
15649 + ieee80211/ieee80211_softmac.o \
15650 + ieee80211/ieee80211_rx.o \
15651 + ieee80211/ieee80211_tx.o \
15652 + ieee80211/ieee80211_wx.o \
15653 + ieee80211/ieee80211_module.o \
15654 + ieee80211/ieee80211_softmac_wx.o \
15655 + ieee80211/ieee80211_crypt.o \
15656 + ieee80211/ieee80211_crypt_tkip.o \
15657 + ieee80211/ieee80211_crypt_ccmp.o \
15658 + ieee80211/ieee80211_crypt_wep.o
15660 +obj-$(CONFIG_RTL8187SE) += rtl8187se.o
15663 +++ b/drivers/staging/rtl8187se/r8180_93cx6.c
15666 + This files contains card eeprom (93c46 or 93c56) programming routines,
15667 + memory is addressed by 16 bits words.
15669 + This is part of rtl8180 OpenSource driver.
15670 + Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
15671 + Released under the terms of GPL (General Public Licence)
15673 + Parts of this driver are based on the GPL part of the
15674 + official realtek driver.
15676 + Parts of this driver are based on the rtl8180 driver skeleton
15677 + from Patric Schenke & Andres Salomon.
15679 + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
15681 + We want to tanks the Authors of those projects and the Ndiswrapper
15685 +#include "r8180_93cx6.h"
15687 +void eprom_cs(struct net_device *dev, short bit)
15690 + write_nic_byte(dev, EPROM_CMD,
15691 + (1<<EPROM_CS_SHIFT) | \
15692 + read_nic_byte(dev, EPROM_CMD)); //enable EPROM
15694 + write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD)\
15695 + &~(1<<EPROM_CS_SHIFT)); //disable EPROM
15697 + force_pci_posting(dev);
15698 + udelay(EPROM_DELAY);
15702 +void eprom_ck_cycle(struct net_device *dev)
15704 + write_nic_byte(dev, EPROM_CMD,
15705 + (1<<EPROM_CK_SHIFT) | read_nic_byte(dev,EPROM_CMD));
15706 + force_pci_posting(dev);
15707 + udelay(EPROM_DELAY);
15708 + write_nic_byte(dev, EPROM_CMD,
15709 + read_nic_byte(dev, EPROM_CMD) &~ (1<<EPROM_CK_SHIFT));
15710 + force_pci_posting(dev);
15711 + udelay(EPROM_DELAY);
15715 +void eprom_w(struct net_device *dev,short bit)
15718 + write_nic_byte(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) | \
15719 + read_nic_byte(dev,EPROM_CMD));
15721 + write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev,EPROM_CMD)\
15722 + &~(1<<EPROM_W_SHIFT));
15724 + force_pci_posting(dev);
15725 + udelay(EPROM_DELAY);
15729 +short eprom_r(struct net_device *dev)
15733 + bit=(read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT) );
15734 + udelay(EPROM_DELAY);
15736 + if(bit) return 1;
15741 +void eprom_send_bits_string(struct net_device *dev, short b[], int len)
15745 + for(i=0; i<len; i++){
15746 + eprom_w(dev, b[i]);
15747 + eprom_ck_cycle(dev);
15752 +u32 eprom_read(struct net_device *dev, u32 addr)
15754 + struct r8180_priv *priv = ieee80211_priv(dev);
15755 + short read_cmd[]={1,1,0};
15756 + short addr_str[8];
15762 + //enable EPROM programming
15763 + write_nic_byte(dev, EPROM_CMD,
15764 + (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT));
15765 + force_pci_posting(dev);
15766 + udelay(EPROM_DELAY);
15768 + if (priv->epromtype==EPROM_93c56){
15769 + addr_str[7]=addr & 1;
15770 + addr_str[6]=addr & (1<<1);
15771 + addr_str[5]=addr & (1<<2);
15772 + addr_str[4]=addr & (1<<3);
15773 + addr_str[3]=addr & (1<<4);
15774 + addr_str[2]=addr & (1<<5);
15775 + addr_str[1]=addr & (1<<6);
15776 + addr_str[0]=addr & (1<<7);
15779 + addr_str[5]=addr & 1;
15780 + addr_str[4]=addr & (1<<1);
15781 + addr_str[3]=addr & (1<<2);
15782 + addr_str[2]=addr & (1<<3);
15783 + addr_str[1]=addr & (1<<4);
15784 + addr_str[0]=addr & (1<<5);
15787 + eprom_cs(dev, 1);
15788 + eprom_ck_cycle(dev);
15789 + eprom_send_bits_string(dev, read_cmd, 3);
15790 + eprom_send_bits_string(dev, addr_str, addr_len);
15792 + //keep chip pin D to low state while reading.
15793 + //I'm unsure if it is necessary, but anyway shouldn't hurt
15796 + for(i=0;i<16;i++){
15797 + //eeprom needs a clk cycle between writing opcode&adr
15798 + //and reading data. (eeprom outs a dummy 0)
15799 + eprom_ck_cycle(dev);
15800 + ret |= (eprom_r(dev)<<(15-i));
15803 + eprom_cs(dev, 0);
15804 + eprom_ck_cycle(dev);
15806 + //disable EPROM programming
15807 + write_nic_byte(dev, EPROM_CMD,
15808 + (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT));
15812 +++ b/drivers/staging/rtl8187se/r8180_93cx6.h
15815 + This is part of rtl8180 OpenSource driver
15816 + Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
15817 + Released under the terms of GPL (General Public Licence)
15819 + Parts of this driver are based on the GPL part of the official realtek driver
15820 + Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
15821 + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
15823 + We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
15826 +/*This files contains card eeprom (93c46 or 93c56) programming routines*/
15827 +/*memory is addressed by WORDS*/
15829 +#include "r8180.h"
15830 +#include "r8180_hw.h"
15832 +#define EPROM_DELAY 10
15834 +#define EPROM_ANAPARAM_ADDRLWORD 0xd
15835 +#define EPROM_ANAPARAM_ADDRHWORD 0xe
15837 +#define RFCHIPID 0x6
15838 +#define RFCHIPID_INTERSIL 1
15839 +#define RFCHIPID_RFMD 2
15840 +#define RFCHIPID_PHILIPS 3
15841 +#define RFCHIPID_MAXIM 4
15842 +#define RFCHIPID_GCT 5
15843 +#define RFCHIPID_RTL8225 9
15844 +#ifdef CONFIG_RTL8185B
15845 +#define RF_ZEBRA2 11
15846 +#define EPROM_TXPW_BASE 0x05
15847 +#define RF_ZEBRA4 12
15849 +#define RFCHIPID_RTL8255 0xa
15850 +#define RF_PARAM 0x19
15851 +#define RF_PARAM_DIGPHY_SHIFT 0
15852 +#define RF_PARAM_ANTBDEFAULT_SHIFT 1
15853 +#define RF_PARAM_CARRIERSENSE_SHIFT 2
15854 +#define RF_PARAM_CARRIERSENSE_MASK (3<<2)
15855 +#define ENERGY_TRESHOLD 0x17
15856 +#define EPROM_VERSION 0x1E
15857 +#define MAC_ADR 0x7
15861 +#define EPROM_TXPW_OFDM_CH1_2 0x20
15863 +//#define EPROM_TXPW_CH1_2 0x10
15864 +#define EPROM_TXPW_CH1_2 0x30
15865 +#define EPROM_TXPW_CH3_4 0x11
15866 +#define EPROM_TXPW_CH5_6 0x12
15867 +#define EPROM_TXPW_CH7_8 0x13
15868 +#define EPROM_TXPW_CH9_10 0x14
15869 +#define EPROM_TXPW_CH11_12 0x15
15870 +#define EPROM_TXPW_CH13_14 0x16
15872 +u32 eprom_read(struct net_device *dev,u32 addr); //reads a 16 bits word
15874 +++ b/drivers/staging/rtl8187se/r8180_core.c
15877 + This is part of rtl818x pci OpenSource driver - v 0.1
15878 + Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
15879 + Released under the terms of GPL (General Public License)
15881 + Parts of this driver are based on the GPL part of the official
15884 + Parts of this driver are based on the rtl8180 driver skeleton
15885 + from Patric Schenke & Andres Salomon.
15887 + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
15889 + Parts of BB/RF code are derived from David Young rtl8180 netbsd driver.
15891 + RSSI calc function from 'The Deuce'
15893 + Some ideas borrowed from the 8139too.c driver included in linux kernel.
15895 + We (I?) want to thanks the Authors of those projecs and also the
15896 + Ndiswrapper's project Authors.
15898 + A big big thanks goes also to Realtek corp. for their help in my attempt to
15899 + add RTL8185 and RTL8225 support, and to David Young also.
15903 +double __floatsidf (int i) { return i; }
15904 +unsigned int __fixunsdfsi (double d) { return d; }
15905 +double __adddf3(double a, double b) { return a+b; }
15906 +double __addsf3(float a, float b) { return a+b; }
15907 +double __subdf3(double a, double b) { return a-b; }
15908 +double __extendsfdf2(float a) {return a;}
15912 +#undef DEBUG_TX_DESC2
15913 +#undef RX_DONT_PASS_UL
15914 +#undef DEBUG_EPROM
15915 +#undef DEBUG_RX_VERBOSE
15917 +#undef DEBUG_ZERO_RX
15918 +#undef DEBUG_RX_SKB
15919 +#undef DEBUG_TX_FRAG
15920 +#undef DEBUG_RX_FRAG
15921 +#undef DEBUG_TX_FILLDESC
15925 +#undef DEBUG_RXALLOC
15926 +#undef DEBUG_REGISTERS
15928 +#undef DEBUG_IRQ_TASKLET
15929 +#undef DEBUG_TX_ALLOC
15930 +#undef DEBUG_TX_DESC
15932 +//#define DEBUG_TX
15933 +//#define DEBUG_TX_DESC2
15934 +//#define DEBUG_RX
15935 +//#define DEBUG_RX_SKB
15937 +//#define CONFIG_RTL8180_IO_MAP
15938 +#include <linux/syscalls.h>
15939 +//#include <linux/fcntl.h>
15940 +//#include <asm/uaccess.h>
15941 +#include "r8180_hw.h"
15942 +#include "r8180.h"
15943 +#include "r8180_sa2400.h" /* PHILIPS Radio frontend */
15944 +#include "r8180_max2820.h" /* MAXIM Radio frontend */
15945 +#include "r8180_gct.h" /* GCT Radio frontend */
15946 +#include "r8180_rtl8225.h" /* RTL8225 Radio frontend */
15947 +#include "r8180_rtl8255.h" /* RTL8255 Radio frontend */
15948 +#include "r8180_93cx6.h" /* Card EEPROM */
15949 +#include "r8180_wx.h"
15950 +#include "r8180_dm.h"
15952 +#ifdef CONFIG_RTL8180_PM
15953 +#include "r8180_pm.h"
15956 +#ifdef ENABLE_DOT11D
15957 +#include "dot11d.h"
15960 +#ifdef CONFIG_RTL8185B
15961 +//#define CONFIG_RTL8180_IO_MAP
15964 +#ifndef PCI_VENDOR_ID_BELKIN
15965 + #define PCI_VENDOR_ID_BELKIN 0x1799
15967 +#ifndef PCI_VENDOR_ID_DLINK
15968 + #define PCI_VENDOR_ID_DLINK 0x1186
15971 +static struct pci_device_id rtl8180_pci_id_tbl[] __devinitdata = {
15973 + .vendor = PCI_VENDOR_ID_REALTEK,
15974 +// .device = 0x8180,
15975 + .device = 0x8199,
15976 + .subvendor = PCI_ANY_ID,
15977 + .subdevice = PCI_ANY_ID,
15978 + .driver_data = 0,
15982 + .vendor = PCI_VENDOR_ID_BELKIN,
15983 + .device = 0x6001,
15984 + .subvendor = PCI_ANY_ID,
15985 + .subdevice = PCI_ANY_ID,
15986 + .driver_data = 1,
15988 + { /* Belkin F5D6020 v3 */
15989 + .vendor = PCI_VENDOR_ID_BELKIN,
15990 + .device = 0x6020,
15991 + .subvendor = PCI_ANY_ID,
15992 + .subdevice = PCI_ANY_ID,
15993 + .driver_data = 2,
15995 + { /* D-Link DWL-610 */
15996 + .vendor = PCI_VENDOR_ID_DLINK,
15997 + .device = 0x3300,
15998 + .subvendor = PCI_ANY_ID,
15999 + .subdevice = PCI_ANY_ID,
16000 + .driver_data = 3,
16003 + .vendor = PCI_VENDOR_ID_REALTEK,
16004 + .device = 0x8185,
16005 + .subvendor = PCI_ANY_ID,
16006 + .subdevice = PCI_ANY_ID,
16007 + .driver_data = 4,
16015 + .driver_data = 0,
16020 +static char* ifname = "wlan%d";
16021 +static int hwseqnum = 0;
16022 +//static char* ifname = "ath%d";
16023 +static int hwwep = 0;
16024 +static int channels = 0x3fff;
16026 +#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 )
16027 +#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5])
16028 +MODULE_LICENSE("GPL");
16029 +MODULE_DEVICE_TABLE(pci, rtl8180_pci_id_tbl);
16030 +MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
16031 +MODULE_DESCRIPTION("Linux driver for Realtek RTL8180 / RTL8185 WiFi cards");
16036 +MODULE_PARM(ifname, "s");
16037 +MODULE_PARM_DESC(devname," Net interface name, wlan%d=default");
16039 +MODULE_PARM(hwseqnum,"i");
16040 +MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
16042 +MODULE_PARM(hwwep,"i");
16043 +MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
16045 +MODULE_PARM(channels,"i");
16046 +MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
16049 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 9)
16050 +module_param(ifname, charp, S_IRUGO|S_IWUSR );
16051 +module_param(hwseqnum,int, S_IRUGO|S_IWUSR);
16052 +module_param(hwwep,int, S_IRUGO|S_IWUSR);
16053 +module_param(channels,int, S_IRUGO|S_IWUSR);
16055 +MODULE_PARM(ifname, "s");
16056 +MODULE_PARM(hwseqnum,"i");
16057 +MODULE_PARM(hwwep,"i");
16058 +MODULE_PARM(channels,"i");
16061 +MODULE_PARM_DESC(devname," Net interface name, wlan%d=default");
16062 +//MODULE_PARM_DESC(devname," Net interface name, ath%d=default");
16063 +MODULE_PARM_DESC(hwseqnum," Try to use hardware 802.11 header sequence numbers. Zero=default");
16064 +MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards");
16065 +MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI");
16068 +static int __devinit rtl8180_pci_probe(struct pci_dev *pdev,
16069 + const struct pci_device_id *id);
16071 +static void __devexit rtl8180_pci_remove(struct pci_dev *pdev);
16073 +static void rtl8180_shutdown (struct pci_dev *pdev)
16075 + struct net_device *dev = pci_get_drvdata(pdev);
16077 + pci_disable_device(pdev);
16080 +static struct pci_driver rtl8180_pci_driver = {
16081 + .name = RTL8180_MODULE_NAME, /* Driver name */
16082 + .id_table = rtl8180_pci_id_tbl, /* PCI_ID table */
16083 + .probe = rtl8180_pci_probe, /* probe fn */
16084 + .remove = __devexit_p(rtl8180_pci_remove),/* remove fn */
16085 +#ifdef CONFIG_RTL8180_PM
16086 + .suspend = rtl8180_suspend, /* PM suspend fn */
16087 + .resume = rtl8180_resume, /* PM resume fn */
16089 + .suspend = NULL, /* PM suspend fn */
16090 + .resume = NULL, /* PM resume fn */
16092 + .shutdown = rtl8180_shutdown,
16097 +#ifdef CONFIG_RTL8180_IO_MAP
16099 +u8 read_nic_byte(struct net_device *dev, int x)
16101 + return 0xff&inb(dev->base_addr +x);
16104 +u32 read_nic_dword(struct net_device *dev, int x)
16106 + return inl(dev->base_addr +x);
16109 +u16 read_nic_word(struct net_device *dev, int x)
16111 + return inw(dev->base_addr +x);
16114 +void write_nic_byte(struct net_device *dev, int x,u8 y)
16116 + outb(y&0xff,dev->base_addr +x);
16119 +void write_nic_word(struct net_device *dev, int x,u16 y)
16121 + outw(y,dev->base_addr +x);
16124 +void write_nic_dword(struct net_device *dev, int x,u32 y)
16126 + outl(y,dev->base_addr +x);
16129 +#else /* RTL_IO_MAP */
16131 +u8 read_nic_byte(struct net_device *dev, int x)
16133 + return 0xff&readb((u8*)dev->mem_start +x);
16136 +u32 read_nic_dword(struct net_device *dev, int x)
16138 + return readl((u8*)dev->mem_start +x);
16141 +u16 read_nic_word(struct net_device *dev, int x)
16143 + return readw((u8*)dev->mem_start +x);
16146 +void write_nic_byte(struct net_device *dev, int x,u8 y)
16148 + writeb(y,(u8*)dev->mem_start +x);
16152 +void write_nic_dword(struct net_device *dev, int x,u32 y)
16154 + writel(y,(u8*)dev->mem_start +x);
16158 +void write_nic_word(struct net_device *dev, int x,u16 y)
16160 + writew(y,(u8*)dev->mem_start +x);
16164 +#endif /* RTL_IO_MAP */
16170 +inline void force_pci_posting(struct net_device *dev)
16172 + read_nic_byte(dev,EPROM_CMD);
16173 +#ifndef CONFIG_RTL8180_IO_MAP
16179 +irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs);
16180 +void set_nic_rxring(struct net_device *dev);
16181 +void set_nic_txring(struct net_device *dev);
16182 +static struct net_device_stats *rtl8180_stats(struct net_device *dev);
16183 +void rtl8180_commit(struct net_device *dev);
16184 +void rtl8180_start_tx_beacon(struct net_device *dev);
16186 +/****************************************************************************
16187 + -----------------------------PROCFS STUFF-------------------------
16188 +*****************************************************************************/
16190 +static struct proc_dir_entry *rtl8180_proc = NULL;
16192 +static int proc_get_registers(char *page, char **start,
16193 + off_t offset, int count,
16194 + int *eof, void *data)
16196 + struct net_device *dev = data;
16197 +// struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
16204 + /* This dump the current register page */
16207 + //printk( "\nD: %2x> ", n);
16208 + len += snprintf(page + len, count - len,
16209 + "\nD: %2x > ",n);
16211 + for(i=0;i<16 && n<=max;i++,n++)
16212 + len += snprintf(page + len, count - len,
16213 + "%2x ",read_nic_byte(dev,n));
16215 + // printk("%2x ",read_nic_byte(dev,n));
16217 + len += snprintf(page + len, count - len,"\n");
16226 +int get_curr_tx_free_desc(struct net_device *dev, int priority);
16228 +static int proc_get_stats_hw(char *page, char **start,
16229 + off_t offset, int count,
16230 + int *eof, void *data)
16232 + //struct net_device *dev = data;
16233 + //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
16236 +#ifdef CONFIG_RTL8185B
16239 + len += snprintf(page + len, count - len,
16241 + "Total int: %lu\n"
16242 + "--------------------\n"
16243 + "LP avail desc %d\n"
16244 + "NP avail desc %d\n"
16245 + "--------------------\n"
16246 + "LP phys dma addr %x\n"
16247 + "LP NIC ptr %x\n"
16248 + "LP virt 32base %x\n"
16249 + "LP virt 32tail %x\n"
16250 + "--------------------\n"
16251 + "NP phys dma addr %x\n"
16252 + "NP NIC ptr %x\n"
16253 + "NP virt 32base %x\n"
16254 + "NP virt 32tail %x\n"
16255 + "--------------------\n"
16256 + "BP phys dma addr %x\n"
16257 + "BP NIC ptr %x\n"
16258 + "BP virt 32base %x\n"
16259 + "BP virt 32tail %x\n",
16260 + priv->stats.ints,
16261 + priv->stats.shints,
16262 + get_curr_tx_free_desc(dev,LOW_PRIORITY),
16263 + get_curr_tx_free_desc(dev,NORM_PRIORITY),
16264 + (u32)priv->txvipringdma,
16265 + read_nic_dword(dev,TLPDA),
16266 + (u32)priv->txvipring,
16267 + (u32)priv->txvipringtail,
16268 + (u32)priv->txvopringdma,
16269 + read_nic_dword(dev,TNPDA),
16270 + (u32)priv->txvopring,
16271 + (u32)priv->txvopringtail,
16272 + (u32)priv->txbeaconringdma,
16273 + read_nic_dword(dev,TBDA),
16274 + (u32)priv->txbeaconring,
16275 + (u32)priv->txbeaconringtail);
16282 +static int proc_get_stats_rx(char *page, char **start,
16283 + off_t offset, int count,
16284 + int *eof, void *data)
16286 + struct net_device *dev = data;
16287 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
16291 + len += snprintf(page + len, count - len,
16292 + /* "RX descriptor not available: %lu\n"
16293 + "RX incomplete (missing last descriptor): %lu\n"
16294 + "RX not data: %lu\n"
16295 + //"RX descriptor pointer reset: %lu\n"
16296 + "RX descriptor pointer lost: %lu\n"
16297 + //"RX pointer workaround: %lu\n"
16298 + "RX error int: %lu\n"
16299 + "RX fifo overflow: %lu\n"
16301 + "RX packet: %lu\n"
16302 + "RX bytes: %lu\n"
16303 + "RX DMA fail: %lu\n",
16304 + priv->stats.rxrdu,
16305 + priv->stats.rxnolast,
16306 + priv->stats.rxnodata,
16307 + //priv->stats.rxreset,
16308 + priv->stats.rxnopointer,
16309 + //priv->stats.rxwrkaround,
16310 + priv->stats.rxerr,
16311 + priv->stats.rxoverflow,
16312 + priv->stats.rxint,
16313 + priv->ieee80211->stats.rx_packets,
16314 + priv->ieee80211->stats.rx_bytes,
16315 + priv->stats.rxdmafail */
16317 + "RX Retry: %lu\n"
16318 + "RX CRC Error(0-500): %lu\n"
16319 + "RX CRC Error(500-1000): %lu\n"
16320 + "RX CRC Error(>1000): %lu\n"
16321 + "RX ICV Error: %lu\n",
16322 + priv->stats.rxint,
16323 + priv->stats.rxerr,
16324 + priv->stats.rxcrcerrmin,
16325 + priv->stats.rxcrcerrmid,
16326 + priv->stats.rxcrcerrmax,
16327 + priv->stats.rxicverr
16335 +static int proc_get_stats_ieee(char *page, char **start,
16336 + off_t offset, int count,
16337 + int *eof, void *data)
16339 + struct net_device *dev = data;
16340 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
16344 + len += snprintf(page + len, count - len,
16345 + "TXed association requests: %u\n"
16346 + "TXed authentication requests: %u\n"
16347 + "RXed successful association response: %u\n"
16348 + "RXed failed association response: %u\n"
16349 + "RXed successful authentication response: %u\n"
16350 + "RXed failed authentication response: %u\n"
16351 + "Association requests without response: %u\n"
16352 + "Authentication requests without response: %u\n"
16353 + "TX probe response: %u\n"
16354 + "RX probe request: %u\n"
16355 + "TX probe request: %lu\n"
16356 + "RX authentication requests: %lu\n"
16357 + "RX association requests: %lu\n"
16358 + "Reassociations: %lu\n",
16359 + priv->ieee80211->ieee_stats.tx_ass,
16360 + priv->ieee80211->ieee_stats.tx_aut,
16361 + priv->ieee80211->ieee_stats.rx_ass_ok,
16362 + priv->ieee80211->ieee_stats.rx_ass_err,
16363 + priv->ieee80211->ieee_stats.rx_aut_ok,
16364 + priv->ieee80211->ieee_stats.rx_aut_err,
16365 + priv->ieee80211->ieee_stats.ass_noresp,
16366 + priv->ieee80211->ieee_stats.aut_noresp,
16367 + priv->ieee80211->ieee_stats.tx_probe,
16368 + priv->ieee80211->ieee_stats.rx_probe,
16369 + priv->ieee80211->ieee_stats.tx_probe_rq,
16370 + priv->ieee80211->ieee_stats.rx_auth_rq,
16371 + priv->ieee80211->ieee_stats.rx_assoc_rq,
16372 + priv->ieee80211->ieee_stats.reassoc);
16379 +static int proc_get_stats_ap(char *page, char **start,
16380 + off_t offset, int count,
16381 + int *eof, void *data)
16383 + struct net_device *dev = data;
16384 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
16385 + struct mac_htable_t *list;
16389 + if(priv->ieee80211->iw_mode != IW_MODE_MASTER){
16390 + len += snprintf(page + len, count - len,
16391 + "Card is not acting as AP...\n"
16394 + len += snprintf(page + len, count - len,
16395 + "List of associated STA:\n"
16398 + for(i=0;i<MAC_HTABLE_ENTRY;i++)
16399 + for (list = priv->ieee80211->assoc_htable[i]; list!=NULL; list = list->next){
16400 + len += snprintf(page + len, count - len,
16401 + MACSTR"\n",MAC2STR(list->adr));
16410 +static int proc_get_stats_tx(char *page, char **start,
16411 + off_t offset, int count,
16412 + int *eof, void *data)
16414 + struct net_device *dev = data;
16415 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
16418 + unsigned long totalOK;
16420 + totalOK=priv->stats.txnpokint+priv->stats.txhpokint+priv->stats.txlpokint;
16421 + len += snprintf(page + len, count - len,
16422 + /* "TX normal priority ok int: %lu\n"
16423 + "TX normal priority error int: %lu\n"
16424 + "TX high priority ok int: %lu\n"
16425 + "TX high priority failed error int: %lu\n"
16426 + "TX low priority ok int: %lu\n"
16427 + "TX low priority failed error int: %lu\n"
16428 + "TX bytes: %lu\n"
16429 + "TX packets: %lu\n"
16430 + "TX queue resume: %lu\n"
16431 + "TX queue stopped?: %d\n"
16432 + "TX fifo overflow: %lu\n"
16433 + //"SW TX stop: %lu\n"
16434 + //"SW TX wake: %lu\n"
16435 + "TX beacon: %lu\n"
16436 + "TX beacon aborted: %lu\n",
16437 + priv->stats.txnpokint,
16438 + priv->stats.txnperr,
16439 + priv->stats.txhpokint,
16440 + priv->stats.txhperr,
16441 + priv->stats.txlpokint,
16442 + priv->stats.txlperr,
16443 + priv->ieee80211->stats.tx_bytes,
16444 + priv->ieee80211->stats.tx_packets,
16445 + priv->stats.txresumed,
16446 + netif_queue_stopped(dev),
16447 + priv->stats.txoverflow,
16448 + //priv->ieee80211->ieee_stats.swtxstop,
16449 + //priv->ieee80211->ieee_stats.swtxawake,
16450 + priv->stats.txbeacon,
16451 + priv->stats.txbeaconerr */
16453 + "TX Error: %lu\n"
16454 + "TX Retry: %lu\n"
16455 + "TX beacon OK: %lu\n"
16456 + "TX beacon error: %lu\n",
16458 + priv->stats.txnperr+priv->stats.txhperr+priv->stats.txlperr,
16459 + priv->stats.txretry,
16460 + priv->stats.txbeacon,
16461 + priv->stats.txbeaconerr
16469 +#if WIRELESS_EXT < 17
16470 +static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
16472 + struct r8180_priv *priv = ieee80211_priv(dev);
16474 + return &priv->wstats;
16477 +void rtl8180_proc_module_init(void)
16479 + DMESG("Initializing proc filesystem");
16480 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
16481 + rtl8180_proc=create_proc_entry(RTL8180_MODULE_NAME, S_IFDIR, proc_net);
16483 + rtl8180_proc=create_proc_entry(RTL8180_MODULE_NAME, S_IFDIR, init_net.proc_net);
16488 +void rtl8180_proc_module_remove(void)
16490 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
16491 + remove_proc_entry(RTL8180_MODULE_NAME, proc_net);
16493 + remove_proc_entry(RTL8180_MODULE_NAME, init_net.proc_net);
16498 +void rtl8180_proc_remove_one(struct net_device *dev)
16500 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
16501 + if (priv->dir_dev) {
16502 + remove_proc_entry("stats-hw", priv->dir_dev);
16503 + remove_proc_entry("stats-tx", priv->dir_dev);
16504 + remove_proc_entry("stats-rx", priv->dir_dev);
16505 +// remove_proc_entry("stats-ieee", priv->dir_dev);
16506 +// remove_proc_entry("stats-ap", priv->dir_dev);
16507 + remove_proc_entry("registers", priv->dir_dev);
16508 + remove_proc_entry(dev->name, rtl8180_proc);
16509 + priv->dir_dev = NULL;
16514 +void rtl8180_proc_init_one(struct net_device *dev)
16516 + struct proc_dir_entry *e;
16517 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
16518 + priv->dir_dev = create_proc_entry(dev->name,
16519 + S_IFDIR | S_IRUGO | S_IXUGO,
16521 + if (!priv->dir_dev) {
16522 + DMESGE("Unable to initialize /proc/net/rtl8180/%s\n",
16527 + e = create_proc_read_entry("stats-hw", S_IFREG | S_IRUGO,
16528 + priv->dir_dev, proc_get_stats_hw, dev);
16531 + DMESGE("Unable to initialize "
16532 + "/proc/net/rtl8180/%s/stats-hw\n",
16536 + e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO,
16537 + priv->dir_dev, proc_get_stats_rx, dev);
16540 + DMESGE("Unable to initialize "
16541 + "/proc/net/rtl8180/%s/stats-rx\n",
16546 + e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO,
16547 + priv->dir_dev, proc_get_stats_tx, dev);
16550 + DMESGE("Unable to initialize "
16551 + "/proc/net/rtl8180/%s/stats-tx\n",
16555 + e = create_proc_read_entry("stats-ieee", S_IFREG | S_IRUGO,
16556 + priv->dir_dev, proc_get_stats_ieee, dev);
16559 + DMESGE("Unable to initialize "
16560 + "/proc/net/rtl8180/%s/stats-ieee\n",
16565 + e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO,
16566 + priv->dir_dev, proc_get_stats_ap, dev);
16569 + DMESGE("Unable to initialize "
16570 + "/proc/net/rtl8180/%s/stats-ap\n",
16575 + e = create_proc_read_entry("registers", S_IFREG | S_IRUGO,
16576 + priv->dir_dev, proc_get_registers, dev);
16579 + DMESGE("Unable to initialize "
16580 + "/proc/net/rtl8180/%s/registers\n",
16584 +/****************************************************************************
16585 + -----------------------------MISC STUFF-------------------------
16586 +*****************************************************************************/
16588 + FIXME: check if we can use some standard already-existent
16589 + data type+functions in kernel
16592 +short buffer_add(struct buffer **buffer, u32 *buf, dma_addr_t dma,
16593 + struct buffer **bufferhead)
16596 + DMESG("adding buffer to TX/RX struct");
16599 + struct buffer *tmp;
16603 + *buffer = kmalloc(sizeof(struct buffer),GFP_KERNEL);
16605 + if (*buffer == NULL) {
16606 + DMESGE("Failed to kmalloc head of TX/RX struct");
16609 + (*buffer)->next=*buffer;
16610 + (*buffer)->buf=buf;
16611 + (*buffer)->dma=dma;
16612 + if(bufferhead !=NULL)
16613 + (*bufferhead) = (*buffer);
16618 + while(tmp->next!=(*buffer)) tmp=tmp->next;
16619 + if ((tmp->next= kmalloc(sizeof(struct buffer),GFP_KERNEL)) == NULL){
16620 + DMESGE("Failed to kmalloc TX/RX struct");
16623 + tmp->next->buf=buf;
16624 + tmp->next->dma=dma;
16625 + tmp->next->next=*buffer;
16631 +void buffer_free(struct net_device *dev,struct buffer **buffer,int len,short
16635 + struct buffer *tmp,*next;
16636 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
16637 + struct pci_dev *pdev=priv->pdev;
16640 + if(! *buffer) return;
16642 + /*for(tmp=*buffer; tmp->next != *buffer; tmp=tmp->next)
16649 + pci_free_consistent(pdev,len,
16650 + tmp->buf,tmp->dma);
16652 + pci_unmap_single(pdev, tmp->dma,
16653 + len,PCI_DMA_FROMDEVICE);
16659 + while(next != *buffer);
16665 +void print_buffer(u32 *buffer, int len)
16668 + u8 *buf =(u8*)buffer;
16670 + printk("ASCII BUFFER DUMP (len: %x):\n",len);
16672 + for(i=0;i<len;i++)
16673 + printk("%c",buf[i]);
16675 + printk("\nBINARY BUFFER DUMP (len: %x):\n",len);
16677 + for(i=0;i<len;i++)
16678 + printk("%02x",buf[i]);
16684 +int get_curr_tx_free_desc(struct net_device *dev, int priority)
16686 + struct r8180_priv *priv = ieee80211_priv(dev);
16691 + switch (priority){
16692 + case MANAGE_PRIORITY:
16693 + head = priv->txmapringhead;
16694 + tail = priv->txmapringtail;
16696 + case BK_PRIORITY:
16697 + head = priv->txbkpringhead;
16698 + tail = priv->txbkpringtail;
16700 + case BE_PRIORITY:
16701 + head = priv->txbepringhead;
16702 + tail = priv->txbepringtail;
16704 + case VI_PRIORITY:
16705 + head = priv->txvipringhead;
16706 + tail = priv->txvipringtail;
16708 + case VO_PRIORITY:
16709 + head = priv->txvopringhead;
16710 + tail = priv->txvopringtail;
16712 + case HI_PRIORITY:
16713 + head = priv->txhpringhead;
16714 + tail = priv->txhpringtail;
16720 + //DMESG("%x %x", head, tail);
16722 + /* FIXME FIXME FIXME FIXME */
16725 + if( head <= tail ) return priv->txringcount-1 - (tail - head)/8;
16726 + return (head - tail)/8/4;
16728 + if( head <= tail )
16729 + ret = priv->txringcount - (tail - head)/8;
16731 + ret = (head - tail)/8;
16733 + if(ret > priv->txringcount ) DMESG("BUG");
16739 +short check_nic_enought_desc(struct net_device *dev, int priority)
16741 + struct r8180_priv *priv = ieee80211_priv(dev);
16742 + struct ieee80211_device *ieee = netdev_priv(dev);
16744 + int requiredbyte, required;
16745 + requiredbyte = priv->ieee80211->fts + sizeof(struct ieee80211_header_data);
16747 + if(ieee->current_network.QoS_Enable) {
16748 + requiredbyte += 2;
16751 + required = requiredbyte / (priv->txbuffsize-4);
16752 + if (requiredbyte % priv->txbuffsize) required++;
16753 + /* for now we keep two free descriptor as a safety boundary
16754 + * between the tail and the head
16757 + return (required+2 < get_curr_tx_free_desc(dev,priority));
16761 +/* This function is only for debuging purpose */
16762 +void check_tx_ring(struct net_device *dev, int pri)
16764 + static int maxlog =3;
16765 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
16767 + struct buffer *buf;
16774 + struct buffer* buffer;
16777 + if (maxlog <0 ) return;
16780 + case MANAGE_PRIORITY:
16781 + tail = priv->txmapringtail;
16782 + begin = priv->txmapring;
16783 + head = priv->txmapringhead;
16784 + nic = read_nic_dword(dev,TX_MANAGEPRIORITY_RING_ADDR);
16785 + buffer = priv->txmapbufs;
16786 + nicbegin = priv->txmapringdma;
16790 + case BK_PRIORITY:
16791 + tail = priv->txbkpringtail;
16792 + begin = priv->txbkpring;
16793 + head = priv->txbkpringhead;
16794 + nic = read_nic_dword(dev,TX_BKPRIORITY_RING_ADDR);
16795 + buffer = priv->txbkpbufs;
16796 + nicbegin = priv->txbkpringdma;
16799 + case BE_PRIORITY:
16800 + tail = priv->txbepringtail;
16801 + begin = priv->txbepring;
16802 + head = priv->txbepringhead;
16803 + nic = read_nic_dword(dev,TX_BEPRIORITY_RING_ADDR);
16804 + buffer = priv->txbepbufs;
16805 + nicbegin = priv->txbepringdma;
16808 + case VI_PRIORITY:
16809 + tail = priv->txvipringtail;
16810 + begin = priv->txvipring;
16811 + head = priv->txvipringhead;
16812 + nic = read_nic_dword(dev,TX_VIPRIORITY_RING_ADDR);
16813 + buffer = priv->txvipbufs;
16814 + nicbegin = priv->txvipringdma;
16818 + case VO_PRIORITY:
16819 + tail = priv->txvopringtail;
16820 + begin = priv->txvopring;
16821 + head = priv->txvopringhead;
16822 + nic = read_nic_dword(dev,TX_VOPRIORITY_RING_ADDR);
16823 + buffer = priv->txvopbufs;
16824 + nicbegin = priv->txvopringdma;
16827 + case HI_PRIORITY:
16828 + tail = priv->txhpringtail;
16829 + begin = priv->txhpring;
16830 + head = priv->txhpringhead;
16831 + nic = read_nic_dword(dev,TX_HIGHPRIORITY_RING_ADDR);
16832 + buffer = priv->txhpbufs;
16833 + nicbegin = priv->txhpringdma;
16841 + if(!priv->txvopbufs)
16842 + DMESGE ("NIC TX ack, but TX queue corrupted!");
16845 + for(i=0,buf=buffer, tmp=begin;
16846 + tmp<begin+(priv->txringcount)*8;
16847 + tmp+=8,buf=buf->next,i++)
16849 + DMESG("BUF%d %s %x %s. Next : %x",i,
16850 + *tmp & (1<<31) ? "filled" : "empty",
16852 + *tmp & (1<<15)? "ok": "err", *(tmp+4));
16855 + DMESG("nic at %d",
16856 + (nic-nicbegin) / 8 /4);
16857 + DMESG("tail at %d", ((int)tail - (int)begin) /8 /4);
16858 + DMESG("head at %d", ((int)head - (int)begin) /8 /4);
16859 + DMESG("check free desc returns %d", check_nic_enought_desc(dev,pri));
16860 + DMESG("free desc is %d\n", get_curr_tx_free_desc(dev,pri));
16861 + //rtl8180_reset(dev);
16867 +/* this function is only for debugging purpose */
16868 +void check_rxbuf(struct net_device *dev)
16870 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
16872 + struct buffer *buf;
16875 +#ifdef CONFIG_RTL8185B
16876 + rx_desc_size = 8;
16878 + rx_desc_size = 4;
16881 + if(!priv->rxbuffer)
16882 + DMESGE ("NIC RX ack, but RX queue corrupted!");
16886 + for(buf=priv->rxbuffer, tmp=priv->rxring;
16887 + tmp < priv->rxring+(priv->rxringcount)*rx_desc_size;
16888 + tmp+=rx_desc_size, buf=buf->next)
16890 + DMESG("BUF %s %x",
16891 + *tmp & (1<<31) ? "empty" : "filled",
16899 +void dump_eprom(struct net_device *dev)
16902 + for(i=0; i<63; i++)
16903 + DMESG("EEPROM addr %x : %x", i, eprom_read(dev,i));
16907 +void rtl8180_dump_reg(struct net_device *dev)
16913 + DMESG("Dumping NIC register map");
16917 + printk( "\nD: %2x> ", n);
16918 + for(i=0;i<16 && n<=max;i++,n++)
16919 + printk("%2x ",read_nic_byte(dev,n));
16925 +void fix_tx_fifo(struct net_device *dev)
16927 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
16930 +#ifdef DEBUG_TX_ALLOC
16931 + DMESG("FIXING TX FIFOs");
16933 + for (tmp=priv->txmapring, i=0;
16934 + i < priv->txringcount;
16936 + *tmp = *tmp &~ (1<<31);
16939 + for (tmp=priv->txbkpring, i=0;
16940 + i < priv->txringcount;
16942 + *tmp = *tmp &~ (1<<31);
16945 + for (tmp=priv->txbepring, i=0;
16946 + i < priv->txringcount;
16948 + *tmp = *tmp &~ (1<<31);
16950 + for (tmp=priv->txvipring, i=0;
16951 + i < priv->txringcount;
16953 + *tmp = *tmp &~ (1<<31);
16956 + for (tmp=priv->txvopring, i=0;
16957 + i < priv->txringcount;
16959 + *tmp = *tmp &~ (1<<31);
16962 + for (tmp=priv->txhpring, i=0;
16963 + i < priv->txringcount;
16965 + *tmp = *tmp &~ (1<<31);
16968 + for (tmp=priv->txbeaconring, i=0;
16969 + i < priv->txbeaconcount;
16971 + *tmp = *tmp &~ (1<<31);
16973 +#ifdef DEBUG_TX_ALLOC
16974 + DMESG("TX FIFOs FIXED");
16976 + priv->txmapringtail = priv->txmapring;
16977 + priv->txmapringhead = priv->txmapring;
16978 + priv->txmapbufstail = priv->txmapbufs;
16980 + priv->txbkpringtail = priv->txbkpring;
16981 + priv->txbkpringhead = priv->txbkpring;
16982 + priv->txbkpbufstail = priv->txbkpbufs;
16984 + priv->txbepringtail = priv->txbepring;
16985 + priv->txbepringhead = priv->txbepring;
16986 + priv->txbepbufstail = priv->txbepbufs;
16988 + priv->txvipringtail = priv->txvipring;
16989 + priv->txvipringhead = priv->txvipring;
16990 + priv->txvipbufstail = priv->txvipbufs;
16992 + priv->txvopringtail = priv->txvopring;
16993 + priv->txvopringhead = priv->txvopring;
16994 + priv->txvopbufstail = priv->txvopbufs;
16996 + priv->txhpringtail = priv->txhpring;
16997 + priv->txhpringhead = priv->txhpring;
16998 + priv->txhpbufstail = priv->txhpbufs;
17000 + priv->txbeaconringtail = priv->txbeaconring;
17001 + priv->txbeaconbufstail = priv->txbeaconbufs;
17002 + set_nic_txring(dev);
17004 + ieee80211_reset_queue(priv->ieee80211);
17005 + priv->ack_tx_to_ieee = 0;
17009 +void fix_rx_fifo(struct net_device *dev)
17011 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17013 + struct buffer *rxbuf;
17016 +#ifdef CONFIG_RTL8185B
17017 + rx_desc_size = 8; // 4*8 = 32 bytes
17019 + rx_desc_size = 4;
17022 +#ifdef DEBUG_RXALLOC
17023 + DMESG("FIXING RX FIFO");
17024 + check_rxbuf(dev);
17027 + for (tmp=priv->rxring, rxbuf=priv->rxbufferhead;
17028 + (tmp < (priv->rxring)+(priv->rxringcount)*rx_desc_size);
17029 + tmp+=rx_desc_size,rxbuf=rxbuf->next){
17030 + *(tmp+2) = rxbuf->dma;
17031 + *tmp=*tmp &~ 0xfff;
17032 + *tmp=*tmp | priv->rxbuffersize;
17036 +#ifdef DEBUG_RXALLOC
17037 + DMESG("RX FIFO FIXED");
17038 + check_rxbuf(dev);
17041 + priv->rxringtail=priv->rxring;
17042 + priv->rxbuffer=priv->rxbufferhead;
17043 + priv->rx_skb_complete=1;
17044 + set_nic_rxring(dev);
17048 +/****************************************************************************
17049 + ------------------------------HW STUFF---------------------------
17050 +*****************************************************************************/
17052 +unsigned char QUALITY_MAP[] = {
17053 + 0x64, 0x64, 0x64, 0x63, 0x63, 0x62, 0x62, 0x61,
17054 + 0x61, 0x60, 0x60, 0x5f, 0x5f, 0x5e, 0x5d, 0x5c,
17055 + 0x5b, 0x5a, 0x59, 0x57, 0x56, 0x54, 0x52, 0x4f,
17056 + 0x4c, 0x49, 0x45, 0x41, 0x3c, 0x37, 0x31, 0x29,
17057 + 0x24, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
17058 + 0x22, 0x22, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20,
17059 + 0x20, 0x20, 0x20, 0x1f, 0x1f, 0x1e, 0x1e, 0x1e,
17060 + 0x1d, 0x1d, 0x1c, 0x1c, 0x1b, 0x1a, 0x19, 0x19,
17061 + 0x18, 0x17, 0x16, 0x15, 0x14, 0x12, 0x11, 0x0f,
17062 + 0x0e, 0x0c, 0x0a, 0x08, 0x06, 0x04, 0x01, 0x00
17065 +unsigned char STRENGTH_MAP[] = {
17066 + 0x64, 0x64, 0x63, 0x62, 0x61, 0x60, 0x5f, 0x5e,
17067 + 0x5d, 0x5c, 0x5b, 0x5a, 0x57, 0x54, 0x52, 0x50,
17068 + 0x4e, 0x4c, 0x4a, 0x48, 0x46, 0x44, 0x41, 0x3f,
17069 + 0x3c, 0x3a, 0x37, 0x36, 0x36, 0x1c, 0x1c, 0x1b,
17070 + 0x1b, 0x1a, 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17,
17071 + 0x17, 0x16, 0x16, 0x15, 0x15, 0x14, 0x14, 0x13,
17072 + 0x13, 0x12, 0x12, 0x11, 0x11, 0x10, 0x10, 0x0f,
17073 + 0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b,
17074 + 0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07,
17075 + 0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x02, 0x00
17078 +void rtl8180_RSSI_calc(struct net_device *dev, u8 *rssi, u8 *qual){
17079 + //void Mlme_UpdateRssiSQ(struct net_device *dev, u8 *rssi, u8 *qual){
17080 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17090 + orig_qual = *qual;
17091 + _rssi = 0; // avoid gcc complains..
17094 + temp = QUALITY_MAP[q];
17106 + switch(priv->rf_chip){
17107 + case RFCHIPID_RFMD:
17110 + if ( !lsb || !(temp2 <= 0x3c) ) {
17113 + temp2 = 100 * temp2 / 0x3c;
17115 + *rssi = temp2 & 0xff;
17116 + _rssi = temp2 & 0xff;
17118 + case RFCHIPID_INTERSIL:
17120 + temp2 &= 0xfffffffe;
17126 + temp2 = 0x4950df;
17129 + if ( temp2 <= 0x3e0000 ) {
17130 + if ( temp2 < 0xffef0000 )
17131 + temp2 = 0xffef0000;
17133 + temp2 = 0x3e0000;
17136 + temp2 -= 0xf0000;
17138 + temp2 += 0xf0000;
17141 + temp3 = 0x4d0000;
17144 + temp3 = temp3 / 0x6d;
17146 + _rssi = temp3 & 0xff;
17147 + *rssi = temp3 & 0xff;
17149 + case RFCHIPID_GCT:
17152 + if ( ! lsb || !(temp2 <= 0x3c) ){
17155 + temp2 = (100 * temp2) / 0x3c;
17157 + *rssi = temp2 & 0xff;
17158 + _rssi = temp2 & 0xff;
17160 + case RFCHIPID_PHILIPS:
17161 + if( orig_qual <= 0x4e ){
17162 + _rssi = STRENGTH_MAP[orig_qual];
17165 + orig_qual -= 0x80;
17166 + if ( !orig_qual ){
17177 + case RFCHIPID_MAXIM:
17185 + *rssi = temp2 & 0xff;
17186 + _rssi = temp2 & 0xff;
17190 + if ( _rssi < 0x64 ){
17191 + if ( _rssi == 0 ) {
17202 +void rtl8180_irq_enable(struct net_device *dev)
17204 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17205 + priv->irq_enabled = 1;
17207 + write_nic_word(dev,INTA_MASK,INTA_RXOK | INTA_RXDESCERR | INTA_RXOVERFLOW |\
17208 + INTA_TXOVERFLOW | INTA_HIPRIORITYDESCERR | INTA_HIPRIORITYDESCOK |\
17209 + INTA_NORMPRIORITYDESCERR | INTA_NORMPRIORITYDESCOK |\
17210 + INTA_LOWPRIORITYDESCERR | INTA_LOWPRIORITYDESCOK | INTA_TIMEOUT);
17212 + write_nic_word(dev,INTA_MASK, priv->irq_mask);
17216 +void rtl8180_irq_disable(struct net_device *dev)
17218 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17220 +#ifdef CONFIG_RTL8185B
17221 + write_nic_dword(dev,IMR,0);
17223 + write_nic_word(dev,INTA_MASK,0);
17225 + force_pci_posting(dev);
17226 + priv->irq_enabled = 0;
17230 +void rtl8180_set_mode(struct net_device *dev,int mode)
17233 + ecmd=read_nic_byte(dev, EPROM_CMD);
17234 + ecmd=ecmd &~ EPROM_CMD_OPERATING_MODE_MASK;
17235 + ecmd=ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
17236 + ecmd=ecmd &~ (1<<EPROM_CS_SHIFT);
17237 + ecmd=ecmd &~ (1<<EPROM_CK_SHIFT);
17238 + write_nic_byte(dev, EPROM_CMD, ecmd);
17241 +void rtl8180_adapter_start(struct net_device *dev);
17242 +void rtl8180_beacon_tx_enable(struct net_device *dev);
17244 +void rtl8180_update_msr(struct net_device *dev)
17246 + struct r8180_priv *priv = ieee80211_priv(dev);
17250 + msr = read_nic_byte(dev, MSR);
17251 + msr &= ~ MSR_LINK_MASK;
17253 + rxconf=read_nic_dword(dev,RX_CONF);
17255 + if(priv->ieee80211->state == IEEE80211_LINKED)
17257 + if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
17258 + msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
17259 + else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
17260 + msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
17261 + else if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
17262 + msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
17264 + msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
17265 + rxconf |= (1<<RX_CHECK_BSSID_SHIFT);
17268 + msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
17269 + rxconf &= ~(1<<RX_CHECK_BSSID_SHIFT);
17272 + write_nic_byte(dev, MSR, msr);
17273 + write_nic_dword(dev, RX_CONF, rxconf);
17279 +void rtl8180_set_chan(struct net_device *dev,short ch)
17281 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17283 + if((ch > 14) || (ch < 1))
17285 + printk("In %s: Invalid chnanel %d\n", __FUNCTION__, ch);
17290 + //printk("in %s:channel is %d\n",__FUNCTION__,ch);
17291 + priv->rf_set_chan(dev,priv->chan);
17296 +void rtl8180_rx_enable(struct net_device *dev)
17300 + /* for now we accept data, management & ctl frame*/
17301 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17303 + rxconf=read_nic_dword(dev,RX_CONF);
17304 + rxconf = rxconf &~ MAC_FILTER_MASK;
17305 + rxconf = rxconf | (1<<ACCEPT_MNG_FRAME_SHIFT);
17306 + rxconf = rxconf | (1<<ACCEPT_DATA_FRAME_SHIFT);
17307 + rxconf = rxconf | (1<<ACCEPT_BCAST_FRAME_SHIFT);
17308 + rxconf = rxconf | (1<<ACCEPT_MCAST_FRAME_SHIFT);
17309 +// rxconf = rxconf | (1<<ACCEPT_CRCERR_FRAME_SHIFT);
17310 + if (dev->flags & IFF_PROMISC) DMESG ("NIC in promisc mode");
17312 + if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
17313 + dev->flags & IFF_PROMISC){
17314 + rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
17316 + rxconf = rxconf | (1<<ACCEPT_NICMAC_FRAME_SHIFT);
17317 + if(priv->card_8185 == 0)
17318 + rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
17321 + /*if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
17322 + rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
17323 + rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
17326 + if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
17327 + rxconf = rxconf | (1<<ACCEPT_CTL_FRAME_SHIFT);
17328 + rxconf = rxconf | (1<<ACCEPT_ICVERR_FRAME_SHIFT);
17329 + rxconf = rxconf | (1<<ACCEPT_PWR_FRAME_SHIFT);
17332 + if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
17333 + rxconf = rxconf | (1<<ACCEPT_CRCERR_FRAME_SHIFT);
17335 + //if(!priv->card_8185){
17336 + rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
17337 + rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
17340 + rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
17341 + rxconf = rxconf &~ MAX_RX_DMA_MASK;
17342 + rxconf = rxconf | (MAX_RX_DMA_2048<<MAX_RX_DMA_SHIFT);
17344 + //if(!priv->card_8185)
17345 + rxconf = rxconf | RCR_ONLYERLPKT;
17347 + rxconf = rxconf &~ RCR_CS_MASK;
17348 + if(!priv->card_8185)
17349 + rxconf |= (priv->rcr_csense<<RCR_CS_SHIFT);
17350 +// rxconf &=~ 0xfff00000;
17351 +// rxconf |= 0x90100000;//9014f76f;
17352 + write_nic_dword(dev, RX_CONF, rxconf);
17354 + fix_rx_fifo(dev);
17357 + DMESG("rxconf: %x %x",rxconf ,read_nic_dword(dev,RX_CONF));
17359 + cmd=read_nic_byte(dev,CMD);
17360 + write_nic_byte(dev,CMD,cmd | (1<<CMD_RX_ENABLE_SHIFT));
17362 + /* In rtl8139 driver seems that DMA threshold has to be written
17363 + * after enabling RX, so we rewrite RX_CONFIG register
17366 +// write_nic_dword(dev, RX_CONF, rxconf);
17371 +void set_nic_txring(struct net_device *dev)
17373 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17374 +// DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
17376 + write_nic_dword(dev, TX_MANAGEPRIORITY_RING_ADDR, priv->txmapringdma);
17377 +// DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
17378 + write_nic_dword(dev, TX_BKPRIORITY_RING_ADDR, priv->txbkpringdma);
17379 +// DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
17380 + write_nic_dword(dev, TX_BEPRIORITY_RING_ADDR, priv->txbepringdma);
17381 +// DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
17382 + write_nic_dword(dev, TX_VIPRIORITY_RING_ADDR, priv->txvipringdma);
17383 +// DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
17384 + write_nic_dword(dev, TX_VOPRIORITY_RING_ADDR, priv->txvopringdma);
17385 +// DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
17386 + write_nic_dword(dev, TX_HIGHPRIORITY_RING_ADDR, priv->txhpringdma);
17387 +// DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
17389 + write_nic_dword(dev, TX_BEACON_RING_ADDR, priv->txbeaconringdma);
17393 +void rtl8180_conttx_enable(struct net_device *dev)
17396 + txconf = read_nic_dword(dev,TX_CONF);
17397 + txconf = txconf &~ TX_LOOPBACK_MASK;
17398 + txconf = txconf | (TX_LOOPBACK_CONTINUE <<TX_LOOPBACK_SHIFT);
17399 + write_nic_dword(dev,TX_CONF,txconf);
17403 +void rtl8180_conttx_disable(struct net_device *dev)
17406 + txconf = read_nic_dword(dev,TX_CONF);
17407 + txconf = txconf &~ TX_LOOPBACK_MASK;
17408 + txconf = txconf | (TX_LOOPBACK_NONE <<TX_LOOPBACK_SHIFT);
17409 + write_nic_dword(dev,TX_CONF,txconf);
17413 +void rtl8180_tx_enable(struct net_device *dev)
17419 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17420 + txconf= read_nic_dword(dev,TX_CONF);
17423 + if(priv->card_8185){
17426 + byte = read_nic_byte(dev,CW_CONF);
17427 + byte &= ~(1<<CW_CONF_PERPACKET_CW_SHIFT);
17428 + byte &= ~(1<<CW_CONF_PERPACKET_RETRY_SHIFT);
17429 + write_nic_byte(dev, CW_CONF, byte);
17431 + tx_agc_ctl = read_nic_byte(dev, TX_AGC_CTL);
17432 + tx_agc_ctl &= ~(1<<TX_AGC_CTL_PERPACKET_GAIN_SHIFT);
17433 + tx_agc_ctl &= ~(1<<TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT);
17434 + tx_agc_ctl |=(1<<TX_AGC_CTL_FEEDBACK_ANT);
17435 + write_nic_byte(dev, TX_AGC_CTL, tx_agc_ctl);
17437 + write_nic_word(dev, 0x5e, 0x01);
17438 + force_pci_posting(dev);
17440 + write_nic_word(dev, 0xfe, 0x10);
17441 + force_pci_posting(dev);
17443 + write_nic_word(dev, 0x5e, 0x00);
17444 + force_pci_posting(dev);
17447 + write_nic_byte(dev, 0xec, 0x3f); /* Disable early TX */
17450 + if(priv->card_8185){
17452 + txconf = txconf &~ (1<<TCR_PROBE_NOTIMESTAMP_SHIFT);
17457 + txconf= txconf &~ (1<<TX_CONF_HEADER_AUTOICREMENT_SHIFT);
17459 + txconf= txconf | (1<<TX_CONF_HEADER_AUTOICREMENT_SHIFT);
17462 + txconf = txconf &~ TX_LOOPBACK_MASK;
17463 + txconf = txconf | (TX_LOOPBACK_NONE <<TX_LOOPBACK_SHIFT);
17464 + txconf = txconf &~ TCR_DPRETRY_MASK;
17465 + txconf = txconf &~ TCR_RTSRETRY_MASK;
17466 + txconf = txconf | (priv->retry_data<<TX_DPRETRY_SHIFT);
17467 + txconf = txconf | (priv->retry_rts<<TX_RTSRETRY_SHIFT);
17468 + txconf = txconf &~ (1<<TX_NOCRC_SHIFT);
17470 + if(priv->card_8185){
17471 + if(priv->hw_plcp_len)
17472 + txconf = txconf &~ TCR_PLCP_LEN;
17474 + txconf = txconf | TCR_PLCP_LEN;
17476 + txconf = txconf &~ TCR_SAT;
17478 + txconf = txconf &~ TCR_MXDMA_MASK;
17479 + txconf = txconf | (TCR_MXDMA_2048<<TCR_MXDMA_SHIFT);
17480 + txconf = txconf | TCR_CWMIN;
17481 + txconf = txconf | TCR_DISCW;
17483 +// if(priv->ieee80211->hw_wep)
17484 +// txconf=txconf &~ (1<<TX_NOICV_SHIFT);
17486 + txconf=txconf | (1<<TX_NOICV_SHIFT);
17488 + write_nic_dword(dev,TX_CONF,txconf);
17491 + fix_tx_fifo(dev);
17494 + DMESG("txconf: %x %x",txconf,read_nic_dword(dev,TX_CONF));
17497 + cmd=read_nic_byte(dev,CMD);
17498 + write_nic_byte(dev,CMD,cmd | (1<<CMD_TX_ENABLE_SHIFT));
17501 + write_nic_dword(dev,TX_CONF,txconf);
17504 + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
17505 + write_nic_byte(dev, TX_DMA_POLLING, priv->dma_poll_mask);
17506 + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
17511 +void rtl8180_beacon_tx_enable(struct net_device *dev)
17513 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17515 + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
17516 +#ifdef CONFIG_RTL8185B
17517 + priv->dma_poll_stop_mask &= ~(TPPOLLSTOP_BQ);
17518 + write_nic_byte(dev,TPPollStop, priv->dma_poll_mask);
17520 + priv->dma_poll_mask &=~(1<<TX_DMA_STOP_BEACON_SHIFT);
17521 + write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
17523 + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
17527 +void rtl8180_beacon_tx_disable(struct net_device *dev)
17529 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17531 + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
17532 +#ifdef CONFIG_RTL8185B
17533 + priv->dma_poll_stop_mask |= TPPOLLSTOP_BQ;
17534 + write_nic_byte(dev,TPPollStop, priv->dma_poll_stop_mask);
17536 + priv->dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
17537 + write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
17539 + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
17544 +void rtl8180_rtx_disable(struct net_device *dev)
17547 + struct r8180_priv *priv = ieee80211_priv(dev);
17549 + cmd=read_nic_byte(dev,CMD);
17550 + write_nic_byte(dev, CMD, cmd &~ \
17551 + ((1<<CMD_RX_ENABLE_SHIFT)|(1<<CMD_TX_ENABLE_SHIFT)));
17552 + force_pci_posting(dev);
17554 + /*while (read_nic_byte(dev,CMD) & (1<<CMD_RX_ENABLE_SHIFT))
17558 + if(!priv->rx_skb_complete)
17559 + dev_kfree_skb_any(priv->rx_skb);
17563 +int alloc_tx_beacon_desc_ring(struct net_device *dev, int count)
17567 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17569 + priv->txbeaconring = (u32*)pci_alloc_consistent(priv->pdev,
17570 + sizeof(u32)*8*count,
17571 + &priv->txbeaconringdma);
17572 + if (!priv->txbeaconring) return -1;
17573 + for (tmp=priv->txbeaconring,i=0;i<count;i++){
17574 + *tmp = *tmp &~ (1<<31); // descriptor empty, owned by the drv
17576 + *(tmp+2) = (u32)dma_tmp;
17577 + *(tmp+3) = bufsize;
17580 + *(tmp+4) = (u32)priv->txbeaconringdma+((i+1)*8*4);
17582 + *(tmp+4) = (u32)priv->txbeaconringdma;
17590 +short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count,
17596 + dma_addr_t dma_desc, dma_tmp;
17597 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17598 + struct pci_dev *pdev = priv->pdev;
17601 + if((bufsize & 0xfff) != bufsize) {
17602 + DMESGE ("TX buffer allocation too large");
17605 + desc = (u32*)pci_alloc_consistent(pdev,
17606 + sizeof(u32)*8*count+256, &dma_desc);
17607 + if(desc==NULL) return -1;
17608 + if(dma_desc & 0xff){
17611 + * descriptor's buffer must be 256 byte aligned
17612 + * we shouldn't be here, since we set DMA mask !
17614 + DMESGW("Fixing TX alignment");
17615 + desc = (u32*)((u8*)desc + 256);
17616 +#if (defined(CONFIG_HIGHMEM64G) || defined(CONFIG_64BIT_PHYS_ADDR))
17617 + desc = (u32*)((u64)desc &~ 0xff);
17618 + dma_desc = (dma_addr_t)((u8*)dma_desc + 256);
17619 + dma_desc = (dma_addr_t)((u64)dma_desc &~ 0xff);
17621 + desc = (u32*)((u32)desc &~ 0xff);
17622 + dma_desc = (dma_addr_t)((u8*)dma_desc + 256);
17623 + dma_desc = (dma_addr_t)((u32)dma_desc &~ 0xff);
17627 + for (i=0;i<count;i++)
17629 + buf = (void*)pci_alloc_consistent(pdev,bufsize,&dma_tmp);
17630 + if (buf == NULL) return -ENOMEM;
17634 + case TX_NORMPRIORITY_RING_ADDR:
17635 + if(-1 == buffer_add(&(priv->txnpbufs),buf,dma_tmp,NULL)){
17636 + DMESGE("Unable to allocate mem for buffer NP");
17641 + case TX_LOWPRIORITY_RING_ADDR:
17642 + if(-1 == buffer_add(&(priv->txlpbufs),buf,dma_tmp,NULL)){
17643 + DMESGE("Unable to allocate mem for buffer LP");
17648 + case TX_HIGHPRIORITY_RING_ADDR:
17649 + if(-1 == buffer_add(&(priv->txhpbufs),buf,dma_tmp,NULL)){
17650 + DMESGE("Unable to allocate mem for buffer HP");
17655 + case TX_MANAGEPRIORITY_RING_ADDR:
17656 + if(-1 == buffer_add(&(priv->txmapbufs),buf,dma_tmp,NULL)){
17657 + DMESGE("Unable to allocate mem for buffer NP");
17662 + case TX_BKPRIORITY_RING_ADDR:
17663 + if(-1 == buffer_add(&(priv->txbkpbufs),buf,dma_tmp,NULL)){
17664 + DMESGE("Unable to allocate mem for buffer LP");
17668 + case TX_BEPRIORITY_RING_ADDR:
17669 + if(-1 == buffer_add(&(priv->txbepbufs),buf,dma_tmp,NULL)){
17670 + DMESGE("Unable to allocate mem for buffer NP");
17675 + case TX_VIPRIORITY_RING_ADDR:
17676 + if(-1 == buffer_add(&(priv->txvipbufs),buf,dma_tmp,NULL)){
17677 + DMESGE("Unable to allocate mem for buffer LP");
17681 + case TX_VOPRIORITY_RING_ADDR:
17682 + if(-1 == buffer_add(&(priv->txvopbufs),buf,dma_tmp,NULL)){
17683 + DMESGE("Unable to allocate mem for buffer NP");
17688 + case TX_HIGHPRIORITY_RING_ADDR:
17689 + if(-1 == buffer_add(&(priv->txhpbufs),buf,dma_tmp,NULL)){
17690 + DMESGE("Unable to allocate mem for buffer HP");
17694 + case TX_BEACON_RING_ADDR:
17695 + if(-1 == buffer_add(&(priv->txbeaconbufs),buf,dma_tmp,NULL)){
17696 + DMESGE("Unable to allocate mem for buffer BP");
17701 + *tmp = *tmp &~ (1<<31); // descriptor empty, owned by the drv
17702 + *(tmp+2) = (u32)dma_tmp;
17703 + *(tmp+3) = bufsize;
17706 + *(tmp+4) = (u32)dma_desc+((i+1)*8*4);
17708 + *(tmp+4) = (u32)dma_desc;
17714 + case TX_MANAGEPRIORITY_RING_ADDR:
17715 + priv->txmapringdma=dma_desc;
17716 + priv->txmapring=desc;
17719 + case TX_BKPRIORITY_RING_ADDR:
17720 + priv->txbkpringdma=dma_desc;
17721 + priv->txbkpring=desc;
17724 + case TX_BEPRIORITY_RING_ADDR:
17725 + priv->txbepringdma=dma_desc;
17726 + priv->txbepring=desc;
17729 + case TX_VIPRIORITY_RING_ADDR:
17730 + priv->txvipringdma=dma_desc;
17731 + priv->txvipring=desc;
17734 + case TX_VOPRIORITY_RING_ADDR:
17735 + priv->txvopringdma=dma_desc;
17736 + priv->txvopring=desc;
17739 + case TX_HIGHPRIORITY_RING_ADDR:
17740 + priv->txhpringdma=dma_desc;
17741 + priv->txhpring=desc;
17744 + case TX_BEACON_RING_ADDR:
17745 + priv->txbeaconringdma=dma_desc;
17746 + priv->txbeaconring=desc;
17752 + DMESG("Tx dma physical address: %x",dma_desc);
17759 +void free_tx_desc_rings(struct net_device *dev)
17762 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17763 + struct pci_dev *pdev=priv->pdev;
17764 + int count = priv->txringcount;
17766 + pci_free_consistent(pdev, sizeof(u32)*8*count+256,
17767 + priv->txmapring, priv->txmapringdma);
17768 + buffer_free(dev,&(priv->txmapbufs),priv->txbuffsize,1);
17770 + pci_free_consistent(pdev, sizeof(u32)*8*count+256,
17771 + priv->txbkpring, priv->txbkpringdma);
17772 + buffer_free(dev,&(priv->txbkpbufs),priv->txbuffsize,1);
17774 + pci_free_consistent(pdev, sizeof(u32)*8*count+256,
17775 + priv->txbepring, priv->txbepringdma);
17776 + buffer_free(dev,&(priv->txbepbufs),priv->txbuffsize,1);
17778 + pci_free_consistent(pdev, sizeof(u32)*8*count+256,
17779 + priv->txvipring, priv->txvipringdma);
17780 + buffer_free(dev,&(priv->txvipbufs),priv->txbuffsize,1);
17782 + pci_free_consistent(pdev, sizeof(u32)*8*count+256,
17783 + priv->txvopring, priv->txvopringdma);
17784 + buffer_free(dev,&(priv->txvopbufs),priv->txbuffsize,1);
17786 + pci_free_consistent(pdev, sizeof(u32)*8*count+256,
17787 + priv->txhpring, priv->txhpringdma);
17788 + buffer_free(dev,&(priv->txhpbufs),priv->txbuffsize,1);
17790 + count = priv->txbeaconcount;
17791 + pci_free_consistent(pdev, sizeof(u32)*8*count+256,
17792 + priv->txbeaconring, priv->txbeaconringdma);
17793 + buffer_free(dev,&(priv->txbeaconbufs),priv->txbuffsize,1);
17797 +void free_beacon_desc_ring(struct net_device *dev,int count)
17800 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17801 + struct pci_dev *pdev=priv->pdev;
17803 + pci_free_consistent(pdev, sizeof(u32)*8*count+256,
17804 + priv->txbeaconring, priv->txbeaconringdma);
17806 + if (priv->beacon_buf)
17807 + pci_free_consistent(priv->pdev,
17808 + priv->master_beaconsize,priv->beacon_buf,priv->beacondmabuf);
17812 +void free_rx_desc_ring(struct net_device *dev)
17814 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17815 + struct pci_dev *pdev = priv->pdev;
17817 + int count = priv->rxringcount;
17819 +#ifdef CONFIG_RTL8185B
17820 + pci_free_consistent(pdev, sizeof(u32)*8*count+256,
17821 + priv->rxring, priv->rxringdma);
17823 + pci_free_consistent(pdev, sizeof(u32)*4*count+256,
17824 + priv->rxring, priv->rxringdma);
17827 + buffer_free(dev,&(priv->rxbuffer),priv->rxbuffersize,0);
17831 +short alloc_rx_desc_ring(struct net_device *dev, u16 bufsize, int count)
17836 + dma_addr_t dma_desc,dma_tmp;
17837 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17838 + struct pci_dev *pdev=priv->pdev;
17842 +#ifdef CONFIG_RTL8185B
17843 + rx_desc_size = 8; // 4*8 = 32 bytes
17845 + rx_desc_size = 4;
17848 + if((bufsize & 0xfff) != bufsize){
17849 + DMESGE ("RX buffer allocation too large");
17853 + desc = (u32*)pci_alloc_consistent(pdev,sizeof(u32)*rx_desc_size*count+256,
17856 + if(dma_desc & 0xff){
17859 + * descriptor's buffer must be 256 byte aligned
17860 + * should never happen since we specify the DMA mask
17863 + DMESGW("Fixing RX alignment");
17864 + desc = (u32*)((u8*)desc + 256);
17865 +#if (defined(CONFIG_HIGHMEM64G) || defined(CONFIG_64BIT_PHYS_ADDR))
17866 + desc = (u32*)((u64)desc &~ 0xff);
17867 + dma_desc = (dma_addr_t)((u8*)dma_desc + 256);
17868 + dma_desc = (dma_addr_t)((u64)dma_desc &~ 0xff);
17870 + desc = (u32*)((u32)desc &~ 0xff);
17871 + dma_desc = (dma_addr_t)((u8*)dma_desc + 256);
17872 + dma_desc = (dma_addr_t)((u32)dma_desc &~ 0xff);
17876 + priv->rxring=desc;
17877 + priv->rxringdma=dma_desc;
17880 + for (i=0;i<count;i++){
17882 + if ((buf= kmalloc(bufsize * sizeof(u8),GFP_ATOMIC)) == NULL){
17883 + DMESGE("Failed to kmalloc RX buffer");
17887 + dma_tmp = pci_map_single(pdev,buf,bufsize * sizeof(u8),
17888 + PCI_DMA_FROMDEVICE);
17890 +#ifdef DEBUG_ZERO_RX
17892 + for(j=0;j<bufsize;j++) ((u8*)buf)[i] = 0;
17895 + //buf = (void*)pci_alloc_consistent(pdev,bufsize,&dma_tmp);
17896 + if(-1 == buffer_add(&(priv->rxbuffer), buf,dma_tmp,
17897 + &(priv->rxbufferhead))){
17898 + DMESGE("Unable to allocate mem RX buf");
17901 + *tmp = 0; //zero pads the header of the descriptor
17902 + *tmp = *tmp |( bufsize&0xfff);
17903 + *(tmp+2) = (u32)dma_tmp;
17904 + *tmp = *tmp |(1<<31); // descriptor void, owned by the NIC
17906 +#ifdef DEBUG_RXALLOC
17907 + DMESG("Alloc %x size buffer, DMA mem @ %x, virtual mem @ %x",
17908 + (u32)(bufsize&0xfff), (u32)dma_tmp, (u32)buf);
17911 + tmp=tmp+rx_desc_size;
17914 + *(tmp-rx_desc_size) = *(tmp-rx_desc_size) | (1<<30); // this is the last descriptor
17917 +#ifdef DEBUG_RXALLOC
17918 + DMESG("RX DMA physical address: %x",dma_desc);
17925 +void set_nic_rxring(struct net_device *dev)
17928 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
17930 + //rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
17932 + pgreg=read_nic_byte(dev, PGSELECT);
17933 + write_nic_byte(dev, PGSELECT, pgreg &~ (1<<PGSELECT_PG_SHIFT));
17935 + //rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
17937 + write_nic_dword(dev, RXRING_ADDR,priv->rxringdma);
17941 +void rtl8180_reset(struct net_device *dev)
17943 + //u32 txconf = 0x80e00707; //FIXME: Make me understandable
17946 + //write_nic_dword(dev,TX_CONF,txconf);
17948 + rtl8180_irq_disable(dev);
17950 + cr=read_nic_byte(dev,CMD);
17952 + cr = cr | (1<<CMD_RST_SHIFT);
17953 + write_nic_byte(dev,CMD,cr);
17955 + force_pci_posting(dev);
17959 + if(read_nic_byte(dev,CMD) & (1<<CMD_RST_SHIFT))
17960 + DMESGW("Card reset timeout!");
17962 + DMESG("Card successfully reset");
17964 +//#ifndef CONFIG_RTL8185B
17965 + rtl8180_set_mode(dev,EPROM_CMD_LOAD);
17966 + force_pci_posting(dev);
17971 +inline u16 ieeerate2rtlrate(int rate)
18004 +static u16 rtl_rate[] = {10,20,55,110,60,90,120,180,240,360,480,540,720};
18005 +inline u16 rtl8180_rate2rate(short rate)
18007 + if (rate >12) return 10;
18008 + return rtl_rate[rate];
18010 +inline u8 rtl8180_IsWirelessBMode(u16 rate)
18012 + if( ((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220) )
18016 +u16 N_DBPSOfRate(u16 DataRate);
18017 +u16 ComputeTxTime(
18020 + u8 bManagementFrame,
18021 + u8 bShortPreamble
18028 + if( rtl8180_IsWirelessBMode(DataRate) )
18030 + if( bManagementFrame || !bShortPreamble || DataRate == 10 )
18031 + { // long preamble
18032 + FrameTime = (u16)(144+48+(FrameLength*8/(DataRate/10)));
18035 + { // Short preamble
18036 + FrameTime = (u16)(72+24+(FrameLength*8/(DataRate/10)));
18038 + if( ( FrameLength*8 % (DataRate/10) ) != 0 ) //Get the Ceilling
18040 + } else { //802.11g DSSS-OFDM PLCP length field calculation.
18041 + N_DBPS = N_DBPSOfRate(DataRate);
18042 + Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
18043 + + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
18044 + FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
18046 + return FrameTime;
18048 +u16 N_DBPSOfRate(u16 DataRate)
18096 +// For Netgear case, they want good-looking singal strength.
18097 +// 2004.12.05, by rcnjko.
18100 +NetgearSignalStrengthTranslate(
18107 + // Step 1. Scale mapping.
18108 + if(CurrSS >= 71 && CurrSS <= 100)
18110 + RetSS = 90 + ((CurrSS - 70) / 3);
18112 + else if(CurrSS >= 41 && CurrSS <= 70)
18114 + RetSS = 78 + ((CurrSS - 40) / 3);
18116 + else if(CurrSS >= 31 && CurrSS <= 40)
18118 + RetSS = 66 + (CurrSS - 30);
18120 + else if(CurrSS >= 21 && CurrSS <= 30)
18122 + RetSS = 54 + (CurrSS - 20);
18124 + else if(CurrSS >= 5 && CurrSS <= 20)
18126 + RetSS = 42 + (((CurrSS - 5) * 2) / 3);
18128 + else if(CurrSS == 4)
18132 + else if(CurrSS == 3)
18136 + else if(CurrSS == 2)
18140 + else if(CurrSS == 1)
18148 + //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
18150 + // Step 2. Smoothing.
18153 + RetSS = ((LastSS * 5) + (RetSS)+ 5) / 6;
18155 + //RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
18161 +// Translate 0-100 signal strength index into dBm.
18164 +TranslateToDbm8185(
18165 + u8 SignalStrengthIndex // 0-100 index.
18168 + long SignalPower; // in dBm.
18170 + // Translate to dBm (x=0.5y-95).
18171 + SignalPower = (long)((SignalStrengthIndex + 1) >> 1);
18172 + SignalPower -= 95;
18174 + return SignalPower;
18178 +// Perform signal smoothing for dynamic mechanism.
18179 +// This is different with PerformSignalSmoothing8185 in smoothing fomula.
18180 +// No dramatic adjustion is apply because dynamic mechanism need some degree
18181 +// of correctness. Ported from 8187B.
18182 +// 2007-02-26, by Bruce.
18185 +PerformUndecoratedSignalSmoothing8185(
18186 + struct r8180_priv *priv,
18192 + // Determin the current packet is CCK rate.
18193 + priv->bCurCCKPkt = bCckRate;
18195 + if(priv->UndecoratedSmoothedSS >= 0)
18197 + priv->UndecoratedSmoothedSS = ( (priv->UndecoratedSmoothedSS * 5) + (priv->SignalStrength * 10) ) / 6;
18201 + priv->UndecoratedSmoothedSS = priv->SignalStrength * 10;
18204 + priv->UndercorateSmoothedRxPower = ( (priv->UndercorateSmoothedRxPower * 50) + (priv->RxPower* 11)) / 60;
18206 +// printk("Sommthing SignalSterngth (%d) => UndecoratedSmoothedSS (%d)\n", priv->SignalStrength, priv->UndecoratedSmoothedSS);
18207 +// printk("Sommthing RxPower (%d) => UndecoratedRxPower (%d)\n", priv->RxPower, priv->UndercorateSmoothedRxPower);
18209 + //if(priv->CurCCKRSSI >= 0 && bCckRate)
18212 + priv->CurCCKRSSI = priv->RSSI;
18216 + priv->CurCCKRSSI = 0;
18219 + // Boundary checking.
18220 + // TODO: The overflow condition does happen, if we want to fix,
18221 + // we shall recalculate thresholds first.
18222 + if(priv->UndecoratedSmoothedSS > 100)
18224 +// printk("UndecoratedSmoothedSS(%d) overflow, SignalStrength(%d)\n", priv->UndecoratedSmoothedSS, priv->SignalStrength);
18226 + if(priv->UndecoratedSmoothedSS < 0)
18228 +// printk("UndecoratedSmoothedSS(%d) underflow, SignalStrength(%d)\n", priv->UndecoratedSmoothedSS, priv->SignalStrength);
18235 +/* This is rough RX isr handling routine*/
18236 +void rtl8180_rx(struct net_device *dev)
18238 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
18239 + struct sk_buff *tmp_skb;
18241 + //struct sk_buff *skb;
18242 + short first,last;
18245 + unsigned char quality, signal;
18247 + //u32 *prism_hdr;
18252 + char rxpower = 0;
18254 + long RxAGC_dBm = 0;
18256 + u8 LNA_gain[4]={02, 17, 29, 39};
18258 + struct ieee80211_hdr *hdr;//by amy
18260 + u8 bHwError = 0,bCRC = 0,bICV = 0;
18264 + bool bCckRate = false;
18266 + long SignalStrengthIndex = 0;//+by amy 080312
18267 +// u8 SignalStrength = 0;
18268 + struct ieee80211_rx_stats stats = {
18272 + // .mac_time = jiffies,
18273 + .freq = IEEE80211_24GHZ_BAND,
18276 +#ifdef CONFIG_RTL8185B
18277 + stats.nic_type = NIC_8185B;
18278 + rx_desc_size = 8;
18281 + stats.nic_type = NIC_8185;
18282 + rx_desc_size = 4;
18284 + //printk("receive frame!%d\n",count++);
18285 + //if (!priv->rxbuffer) DMESG ("EE: NIC RX ack, but RX queue corrupted!");
18288 + if ((*(priv->rxringtail)) & (1<<31)) {
18290 + /* we have got an RX int, but the descriptor
18291 + * we are pointing is empty*/
18293 + priv->stats.rxnodata++;
18294 + priv->ieee80211->stats.rx_errors++;
18296 + /* if (! *(priv->rxring) & (1<<31)) {
18298 + priv->stats.rxreset++;
18299 + priv->rxringtail=priv->rxring;
18300 + priv->rxbuffer=priv->rxbufferhead;
18305 + /* Maybe it is possible that the NIC has skipped some descriptors or
18306 + * it has reset its internal pointer to the beginning of the ring
18307 + * we search for the first filled descriptor in the ring, or we break
18308 + * putting again the pointer in the old location if we do not found any.
18309 + * This is quite dangerous, what does happen if the nic writes
18310 + * two descriptor (say A and B) when we have just checked the descriptor
18311 + * A and we are going to check the descriptor B..This might happen if the
18312 + * interrupt was dummy, there was not really filled descriptors and
18313 + * the NIC didn't lose pointer
18316 + //priv->stats.rxwrkaround++;
18318 + tmp = priv->rxringtail;
18319 + while (*(priv->rxringtail) & (1<<31)){
18321 + priv->rxringtail+=4;
18323 + if(priv->rxringtail >=
18324 + (priv->rxring)+(priv->rxringcount )*4)
18325 + priv->rxringtail=priv->rxring;
18327 + priv->rxbuffer=(priv->rxbuffer->next);
18329 + if(priv->rxringtail == tmp ){
18330 + //DMESG("EE: Could not find RX pointer");
18331 + priv->stats.rxnopointer++;
18338 + tmp = priv->rxringtail;
18340 + if(tmp == priv->rxring)
18341 + //tmp = priv->rxring + (priv->rxringcount )*rx_desc_size; xiong-2006-11-15
18342 + tmp = priv->rxring + (priv->rxringcount - 1)*rx_desc_size;
18344 + tmp -= rx_desc_size;
18346 + if(! (*tmp & (1<<31)))
18348 + }while(tmp != priv->rxring);
18350 + if(tmp2) priv->rxringtail = tmp2;
18355 + /* while there are filled descriptors */
18356 + while(!(*(priv->rxringtail) & (1<<31))){
18357 + if(*(priv->rxringtail) & (1<<26))
18358 + DMESGW("RX buffer overflow");
18359 + if(*(priv->rxringtail) & (1<<12))
18360 + priv->stats.rxicverr++;
18362 + if(*(priv->rxringtail) & (1<<27)){
18363 + priv->stats.rxdmafail++;
18364 + //DMESG("EE: RX DMA FAILED at buffer pointed by descriptor %x",(u32)priv->rxringtail);
18368 + pci_dma_sync_single_for_cpu(priv->pdev,
18369 + priv->rxbuffer->dma,
18370 + priv->rxbuffersize * \
18372 + PCI_DMA_FROMDEVICE);
18374 + first = *(priv->rxringtail) & (1<<29) ? 1:0;
18375 + if(first) priv->rx_prevlen=0;
18377 + last = *(priv->rxringtail) & (1<<28) ? 1:0;
18379 + lastlen=((*priv->rxringtail) &0xfff);
18381 + /* if the last descriptor (that should
18382 + * tell us the total packet len) tell
18383 + * us something less than the descriptors
18384 + * len we had until now, then there is some
18386 + * workaround to prevent kernel panic
18388 + if(lastlen < priv->rx_prevlen)
18391 + len=lastlen-priv->rx_prevlen;
18393 + if(*(priv->rxringtail) & (1<<13)) {
18394 +//lastlen=((*priv->rxringtail) &0xfff);
18395 + if ((*(priv->rxringtail) & 0xfff) <500)
18396 + priv->stats.rxcrcerrmin++;
18397 + else if ((*(priv->rxringtail) & 0x0fff) >1000)
18398 + priv->stats.rxcrcerrmax++;
18400 + priv->stats.rxcrcerrmid++;
18405 + len = priv->rxbuffersize;
18408 +#ifdef CONFIG_RTL8185B
18409 + if(first && last) {
18410 + padding = ((*(priv->rxringtail+3))&(0x04000000))>>26;
18411 + }else if(first) {
18412 + padding = ((*(priv->rxringtail+3))&(0x04000000))>>26;
18419 +#ifdef CONFIG_RTL818X_S
18423 + priv->rx_prevlen+=len;
18425 + if(priv->rx_prevlen > MAX_FRAG_THRESHOLD + 100){
18426 + /* HW is probably passing several buggy frames
18427 + * without FD or LD flag set.
18428 + * Throw this garbage away to prevent skb
18429 + * memory exausting
18431 + if(!priv->rx_skb_complete)
18432 + dev_kfree_skb_any(priv->rx_skb);
18433 + priv->rx_skb_complete = 1;
18436 +#ifdef DEBUG_RX_FRAG
18437 + DMESG("Iteration.. len %x",len);
18438 + if(first) DMESG ("First descriptor");
18439 + if(last) DMESG("Last descriptor");
18442 +#ifdef DEBUG_RX_VERBOSE
18443 + print_buffer( priv->rxbuffer->buf, len);
18446 +#ifdef CONFIG_RTL8185B
18447 + signal=(unsigned char)(((*(priv->rxringtail+3))& (0x00ff0000))>>16);
18448 + signal=(signal&0xfe)>>1; // Modify by hikaru 6.6
18450 + quality=(unsigned char)((*(priv->rxringtail+3)) & (0xff));
18452 + stats.mac_time[0] = *(priv->rxringtail+1);
18453 + stats.mac_time[1] = *(priv->rxringtail+2);
18454 + rxpower =((char)(((*(priv->rxringtail+4))& (0x00ff0000))>>16))/2 - 42;
18455 + RSSI = ((u8)(((*(priv->rxringtail+3)) & (0x0000ff00))>> 8)) & (0x7f);
18458 + signal=((*(priv->rxringtail+1))& (0xff0000))>>16;
18459 + signal=(signal&0xfe)>>1; // Modify by hikaru 6.6
18461 + quality=((*(priv->rxringtail+1)) & (0xff));
18463 + stats.mac_time[0] = *(priv->rxringtail+2);
18464 + stats.mac_time[1] = *(priv->rxringtail+3);
18466 + rate=((*(priv->rxringtail)) &
18467 + ((1<<23)|(1<<22)|(1<<21)|(1<<20)))>>20;
18469 + stats.rate = rtl8180_rate2rate(rate);
18470 + //DMESG("%d",rate);
18471 + Antenna = (((*(priv->rxringtail +3))& (0x00008000)) == 0 )? 0:1 ;
18472 +// printk("in rtl8180_rx():Antenna is %d\n",Antenna);
18473 +//by amy for antenna
18474 + if(!rtl8180_IsWirelessBMode(stats.rate))
18477 + RxAGC_dBm = rxpower+1; //bias
18481 + RxAGC_dBm = signal;//bit 0 discard
18483 + LNA = (u8) (RxAGC_dBm & 0x60 ) >> 5 ; //bit 6~ bit 5
18484 + BB = (u8) (RxAGC_dBm & 0x1F); // bit 4 ~ bit 0
18486 + RxAGC_dBm = -( LNA_gain[LNA] + (BB *2) ); //Pin_11b=-(LNA_gain+BB_gain) (dBm)
18488 + RxAGC_dBm +=4; //bias
18491 + if(RxAGC_dBm & 0x80) //absolute value
18492 + RXAGC= ~(RxAGC_dBm)+1;
18493 + bCckRate = rtl8180_IsWirelessBMode(stats.rate);
18494 + // Translate RXAGC into 1-100.
18495 + if(!rtl8180_IsWirelessBMode(stats.rate))
18499 + else if(RXAGC<25)
18501 + RXAGC=(90-RXAGC)*100/65;
18507 + else if(RXAGC<30)
18509 + RXAGC=(95-RXAGC)*100/65;
18511 + priv->SignalStrength = (u8)RXAGC;
18512 + priv->RecvSignalPower = RxAGC_dBm ; // It can use directly by SD3 CMLin
18513 + priv->RxPower = rxpower;
18514 + priv->RSSI = RSSI;
18516 + // SQ translation formular is provided by SD3 DZ. 2006.06.27, by rcnjko.
18517 + if(quality >= 127)
18518 + quality = 1;//0; //0 will cause epc to show signal zero , walk aroud now;
18519 + else if(quality < 27)
18522 + quality = 127 - quality;
18523 + priv->SignalQuality = quality;
18524 + if(!priv->card_8185)
18525 + printk("check your card type\n");
18527 + stats.signal = (u8)quality;//priv->wstats.qual.level = priv->SignalStrength;
18528 + stats.signalstrength = RXAGC;
18529 + if(stats.signalstrength > 100)
18530 + stats.signalstrength = 100;
18531 + stats.signalstrength = (stats.signalstrength * 70)/100 + 30;
18532 + // printk("==========================>rx : RXAGC is %d,signalstrength is %d\n",RXAGC,stats.signalstrength);
18533 + stats.rssi = priv->wstats.qual.qual = priv->SignalQuality;
18534 + stats.noise = priv->wstats.qual.noise = 100 - priv ->wstats.qual.qual;
18536 + bHwError = (((*(priv->rxringtail))& (0x00000fff)) == 4080)| (((*(priv->rxringtail))& (0x04000000)) != 0 )
18537 + | (((*(priv->rxringtail))& (0x08000000)) != 0 )| (((~(*(priv->rxringtail)))& (0x10000000)) != 0 )| (((~(*(priv->rxringtail)))& (0x20000000)) != 0 );
18538 + bCRC = ((*(priv->rxringtail)) & (0x00002000)) >> 13;
18539 + bICV = ((*(priv->rxringtail)) & (0x00001000)) >> 12;
18540 + hdr = (struct ieee80211_hdr *)priv->rxbuffer->buf;
18541 + fc = le16_to_cpu(hdr->frame_ctl);
18542 + type = WLAN_FC_GET_TYPE(fc);
18544 + if((IEEE80211_FTYPE_CTL != type) &&
18545 + (eqMacAddr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3))
18546 + && (!bHwError) && (!bCRC)&& (!bICV))
18549 + // Perform signal smoothing for dynamic mechanism on demand.
18550 + // This is different with PerformSignalSmoothing8185 in smoothing fomula.
18551 + // No dramatic adjustion is apply because dynamic mechanism need some degree
18552 + // of correctness. 2007.01.23, by shien chang.
18553 + PerformUndecoratedSignalSmoothing8185(priv,bCckRate);
18555 + // For good-looking singal strength.
18557 + SignalStrengthIndex = NetgearSignalStrengthTranslate(
18558 + priv->LastSignalStrengthInPercent,
18559 + priv->SignalStrength);
18561 + priv->LastSignalStrengthInPercent = SignalStrengthIndex;
18562 + priv->Stats_SignalStrength = TranslateToDbm8185((u8)SignalStrengthIndex);
18564 + // We need more correct power of received packets and the "SignalStrength" of RxStats is beautified,
18565 + // so we record the correct power here.
18567 + priv->Stats_SignalQuality =(long) (priv->Stats_SignalQuality * 5 + (long)priv->SignalQuality + 5) / 6;
18568 + priv->Stats_RecvSignalPower = (long)(priv->Stats_RecvSignalPower * 5 + priv->RecvSignalPower -1) / 6;
18570 + // Figure out which antenna that received the lasted packet.
18571 + priv->LastRxPktAntenna = Antenna ? 1 : 0; // 0: aux, 1: main.
18573 + SwAntennaDiversityRxOk8185(dev, priv->SignalStrength);
18576 +//by amy for antenna
18585 + if(!priv->rx_skb_complete){
18586 + /* seems that HW sometimes fails to reiceve and
18587 + doesn't provide the last descriptor */
18588 +#ifdef DEBUG_RX_SKB
18589 + DMESG("going to free incomplete skb");
18591 + dev_kfree_skb_any(priv->rx_skb);
18592 + priv->stats.rxnolast++;
18593 +#ifdef DEBUG_RX_SKB
18594 + DMESG("free incomplete skb OK");
18597 + /* support for prism header has been originally added by Christian */
18598 + if(priv->prism_hdr && priv->ieee80211->iw_mode == IW_MODE_MONITOR){
18601 + priv->rx_skb = dev_alloc_skb(len+2+PRISM_HDR_SIZE);
18602 + if(! priv->rx_skb) goto drop;
18604 + prism_hdr = (u32*) skb_put(priv->rx_skb,PRISM_HDR_SIZE);
18605 + prism_hdr[0]=htonl(0x80211001); //version
18606 + prism_hdr[1]=htonl(0x40); //length
18607 + prism_hdr[2]=htonl(stats.mac_time[1]); //mactime (HIGH)
18608 + prism_hdr[3]=htonl(stats.mac_time[0]); //mactime (LOW)
18609 + rdtsc(prism_hdr[5], prism_hdr[4]); //hostime (LOW+HIGH)
18610 + prism_hdr[4]=htonl(prism_hdr[4]); //Byte-Order aendern
18611 + prism_hdr[5]=htonl(prism_hdr[5]); //Byte-Order aendern
18612 + prism_hdr[6]=0x00; //phytype
18613 + prism_hdr[7]=htonl(priv->chan); //channel
18614 + prism_hdr[8]=htonl(stats.rate); //datarate
18615 + prism_hdr[9]=0x00; //antenna
18616 + prism_hdr[10]=0x00; //priority
18617 + prism_hdr[11]=0x00; //ssi_type
18618 + prism_hdr[12]=htonl(stats.signal); //ssi_signal
18619 + prism_hdr[13]=htonl(stats.noise); //ssi_noise
18620 + prism_hdr[14]=0x00; //preamble
18621 + prism_hdr[15]=0x00; //encoding
18625 + priv->rx_skb = dev_alloc_skb(len+2);
18626 + if( !priv->rx_skb) goto drop;
18627 +#ifdef DEBUG_RX_SKB
18628 + DMESG("Alloc initial skb %x",len+2);
18632 + priv->rx_skb_complete=0;
18633 + priv->rx_skb->dev=dev;
18635 + /* if we are here we should have already RXed
18636 + * the first frame.
18637 + * If we get here and the skb is not allocated then
18638 + * we have just throw out garbage (skb not allocated)
18639 + * and we are still rxing garbage....
18641 + if(!priv->rx_skb_complete){
18643 + tmp_skb= dev_alloc_skb(priv->rx_skb->len +len+2);
18645 + if(!tmp_skb) goto drop;
18647 + tmp_skb->dev=dev;
18648 +#ifdef DEBUG_RX_SKB
18649 + DMESG("Realloc skb %x",len+2);
18652 +#ifdef DEBUG_RX_SKB
18653 + DMESG("going copy prev frag %x",priv->rx_skb->len);
18655 + memcpy(skb_put(tmp_skb,priv->rx_skb->len),
18656 + priv->rx_skb->data,
18657 + priv->rx_skb->len);
18658 +#ifdef DEBUG_RX_SKB
18659 + DMESG("skb copy prev frag complete");
18662 + dev_kfree_skb_any(priv->rx_skb);
18663 +#ifdef DEBUG_RX_SKB
18664 + DMESG("prev skb free ok");
18667 + priv->rx_skb=tmp_skb;
18670 +#ifdef DEBUG_RX_SKB
18671 + DMESG("going to copy current payload %x",len);
18673 + if(!priv->rx_skb_complete) {
18674 +#ifdef CONFIG_RTL8185B
18676 + memcpy(skb_put(priv->rx_skb,len),
18677 + (((unsigned char *)priv->rxbuffer->buf) + 2),len);
18680 + memcpy(skb_put(priv->rx_skb,len),
18681 + priv->rxbuffer->buf,len);
18682 +#ifdef CONFIG_RTL8185B
18686 +#ifdef DEBUG_RX_SKB
18687 + DMESG("current fragment skb copy complete");
18690 + if(last && !priv->rx_skb_complete){
18692 +#ifdef DEBUG_RX_SKB
18693 + DMESG("Got last fragment");
18696 + if(priv->rx_skb->len > 4)
18697 + skb_trim(priv->rx_skb,priv->rx_skb->len-4);
18698 +#ifdef DEBUG_RX_SKB
18699 + DMESG("yanked out crc, passing to the upper layer");
18702 +#ifndef RX_DONT_PASS_UL
18703 + if(!ieee80211_rx(priv->ieee80211,
18704 + priv->rx_skb, &stats)){
18706 + DMESGW("Packet not consumed");
18708 +#endif // RX_DONT_PASS_UL
18710 + dev_kfree_skb_any(priv->rx_skb);
18711 +#ifndef RX_DONT_PASS_UL
18716 + DMESG("Rcv frag");
18719 + priv->rx_skb_complete=1;
18724 + pci_dma_sync_single_for_device(priv->pdev,
18725 + priv->rxbuffer->dma,
18726 + priv->rxbuffersize * \
18728 + PCI_DMA_FROMDEVICE);
18731 +drop: // this is used when we have not enought mem
18733 + /* restore the descriptor */
18734 + *(priv->rxringtail+2)=priv->rxbuffer->dma;
18735 + *(priv->rxringtail)=*(priv->rxringtail) &~ 0xfff;
18736 + *(priv->rxringtail)=
18737 + *(priv->rxringtail) | priv->rxbuffersize;
18739 + *(priv->rxringtail)=
18740 + *(priv->rxringtail) | (1<<31);
18741 + //^empty descriptor
18746 + DMESG("Current descriptor: %x",(u32)priv->rxringtail);
18748 + //unsigned long flags;
18749 + //spin_lock_irqsave(&priv->irq_lock,flags);
18751 + priv->rxringtail+=rx_desc_size;
18752 + if(priv->rxringtail >=
18753 + (priv->rxring)+(priv->rxringcount )*rx_desc_size)
18754 + priv->rxringtail=priv->rxring;
18756 + //spin_unlock_irqrestore(&priv->irq_lock,flags);
18759 + priv->rxbuffer=(priv->rxbuffer->next);
18765 +// if(get_curr_tx_free_desc(dev,priority))
18766 +// ieee80211_sta_ps_sleep(priv->ieee80211, &tmp, &tmp2);
18773 +void rtl8180_dma_kick(struct net_device *dev, int priority)
18775 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
18777 + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
18780 + switch(priority){
18782 + case LOW_PRIORITY:
18784 + write_nic_byte(dev,TX_DMA_POLLING,
18785 + (1<< TX_DMA_POLLING_LOWPRIORITY_SHIFT) |
18786 + priv->dma_poll_mask);
18789 + case NORM_PRIORITY:
18791 + write_nic_byte(dev,TX_DMA_POLLING,
18792 + (1<< TX_DMA_POLLING_NORMPRIORITY_SHIFT) |
18793 + priv->dma_poll_mask);
18796 + case HI_PRIORITY:
18798 + write_nic_byte(dev,TX_DMA_POLLING,
18799 + (1<< TX_DMA_POLLING_HIPRIORITY_SHIFT) |
18800 + priv->dma_poll_mask);
18805 + write_nic_byte(dev, TX_DMA_POLLING,
18806 + (1 << (priority + 1)) | priv->dma_poll_mask);
18807 + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
18809 + force_pci_posting(dev);
18813 +void rtl8180_tx_queues_stop(struct net_device *dev)
18815 + //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
18816 + u8 dma_poll_mask = (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
18817 + dma_poll_mask |= (1<<TX_DMA_STOP_HIPRIORITY_SHIFT);
18818 + dma_poll_mask |= (1<<TX_DMA_STOP_NORMPRIORITY_SHIFT);
18819 + dma_poll_mask |= (1<<TX_DMA_STOP_BEACON_SHIFT);
18821 + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
18822 + write_nic_byte(dev,TX_DMA_POLLING,dma_poll_mask);
18823 + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
18827 +void rtl8180_data_hard_stop(struct net_device *dev)
18829 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
18831 + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
18832 +#ifdef CONFIG_RTL8185B
18833 + priv->dma_poll_stop_mask |= TPPOLLSTOP_AC_VIQ;
18834 + write_nic_byte(dev,TPPollStop, priv->dma_poll_stop_mask);
18836 + priv->dma_poll_mask |= (1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
18837 + write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
18839 + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
18843 +void rtl8180_data_hard_resume(struct net_device *dev)
18845 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
18847 + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
18848 +#ifdef CONFIG_RTL8185B
18849 + priv->dma_poll_stop_mask &= ~(TPPOLLSTOP_AC_VIQ);
18850 + write_nic_byte(dev,TPPollStop, priv->dma_poll_stop_mask);
18852 + priv->dma_poll_mask &= ~(1<<TX_DMA_STOP_LOWPRIORITY_SHIFT);
18853 + write_nic_byte(dev,TX_DMA_POLLING,priv->dma_poll_mask);
18855 + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
18859 +/* this function TX data frames when the ieee80211 stack requires this.
18860 + * It checks also if we need to stop the ieee tx queue, eventually do it
18862 +void rtl8180_hard_data_xmit(struct sk_buff *skb,struct net_device *dev, int
18865 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
18867 + struct ieee80211_hdr_3addr *h = (struct ieee80211_hdr_3addr *) skb->data;
18868 + short morefrag = (h->frame_ctl) & IEEE80211_FCTL_MOREFRAGS;
18869 + unsigned long flags;
18871 + //static int count = 0;
18873 + mode = priv->ieee80211->iw_mode;
18875 + rate = ieeerate2rtlrate(rate);
18877 + * This function doesn't require lock because we make
18878 + * sure it's called with the tx_lock already acquired.
18879 + * this come from the kernel's hard_xmit callback (trought
18880 + * the ieee stack, or from the try_wake_queue (again trought
18881 + * the ieee stack.
18883 +#ifdef CONFIG_RTL8185B
18884 + priority = AC2Q(skb->priority);
18886 + priority = LOW_PRIORITY;
18888 + spin_lock_irqsave(&priv->tx_lock,flags);
18890 + if(priv->ieee80211->bHwRadioOff)
18892 + spin_unlock_irqrestore(&priv->tx_lock,flags);
18897 + //printk(KERN_WARNING "priority = %d@%d\n", priority, count++);
18898 + if (!check_nic_enought_desc(dev, priority)){
18899 + //DMESG("Error: no descriptor left by previous TX (avail %d) ",
18900 + // get_curr_tx_free_desc(dev, priority));
18901 + DMESGW("Error: no descriptor left by previous TX (avail %d) ",
18902 + get_curr_tx_free_desc(dev, priority));
18903 + //printk(KERN_WARNING "==============================================================> \n");
18904 + ieee80211_stop_queue(priv->ieee80211);
18906 + rtl8180_tx(dev, skb->data, skb->len, priority, morefrag,0,rate);
18907 + if (!check_nic_enought_desc(dev, priority))
18908 + ieee80211_stop_queue(priv->ieee80211);
18910 + //dev_kfree_skb_any(skb);
18911 + spin_unlock_irqrestore(&priv->tx_lock,flags);
18915 +/* This is a rough attempt to TX a frame
18916 + * This is called by the ieee 80211 stack to TX management frames.
18917 + * If the ring is full packet are dropped (for data frame the queue
18918 + * is stopped before this can happen). For this reason it is better
18919 + * if the descriptors are larger than the largest management frame
18920 + * we intend to TX: i'm unsure what the HW does if it will not found
18921 + * the last fragment of a frame because it has been dropped...
18922 + * Since queues for Management and Data frames are different we
18923 + * might use a different lock than tx_lock (for example mgmt_tx_lock)
18925 +/* these function may loops if invoked with 0 descriptors or 0 len buffer*/
18926 +int rtl8180_hard_start_xmit(struct sk_buff *skb,struct net_device *dev)
18928 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
18930 + unsigned long flags;
18934 +#ifdef CONFIG_RTL8185B
18935 + priority = MANAGE_PRIORITY;
18937 + priority = NORM_PRIORITY;
18940 + spin_lock_irqsave(&priv->tx_lock,flags);
18942 + if(priv->ieee80211->bHwRadioOff)
18944 + spin_unlock_irqrestore(&priv->tx_lock,flags);
18946 + dev_kfree_skb_any(skb);
18950 + rtl8180_tx(dev, skb->data, skb->len, priority,
18951 + 0, 0,ieeerate2rtlrate(priv->ieee80211->basic_rate));
18953 + priv->ieee80211->stats.tx_bytes+=skb->len;
18954 + priv->ieee80211->stats.tx_packets++;
18955 + spin_unlock_irqrestore(&priv->tx_lock,flags);
18957 + dev_kfree_skb_any(skb);
18961 +// longpre 144+48 shortpre 72+24
18962 +u16 rtl8180_len2duration(u32 len, short rate,short* ext)
18971 + duration = ((len+4)<<4) /0x2;
18972 + drift = ((len+4)<<4) % 0x2;
18973 + if(drift ==0 ) break;
18979 + duration = ((len+4)<<4) /0x4;
18980 + drift = ((len+4)<<4) % 0x4;
18981 + if(drift ==0 ) break;
18985 + case 2: //5.5mbps
18987 + duration = ((len+4)<<4) /0xb;
18988 + drift = ((len+4)<<4) % 0xb;
18997 + duration = ((len+4)<<4) /0x16;
18998 + drift = ((len+4)<<4) % 0x16;
19012 +void rtl8180_prepare_beacon(struct net_device *dev)
19015 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
19017 + struct sk_buff *skb;
19019 + u16 word = read_nic_word(dev, BcnItv);
19020 + word &= ~BcnItv_BcnItv; // clear Bcn_Itv
19021 + word |= cpu_to_le16(priv->ieee80211->current_network.beacon_interval);//0x64;
19022 + write_nic_word(dev, BcnItv, word);
19025 + skb = ieee80211_get_beacon(priv->ieee80211);
19027 + rtl8180_tx(dev,skb->data,skb->len,BEACON_PRIORITY,
19028 + 0,0,ieeerate2rtlrate(priv->ieee80211->basic_rate));
19029 + dev_kfree_skb_any(skb);
19032 + //DMESG("size %x",len);
19033 + if(*tail & (1<<31)){
19035 + //DMESG("No more beacon TX desc");
19039 + //while(! *tail & (1<<31)){
19040 + *tail= 0; // zeroes header
19042 + *tail = *tail| (1<<29) ; //fist segment of the packet
19043 + *tail = (*tail) | (1<<28); // last segment
19044 + // *tail = *tail | (1<<18); // this is a beacon frame
19045 + *(tail+3)=*(tail+3) &~ 0xfff;
19046 + *(tail+3)=*(tail+3) | len; // buffer lenght
19047 + *tail = *tail |len;
19048 + // zeroes the second 32-bits dword of the descriptor
19050 + *tail = *tail | (rate << 24);
19052 + duration = rtl8180_len2duration(len,rate,&ext);
19054 + *(tail+1) = *(tail+1) | ((duration & 0x7fff)<<16);
19056 + *tail = *tail | (1<<31);
19057 + //^ descriptor ready to be txed
19058 + if((tail - begin)/8 == priv->txbeaconcount-1)
19066 +/* This function do the real dirty work: it enqueues a TX command
19067 + * descriptor in the ring buffer, copyes the frame in a TX buffer
19068 + * and kicks the NIC to ensure it does the DMA transfer.
19070 +short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority,
19071 + short morefrag, short descfrag, int rate)
19073 + struct r8180_priv *priv = ieee80211_priv(dev);
19074 + u32 *tail,*temp_tail;
19081 + //u16 AckCtsTime;
19085 + struct buffer* buflist;
19086 + //unsigned long flags;
19087 +#ifdef CONFIG_RTL8185B
19088 + struct ieee80211_hdr_3addr *frag_hdr = (struct ieee80211_hdr_3addr *)txbuf;
19089 + u8 dest[ETH_ALEN];
19090 + u8 bUseShortPreamble = 0;
19091 + u8 bCTSEnable = 0;
19092 + u8 bRTSEnable = 0;
19093 + //u16 RTSRate = 22;
19094 + //u8 RetryLimit = 0;
19095 + u16 Duration = 0;
19097 + u16 ThisFrameTime = 0;
19098 + u16 TxDescDuration = 0;
19099 + u8 ownbit_flag = false; //added by david woo for sync Tx, 2007.12.14
19102 + switch(priority) {
19103 + case MANAGE_PRIORITY:
19104 + tail=priv->txmapringtail;
19105 + begin=priv->txmapring;
19106 + buflist = priv->txmapbufstail;
19107 + count = priv->txringcount;
19110 + case BK_PRIORITY:
19111 + tail=priv->txbkpringtail;
19112 + begin=priv->txbkpring;
19113 + buflist = priv->txbkpbufstail;
19114 + count = priv->txringcount;
19117 + case BE_PRIORITY:
19118 + tail=priv->txbepringtail;
19119 + begin=priv->txbepring;
19120 + buflist = priv->txbepbufstail;
19121 + count = priv->txringcount;
19124 + case VI_PRIORITY:
19125 + tail=priv->txvipringtail;
19126 + begin=priv->txvipring;
19127 + buflist = priv->txvipbufstail;
19128 + count = priv->txringcount;
19131 + case VO_PRIORITY:
19132 + tail=priv->txvopringtail;
19133 + begin=priv->txvopring;
19134 + buflist = priv->txvopbufstail;
19135 + count = priv->txringcount;
19138 + case HI_PRIORITY:
19139 + tail=priv->txhpringtail;
19140 + begin=priv->txhpring;
19141 + buflist = priv->txhpbufstail;
19142 + count = priv->txringcount;
19145 + case BEACON_PRIORITY:
19146 + tail=priv->txbeaconringtail;
19147 + begin=priv->txbeaconring;
19148 + buflist = priv->txbeaconbufstail;
19149 + count = priv->txbeaconcount;
19157 + //printk("in rtl8180_tx(): rate is %d\n",priv->ieee80211->rate);
19159 + memcpy(&dest, frag_hdr->addr1, ETH_ALEN);
19160 + if (is_multicast_ether_addr(dest) ||
19161 + is_broadcast_ether_addr(dest))
19168 + ThisFrameTime = ComputeTxTime(len + sCrcLng, rtl8180_rate2rate(rate), 0, bUseShortPreamble);
19169 + TxDescDuration = ThisFrameTime;
19170 + } else {// Unicast packet
19174 + //YJ,add,080828,for Keep alive
19175 + priv->NumTxUnicast++;
19177 + // Figure out ACK rate according to BSS basic rate and Tx rate, 2006.03.08 by rcnjko.
19178 + //AckRate = ComputeAckRate( pMgntInfo->mBrates, (u1Byte)(pTcb->DataRate) );
19179 + // Figure out ACK time according to the AckRate and assume long preamble is used on receiver, 2006.03.08, by rcnjko.
19180 + //AckTime = ComputeTxTime( sAckCtsLng/8, AckRate, FALSE, FALSE);
19181 + //For simplicity, just use the 1M basic rate
19182 + //AckTime = ComputeTxTime(14, 540,0, 0); // AckCTSLng = 14 use 1M bps send
19183 + AckTime = ComputeTxTime(14, 10,0, 0); // AckCTSLng = 14 use 1M bps send
19184 + //AckTime = ComputeTxTime(14, 2,false, false); // AckCTSLng = 14 use 1M bps send
19186 + if ( ((len + sCrcLng) > priv->rts) && priv->rts )
19188 + u16 RtsTime, CtsTime;
19193 + // Rate and time required for RTS.
19194 + RtsTime = ComputeTxTime( sAckCtsLng/8,priv->ieee80211->basic_rate, 0, 0);
19195 + // Rate and time required for CTS.
19196 + CtsTime = ComputeTxTime(14, 10,0, 0); // AckCTSLng = 14 use 1M bps send
19198 + // Figure out time required to transmit this frame.
19199 + ThisFrameTime = ComputeTxTime(len + sCrcLng,
19200 + rtl8180_rate2rate(rate),
19202 + bUseShortPreamble);
19204 + // RTS-CTS-ThisFrame-ACK.
19205 + RtsDur = CtsTime + ThisFrameTime + AckTime + 3*aSifsTime;
19207 + TxDescDuration = RtsTime + RtsDur;
19209 + else {// Normal case.
19214 + ThisFrameTime = ComputeTxTime(len + sCrcLng, rtl8180_rate2rate(rate), 0, bUseShortPreamble);
19215 + TxDescDuration = ThisFrameTime + aSifsTime + AckTime;
19218 + if(!(frag_hdr->frame_ctl & IEEE80211_FCTL_MOREFRAGS)) { //no more fragment
19219 + // ThisFrame-ACK.
19220 + Duration = aSifsTime + AckTime;
19221 + } else { // One or more fragments remained.
19222 + u16 NextFragTime;
19223 + NextFragTime = ComputeTxTime( len + sCrcLng, //pretend following packet length equal current packet
19224 + rtl8180_rate2rate(rate),
19226 + bUseShortPreamble );
19228 + //ThisFrag-ACk-NextFrag-ACK.
19229 + Duration = NextFragTime + 3*aSifsTime + 2*AckTime;
19232 + } // End of Unicast packet
19234 + frag_hdr->duration_id = Duration;
19237 + buflen=priv->txbuffsize;
19239 + temp_tail = tail;
19240 +//printk("================================>buflen = %d, remain = %d!\n", buflen,remain);
19241 + while(remain!=0){
19242 +#ifdef DEBUG_TX_FRAG
19243 + DMESG("TX iteration");
19246 + DMESG("TX: filling descriptor %x",(u32)tail);
19250 + DMESGE("TX buffer error, cannot TX frames. pri %d.", priority);
19251 + //spin_unlock_irqrestore(&priv->tx_lock,flags);
19254 + buf=buflist->buf;
19256 + if( (*tail & (1<<31)) && (priority != BEACON_PRIORITY)){
19258 + DMESGW("No more TX desc, returning %x of %x",
19260 + priv->stats.txrdu++;
19261 +#ifdef DEBUG_TX_DESC
19262 + check_tx_ring(dev,priority);
19263 + // netif_stop_queue(dev);
19264 + // netif_carrier_off(dev);
19266 + // spin_unlock_irqrestore(&priv->tx_lock,flags);
19272 + *tail= 0; // zeroes header
19279 + if(priv->card_8185){
19280 + //FIXME: this should be triggered by HW encryption parameters.
19281 + *tail |= (1<<15); //no encrypt
19282 +// *tail |= (1<<30); //raise int when completed
19284 + // *tail = *tail | (1<<16);
19285 + if(remain==len && !descfrag) {
19286 + ownbit_flag = false; //added by david woo,2007.12.14
19287 +#ifdef DEBUG_TX_FRAG
19288 + DMESG("First descriptor");
19290 + *tail = *tail| (1<<29) ; //fist segment of the packet
19291 + *tail = *tail |(len);
19293 + ownbit_flag = true;
19296 + for(i=0;i<buflen&& remain >0;i++,remain--){
19297 + ((u8*)buf)[i]=txbuf[i]; //copy data into descriptor pointed DMAble buffer
19298 + if(remain == 4 && i+4 >= buflen) break;
19299 + /* ensure the last desc has at least 4 bytes payload */
19302 + txbuf = txbuf + i;
19303 + *(tail+3)=*(tail+3) &~ 0xfff;
19304 + *(tail+3)=*(tail+3) | i; // buffer lenght
19305 + // Use short preamble or not
19306 + if (priv->ieee80211->current_network.capability&WLAN_CAPABILITY_SHORT_PREAMBLE)
19307 + if (priv->plcp_preamble_mode==1 && rate!=0) // short mode now, not long!
19308 + // *tail |= (1<<16); // enable short preamble mode.
19310 +#ifdef CONFIG_RTL8185B
19312 + *tail |= (1<<18);
19315 + if(bRTSEnable) //rts enable
19317 + *tail |= ((ieeerate2rtlrate(priv->ieee80211->basic_rate))<<19);//RTS RATE
19318 + *tail |= (1<<23);//rts enable
19319 + *(tail+1) |=(RtsDur&0xffff);//RTS Duration
19321 + *(tail+3) |= ((TxDescDuration&0xffff)<<16); //DURATION
19322 +// *(tail+3) |= (0xe6<<16);
19323 + *(tail+5) |= (11<<8);//(priv->retry_data<<8); //retry lim ;
19326 +#ifdef CONFIG_RTL8187B
19327 + if ( (len>priv->rts) && priv->rts && priority!=MANAGE_PRIORITY){
19329 + if ( (len>priv->rts) && priv->rts && priority==LOW_PRIORITY){
19331 + *tail |= (1<<23); //enalbe RTS function
19332 + *tail |= (0<<19); //use 1M bps send RTS packet
19333 + AckCtsTime = ComputeTxTime(14, 10,0, 0); // AckCTSLng = 14 use 1M bps send
19334 + FrameTime = ComputeTxTime(len + 4, rtl8180_rate2rate(rate), 0, *tail&(1<<16));
19335 + // RTS/CTS time is calculate as follow
19336 + duration = FrameTime + 3*10 + 2*AckCtsTime; //10us is the SifsTime;
19337 + *(tail+1) |= duration; //Need to edit here! ----hikaru
19339 + *(tail+1)= 0; // zeroes the second 32-bits dword of the descriptor
19343 + *tail = *tail | ((rate&0xf) << 24);
19344 + //DMESG("rate %d",rate);
19346 + if(priv->card_8185){
19349 + *(tail+5)&= ~(1<<24); /* tx ant 0 */
19351 + *(tail+5) &= ~(1<<23); /* random tx agc 23-16 */
19352 + *(tail+5) |= (1<<22)|(1<<21)|(1<<20)|(1<<19)|(1<<18)|(1<<17)|(1<<16);
19355 +~((1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8));
19356 + *(tail+5) |= (7<<8); // Max retry limit
19358 + *(tail+5) &= ~((1<<7)|(1<<6)|(1<<5)|(1<<4)|(1<<3)|(1<<2)|(1<<1)|(1<<0));
19359 + *(tail+5) |= (8<<4); // Max contention window
19360 + *(tail+6) |= 4; // Min contention window
19362 + // *(tail+5) = 0;
19365 + /* hw_plcp_len is not used for rtl8180 chip */
19367 + if(priv->card_8185 == 0 || !priv->hw_plcp_len){
19369 + duration = rtl8180_len2duration(len,
19374 + DMESG("PLCP duration %d",duration );
19375 + //DMESG("drift %d",drift);
19376 + DMESG("extension %s", (ext==1) ? "on":"off");
19378 + *(tail+1) = *(tail+1) | ((duration & 0x7fff)<<16);
19379 + if(ext) *(tail+1) = *(tail+1) |(1<<31); //plcp length extension
19382 + if(morefrag) *tail = (*tail) | (1<<17); // more fragment
19383 + if(!remain) *tail = (*tail) | (1<<28); // last segment of frame
19385 +#ifdef DEBUG_TX_FRAG
19386 + if(!remain)DMESG("Last descriptor");
19387 + if(morefrag)DMESG("More frag");
19389 + *(tail+5) = *(tail+5)|(2<<27);
19390 + *(tail+7) = *(tail+7)|(1<<4);
19395 + *tail = *tail | (1<<31); // descriptor ready to be txed
19398 +#ifdef DEBUG_TX_DESC2
19399 + printk("tx desc is:\n");
19400 + DMESG("%8x %8x %8x %8x %8x %8x %8x %8x", tail[0], tail[1], tail[2], tail[3],
19401 + tail[4], tail[5], tail[6], tail[7]);
19404 + if((tail - begin)/8 == count-1)
19410 + buflist=buflist->next;
19414 + switch(priority) {
19415 + case MANAGE_PRIORITY:
19416 + priv->txmapringtail=tail;
19417 + priv->txmapbufstail=buflist;
19420 + case BK_PRIORITY:
19421 + priv->txbkpringtail=tail;
19422 + priv->txbkpbufstail=buflist;
19425 + case BE_PRIORITY:
19426 + priv->txbepringtail=tail;
19427 + priv->txbepbufstail=buflist;
19430 + case VI_PRIORITY:
19431 + priv->txvipringtail=tail;
19432 + priv->txvipbufstail=buflist;
19435 + case VO_PRIORITY:
19436 + priv->txvopringtail=tail;
19437 + priv->txvopbufstail=buflist;
19440 + case HI_PRIORITY:
19441 + priv->txhpringtail=tail;
19442 + priv->txhpbufstail = buflist;
19445 + case BEACON_PRIORITY:
19446 + /* the HW seems to be happy with the 1st
19447 + * descriptor filled and the 2nd empty...
19448 + * So always update descriptor 1 and never
19451 + // priv->txbeaconringtail=tail;
19452 + // priv->txbeaconbufstail=buflist;
19458 + //rtl8180_dma_kick(dev,priority);
19460 + *temp_tail = *temp_tail | (1<<31); // descriptor ready to be txed
19461 + rtl8180_dma_kick(dev,priority);
19462 + //spin_unlock_irqrestore(&priv->tx_lock,flags);
19469 +void rtl8180_irq_rx_tasklet(struct r8180_priv * priv);
19472 +void rtl8180_link_change(struct net_device *dev)
19474 + struct r8180_priv *priv = ieee80211_priv(dev);
19475 + u16 beacon_interval;
19477 + struct ieee80211_network *net = &priv->ieee80211->current_network;
19478 +// rtl8180_adapter_start(dev);
19479 + rtl8180_update_msr(dev);
19482 + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
19484 + write_nic_dword(dev,BSSID,((u32*)net->bssid)[0]);
19485 + write_nic_word(dev,BSSID+4,((u16*)net->bssid)[2]);
19488 + beacon_interval = read_nic_dword(dev,BEACON_INTERVAL);
19489 + beacon_interval &= ~ BEACON_INTERVAL_MASK;
19490 + beacon_interval |= net->beacon_interval;
19491 + write_nic_dword(dev, BEACON_INTERVAL, beacon_interval);
19493 + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
19497 + u16 atim = read_nic_dword(dev,ATIM);
19498 + u16 = u16 &~ ATIM_MASK;
19499 + u16 = u16 | beacon->atim;
19502 + if (net->capability & WLAN_CAPABILITY_PRIVACY) {
19503 + if (priv->hw_wep) {
19504 + DMESG("Enabling hardware WEP support");
19505 + rtl8180_set_hw_wep(dev);
19506 + priv->ieee80211->host_encrypt=0;
19507 + priv->ieee80211->host_decrypt=0;
19509 +#ifndef CONFIG_IEEE80211_NOWEP
19511 + priv->ieee80211->host_encrypt=1;
19512 + priv->ieee80211->host_decrypt=1;
19516 +#ifndef CONFIG_IEEE80211_NOWEP
19518 + priv->ieee80211->host_encrypt=0;
19519 + priv->ieee80211->host_decrypt=0;
19525 + if(priv->card_8185)
19526 + rtl8180_set_chan(dev, priv->chan);
19531 +void rtl8180_rq_tx_ack(struct net_device *dev){
19533 + struct r8180_priv *priv = ieee80211_priv(dev);
19534 +// printk("====================>%s\n",__FUNCTION__);
19535 + write_nic_byte(dev,CONFIG4,read_nic_byte(dev,CONFIG4)|CONFIG4_PWRMGT);
19536 + priv->ack_tx_to_ieee = 1;
19539 +short rtl8180_is_tx_queue_empty(struct net_device *dev){
19541 + struct r8180_priv *priv = ieee80211_priv(dev);
19544 + for (d = priv->txmapring;
19545 + d < priv->txmapring + priv->txringcount;d+=8)
19546 + if(*d & (1<<31)) return 0;
19548 + for (d = priv->txbkpring;
19549 + d < priv->txbkpring + priv->txringcount;d+=8)
19550 + if(*d & (1<<31)) return 0;
19552 + for (d = priv->txbepring;
19553 + d < priv->txbepring + priv->txringcount;d+=8)
19554 + if(*d & (1<<31)) return 0;
19556 + for (d = priv->txvipring;
19557 + d < priv->txvipring + priv->txringcount;d+=8)
19558 + if(*d & (1<<31)) return 0;
19560 + for (d = priv->txvopring;
19561 + d < priv->txvopring + priv->txringcount;d+=8)
19562 + if(*d & (1<<31)) return 0;
19564 + for (d = priv->txhpring;
19565 + d < priv->txhpring + priv->txringcount;d+=8)
19566 + if(*d & (1<<31)) return 0;
19569 +/* FIXME FIXME 5msecs is random */
19570 +#define HW_WAKE_DELAY 5
19572 +void rtl8180_hw_wakeup(struct net_device *dev)
19574 + unsigned long flags;
19576 + struct r8180_priv *priv = ieee80211_priv(dev);
19578 + spin_lock_irqsave(&priv->ps_lock,flags);
19579 + //DMESG("Waken up!");
19580 + write_nic_byte(dev,CONFIG4,read_nic_byte(dev,CONFIG4)&~CONFIG4_PWRMGT);
19582 + if(priv->rf_wakeup)
19583 + priv->rf_wakeup(dev);
19584 +// mdelay(HW_WAKE_DELAY);
19585 + spin_unlock_irqrestore(&priv->ps_lock,flags);
19588 +void rtl8180_hw_sleep_down(struct net_device *dev)
19590 + unsigned long flags;
19592 + struct r8180_priv *priv = ieee80211_priv(dev);
19594 + spin_lock_irqsave(&priv->ps_lock,flags);
19595 + //DMESG("Sleep!");
19597 + if(priv->rf_sleep)
19598 + priv->rf_sleep(dev);
19599 + spin_unlock_irqrestore(&priv->ps_lock,flags);
19603 +void rtl8180_hw_sleep(struct net_device *dev, u32 th, u32 tl)
19606 + struct r8180_priv *priv = ieee80211_priv(dev);
19608 + u32 rb = jiffies;
19609 + unsigned long flags;
19611 + spin_lock_irqsave(&priv->ps_lock,flags);
19613 + /* Writing HW register with 0 equals to disable
19614 + * the timer, that is not really what we want
19616 + tl -= MSECS(4+16+7);
19618 + //if(tl == 0) tl = 1;
19620 + /* FIXME HACK FIXME HACK */
19621 +// force_pci_posting(dev);
19624 +// rb = read_nic_dword(dev, TSFTR);
19626 + /* If the interval in witch we are requested to sleep is too
19627 + * short then give up and remain awake
19629 + if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME))
19630 + ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
19631 + spin_unlock_irqrestore(&priv->ps_lock,flags);
19632 + printk("too short to sleep\n");
19636 +// write_nic_dword(dev, TimerInt, tl);
19637 +// rb = read_nic_dword(dev, TSFTR);
19639 + u32 tmp = (tl>rb)?(tl-rb):(rb-tl);
19643 + priv->DozePeriodInPast2Sec += jiffies_to_msecs(tmp);
19645 + queue_delayed_work(priv->ieee80211->wq, &priv->ieee80211->hw_wakeup_wq, tmp); //as tl may be less than rb
19647 + /* if we suspect the TimerInt is gone beyond tl
19648 + * while setting it, then give up
19651 + if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))||
19652 + ((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) {
19653 + spin_unlock_irqrestore(&priv->ps_lock,flags);
19657 +// if(priv->rf_sleep)
19658 +// priv->rf_sleep(dev);
19660 + queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq);
19661 + spin_unlock_irqrestore(&priv->ps_lock,flags);
19665 +//void rtl8180_wmm_param_update(struct net_device *dev,u8 *ac_param)
19666 +#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
19667 +void rtl8180_wmm_param_update(struct work_struct * work)
19669 + struct ieee80211_device * ieee = container_of(work, struct ieee80211_device,wmm_param_update_wq);
19670 + //struct r8180_priv *priv = (struct r8180_priv*)(ieee->priv);
19671 + struct net_device *dev = ieee->dev;
19673 +void rtl8180_wmm_param_update(struct ieee80211_device *ieee)
19675 + struct net_device *dev = ieee->dev;
19676 + struct r8180_priv *priv = ieee80211_priv(dev);
19678 + u8 *ac_param = (u8 *)(ieee->current_network.wmm_param);
19679 + u8 mode = ieee->current_network.mode;
19681 + AC_PARAM AcParam;
19682 + PAC_PARAM pAcParam;
19685 +#ifndef CONFIG_RTL8185B
19686 + //for legacy 8185 keep the PARAM unchange.
19689 + if(!ieee->current_network.QoS_Enable){
19690 + //legacy ac_xx_param update
19691 + AcParam.longData = 0;
19692 + AcParam.f.AciAifsn.f.AIFSN = 2; // Follow 802.11 DIFS.
19693 + AcParam.f.AciAifsn.f.ACM = 0;
19694 + AcParam.f.Ecw.f.ECWmin = 3; // Follow 802.11 CWmin.
19695 + AcParam.f.Ecw.f.ECWmax = 7; // Follow 802.11 CWmax.
19696 + AcParam.f.TXOPLimit = 0;
19697 + for(eACI = 0; eACI < AC_MAX; eACI++){
19698 + AcParam.f.AciAifsn.f.ACI = (u8)eACI;
19702 + pAcParam = (PAC_PARAM)(&AcParam);
19703 + // Retrive paramters to udpate.
19704 + u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN *(((mode&IEEE_G) == IEEE_G)?9:20) + aSifsTime;
19705 + u4bAcParam = ((((u32)(pAcParam->f.TXOPLimit))<<AC_PARAM_TXOP_LIMIT_OFFSET)|
19706 + (((u32)(pAcParam->f.Ecw.f.ECWmax))<<AC_PARAM_ECW_MAX_OFFSET)|
19707 + (((u32)(pAcParam->f.Ecw.f.ECWmin))<<AC_PARAM_ECW_MIN_OFFSET)|
19708 + (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET));
19711 + write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
19715 + write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
19719 + write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
19723 + write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
19727 + printk(KERN_WARNING "SetHwReg8185():invalid ACI: %d!\n", eACI);
19735 + for(i = 0; i < AC_MAX; i++){
19736 + //AcParam.longData = 0;
19737 + pAcParam = (AC_PARAM * )ac_param;
19743 + // Retrive paramters to udpate.
19744 + eACI = pAcParam->f.AciAifsn.f.ACI;
19745 + //Mode G/A: slotTimeTimer = 9; Mode B: 20
19746 + u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * (((mode&IEEE_G) == IEEE_G)?9:20) + aSifsTime;
19747 + u4bAcParam = ( (((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) |
19748 + (((u32)(pAcParam->f.Ecw.f.ECWmax)) << AC_PARAM_ECW_MAX_OFFSET) |
19749 + (((u32)(pAcParam->f.Ecw.f.ECWmin)) << AC_PARAM_ECW_MIN_OFFSET) |
19750 + (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET));
19754 + write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
19758 + write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
19762 + write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
19766 + write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
19770 + printk(KERN_WARNING "SetHwReg8185(): invalid ACI: %d !\n", eACI);
19774 + ac_param += (sizeof(AC_PARAM));
19779 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
19780 +void rtl8180_tx_irq_wq(struct work_struct *work);
19782 +void rtl8180_tx_irq_wq(struct net_device *dev);
19788 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
19789 +void rtl8180_restart_wq(struct work_struct *work);
19790 +//void rtl8180_rq_tx_ack(struct work_struct *work);
19792 + void rtl8180_restart_wq(struct net_device *dev);
19793 +//void rtl8180_rq_tx_ack(struct net_device *dev);
19795 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
19796 +void rtl8180_watch_dog_wq(struct work_struct *work);
19798 +void rtl8180_watch_dog_wq(struct net_device *dev);
19800 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
19801 +void rtl8180_hw_wakeup_wq(struct work_struct *work);
19803 +void rtl8180_hw_wakeup_wq(struct net_device *dev);
19806 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
19807 +void rtl8180_hw_sleep_wq(struct work_struct *work);
19809 +void rtl8180_hw_sleep_wq(struct net_device *dev);
19814 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
19815 +void rtl8180_sw_antenna_wq(struct work_struct *work);
19817 +void rtl8180_sw_antenna_wq(struct net_device *dev);
19819 + void rtl8180_watch_dog(struct net_device *dev);
19820 +void watch_dog_adaptive(unsigned long data)
19822 + struct r8180_priv* priv = ieee80211_priv((struct net_device *)data);
19823 +// DMESG("---->watch_dog_adaptive()\n");
19826 + DMESG("<----watch_dog_adaptive():driver is not up!\n");
19830 + // queue_work(priv->ieee80211->wq,&priv->ieee80211->watch_dog_wq);
19833 + // Tx High Power Mechanism.
19835 + if(CheckHighPower((struct net_device *)data))
19837 + queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->tx_pw_wq);
19841 +#ifdef CONFIG_RTL818X_S
19842 + // Tx Power Tracking on 87SE.
19844 + //if( priv->bTxPowerTrack ) //lzm mod 080826
19845 + if( CheckTxPwrTracking((struct net_device *)data));
19846 + TxPwrTracking87SE((struct net_device *)data);
19850 + // Perform DIG immediately.
19852 + if(CheckDig((struct net_device *)data) == true)
19854 + queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_dig_wq);
19859 + rtl8180_watch_dog((struct net_device *)data);
19862 + queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->GPIOChangeRFWorkItem);
19864 + priv->watch_dog_timer.expires = jiffies + MSECS(IEEE80211_WATCH_DOG_TIME);
19865 + add_timer(&priv->watch_dog_timer);
19866 +// DMESG("<----watch_dog_adaptive()\n");
19869 +#ifdef ENABLE_DOT11D
19871 +static CHANNEL_LIST ChannelPlan[] = {
19872 + {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64},19}, //FCC
19873 + {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
19874 + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
19875 + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Spain. Change to ETSI.
19876 + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //France. Change to ETSI.
19877 + {{14,36,40,44,48,52,56,60,64},9}, //MKK
19878 + {{1,2,3,4,5,6,7,8,9,10,11,12,13,14, 36,40,44,48,52,56,60,64},22},//MKK1
19879 + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Israel.
19880 + {{1,2,3,4,5,6,7,8,9,10,11,12,13,34,38,42,46},17}, // For 11a , TELEC
19881 + {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}, //For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626
19882 + {{1,2,3,4,5,6,7,8,9,10,11,12,13},13} //world wide 13: ch1~ch11 active scan, ch12~13 passive //lzm add 080826
19885 +static void rtl8180_set_channel_map(u8 channel_plan, struct ieee80211_device *ieee)
19890 + ieee->MinPassiveChnlNum=MAX_CHANNEL_NUMBER+1;
19891 + ieee->IbssStartChnl=0;
19893 + switch (channel_plan)
19895 + case COUNTRY_CODE_FCC:
19896 + case COUNTRY_CODE_IC:
19897 + case COUNTRY_CODE_ETSI:
19898 + case COUNTRY_CODE_SPAIN:
19899 + case COUNTRY_CODE_FRANCE:
19900 + case COUNTRY_CODE_MKK:
19901 + case COUNTRY_CODE_MKK1:
19902 + case COUNTRY_CODE_ISRAEL:
19903 + case COUNTRY_CODE_TELEC:
19905 + Dot11d_Init(ieee);
19906 + ieee->bGlobalDomain = false;
19907 + if (ChannelPlan[channel_plan].Len != 0){
19908 + // Clear old channel map
19909 + memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
19910 + // Set new channel map
19911 + for (i=0;i<ChannelPlan[channel_plan].Len;i++)
19913 + if(ChannelPlan[channel_plan].Channel[i] <= 14)
19914 + GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1;
19919 + case COUNTRY_CODE_GLOBAL_DOMAIN:
19921 + GET_DOT11D_INFO(ieee)->bEnabled = 0;
19922 + Dot11d_Reset(ieee);
19923 + ieee->bGlobalDomain = true;
19926 + case COUNTRY_CODE_WORLD_WIDE_13_INDEX://lzm add 080826
19928 + ieee->MinPassiveChnlNum=12;
19929 + ieee->IbssStartChnl= 10;
19934 + Dot11d_Init(ieee);
19935 + ieee->bGlobalDomain = false;
19936 + memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
19937 + for (i=1;i<=14;i++)
19939 + GET_DOT11D_INFO(ieee)->channel_map[i] = 1;
19947 +//Add for RF power on power off by lizhaoming 080512
19948 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
19949 +void GPIOChangeRFWorkItemCallBack(struct work_struct *work);
19951 +void GPIOChangeRFWorkItemCallBack(struct ieee80211_device *ieee);
19955 +static void rtl8180_statistics_init(struct Stats *pstats)
19957 + memset(pstats, 0, sizeof(struct Stats));
19959 +static void rtl8180_link_detect_init(plink_detect_t plink_detect)
19961 + memset(plink_detect, 0, sizeof(link_detect_t));
19962 + plink_detect->SlotNum = DEFAULT_SLOT_NUM;
19964 +//YJ,add,080828,end
19966 +short rtl8180_init(struct net_device *dev)
19968 + struct r8180_priv *priv = ieee80211_priv(dev);
19977 +#ifdef ENABLE_DOT11D
19979 + for(i=0;i<0xFF;i++) {
19981 + printk("\n[%x]: ", i/16);
19982 + printk("\t%4.4x", eprom_read(dev,i));
19985 + priv->channel_plan = eprom_read(dev, EEPROM_COUNTRY_CODE>>1) & 0xFF;
19986 + if(priv->channel_plan > COUNTRY_CODE_GLOBAL_DOMAIN){
19987 + printk("rtl8180_init:Error channel plan! Set to default.\n");
19988 + priv->channel_plan = 0;
19990 + //priv->channel_plan = 9; //Global Domain
19992 + DMESG("Channel plan is %d\n",priv->channel_plan);
19993 + rtl8180_set_channel_map(priv->channel_plan, priv->ieee80211);
19996 + //Set Default Channel Plan
19998 + DMESG("No channels, aborting");
20002 + priv->channel_plan = 0;//hikaru
20003 + // set channels 1..14 allowed in given locale
20004 + for (i=1; i<=14; i++) {
20005 + (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01);
20010 + //memcpy(priv->stats,0,sizeof(struct Stats));
20012 + //FIXME: these constants are placed in a bad pleace.
20013 + priv->txbuffsize = 2048;//1024;
20014 + priv->txringcount = 32;//32;
20015 + priv->rxbuffersize = 2048;//1024;
20016 + priv->rxringcount = 64;//32;
20017 + priv->txbeaconcount = 2;
20018 + priv->rx_skb_complete = 1;
20019 + //priv->txnp_pending.ispending=0;
20020 + /* ^^ the SKB does not containt a partial RXed
20021 + * packet (is empty)
20024 +#ifdef CONFIG_RTL8185B
20025 +#ifdef CONFIG_RTL818X_S
20026 + priv->RegThreeWireMode = HW_THREE_WIRE_SI;
20028 + priv->RegThreeWireMode = SW_THREE_WIRE;
20032 +//Add for RF power on power off by lizhaoming 080512
20033 + priv->RFChangeInProgress = false;
20034 + priv->SetRFPowerStateInProgress = false;
20035 + priv->RFProgType = 0;
20036 + priv->bInHctTest = false;
20038 + priv->irq_enabled=0;
20040 +//YJ,modified,080828
20042 + priv->stats.rxdmafail=0;
20043 + priv->stats.txrdu=0;
20044 + priv->stats.rxrdu=0;
20045 + priv->stats.rxnolast=0;
20046 + priv->stats.rxnodata=0;
20047 + //priv->stats.rxreset=0;
20048 + //priv->stats.rxwrkaround=0;
20049 + priv->stats.rxnopointer=0;
20050 + priv->stats.txnperr=0;
20051 + priv->stats.txresumed=0;
20052 + priv->stats.rxerr=0;
20053 + priv->stats.rxoverflow=0;
20054 + priv->stats.rxint=0;
20055 + priv->stats.txnpokint=0;
20056 + priv->stats.txhpokint=0;
20057 + priv->stats.txhperr=0;
20058 + priv->stats.ints=0;
20059 + priv->stats.shints=0;
20060 + priv->stats.txoverflow=0;
20061 + priv->stats.txbeacon=0;
20062 + priv->stats.txbeaconerr=0;
20063 + priv->stats.txlperr=0;
20064 + priv->stats.txlpokint=0;
20065 + priv->stats.txretry=0;//tony 20060601
20066 + priv->stats.rxcrcerrmin=0;
20067 + priv->stats.rxcrcerrmid=0;
20068 + priv->stats.rxcrcerrmax=0;
20069 + priv->stats.rxicverr=0;
20071 + rtl8180_statistics_init(&priv->stats);
20072 + rtl8180_link_detect_init(&priv->link_detect);
20074 +//YJ,modified,080828,end
20077 + priv->ack_tx_to_ieee = 0;
20078 + priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL;
20079 + priv->ieee80211->iw_mode = IW_MODE_INFRA;
20080 + priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN |
20081 + IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ |
20082 + IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE;
20083 + priv->ieee80211->active_scan = 1;
20084 + priv->ieee80211->rate = 110; //11 mbps
20085 + priv->ieee80211->modulation = IEEE80211_CCK_MODULATION;
20086 + priv->ieee80211->host_encrypt = 1;
20087 + priv->ieee80211->host_decrypt = 1;
20088 + priv->ieee80211->sta_wake_up = rtl8180_hw_wakeup;
20089 + priv->ieee80211->ps_request_tx_ack = rtl8180_rq_tx_ack;
20090 + priv->ieee80211->enter_sleep_state = rtl8180_hw_sleep;
20091 + priv->ieee80211->ps_is_queue_empty = rtl8180_is_tx_queue_empty;
20093 + priv->hw_wep = hwwep;
20094 + priv->prism_hdr=0;
20096 + priv->retry_rts = DEFAULT_RETRY_RTS;
20097 + priv->retry_data = DEFAULT_RETRY_DATA;
20098 + priv->RFChangeInProgress = false;
20099 + priv->SetRFPowerStateInProgress = false;
20100 + priv->RFProgType = 0;
20101 + priv->bInHctTest = false;
20102 + priv->bInactivePs = true;//false;
20103 + priv->ieee80211->bInactivePs = priv->bInactivePs;
20104 + priv->bSwRfProcessing = false;
20105 + priv->eRFPowerState = eRfOff;
20106 + priv->RfOffReason = 0;
20107 + priv->LedStrategy = SW_LED_MODE0;
20108 + //priv->NumRxOkInPeriod = 0; //YJ,del,080828
20109 + //priv->NumTxOkInPeriod = 0; //YJ,del,080828
20110 + priv->TxPollingTimes = 0;//lzm add 080826
20111 + priv->bLeisurePs = true;
20112 + priv->dot11PowerSaveMode = eActive;
20113 +//by amy for antenna
20114 + priv->AdMinCheckPeriod = 5;
20115 + priv->AdMaxCheckPeriod = 10;
20116 +// Lower signal strength threshold to fit the HW participation in antenna diversity. +by amy 080312
20117 + priv->AdMaxRxSsThreshold = 30;//60->30
20118 + priv->AdRxSsThreshold = 20;//50->20
20119 + priv->AdCheckPeriod = priv->AdMinCheckPeriod;
20120 + priv->AdTickCount = 0;
20121 + priv->AdRxSignalStrength = -1;
20122 + priv->RegSwAntennaDiversityMechanism = 0;
20123 + priv->RegDefaultAntenna = 0;
20124 + priv->SignalStrength = 0;
20125 + priv->AdRxOkCnt = 0;
20126 + priv->CurrAntennaIndex = 0;
20127 + priv->AdRxSsBeforeSwitched = 0;
20128 + init_timer(&priv->SwAntennaDiversityTimer);
20129 + priv->SwAntennaDiversityTimer.data = (unsigned long)dev;
20130 + priv->SwAntennaDiversityTimer.function = (void *)SwAntennaDiversityTimerCallback;
20131 +//by amy for antenna
20133 + priv->bDigMechanism = 1;
20134 + priv->InitialGain = 6;
20135 + priv->bXtalCalibration = false;
20136 + priv->XtalCal_Xin = 0;
20137 + priv->XtalCal_Xout = 0;
20138 + priv->bTxPowerTrack = false;
20139 + priv->ThermalMeter = 0;
20140 + priv->FalseAlarmRegValue = 0;
20141 + priv->RegDigOfdmFaUpTh = 0xc; // Upper threhold of OFDM false alarm, which is used in DIG.
20142 + priv->DIG_NumberFallbackVote = 0;
20143 + priv->DIG_NumberUpgradeVote = 0;
20144 + priv->LastSignalStrengthInPercent = 0;
20145 + priv->Stats_SignalStrength = 0;
20146 + priv->LastRxPktAntenna = 0;
20147 + priv->SignalQuality = 0; // in 0-100 index.
20148 + priv->Stats_SignalQuality = 0;
20149 + priv->RecvSignalPower = 0; // in dBm.
20150 + priv->Stats_RecvSignalPower = 0;
20151 + priv->AdMainAntennaRxOkCnt = 0;
20152 + priv->AdAuxAntennaRxOkCnt = 0;
20153 + priv->bHWAdSwitched = false;
20154 + priv->bRegHighPowerMechanism = true;
20155 + priv->RegHiPwrUpperTh = 77;
20156 + priv->RegHiPwrLowerTh = 75;
20157 + priv->RegRSSIHiPwrUpperTh = 70;
20158 + priv->RegRSSIHiPwrLowerTh = 20;
20159 + priv->bCurCCKPkt = false;
20160 + priv->UndecoratedSmoothedSS = -1;
20161 + priv->bToUpdateTxPwr = false;
20162 + priv->CurCCKRSSI = 0;
20163 + priv->RxPower = 0;
20166 + priv->NumTxOkTotal = 0;
20167 + priv->NumTxUnicast = 0;
20168 + priv->keepAliveLevel = DEFAULT_KEEP_ALIVE_LEVEL;
20169 + priv->PowerProfile = POWER_PROFILE_AC;
20170 + //YJ,add,080828,end
20171 +//by amy for rate adaptive
20172 + priv->CurrRetryCnt=0;
20173 + priv->LastRetryCnt=0;
20174 + priv->LastTxokCnt=0;
20175 + priv->LastRxokCnt=0;
20176 + priv->LastRetryRate=0;
20177 + priv->bTryuping=0;
20178 + priv->CurrTxRate=0;
20179 + priv->CurrRetryRate=0;
20180 + priv->TryupingCount=0;
20181 + priv->TryupingCountNoData=0;
20182 + priv->TryDownCountLowData=0;
20183 + priv->LastTxOKBytes=0;
20184 + priv->LastFailTxRate=0;
20185 + priv->LastFailTxRateSS=0;
20186 + priv->FailTxRateCount=0;
20187 + priv->LastTxThroughput=0;
20188 + priv->NumTxOkBytesTotal=0;
20189 + priv->ForcedDataRate = 0;
20190 + priv->RegBModeGainStage = 1;
20192 +//by amy for rate adaptive
20194 + priv->promisc = (dev->flags & IFF_PROMISC) ? 1:0;
20195 + spin_lock_init(&priv->irq_lock);
20196 + spin_lock_init(&priv->irq_th_lock);
20197 + spin_lock_init(&priv->tx_lock);
20198 + spin_lock_init(&priv->ps_lock);
20199 + spin_lock_init(&priv->rf_ps_lock);
20200 + sema_init(&priv->wx_sem,1);
20201 + sema_init(&priv->rf_state,1);
20202 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
20203 + INIT_WORK(&priv->reset_wq,(void*) rtl8180_restart_wq);
20204 + INIT_WORK(&priv->tx_irq_wq,(void*) rtl8180_tx_irq_wq);
20205 + INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8180_hw_wakeup_wq);
20206 + INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8180_hw_sleep_wq);
20207 + //INIT_DELAYED_WORK(&priv->ieee80211->watch_dog_wq,(void*) rtl8180_watch_dog_wq);
20208 + //INIT_DELAYED_WORK(&priv->ieee80211->sw_antenna_wq,(void*) rtl8180_sw_antenna_wq);
20209 + INIT_WORK(&priv->ieee80211->wmm_param_update_wq,(void*) rtl8180_wmm_param_update);
20210 + INIT_DELAYED_WORK(&priv->ieee80211->rate_adapter_wq,(void*)rtl8180_rate_adapter);//+by amy 080312
20211 + INIT_DELAYED_WORK(&priv->ieee80211->hw_dig_wq,(void*)rtl8180_hw_dig_wq);//+by amy 080312
20212 + INIT_DELAYED_WORK(&priv->ieee80211->tx_pw_wq,(void*)rtl8180_tx_pw_wq);//+by amy 080312
20214 + //add for RF power on power off by lizhaoming 080512
20215 + INIT_DELAYED_WORK(&priv->ieee80211->GPIOChangeRFWorkItem,(void*) GPIOChangeRFWorkItemCallBack);
20217 + INIT_WORK(&priv->reset_wq,(void*) rtl8180_restart_wq,dev);
20218 + INIT_WORK(&priv->tx_irq_wq,(void*) rtl8180_tx_irq_wq,dev);
20219 + //INIT_WORK(&priv->ieee80211->watch_dog_wq,(void*) rtl8180_watch_dog_wq,dev);
20220 + INIT_WORK(&priv->ieee80211->hw_wakeup_wq,(void*) rtl8180_hw_wakeup_wq,dev);
20221 + INIT_WORK(&priv->ieee80211->hw_sleep_wq,(void*) rtl8180_hw_sleep_wq,dev);
20222 + //INIT_WORK(&priv->ieee80211->sw_antenna_wq,(void*) rtl8180_sw_antenna_wq,dev);
20223 + INIT_WORK(&priv->ieee80211->wmm_param_update_wq,(void*) rtl8180_wmm_param_update,priv->ieee80211);
20224 + INIT_WORK(&priv->ieee80211->rate_adapter_wq,(void*)rtl8180_rate_adapter,dev);//+by amy 080312
20225 + INIT_WORK(&priv->ieee80211->hw_dig_wq,(void*)rtl8180_hw_dig_wq,dev);//+by amy 080312
20226 + INIT_WORK(&priv->ieee80211->tx_pw_wq,(void*)rtl8180_tx_pw_wq,dev);//+by amy 080312
20228 + //add for RF power on power off by lizhaoming 080512
20229 + INIT_WORK(&priv->ieee80211->GPIOChangeRFWorkItem,(void*) GPIOChangeRFWorkItemCallBack, priv->ieee80211);
20231 + //INIT_WORK(&priv->reset_wq,(void*) rtl8180_restart_wq,dev);
20233 + tasklet_init(&priv->irq_rx_tasklet,
20234 + (void(*)(unsigned long)) rtl8180_irq_rx_tasklet,
20235 + (unsigned long)priv);
20237 + init_timer(&priv->watch_dog_timer);
20238 + priv->watch_dog_timer.data = (unsigned long)dev;
20239 + priv->watch_dog_timer.function = watch_dog_adaptive;
20243 +//by amy for rate adaptive
20244 + init_timer(&priv->rateadapter_timer);
20245 + priv->rateadapter_timer.data = (unsigned long)dev;
20246 + priv->rateadapter_timer.function = timer_rate_adaptive;
20247 + priv->RateAdaptivePeriod= RATE_ADAPTIVE_TIMER_PERIOD;
20248 + priv->bEnhanceTxPwr=false;
20249 +//by amy for rate adaptive
20251 + //priv->ieee80211->func =
20252 + // kmalloc(sizeof(struct ieee80211_helper_functions),GFP_KERNEL);
20253 + //memset(priv->ieee80211->func, 0,
20254 + // sizeof(struct ieee80211_helper_functions));
20256 + priv->ieee80211->softmac_hard_start_xmit = rtl8180_hard_start_xmit;
20257 + priv->ieee80211->set_chan = rtl8180_set_chan;
20258 + priv->ieee80211->link_change = rtl8180_link_change;
20259 + priv->ieee80211->softmac_data_hard_start_xmit = rtl8180_hard_data_xmit;
20260 + priv->ieee80211->data_hard_stop = rtl8180_data_hard_stop;
20261 + priv->ieee80211->data_hard_resume = rtl8180_data_hard_resume;
20263 + priv->ieee80211->init_wmmparam_flag = 0;
20265 + priv->ieee80211->start_send_beacons = rtl8180_start_tx_beacon;
20266 + priv->ieee80211->stop_send_beacons = rtl8180_beacon_tx_disable;
20267 + priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
20269 +#ifdef CONFIG_RTL8185B
20270 + priv->MWIEnable = 0;
20272 + priv->ShortRetryLimit = 7;
20273 + priv->LongRetryLimit = 7;
20274 + priv->EarlyRxThreshold = 7;
20276 + priv->CSMethod = (0x01 << 29);
20278 + priv->TransmitConfig =
20279 + 1<<TCR_DurProcMode_OFFSET | //for RTL8185B, duration setting by HW
20280 + (7<<TCR_MXDMA_OFFSET) | // Max DMA Burst Size per Tx DMA Burst, 7: reservied.
20281 + (priv->ShortRetryLimit<<TCR_SRL_OFFSET) | // Short retry limit
20282 + (priv->LongRetryLimit<<TCR_LRL_OFFSET) | // Long retry limit
20283 + (0 ? TCR_SAT : 0); // FALSE: HW provies PLCP length and LENGEXT, TURE: SW proiveds them
20285 + priv->ReceiveConfig =
20286 +#ifdef CONFIG_RTL818X_S
20291 + RCR_AMF | RCR_ADF | //accept management/data
20292 + RCR_ACF | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko.
20293 + RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC
20294 + //RCR_AICV | RCR_ACRC32 | //accept ICV/CRC error packet
20295 + (7<<RCR_MXDMA_OFFSET) | // Max DMA Burst Size per Rx DMA Burst, 7: unlimited.
20296 + (priv->EarlyRxThreshold<<RCR_FIFO_OFFSET) | // Rx FIFO Threshold, 7: No Rx threshold.
20297 + (priv->EarlyRxThreshold == 7 ? RCR_ONLYERLPKT:0);
20299 + priv->IntrMask = IMR_TMGDOK | IMR_TBDER | IMR_THPDER |
20300 + IMR_THPDER | IMR_THPDOK |
20301 + IMR_TVODER | IMR_TVODOK |
20302 + IMR_TVIDER | IMR_TVIDOK |
20303 + IMR_TBEDER | IMR_TBEDOK |
20304 + IMR_TBKDER | IMR_TBKDOK |
20305 + IMR_RDU | // To handle the defragmentation not enough Rx descriptors case. Annie, 2006-03-27.
20306 + IMR_RER | IMR_ROK |
20307 + IMR_RQoSOK; // <NOTE> ROK and RQoSOK are mutually exclusive, so, we must handle RQoSOK interrupt to receive QoS frames, 2005.12.09, by rcnjko.
20309 + priv->InitialGain = 6;
20312 + hw_version =( read_nic_dword(dev, TCR) & TCR_HWVERID_MASK)>>TCR_HWVERID_SHIFT;
20314 + switch (hw_version){
20315 +#ifdef CONFIG_RTL8185B
20316 + case HW_VERID_R8185B_B:
20317 +#ifdef CONFIG_RTL818X_S
20318 + priv->card_8185 = VERSION_8187S_C;
20319 + DMESG("MAC controller is a RTL8187SE b/g");
20320 + priv->phy_ver = 2;
20323 + DMESG("MAC controller is a RTL8185B b/g");
20324 + priv->card_8185 = 3;
20325 + priv->phy_ver = 2;
20329 + case HW_VERID_R8185_ABC:
20330 + DMESG("MAC controller is a RTL8185 b/g");
20331 + priv->card_8185 = 1;
20332 + /* you should not find a card with 8225 PHY ver < C*/
20333 + priv->phy_ver = 2;
20336 + case HW_VERID_R8185_D:
20337 + DMESG("MAC controller is a RTL8185 b/g (V. D)");
20338 + priv->card_8185 = 2;
20339 + /* you should not find a card with 8225 PHY ver < C*/
20340 + priv->phy_ver = 2;
20343 + case HW_VERID_R8180_ABCD:
20344 + DMESG("MAC controller is a RTL8180");
20345 + priv->card_8185 = 0;
20348 + case HW_VERID_R8180_F:
20349 + DMESG("MAC controller is a RTL8180 (v. F)");
20350 + priv->card_8185 = 0;
20354 + DMESGW("MAC chip not recognized: version %x. Assuming RTL8180",hw_version);
20355 + priv->card_8185 = 0;
20359 + if(priv->card_8185){
20360 + priv->ieee80211->modulation |= IEEE80211_OFDM_MODULATION;
20361 + priv->ieee80211->short_slot = 1;
20363 + /* you should not found any 8185 Ver B Card */
20364 + priv->card_8185_Bversion = 0;
20366 +#ifdef CONFIG_RTL8185B
20367 +#ifdef CONFIG_RTL818X_S
20368 + // just for sync 85
20369 + priv->card_type = PCI;
20370 + DMESG("This is a PCI NIC");
20372 + config3 = read_nic_byte(dev, CONFIG3);
20373 + if(config3 & 0x8){
20374 + priv->card_type = CARDBUS;
20375 + DMESG("This is a CARDBUS NIC");
20377 + else if( config3 & 0x4){
20378 + priv->card_type = MINIPCI;
20379 + DMESG("This is a MINI-PCI NIC");
20381 + priv->card_type = PCI;
20382 + DMESG("This is a PCI NIC");
20386 + priv->enable_gpio0 = 0;
20388 +//by amy for antenna
20389 +#ifdef CONFIG_RTL8185B
20390 + usValue = eprom_read(dev, EEPROM_SW_REVD_OFFSET);
20391 + DMESG("usValue is 0x%x\n",usValue);
20392 +#ifdef CONFIG_RTL818X_S
20393 + //3Read AntennaDiversity
20394 + // SW Antenna Diversity.
20395 + if( (usValue & EEPROM_SW_AD_MASK) != EEPROM_SW_AD_ENABLE )
20397 + priv->EEPROMSwAntennaDiversity = false;
20398 + //printk("EEPROM Disable SW Antenna Diversity\n");
20402 + priv->EEPROMSwAntennaDiversity = true;
20403 + //printk("EEPROM Enable SW Antenna Diversity\n");
20405 + // Default Antenna to use.
20406 + if( (usValue & EEPROM_DEF_ANT_MASK) != EEPROM_DEF_ANT_1 )
20408 + priv->EEPROMDefaultAntenna1 = false;
20409 + //printk("EEPROM Default Antenna 0\n");
20413 + priv->EEPROMDefaultAntenna1 = true;
20414 + //printk("EEPROM Default Antenna 1\n");
20418 + // Antenna diversity mechanism. Added by Roger, 2007.11.05.
20420 + if( priv->RegSwAntennaDiversityMechanism == 0 ) // Auto
20421 + {// 0: default from EEPROM.
20422 + priv->bSwAntennaDiverity = priv->EEPROMSwAntennaDiversity;
20425 + {// 1:disable antenna diversity, 2: enable antenna diversity.
20426 + priv->bSwAntennaDiverity = ((priv->RegSwAntennaDiversityMechanism == 1)? false : true);
20428 + //printk("bSwAntennaDiverity = %d\n", priv->bSwAntennaDiverity);
20432 + // Default antenna settings. Added by Roger, 2007.11.05.
20434 + if( priv->RegDefaultAntenna == 0)
20435 + {// 0: default from EEPROM.
20436 + priv->bDefaultAntenna1 = priv->EEPROMDefaultAntenna1;
20439 + {// 1: main, 2: aux.
20440 + priv->bDefaultAntenna1 = ((priv->RegDefaultAntenna== 2) ? true : false);
20442 + //printk("bDefaultAntenna1 = %d\n", priv->bDefaultAntenna1);
20445 +//by amy for antenna
20446 + /* rtl8185 can calc plcp len in HW.*/
20447 + priv->hw_plcp_len = 1;
20449 + priv->plcp_preamble_mode = 2;
20450 + /*the eeprom type is stored in RCR register bit #6 */
20451 + if (RCR_9356SEL & read_nic_dword(dev, RCR)){
20452 + priv->epromtype=EPROM_93c56;
20453 + //DMESG("Reported EEPROM chip is a 93c56 (2Kbit)");
20455 + priv->epromtype=EPROM_93c46;
20456 + //DMESG("Reported EEPROM chip is a 93c46 (1Kbit)");
20459 + dev->get_stats = rtl8180_stats;
20461 + dev->dev_addr[0]=eprom_read(dev,MAC_ADR) & 0xff;
20462 + dev->dev_addr[1]=(eprom_read(dev,MAC_ADR) & 0xff00)>>8;
20463 + dev->dev_addr[2]=eprom_read(dev,MAC_ADR+1) & 0xff;
20464 + dev->dev_addr[3]=(eprom_read(dev,MAC_ADR+1) & 0xff00)>>8;
20465 + dev->dev_addr[4]=eprom_read(dev,MAC_ADR+2) & 0xff;
20466 + dev->dev_addr[5]=(eprom_read(dev,MAC_ADR+2) & 0xff00)>>8;
20467 + //DMESG("Card MAC address is "MAC_FMT, MAC_ARG(dev->dev_addr));
20470 + for(i=1,j=0; i<14; i+=2,j++){
20472 + word = eprom_read(dev,EPROM_TXPW_CH1_2 + j);
20473 + priv->chtxpwr[i]=word & 0xff;
20474 + priv->chtxpwr[i+1]=(word & 0xff00)>>8;
20475 +#ifdef DEBUG_EPROM
20476 + DMESG("tx word %x:%x",j,word);
20477 + DMESG("ch %d pwr %x",i,priv->chtxpwr[i]);
20478 + DMESG("ch %d pwr %x",i+1,priv->chtxpwr[i+1]);
20481 + if(priv->card_8185){
20482 + for(i=1,j=0; i<14; i+=2,j++){
20484 + word = eprom_read(dev,EPROM_TXPW_OFDM_CH1_2 + j);
20485 + priv->chtxpwr_ofdm[i]=word & 0xff;
20486 + priv->chtxpwr_ofdm[i+1]=(word & 0xff00)>>8;
20487 +#ifdef DEBUG_EPROM
20488 + DMESG("ofdm tx word %x:%x",j,word);
20489 + DMESG("ofdm ch %d pwr %x",i,priv->chtxpwr_ofdm[i]);
20490 + DMESG("ofdm ch %d pwr %x",i+1,priv->chtxpwr_ofdm[i+1]);
20495 + //3Read crystal calibtration and thermal meter indication on 87SE.
20497 + // By SD3 SY's request. Added by Roger, 2007.12.11.
20499 + tmpu16 = eprom_read(dev, EEPROM_RSV>>1);
20501 + //printk("ReadAdapterInfo8185(): EEPROM_RSV(%04x)\n", tmpu16);
20503 + // Crystal calibration for Xin and Xout resp.
20504 + priv->XtalCal_Xout = tmpu16 & EEPROM_XTAL_CAL_XOUT_MASK; // 0~7.5pF
20505 + priv->XtalCal_Xin = (tmpu16 & EEPROM_XTAL_CAL_XIN_MASK)>>4; // 0~7.5pF
20506 + if((tmpu16 & EEPROM_XTAL_CAL_ENABLE)>>12)
20507 + priv->bXtalCalibration = true;
20509 + // Thermal meter reference indication.
20510 + priv->ThermalMeter = (u8)((tmpu16 & EEPROM_THERMAL_METER_MASK)>>8);
20511 + if((tmpu16 & EEPROM_THERMAL_METER_ENABLE)>>13)
20512 + priv->bTxPowerTrack = true;
20515 +#ifdef CONFIG_RTL8185B
20516 + word = eprom_read(dev,EPROM_TXPW_BASE);
20517 + priv->cck_txpwr_base = word & 0xf;
20518 + priv->ofdm_txpwr_base = (word>>4) & 0xf;
20521 + version = eprom_read(dev,EPROM_VERSION);
20522 + DMESG("EEPROM version %x",version);
20523 + if( (!priv->card_8185) && version < 0x0101){
20524 + DMESG ("EEPROM version too old, assuming defaults");
20525 + DMESG ("If you see this message *plase* send your \
20526 +DMESG output to andreamrl@tiscali.it THANKS");
20529 + priv->diversity=1;
20530 + priv->cs_treshold=0xc;
20531 + priv->rcr_csense=1;
20532 + priv->rf_chip=RFCHIPID_PHILIPS;
20534 + if(!priv->card_8185){
20535 + u8 rfparam = eprom_read(dev,RF_PARAM);
20536 + DMESG("RfParam: %x",rfparam);
20538 + priv->digphy = rfparam & (1<<RF_PARAM_DIGPHY_SHIFT) ? 0:1;
20539 + priv->antb = rfparam & (1<<RF_PARAM_ANTBDEFAULT_SHIFT) ? 1:0;
20541 + priv->rcr_csense = (rfparam & RF_PARAM_CARRIERSENSE_MASK) >>
20542 + RF_PARAM_CARRIERSENSE_SHIFT;
20544 + priv->diversity =
20545 + (read_nic_byte(dev,CONFIG2)&(1<<CONFIG2_ANTENNA_SHIFT)) ? 1:0;
20547 + priv->rcr_csense = 3;
20550 + priv->cs_treshold = (eprom_read(dev,ENERGY_TRESHOLD)&0xff00) >>8;
20552 + priv->rf_chip = 0xff & eprom_read(dev,RFCHIPID);
20555 +#ifdef CONFIG_RTL8185B
20556 +#ifdef CONFIG_RTL818X_S
20557 + priv->rf_chip = RF_ZEBRA4;
20558 + priv->rf_sleep = rtl8225z4_rf_sleep;
20559 + priv->rf_wakeup = rtl8225z4_rf_wakeup;
20561 + priv->rf_chip = RF_ZEBRA2;
20563 + //DMESG("Card reports RF frontend Realtek 8225z2");
20564 + //DMESGW("This driver has EXPERIMENTAL support for this chipset.");
20565 + //DMESGW("use it with care and at your own risk and");
20566 + DMESGW("**PLEASE** REPORT SUCCESSFUL/UNSUCCESSFUL TO Realtek!");
20568 + priv->rf_close = rtl8225z2_rf_close;
20569 + priv->rf_init = rtl8225z2_rf_init;
20570 + priv->rf_set_chan = rtl8225z2_rf_set_chan;
20571 + priv->rf_set_sens = NULL;
20572 + //priv->rf_sleep = rtl8225_rf_sleep;
20573 + //priv->rf_wakeup = rtl8225_rf_wakeup;
20576 + /* check RF frontend chipset */
20577 + switch (priv->rf_chip) {
20579 + case RFCHIPID_RTL8225:
20581 + if(priv->card_8185){
20582 + DMESG("Card reports RF frontend Realtek 8225");
20583 + DMESGW("This driver has EXPERIMENTAL support for this chipset.");
20584 + DMESGW("use it with care and at your own risk and");
20585 + DMESGW("**PLEASE** REPORT SUCCESS/INSUCCESS TO andreamrl@tiscali.it");
20587 + priv->rf_close = rtl8225_rf_close;
20588 + priv->rf_init = rtl8225_rf_init;
20589 + priv->rf_set_chan = rtl8225_rf_set_chan;
20590 + priv->rf_set_sens = NULL;
20591 + priv->rf_sleep = rtl8225_rf_sleep;
20592 + priv->rf_wakeup = rtl8225_rf_wakeup;
20595 + DMESGW("Detected RTL8225 radio on a card recognized as RTL8180");
20596 + DMESGW("This could not be... something went wrong....");
20601 + case RFCHIPID_RTL8255:
20602 + if(priv->card_8185){
20603 + DMESG("Card reports RF frontend Realtek 8255");
20604 + DMESGW("This driver has EXPERIMENTAL support for this chipset.");
20605 + DMESGW("use it with care and at your own risk and");
20606 + DMESGW("**PLEASE** REPORT SUCCESS/INSUCCESS TO andreamrl@tiscali.it");
20608 + priv->rf_close = rtl8255_rf_close;
20609 + priv->rf_init = rtl8255_rf_init;
20610 + priv->rf_set_chan = rtl8255_rf_set_chan;
20611 + priv->rf_set_sens = NULL;
20612 + priv->rf_sleep = NULL;
20613 + priv->rf_wakeup = NULL;
20616 + DMESGW("Detected RTL8255 radio on a card recognized as RTL8180");
20617 + DMESGW("This could not be... something went wrong....");
20623 + case RFCHIPID_INTERSIL:
20624 + DMESGW("Card reports RF frontend by Intersil.");
20625 + DMESGW("This driver has NO support for this chipset.");
20629 + case RFCHIPID_RFMD:
20630 + DMESGW("Card reports RF frontend by RFMD.");
20631 + DMESGW("This driver has NO support for this chipset.");
20635 + case RFCHIPID_GCT:
20636 + DMESGW("Card reports RF frontend by GCT.");
20637 + DMESGW("This driver has EXPERIMENTAL support for this chipset.");
20638 + DMESGW("use it with care and at your own risk and");
20639 + DMESGW("**PLEASE** REPORT SUCCESS/INSUCCESS TO andreamrl@tiscali.it");
20640 + priv->rf_close = gct_rf_close;
20641 + priv->rf_init = gct_rf_init;
20642 + priv->rf_set_chan = gct_rf_set_chan;
20643 + priv->rf_set_sens = NULL;
20644 + priv->rf_sleep = NULL;
20645 + priv->rf_wakeup = NULL;
20648 + case RFCHIPID_MAXIM:
20649 + DMESGW("Card reports RF frontend by MAXIM.");
20650 + DMESGW("This driver has EXPERIMENTAL support for this chipset.");
20651 + DMESGW("use it with care and at your own risk and");
20652 + DMESGW("**PLEASE** REPORT SUCCESS/INSUCCESS TO andreamrl@tiscali.it");
20653 + priv->rf_close = maxim_rf_close;
20654 + priv->rf_init = maxim_rf_init;
20655 + priv->rf_set_chan = maxim_rf_set_chan;
20656 + priv->rf_set_sens = NULL;
20657 + priv->rf_sleep = NULL;
20658 + priv->rf_wakeup = NULL;
20661 + case RFCHIPID_PHILIPS:
20662 + DMESG("Card reports RF frontend by Philips.");
20663 + DMESG("OK! Philips SA2400 radio chipset is supported.");
20664 + priv->rf_close = sa2400_rf_close;
20665 + priv->rf_init = sa2400_rf_init;
20666 + priv->rf_set_chan = sa2400_rf_set_chan;
20667 + priv->rf_set_sens = sa2400_rf_set_sens;
20668 + priv->sens = SA2400_RF_DEF_SENS; /* default sensitivity */
20669 + priv->max_sens = SA2400_RF_MAX_SENS; /* maximum sensitivity */
20670 + priv->rf_sleep = NULL;
20671 + priv->rf_wakeup = NULL;
20673 + if(priv->digphy){
20674 + DMESGW("Digital PHY found");
20675 + DMESGW("Philips DIGITAL PHY is untested! *Please*\
20676 + report success/failure to <andreamrl@tiscali.it>");
20678 + DMESG ("Analog PHY found");
20684 + DMESGW("Unknown RF module %x",priv->rf_chip);
20685 + DMESGW("Exiting...");
20692 + if(!priv->card_8185){
20694 + DMESG ("Antenna B is default antenna");
20696 + DMESG ("Antenna A is default antenna");
20698 + if(priv->diversity)
20699 + DMESG ("Antenna diversity is enabled");
20701 + DMESG("Antenna diversity is disabled");
20703 + DMESG("Carrier sense %d",priv->rcr_csense);
20706 + if (0!=alloc_rx_desc_ring(dev, priv->rxbuffersize, priv->rxringcount))
20709 + if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
20710 + TX_MANAGEPRIORITY_RING_ADDR))
20713 + if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
20714 + TX_BKPRIORITY_RING_ADDR))
20717 + if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
20718 + TX_BEPRIORITY_RING_ADDR))
20721 + if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
20722 + TX_VIPRIORITY_RING_ADDR))
20725 + if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
20726 + TX_VOPRIORITY_RING_ADDR))
20729 + if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
20730 + TX_HIGHPRIORITY_RING_ADDR))
20733 + if (0!=alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txbeaconcount,
20734 + TX_BEACON_RING_ADDR))
20738 + //priv->beacon_buf=NULL;
20740 + if(!priv->card_8185){
20742 + if(read_nic_byte(dev, CONFIG0) & (1<<CONFIG0_WEP40_SHIFT))
20743 + DMESG ("40-bit WEP is supported in hardware");
20745 + DMESG ("40-bit WEP is NOT supported in hardware");
20747 + if(read_nic_byte(dev,CONFIG0) & (1<<CONFIG0_WEP104_SHIFT))
20748 + DMESG ("104-bit WEP is supported in hardware");
20750 + DMESG ("104-bit WEP is NOT supported in hardware");
20752 +#if !defined(SA_SHIRQ)
20753 + if(request_irq(dev->irq, (void *)rtl8180_interrupt, IRQF_SHARED, dev->name, dev)){
20755 + if(request_irq(dev->irq, (void *)rtl8180_interrupt, SA_SHIRQ, dev->name, dev)){
20757 + DMESGE("Error allocating IRQ %d",dev->irq);
20760 + priv->irq=dev->irq;
20761 + DMESG("IRQ %d",dev->irq);
20764 +#ifdef DEBUG_EPROM
20773 +void rtl8180_no_hw_wep(struct net_device *dev)
20775 + struct r8180_priv *priv = ieee80211_priv(dev);
20777 + if(!priv->card_8185)
20781 + security = read_nic_byte(dev, SECURITY);
20782 + security &=~(1<<SECURITY_WEP_TX_ENABLE_SHIFT);
20783 + security &=~(1<<SECURITY_WEP_RX_ENABLE_SHIFT);
20785 + write_nic_byte(dev, SECURITY, security);
20792 + write_nic_dword(dev,TX_CONF,read_nic_dword(dev,TX_CONF) |
20793 + (1<<TX_NOICV_SHIFT) );
20795 +// priv->ieee80211->hw_wep=0;
20799 +void rtl8180_set_hw_wep(struct net_device *dev)
20801 + struct r8180_priv *priv = ieee80211_priv(dev);
20806 + pgreg=read_nic_byte(dev, PGSELECT);
20807 + write_nic_byte(dev, PGSELECT, pgreg &~ (1<<PGSELECT_PG_SHIFT));
20809 + key0_word4 = read_nic_dword(dev, KEY0+4+4+4);
20810 + key0_word4 &= ~ 0xff;
20811 + key0_word4 |= priv->key0[3]& 0xff;
20812 + write_nic_dword(dev,KEY0,(priv->key0[0]));
20813 + write_nic_dword(dev,KEY0+4,(priv->key0[1]));
20814 + write_nic_dword(dev,KEY0+4+4,(priv->key0[2]));
20815 + write_nic_dword(dev,KEY0+4+4+4,(key0_word4));
20818 + TX_CONF,read_nic_dword(dev,TX_CONF) &~(1<<TX_NOICV_SHIFT));
20821 + security = read_nic_byte(dev,SECURITY);
20822 + security |= (1<<SECURITY_WEP_TX_ENABLE_SHIFT);
20823 + security |= (1<<SECURITY_WEP_RX_ENABLE_SHIFT);
20824 + security &= ~ SECURITY_ENCRYP_MASK;
20825 + security |= (SECURITY_ENCRYP_104<<SECURITY_ENCRYP_SHIFT);
20827 + write_nic_byte(dev, SECURITY, security);
20829 + DMESG("key %x %x %x %x",read_nic_dword(dev,KEY0+4+4+4),
20830 + read_nic_dword(dev,KEY0+4+4),read_nic_dword(dev,KEY0+4),
20831 + read_nic_dword(dev,KEY0));
20833 + //priv->ieee80211->hw_wep=1;
20837 +void rtl8185_rf_pins_enable(struct net_device *dev)
20840 +// tmp = read_nic_word(dev, RFPinsEnable);
20841 + write_nic_word(dev, RFPinsEnable, 0x1fff);// | tmp);
20842 +// write_nic_word(dev, RFPinsEnable,7 | tmp);
20846 +void rtl8185_set_anaparam2(struct net_device *dev, u32 a)
20850 + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
20852 + conf3 = read_nic_byte(dev, CONFIG3);
20853 + write_nic_byte(dev, CONFIG3, conf3 | (1<<CONFIG3_ANAPARAM_W_SHIFT));
20854 + write_nic_dword(dev, ANAPARAM2, a);
20856 + conf3 = read_nic_byte(dev, CONFIG3);
20857 + write_nic_byte(dev, CONFIG3, conf3 &~(1<<CONFIG3_ANAPARAM_W_SHIFT));
20858 + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
20863 +void rtl8180_set_anaparam(struct net_device *dev, u32 a)
20867 + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
20869 + conf3 = read_nic_byte(dev, CONFIG3);
20870 + write_nic_byte(dev, CONFIG3, conf3 | (1<<CONFIG3_ANAPARAM_W_SHIFT));
20871 + write_nic_dword(dev, ANAPARAM, a);
20873 + conf3 = read_nic_byte(dev, CONFIG3);
20874 + write_nic_byte(dev, CONFIG3, conf3 &~(1<<CONFIG3_ANAPARAM_W_SHIFT));
20875 + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
20879 +void rtl8185_tx_antenna(struct net_device *dev, u8 ant)
20881 + write_nic_byte(dev, TX_ANTENNA, ant);
20882 + force_pci_posting(dev);
20887 +void rtl8185_write_phy(struct net_device *dev, u8 adr, u32 data)
20895 + phyw= ((data<<8) | adr);
20898 + write_nic_dword(dev, PHY_ADR, phyw);
20900 + //read_nic_dword(dev, PHY_ADR);
20901 + for(i=0;i<10;i++){
20902 + write_nic_dword(dev, PHY_ADR, 0xffffff7f & phyw);
20903 + phyr = read_nic_byte(dev, PHY_READ);
20904 + if(phyr == (data&0xff)) break;
20908 + // Note that, we must write 0xff7c after 0x7d-0x7f to write BB register.
20909 + write_nic_byte(dev, 0x7f, ((phyw & 0xff000000) >> 24));
20910 + write_nic_byte(dev, 0x7e, ((phyw & 0x00ff0000) >> 16));
20911 + write_nic_byte(dev, 0x7d, ((phyw & 0x0000ff00) >> 8));
20912 + write_nic_byte(dev, 0x7c, ((phyw & 0x000000ff) ));
20914 + /* this is ok to fail when we write AGC table. check for AGC table might be
20915 + * done by masking with 0x7f instead of 0xff
20917 + //if(phyr != (data&0xff)) DMESGW("Phy write timeout %x %x %x", phyr, data,adr);
20921 +inline void write_phy_ofdm (struct net_device *dev, u8 adr, u32 data)
20923 + data = data & 0xff;
20924 + rtl8185_write_phy(dev, adr, data);
20928 +void write_phy_cck (struct net_device *dev, u8 adr, u32 data)
20930 + data = data & 0xff;
20931 + rtl8185_write_phy(dev, adr, data | 0x10000);
20936 + * I hope this is enougth
20938 +#define MAX_PHY 70
20939 +void write_phy(struct net_device *dev, u8 adr, u8 data)
20946 + phy |= 0x80; /* this should enable writing */
20947 + phy |= (data<<8);
20949 + //PHY_ADR, PHY_R and PHY_W are contig and treated as one dword
20950 + write_nic_dword(dev,PHY_ADR, phy);
20955 + write_nic_dword(dev,PHY_ADR, phy);
20956 + for(i=0;i<MAX_PHY;i++){
20957 + phy=read_nic_dword(dev,PHY_ADR);
20958 + phy= phy & 0xff0000;
20960 + if(phy == data){ //SUCCESS!
20961 + force_pci_posting(dev);
20962 + mdelay(3); //random value
20964 + DMESG("Phy wr %x,%x",adr,data);
20968 + force_pci_posting(dev);
20969 + mdelay(3); //random value
20972 + DMESGW ("Phy writing %x %x failed!", adr,data);
20975 +void rtl8185_set_rate(struct net_device *dev)
20979 + int basic_rate,min_rr_rate,max_rr_rate;
20981 +// struct r8180_priv *priv = ieee80211_priv(dev);
20983 + //if (ieee80211_is_54g(priv->ieee80211->current_network) &&
20984 +// priv->ieee80211->state == IEEE80211_LINKED){
20985 + basic_rate = ieeerate2rtlrate(240);
20986 + min_rr_rate = ieeerate2rtlrate(60);
20987 + max_rr_rate = ieeerate2rtlrate(240);
20991 +// basic_rate = ieeerate2rtlrate(20);
20992 +// min_rr_rate = ieeerate2rtlrate(10);
20993 +// max_rr_rate = ieeerate2rtlrate(110);
20996 + write_nic_byte(dev, RESP_RATE,
20997 + max_rr_rate<<MAX_RESP_RATE_SHIFT| min_rr_rate<<MIN_RESP_RATE_SHIFT);
20999 + word = read_nic_word(dev, BRSR);
21000 + word &= ~BRSR_MBR_8185;
21003 + for(i=0;i<=basic_rate;i++)
21006 + write_nic_word(dev, BRSR, word);
21007 + //DMESG("RR:%x BRSR: %x", read_nic_byte(dev,RESP_RATE),read_nic_word(dev,BRSR));
21012 +void rtl8180_adapter_start(struct net_device *dev)
21014 + struct r8180_priv *priv = ieee80211_priv(dev);
21020 + rtl8180_rtx_disable(dev);
21021 + rtl8180_reset(dev);
21023 + /* seems that 0xffff or 0xafff will cause
21024 + * HW interrupt line crash
21027 + //priv->irq_mask = 0xafff;
21028 +// priv->irq_mask = 0x4fcf;
21030 + /* enable beacon timeout, beacon TX ok and err
21031 + * LP tx ok and err, HP TX ok and err, NP TX ok and err,
21032 + * RX ok and ERR, and GP timer */
21033 + priv->irq_mask = 0x6fcf;
21035 + priv->dma_poll_mask = 0;
21037 + rtl8180_beacon_tx_disable(dev);
21039 + if(priv->card_type == CARDBUS ){
21040 + config3=read_nic_byte(dev, CONFIG3);
21041 + write_nic_byte(dev,CONFIG3,config3 | CONFIG3_FuncRegEn);
21042 + write_nic_word(dev,FEMR, FEMR_INTR | FEMR_WKUP | FEMR_GWAKE |
21043 + read_nic_word(dev, FEMR));
21045 + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
21046 + write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
21047 + write_nic_word(dev, MAC4, ((u32*)dev->dev_addr)[1] & 0xffff );
21048 + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
21050 + rtl8180_update_msr(dev);
21052 + if(!priv->card_8185){
21053 + anaparam = eprom_read(dev,EPROM_ANAPARAM_ADDRLWORD);
21054 + anaparam |= eprom_read(dev,EPROM_ANAPARAM_ADDRHWORD)<<16;
21056 + rtl8180_set_anaparam(dev,anaparam);
21058 + /* These might be unnecessary since we do in rx_enable / tx_enable */
21059 + fix_rx_fifo(dev);
21060 + fix_tx_fifo(dev);
21061 + /*set_nic_rxring(dev);
21062 + set_nic_txring(dev);*/
21064 + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
21067 + The following is very strange. seems to be that 1 means test mode,
21068 + but we need to acknolwledges the nic when a packet is ready
21069 + altought we set it to 0
21072 + write_nic_byte(dev,
21073 + CONFIG2, read_nic_byte(dev,CONFIG2) &~\
21074 + (1<<CONFIG2_DMA_POLLING_MODE_SHIFT));
21075 + //^the nic isn't in test mode
21076 + if(priv->card_8185)
21077 + write_nic_byte(dev,
21078 + CONFIG2, read_nic_byte(dev,CONFIG2)|(1<<4));
21080 + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
21082 + write_nic_dword(dev,INT_TIMEOUT,0);
21083 +#ifdef DEBUG_REGISTERS
21084 + rtl8180_dump_reg(dev);
21087 + if(!priv->card_8185)
21090 + experimental - this might be needed to calibrate AGC,
21091 + anyway it shouldn't hurt
21093 + write_nic_byte(dev, CONFIG5,
21094 + read_nic_byte(dev, CONFIG5) | (1<<AGCRESET_SHIFT));
21095 + read_nic_byte(dev, CONFIG5);
21097 + write_nic_byte(dev, CONFIG5,
21098 + read_nic_byte(dev, CONFIG5) &~ (1<<AGCRESET_SHIFT));
21101 + write_nic_byte(dev, WPA_CONFIG, 0);
21102 + //write_nic_byte(dev, TESTR, 0xd);
21105 + rtl8180_no_hw_wep(dev);
21107 + if(priv->card_8185){
21108 + rtl8185_set_rate(dev);
21109 + write_nic_byte(dev, RATE_FALLBACK, 0x81);
21110 + // write_nic_byte(dev, 0xdf, 0x15);
21112 + word = read_nic_word(dev, BRSR);
21113 + word &= ~BRSR_MBR;
21114 + word &= ~BRSR_BPLCP;
21115 + word |= ieeerate2rtlrate(priv->ieee80211->basic_rate);
21119 + write_nic_word(dev, BRSR, word);
21123 + if(priv->card_8185){
21124 + write_nic_byte(dev, GP_ENABLE,read_nic_byte(dev, GP_ENABLE) & ~(1<<6));
21126 + //FIXME cfg 3 ClkRun enable - isn't it ReadOnly ?
21127 + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
21128 + write_nic_byte(dev,CONFIG3, read_nic_byte(dev, CONFIG3)
21129 +|(1<<CONFIG3_CLKRUN_SHIFT));
21130 + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
21134 + priv->rf_init(dev);
21136 + if(priv->rf_set_sens != NULL)
21137 + priv->rf_set_sens(dev,priv->sens);
21138 + rtl8180_irq_enable(dev);
21140 + netif_start_queue(dev);
21141 + /*DMESG ("lfree %d",get_curr_tx_free_desc(dev,LOW_PRIORITY));
21143 + DMESG ("nfree %d",get_curr_tx_free_desc(dev,NORM_PRIORITY));
21145 + DMESG ("hfree %d",get_curr_tx_free_desc(dev,HI_PRIORITY));
21146 + if(check_nic_enought_desc(dev,NORM_PRIORITY)) DMESG("NORM OK");
21147 + if(check_nic_enought_desc(dev,HI_PRIORITY)) DMESG("HI OK");
21148 + if(check_nic_enought_desc(dev,LOW_PRIORITY)) DMESG("LOW OK");*/
21153 +/* this configures registers for beacon tx and enables it via
21154 + * rtl8180_beacon_tx_enable(). rtl8180_beacon_tx_disable() might
21155 + * be used to stop beacon transmission
21157 +void rtl8180_start_tx_beacon(struct net_device *dev)
21159 +// struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
21161 +// DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
21163 + DMESG("Enabling beacon TX");
21164 + //write_nic_byte(dev, 0x42,0xe6);// TCR
21165 +// set_nic_txring(dev);
21166 +// fix_tx_fifo(dev);
21167 + rtl8180_prepare_beacon(dev);
21168 + rtl8180_irq_disable(dev);
21169 + rtl8180_beacon_tx_enable(dev);
21171 + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
21172 + //write_nic_byte(dev,0x9d,0x20); //DMA Poll
21173 + //write_nic_word(dev,0x7a,0);
21174 + //write_nic_word(dev,0x7a,0x8000);
21177 + word = read_nic_word(dev, BcnItv);
21178 + word &= ~BcnItv_BcnItv; // clear Bcn_Itv
21179 + word |= priv->ieee80211->current_network.beacon_interval;//0x64;
21180 + write_nic_word(dev, BcnItv, word);
21183 + word = read_nic_word(dev, AtimWnd) &~ AtimWnd_AtimWnd;
21184 + write_nic_word(dev, AtimWnd,word);// word |=
21185 +//priv->ieee80211->current_network.atim_window);
21187 + word = read_nic_word(dev, BintrItv);
21188 + word &= ~BintrItv_BintrItv;
21189 + word |= 1000;/*priv->ieee80211->current_network.beacon_interval *
21190 + ((priv->txbeaconcount > 1)?(priv->txbeaconcount-1):1);
21191 + // FIXME: check if correct ^^ worked with 0x3e8;
21193 + write_nic_word(dev, BintrItv, word);
21196 + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
21198 +// rtl8180_beacon_tx_enable(dev);
21199 +#ifdef CONFIG_RTL8185B
21200 + rtl8185b_irq_enable(dev);
21202 + rtl8180_irq_enable(dev);
21204 + /* VV !!!!!!!!!! VV*/
21206 + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
21207 + write_nic_byte(dev,0x9d,0x00);
21208 + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);
21210 +// DMESG("ring %x %x", priv->txlpringdma,read_nic_dword(dev,TLPDA));
21216 +/***************************************************************************
21217 + -------------------------------NET STUFF---------------------------
21218 +***************************************************************************/
21219 +static struct net_device_stats *rtl8180_stats(struct net_device *dev)
21221 + struct r8180_priv *priv = ieee80211_priv(dev);
21223 + return &priv->ieee80211->stats;
21226 +// Change current and default preamble mode.
21227 +// 2005.01.06, by rcnjko.
21230 +MgntActSet_802_11_PowerSaveMode(
21231 + struct r8180_priv *priv,
21232 + RT_PS_MODE rtPsMode
21236 + // Currently, we do not change power save mode on IBSS mode.
21237 + if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
21243 + // <RJ_NOTE> If we make HW to fill up the PwrMgt bit for us,
21244 + // some AP will not response to our mgnt frames with PwrMgt bit set,
21245 + // e.g. cannot associate the AP.
21246 + // So I commented out it. 2005.02.16, by rcnjko.
21248 +// // Change device's power save mode.
21249 +// Adapter->HalFunc.SetPSModeHandler( Adapter, rtPsMode );
21251 + // Update power save mode configured.
21252 +// priv->dot11PowerSaveMode = rtPsMode;
21253 + priv->ieee80211->ps = rtPsMode;
21254 + // Determine ListenInterval.
21256 + if(priv->dot11PowerSaveMode == eMaxPs)
21258 + priv->ieee80211->ListenInterval = 10;
21262 + priv->ieee80211->ListenInterval = 2;
21268 +//================================================================================
21269 +// Leisure Power Save in linked state.
21270 +//================================================================================
21274 +// Enter the leisure power save mode.
21278 + struct r8180_priv *priv
21281 + if (priv->bLeisurePs)
21283 + if (priv->ieee80211->ps == IEEE80211_PS_DISABLED)
21285 + //printk("----Enter PS\n");
21286 + MgntActSet_802_11_PowerSaveMode(priv, IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST);//IEEE80211_PS_ENABLE
21294 +// Leave the leisure power save mode.
21298 + struct r8180_priv *priv
21301 + if (priv->bLeisurePs)
21303 + if (priv->ieee80211->ps != IEEE80211_PS_DISABLED)
21305 + //printk("----Leave PS\n");
21306 + MgntActSet_802_11_PowerSaveMode(priv, IEEE80211_PS_DISABLED);
21310 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
21311 +void rtl8180_hw_wakeup_wq (struct work_struct *work)
21313 +// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
21314 +// struct ieee80211_device * ieee = (struct ieee80211_device*)
21315 +// container_of(work, struct ieee80211_device, watch_dog_wq);
21316 + struct delayed_work *dwork = container_of(work,struct delayed_work,work);
21317 + struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq);
21318 + struct net_device *dev = ieee->dev;
21320 +void rtl8180_hw_wakeup_wq(struct net_device *dev)
21322 + struct r8180_priv *priv = ieee80211_priv(dev);
21325 +// printk("dev is %d\n",dev);
21326 +// printk("&*&(^*(&(&=========>%s()\n", __FUNCTION__);
21327 + rtl8180_hw_wakeup(dev);
21331 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
21332 +void rtl8180_hw_sleep_wq (struct work_struct *work)
21334 +// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
21335 +// struct ieee80211_device * ieee = (struct ieee80211_device*)
21336 +// container_of(work, struct ieee80211_device, watch_dog_wq);
21337 + struct delayed_work *dwork = container_of(work,struct delayed_work,work);
21338 + struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_sleep_wq);
21339 + struct net_device *dev = ieee->dev;
21341 +void rtl8180_hw_sleep_wq(struct net_device *dev)
21343 + struct r8180_priv *priv = ieee80211_priv(dev);
21346 + rtl8180_hw_sleep_down(dev);
21349 +//YJ,add,080828,for KeepAlive
21350 +static void MgntLinkKeepAlive(struct r8180_priv *priv )
21352 + if (priv->keepAliveLevel == 0)
21355 + if(priv->ieee80211->state == IEEE80211_LINKED)
21360 + //printk("LastTx:%d Tx:%d LastRx:%d Rx:%ld Idle:%d\n",priv->link_detect.LastNumTxUnicast,priv->NumTxUnicast, priv->link_detect.LastNumRxUnicast, priv->ieee80211->NumRxUnicast, priv->link_detect.IdleCount);
21362 + if ( (priv->keepAliveLevel== 2) ||
21363 + (priv->link_detect.LastNumTxUnicast == priv->NumTxUnicast &&
21364 + priv->link_detect.LastNumRxUnicast == priv->ieee80211->NumRxUnicast )
21367 + priv->link_detect.IdleCount++;
21370 + // Send a Keep-Alive packet packet to AP if we had been idle for a while.
21372 + if(priv->link_detect.IdleCount >= ((KEEP_ALIVE_INTERVAL / CHECK_FOR_HANG_PERIOD)-1) )
21374 + priv->link_detect.IdleCount = 0;
21375 + ieee80211_sta_ps_send_null_frame(priv->ieee80211, false);
21380 + priv->link_detect.IdleCount = 0;
21382 + priv->link_detect.LastNumTxUnicast = priv->NumTxUnicast;
21383 + priv->link_detect.LastNumRxUnicast = priv->ieee80211->NumRxUnicast;
21386 +//YJ,add,080828,for KeepAlive,end
21388 +static u8 read_acadapter_file(char *filename);
21389 +void rtl8180_watch_dog(struct net_device *dev)
21391 + struct r8180_priv *priv = ieee80211_priv(dev);
21392 + bool bEnterPS = false;
21393 + bool bBusyTraffic = false;
21394 + u32 TotalRxNum = 0;
21395 + u16 SlotIndex = 0;
21398 + if(priv->ieee80211->actscanning == false){
21399 + if((priv->ieee80211->iw_mode != IW_MODE_ADHOC) && (priv->ieee80211->state == IEEE80211_NOLINK) && (priv->ieee80211->beinretry == false) && (priv->eRFPowerState == eRfOn)){
21404 + //YJ,add,080828,for link state check
21405 + if((priv->ieee80211->state == IEEE80211_LINKED) && (priv->ieee80211->iw_mode == IW_MODE_INFRA)){
21406 + SlotIndex = (priv->link_detect.SlotIndex++) % priv->link_detect.SlotNum;
21407 + priv->link_detect.RxFrameNum[SlotIndex] = priv->ieee80211->NumRxDataInPeriod + priv->ieee80211->NumRxBcnInPeriod;
21408 + for( i=0; i<priv->link_detect.SlotNum; i++ )
21409 + TotalRxNum+= priv->link_detect.RxFrameNum[i];
21410 + //printk("&&&&&=== TotalRxNum = %d\n", TotalRxNum);
21411 + if(TotalRxNum == 0){
21412 + priv->ieee80211->state = IEEE80211_ASSOCIATING;
21413 + queue_work(priv->ieee80211->wq, &priv->ieee80211->associate_procedure_wq);
21417 + //YJ,add,080828,for KeepAlive
21418 + MgntLinkKeepAlive(priv);
21420 + //YJ,add,080828,for LPS
21422 + if(priv->PowerProfile == POWER_PROFILE_BATTERY )
21424 + //Turn on LeisurePS on battery power
21425 + //printk("!!!!!On battery power\n");
21426 + priv->bLeisurePs = true;
21428 + else if(priv->PowerProfile == POWER_PROFILE_AC )
21430 + // Turn off LeisurePS on AC power
21431 + //printk("----On AC power\n");
21432 + LeisurePSLeave(priv);
21433 + priv->bLeisurePs= false;
21438 +#ifndef ENABLE_LPS
21439 + if(priv->ieee80211->state == IEEE80211_LINKED){
21440 + if( priv->NumRxOkInPeriod> 666 ||
21441 + priv->NumTxOkInPeriod > 666 ) {
21442 + bBusyTraffic = true;
21444 + if((priv->ieee80211->NumRxData + priv->NumTxOkInPeriod)<8) {
21448 + LeisurePSEnter(priv);
21451 + LeisurePSLeave(priv);
21455 + LeisurePSLeave(priv);
21458 + priv->NumRxOkInPeriod = 0;
21459 + priv->NumTxOkInPeriod = 0;
21460 + priv->ieee80211->NumRxData = 0;
21463 + if(priv->ieee80211->state == IEEE80211_LINKED){
21464 + priv->link_detect.NumRxOkInPeriod = priv->ieee80211->NumRxDataInPeriod;
21465 + //printk("TxOk=%d RxOk=%d\n", priv->link_detect.NumTxOkInPeriod, priv->link_detect.NumRxOkInPeriod);
21466 + if( priv->link_detect.NumRxOkInPeriod> 666 ||
21467 + priv->link_detect.NumTxOkInPeriod> 666 ) {
21468 + bBusyTraffic = true;
21470 + if(((priv->link_detect.NumRxOkInPeriod + priv->link_detect.NumTxOkInPeriod) > 8)
21471 + || (priv->link_detect.NumRxOkInPeriod > 2)) {
21479 + LeisurePSEnter(priv);
21482 + LeisurePSLeave(priv);
21486 + LeisurePSLeave(priv);
21489 + priv->link_detect.bBusyTraffic = bBusyTraffic;
21490 + priv->link_detect.NumRxOkInPeriod = 0;
21491 + priv->link_detect.NumTxOkInPeriod = 0;
21492 + priv->ieee80211->NumRxDataInPeriod = 0;
21493 + priv->ieee80211->NumRxBcnInPeriod = 0;
21496 +int _rtl8180_up(struct net_device *dev)
21498 + struct r8180_priv *priv = ieee80211_priv(dev);
21503 + DMESG("Bringing up iface");
21504 +#ifdef CONFIG_RTL8185B
21505 + rtl8185b_adapter_start(dev);
21506 + rtl8185b_rx_enable(dev);
21507 + rtl8185b_tx_enable(dev);
21509 + rtl8180_adapter_start(dev);
21510 + rtl8180_rx_enable(dev);
21511 + rtl8180_tx_enable(dev);
21514 + if(priv->bInactivePs){
21515 + if(priv->ieee80211->iw_mode == IW_MODE_ADHOC)
21521 + timer_rate_adaptive((unsigned long)dev);
21524 + watch_dog_adaptive((unsigned long)dev);
21526 + if(priv->bSwAntennaDiverity)
21527 + SwAntennaDiversityTimerCallback(dev);
21530 + ieee80211_softmac_start_protocol(priv->ieee80211);
21532 +//Add for RF power on power off by lizhaoming 080512
21533 +// priv->eRFPowerState = eRfOn;
21534 +// printk("\n--------Start queue_work:GPIOChangeRFWorkItem");
21535 +// queue_delayed_work(priv->ieee80211->wq,&priv->ieee80211->GPIOChangeRFWorkItem,1000);
21541 +int rtl8180_open(struct net_device *dev)
21543 + struct r8180_priv *priv = ieee80211_priv(dev);
21546 + down(&priv->wx_sem);
21547 + ret = rtl8180_up(dev);
21548 + up(&priv->wx_sem);
21554 +int rtl8180_up(struct net_device *dev)
21556 + struct r8180_priv *priv = ieee80211_priv(dev);
21558 + if (priv->up == 1) return -1;
21560 + return _rtl8180_up(dev);
21564 +int rtl8180_close(struct net_device *dev)
21566 + struct r8180_priv *priv = ieee80211_priv(dev);
21569 + down(&priv->wx_sem);
21570 + ret = rtl8180_down(dev);
21571 + up(&priv->wx_sem);
21577 +int rtl8180_down(struct net_device *dev)
21579 + struct r8180_priv *priv = ieee80211_priv(dev);
21581 + if (priv->up == 0) return -1;
21585 + ieee80211_softmac_stop_protocol(priv->ieee80211);
21587 + if (!netif_queue_stopped(dev))
21588 + netif_stop_queue(dev);
21589 + rtl8180_rtx_disable(dev);
21590 + rtl8180_irq_disable(dev);
21591 + del_timer_sync(&priv->watch_dog_timer);
21592 + //cancel_delayed_work(&priv->ieee80211->watch_dog_wq);
21594 + del_timer_sync(&priv->rateadapter_timer);
21595 + cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
21597 + cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
21598 + cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
21599 + cancel_delayed_work(&priv->ieee80211->hw_dig_wq);
21600 + cancel_delayed_work(&priv->ieee80211->tx_pw_wq);
21601 + del_timer_sync(&priv->SwAntennaDiversityTimer);
21602 + SetZebraRFPowerState8185(dev,eRfOff);
21603 + //ieee80211_softmac_stop_protocol(priv->ieee80211);
21604 + memset(&(priv->ieee80211->current_network),0,sizeof(struct ieee80211_network));
21605 + priv->ieee80211->state = IEEE80211_NOLINK;
21609 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
21610 +void rtl8180_restart_wq(struct work_struct *work)
21612 + struct r8180_priv *priv = container_of(work, struct r8180_priv, reset_wq);
21613 + struct net_device *dev = priv->dev;
21615 +void rtl8180_restart_wq(struct net_device *dev)
21617 + struct r8180_priv *priv = ieee80211_priv(dev);
21619 + down(&priv->wx_sem);
21621 + rtl8180_commit(dev);
21623 + up(&priv->wx_sem);
21626 +void rtl8180_restart(struct net_device *dev)
21628 + struct r8180_priv *priv = ieee80211_priv(dev);
21629 + //rtl8180_commit(dev);
21630 + schedule_work(&priv->reset_wq);
21631 + //DMESG("TXTIMEOUT");
21635 +void rtl8180_commit(struct net_device *dev)
21637 + struct r8180_priv *priv = ieee80211_priv(dev);
21639 + if (priv->up == 0) return ;
21641 + del_timer_sync(&priv->watch_dog_timer);
21642 + //cancel_delayed_work(&priv->ieee80211->watch_dog_wq);
21644 +//by amy for rate adaptive
21645 + del_timer_sync(&priv->rateadapter_timer);
21646 + cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
21647 +//by amy for rate adaptive
21649 + cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
21650 + cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
21651 + cancel_delayed_work(&priv->ieee80211->hw_dig_wq);
21652 + cancel_delayed_work(&priv->ieee80211->tx_pw_wq);
21653 + del_timer_sync(&priv->SwAntennaDiversityTimer);
21654 + ieee80211_softmac_stop_protocol(priv->ieee80211);
21655 + rtl8180_irq_disable(dev);
21656 + rtl8180_rtx_disable(dev);
21657 + _rtl8180_up(dev);
21661 +static void r8180_set_multicast(struct net_device *dev)
21663 + struct r8180_priv *priv = ieee80211_priv(dev);
21666 + //down(&priv->wx_sem);
21668 + promisc = (dev->flags & IFF_PROMISC) ? 1:0;
21670 + if (promisc != priv->promisc)
21671 + rtl8180_restart(dev);
21673 + priv->promisc = promisc;
21675 + //up(&priv->wx_sem);
21679 +/* this is called by the kernel when it needs to TX a 802.3 encapsulated frame*/
21680 +int rtl8180_8023_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
21682 + struct r8180_priv *priv = ieee80211_priv(dev);
21684 + unsigned long flags;
21686 + spin_lock_irqsave(&priv->tx_lock,flags);
21687 + ret = ieee80211_r8180_8023_hardstartxmit(skb,priv->ieee80211);
21688 + spin_unlock_irqrestore(&priv->tx_lock,flags);
21693 +int r8180_set_mac_adr(struct net_device *dev, void *mac)
21695 + struct r8180_priv *priv = ieee80211_priv(dev);
21696 + struct sockaddr *addr = mac;
21698 + down(&priv->wx_sem);
21700 + memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
21702 + if(priv->ieee80211->iw_mode == IW_MODE_MASTER)
21703 + memcpy(priv->ieee80211->current_network.bssid, dev->dev_addr, ETH_ALEN);
21706 + rtl8180_down(dev);
21710 + up(&priv->wx_sem);
21715 +/* based on ipw2200 driver */
21716 +int rtl8180_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
21718 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
21720 + struct iwreq *wrq = (struct iwreq *) rq;
21723 + case RTL_IOCTL_WPA_SUPPLICANT:
21724 + ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data);
21728 + return -EOPNOTSUPP;
21731 + return -EOPNOTSUPP;
21736 +/****************************************************************************
21737 + -----------------------------PCI STUFF---------------------------
21738 +*****************************************************************************/
21741 +static int __devinit rtl8180_pci_probe(struct pci_dev *pdev,
21742 + const struct pci_device_id *id)
21744 + unsigned long ioaddr = 0;
21745 + struct net_device *dev = NULL;
21746 + struct r8180_priv *priv= NULL;
21750 +#ifdef CONFIG_RTL8180_IO_MAP
21751 + unsigned long pio_start, pio_len, pio_flags;
21753 + unsigned long pmem_start, pmem_len, pmem_flags;
21754 +#endif //end #ifdef RTL_IO_MAP
21756 + DMESG("Configuring chip resources");
21758 + if( pci_enable_device (pdev) ){
21759 + DMESG("Failed to enable PCI device");
21763 + pci_set_master(pdev);
21764 + //pci_set_wmi(pdev);
21765 + pci_set_dma_mask(pdev, 0xffffff00ULL);
21766 + pci_set_consistent_dma_mask(pdev,0xffffff00ULL);
21767 + dev = alloc_ieee80211(sizeof(struct r8180_priv));
21770 + priv = ieee80211_priv(dev);
21771 + priv->ieee80211 = netdev_priv(dev);
21773 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
21774 + SET_MODULE_OWNER(dev);
21776 + pci_set_drvdata(pdev, dev);
21777 + SET_NETDEV_DEV(dev, &pdev->dev);
21779 + priv = ieee80211_priv(dev);
21780 +// memset(priv,0,sizeof(struct r8180_priv));
21784 +#ifdef CONFIG_RTL8180_IO_MAP
21786 + pio_start = (unsigned long)pci_resource_start (pdev, 0);
21787 + pio_len = (unsigned long)pci_resource_len (pdev, 0);
21788 + pio_flags = (unsigned long)pci_resource_flags (pdev, 0);
21790 + if (!(pio_flags & IORESOURCE_IO)) {
21791 + DMESG("region #0 not a PIO resource, aborting");
21795 + //DMESG("IO space @ 0x%08lx", pio_start );
21796 + if( ! request_region( pio_start, pio_len, RTL8180_MODULE_NAME ) ){
21797 + DMESG("request_region failed!");
21801 + ioaddr = pio_start;
21802 + dev->base_addr = ioaddr; // device I/O address
21806 + pmem_start = pci_resource_start(pdev, 1);
21807 + pmem_len = pci_resource_len(pdev, 1);
21808 + pmem_flags = pci_resource_flags (pdev, 1);
21810 + if (!(pmem_flags & IORESOURCE_MEM)) {
21811 + DMESG("region #1 not a MMIO resource, aborting");
21815 + //DMESG("Memory mapped space @ 0x%08lx ", pmem_start);
21816 + if( ! request_mem_region(pmem_start, pmem_len, RTL8180_MODULE_NAME)) {
21817 + DMESG("request_mem_region failed!");
21822 + ioaddr = (unsigned long)ioremap_nocache( pmem_start, pmem_len);
21823 + if( ioaddr == (unsigned long)NULL ){
21824 + DMESG("ioremap failed!");
21825 + // release_mem_region( pmem_start, pmem_len );
21829 + dev->mem_start = ioaddr; // shared mem start
21830 + dev->mem_end = ioaddr + pci_resource_len(pdev, 0); // shared mem end
21832 +#endif //end #ifdef RTL_IO_MAP
21834 +#ifdef CONFIG_RTL8185B
21835 + //pci_read_config_byte(pdev, 0x05, ptr);
21836 + //pci_write_config_byte(pdev, 0x05, (*ptr) & (~0x04));
21837 + pci_read_config_byte(pdev, 0x05, &unit);
21838 + pci_write_config_byte(pdev, 0x05, unit & (~0x04));
21841 + dev->irq = pdev->irq;
21844 + dev->open = rtl8180_open;
21845 + dev->stop = rtl8180_close;
21846 + //dev->hard_start_xmit = ieee80211_xmit;
21847 + dev->tx_timeout = rtl8180_restart;
21848 + dev->wireless_handlers = &r8180_wx_handlers_def;
21849 + dev->do_ioctl = rtl8180_ioctl;
21850 + dev->set_multicast_list = r8180_set_multicast;
21851 + dev->set_mac_address = r8180_set_mac_adr;
21853 +#if WIRELESS_EXT >= 12
21854 +#if WIRELESS_EXT < 17
21855 + dev->get_wireless_stats = r8180_get_wireless_stats;
21857 + dev->wireless_handlers = (struct iw_handler_def *) &r8180_wx_handlers_def;
21860 + dev->type=ARPHRD_ETHER;
21861 + dev->watchdog_timeo = HZ*3; //added by david woo, 2007.12.13
21863 + if (dev_alloc_name(dev, ifname) < 0){
21864 + DMESG("Oops: devname already taken! Trying wlan%%d...\n");
21865 + ifname = "wlan%d";
21866 + // ifname = "ath%d";
21867 + dev_alloc_name(dev, ifname);
21871 + if(rtl8180_init(dev)!=0){
21872 + DMESG("Initialization failed");
21876 + netif_carrier_off(dev);
21878 + register_netdev(dev);
21880 + rtl8180_proc_init_one(dev);
21882 + DMESG("Driver probe completed\n");
21887 +#ifdef CONFIG_RTL8180_IO_MAP
21889 + if( dev->base_addr != 0 ){
21891 + release_region(dev->base_addr,
21892 + pci_resource_len(pdev, 0) );
21895 + if( dev->mem_start != (unsigned long)NULL ){
21896 + iounmap( (void *)dev->mem_start );
21897 + release_mem_region( pci_resource_start(pdev, 1),
21898 + pci_resource_len(pdev, 1) );
21900 +#endif //end #ifdef RTL_IO_MAP
21907 + free_irq(dev->irq, dev);
21910 + free_ieee80211(dev);
21913 + pci_disable_device(pdev);
21915 + DMESG("wlan driver load failed\n");
21916 + pci_set_drvdata(pdev, NULL);
21922 +static void __devexit rtl8180_pci_remove(struct pci_dev *pdev)
21924 + struct r8180_priv *priv;
21925 + struct net_device *dev = pci_get_drvdata(pdev);
21928 + unregister_netdev(dev);
21930 + priv=ieee80211_priv(dev);
21932 + rtl8180_proc_remove_one(dev);
21933 + rtl8180_down(dev);
21934 + priv->rf_close(dev);
21935 + rtl8180_reset(dev);
21936 + //rtl8180_rtx_disable(dev);
21937 + //rtl8180_irq_disable(dev);
21939 + //write_nic_word(dev,INTA,read_nic_word(dev,INTA));
21940 + //force_pci_posting(dev);
21945 + DMESG("Freeing irq %d",dev->irq);
21946 + free_irq(dev->irq, dev);
21951 + free_rx_desc_ring(dev);
21952 + free_tx_desc_rings(dev);
21953 + // free_beacon_desc_ring(dev,priv->txbeaconcount);
21955 +#ifdef CONFIG_RTL8180_IO_MAP
21957 + if( dev->base_addr != 0 ){
21959 + release_region(dev->base_addr,
21960 + pci_resource_len(pdev, 0) );
21963 + if( dev->mem_start != (unsigned long)NULL ){
21964 + iounmap( (void *)dev->mem_start );
21965 + release_mem_region( pci_resource_start(pdev, 1),
21966 + pci_resource_len(pdev, 1) );
21968 +#endif /*end #ifdef RTL_IO_MAP*/
21970 + free_ieee80211(dev);
21972 + pci_disable_device(pdev);
21974 + DMESG("wlan driver removed\n");
21978 +/* fun with the built-in ieee80211 stack... */
21979 +extern int ieee80211_crypto_init(void);
21980 +extern void ieee80211_crypto_deinit(void);
21981 +extern int ieee80211_crypto_tkip_init(void);
21982 +extern void ieee80211_crypto_tkip_exit(void);
21983 +extern int ieee80211_crypto_ccmp_init(void);
21984 +extern void ieee80211_crypto_ccmp_exit(void);
21985 +extern int ieee80211_crypto_wep_init(void);
21986 +extern void ieee80211_crypto_wep_exit(void);
21988 +static int __init rtl8180_pci_module_init(void)
21992 + ret = ieee80211_crypto_init();
21994 + printk(KERN_ERR "ieee80211_crypto_init() failed %d\n", ret);
21997 + ret = ieee80211_crypto_tkip_init();
21999 + printk(KERN_ERR "ieee80211_crypto_tkip_init() failed %d\n", ret);
22002 + ret = ieee80211_crypto_ccmp_init();
22004 + printk(KERN_ERR "ieee80211_crypto_ccmp_init() failed %d\n", ret);
22007 + ret = ieee80211_crypto_wep_init();
22009 + printk(KERN_ERR "ieee80211_crypto_wep_init() failed %d\n", ret);
22013 + printk(KERN_INFO "\nLinux kernel driver for RTL8180 \
22014 +/ RTL8185 based WLAN cards\n");
22015 + printk(KERN_INFO "Copyright (c) 2004-2005, Andrea Merello\n");
22016 + DMESG("Initializing module");
22017 + DMESG("Wireless extensions version %d", WIRELESS_EXT);
22018 + rtl8180_proc_module_init();
22020 +#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22))
22021 + if(0!=pci_module_init(&rtl8180_pci_driver))
22023 + if(0!=pci_register_driver(&rtl8180_pci_driver))
22025 + //if(0!=pci_module_init(&rtl8180_pci_driver))
22027 + DMESG("No device found");
22028 + /*pci_unregister_driver (&rtl8180_pci_driver);*/
22035 +static void __exit rtl8180_pci_module_exit(void)
22037 + pci_unregister_driver (&rtl8180_pci_driver);
22038 + rtl8180_proc_module_remove();
22039 + ieee80211_crypto_deinit();
22040 + ieee80211_crypto_tkip_exit();
22041 + ieee80211_crypto_ccmp_exit();
22042 + ieee80211_crypto_wep_exit();
22043 + DMESG("Exiting");
22047 +void rtl8180_try_wake_queue(struct net_device *dev, int pri)
22049 + unsigned long flags;
22050 + short enough_desc;
22051 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
22053 + spin_lock_irqsave(&priv->tx_lock,flags);
22054 + enough_desc = check_nic_enought_desc(dev,pri);
22055 + spin_unlock_irqrestore(&priv->tx_lock,flags);
22058 + ieee80211_wake_queue(priv->ieee80211);
22061 +/*****************************************************************************
22062 + -----------------------------IRQ STUFF---------------------------
22063 +******************************************************************************/
22065 +void rtl8180_tx_isr(struct net_device *dev, int pri,short error)
22067 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
22069 + u32 *tail; //tail virtual addr
22070 + u32 *head; //head virtual addr
22071 + u32 *begin;//start of ring virtual addr
22072 + u32 *nicv; //nic pointer virtual addr
22073 +// u32 *txdv; //packet just TXed
22074 + u32 nic; //nic pointer physical addr
22075 + u32 nicbegin;// start of ring physical addr
22077 + unsigned long flag;
22078 + /* physical addr are ok on 32 bits since we set DMA mask*/
22083 + if (error) priv->stats.txretry++; //tony 20060601
22084 + spin_lock_irqsave(&priv->tx_lock,flag);
22086 + case MANAGE_PRIORITY:
22087 + tail = priv->txmapringtail;
22088 + begin = priv->txmapring;
22089 + head = priv->txmapringhead;
22090 + nic = read_nic_dword(dev,TX_MANAGEPRIORITY_RING_ADDR);
22091 + nicbegin = priv->txmapringdma;
22094 + case BK_PRIORITY:
22095 + tail = priv->txbkpringtail;
22096 + begin = priv->txbkpring;
22097 + head = priv->txbkpringhead;
22098 + nic = read_nic_dword(dev,TX_BKPRIORITY_RING_ADDR);
22099 + nicbegin = priv->txbkpringdma;
22102 + case BE_PRIORITY:
22103 + tail = priv->txbepringtail;
22104 + begin = priv->txbepring;
22105 + head = priv->txbepringhead;
22106 + nic = read_nic_dword(dev,TX_BEPRIORITY_RING_ADDR);
22107 + nicbegin = priv->txbepringdma;
22110 + case VI_PRIORITY:
22111 + tail = priv->txvipringtail;
22112 + begin = priv->txvipring;
22113 + head = priv->txvipringhead;
22114 + nic = read_nic_dword(dev,TX_VIPRIORITY_RING_ADDR);
22115 + nicbegin = priv->txvipringdma;
22118 + case VO_PRIORITY:
22119 + tail = priv->txvopringtail;
22120 + begin = priv->txvopring;
22121 + head = priv->txvopringhead;
22122 + nic = read_nic_dword(dev,TX_VOPRIORITY_RING_ADDR);
22123 + nicbegin = priv->txvopringdma;
22126 + case HI_PRIORITY:
22127 + tail = priv->txhpringtail;
22128 + begin = priv->txhpring;
22129 + head = priv->txhpringhead;
22130 + nic = read_nic_dword(dev,TX_HIGHPRIORITY_RING_ADDR);
22131 + nicbegin = priv->txhpringdma;
22135 + spin_unlock_irqrestore(&priv->tx_lock,flag);
22138 +/* DMESG("%x %s %x %x",((int)nic & 0xfff)/8/4,
22139 + *(priv->txnpring + ((int)nic&0xfff)/4/8) & (1<<31) ? "filled" : "empty",
22140 + (priv->txnpringtail - priv->txnpring)/8,(priv->txnpringhead -
22141 +priv->txnpring)/8);
22143 + //nicv = (u32*) ((nic - nicbegin) + (int)begin);
22144 + nicv = (u32*) ((nic - nicbegin) + (u8*)begin);
22145 + if((head <= tail && (nicv > tail || nicv < head)) ||
22146 + (head > tail && (nicv > tail && nicv < head))){
22148 + DMESGW("nic has lost pointer");
22149 +#ifdef DEBUG_TX_DESC
22150 + //check_tx_ring(dev,NORM_PRIORITY);
22151 + check_tx_ring(dev,pri);
22153 + spin_unlock_irqrestore(&priv->tx_lock,flag);
22154 + rtl8180_restart(dev);
22158 + /* we check all the descriptors between the head and the nic,
22159 + * but not the currenly pointed by the nic (the next to be txed)
22160 + * and the previous of the pointed (might be in process ??)
22162 + //if (head == nic) return;
22163 + //DMESG("%x %x",head,nic);
22164 + offs = (nic - nicbegin);
22165 + //DMESG("%x %x %x",nic ,(u32)nicbegin, (int)nic -nicbegin);
22167 + offs = offs / 8 /4;
22169 + hd = (head - begin) /8;
22174 + j = offs + (priv->txringcount -1 -hd);
22175 + // j= priv->txringcount -1- (hd - offs);
22183 +// printk("+++++++++++++check status desc\n");
22184 + if((*head) & (1<<31))
22186 + if(((*head)&(0x10000000)) != 0){
22187 +// printk("++++++++++++++last desc,retry count is %d\n",((*head) & (0x000000ff)));
22188 + priv->CurrRetryCnt += (u16)((*head) & (0x000000ff));
22192 + priv->NumTxOkTotal++;
22193 +// printk("NumTxOkTotal is %d\n",priv->NumTxOkTotal++);
22196 + // printk("in function %s:curr_retry_count is %d\n",__FUNCTION__,((*head) & (0x000000ff)));
22199 + priv->NumTxOkBytesTotal += (*(head+3)) & (0x00000fff);
22201 +// printk("in function %s:curr_txokbyte_count is %d\n",__FUNCTION__,(*(head+3)) & (0x00000fff));
22202 + *head = *head &~ (1<<31);
22204 + if((head - begin)/8 == priv->txringcount-1)
22211 + if(nicv == begin)
22212 + txdv = begin + (priv->txringcount -1)*8;
22216 + txed = !(txdv[0] &(1<<31));
22219 + if(!(txdv[0] & (1<<15))) error = 1;
22220 + //if(!(txdv[0] & (1<<30))) error = 1;
22221 + if(error)DMESG("%x",txdv[0]);
22224 + //DMESG("%x",txdv[0]);
22225 + /* the head has been moved to the last certainly TXed
22226 + * (or at least processed by the nic) packet.
22227 + * The driver take forcefully owning of all these packets
22228 + * If the packet previous of the nic pointer has been
22229 + * processed this doesn't matter: it will be checked
22230 + * here at the next round. Anyway if no more packet are
22231 + * TXed no memory leak occour at all.
22235 + case MANAGE_PRIORITY:
22236 + priv->txmapringhead = head;
22237 + //printk("1==========================================> priority check!\n");
22238 + if(priv->ack_tx_to_ieee){
22239 + // try to implement power-save mode 2008.1.22
22240 + // printk("2==========================================> priority check!\n");
22242 + if(rtl8180_is_tx_queue_empty(dev)){
22243 + // printk("tx queue empty, after send null sleep packet, try to sleep !\n");
22244 + priv->ack_tx_to_ieee = 0;
22245 + ieee80211_ps_tx_ack(priv->ieee80211,!error);
22251 + case BK_PRIORITY:
22252 + priv->txbkpringhead = head;
22255 + case BE_PRIORITY:
22256 + priv->txbepringhead = head;
22259 + case VI_PRIORITY:
22260 + priv->txvipringhead = head;
22263 + case VO_PRIORITY:
22264 + priv->txvopringhead = head;
22267 + case HI_PRIORITY:
22268 + priv->txhpringhead = head;
22272 + /*DMESG("%x %x %x", (priv->txnpringhead - priv->txnpring) /8 ,
22273 + (priv->txnpringtail - priv->txnpring) /8,
22277 + spin_unlock_irqrestore(&priv->tx_lock,flag);
22281 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
22282 +void rtl8180_tx_irq_wq(struct work_struct *work)
22284 + //struct r8180_priv *priv = container_of(work, struct r8180_priv, reset_wq);
22285 + struct delayed_work *dwork = container_of(work,struct delayed_work,work);
22286 + struct ieee80211_device * ieee = (struct ieee80211_device*)
22287 + container_of(dwork, struct ieee80211_device, watch_dog_wq);
22288 + struct net_device *dev = ieee->dev;
22290 +void rtl8180_tx_irq_wq(struct net_device *dev)
22292 + //struct r8180_priv *priv = ieee80211_priv(dev);
22294 + rtl8180_tx_isr(dev,MANAGE_PRIORITY,0);
22296 +irqreturn_t rtl8180_interrupt(int irq, void *netdev, struct pt_regs *regs)
22298 + struct net_device *dev = (struct net_device *) netdev;
22299 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
22300 + unsigned long flags;
22303 + /* We should return IRQ_NONE, but for now let me keep this */
22304 + if(priv->irq_enabled == 0) return IRQ_HANDLED;
22306 + spin_lock_irqsave(&priv->irq_th_lock,flags);
22308 +#ifdef CONFIG_RTL8185B
22310 + inta = read_nic_dword(dev, ISR);// & priv->IntrMask;
22311 + write_nic_dword(dev,ISR,inta); // reset int situation
22313 + inta = read_nic_word(dev,INTA) & priv->irq_mask;
22314 + write_nic_word(dev,INTA,inta); // reset int situation
22317 + priv->stats.shints++;
22319 + //DMESG("Enter interrupt, ISR value = 0x%08x", inta);
22322 + spin_unlock_irqrestore(&priv->irq_th_lock,flags);
22323 + return IRQ_HANDLED;
22325 + most probably we can safely return IRQ_NONE,
22326 + but for now is better to avoid problems
22330 + if(inta == 0xffff){
22331 + /* HW disappared */
22332 + spin_unlock_irqrestore(&priv->irq_th_lock,flags);
22333 + return IRQ_HANDLED;
22336 + priv->stats.ints++;
22338 + DMESG("NIC irq %x",inta);
22340 + //priv->irqpending = inta;
22343 + if(!netif_running(dev)) {
22344 + spin_unlock_irqrestore(&priv->irq_th_lock,flags);
22345 + return IRQ_HANDLED;
22348 + if(inta & ISR_TimeOut){
22349 + write_nic_dword(dev, TimerInt, 0);
22350 + //DMESG("=================>waking up");
22351 +// rtl8180_hw_wakeup(dev);
22354 + if(inta & ISR_TBDOK){
22355 + priv->stats.txbeacon++;
22358 + if(inta & ISR_TBDER){
22359 + priv->stats.txbeaconerr++;
22362 + if(inta & IMR_TMGDOK ) {
22363 +// priv->NumTxOkTotal++;
22364 + rtl8180_tx_isr(dev,MANAGE_PRIORITY,0);
22365 +// schedule_work(&priv->tx_irq_wq);
22369 + if(inta & ISR_THPDER){
22371 + DMESG ("TX high priority ERR");
22373 + priv->stats.txhperr++;
22374 + rtl8180_tx_isr(dev,HI_PRIORITY,1);
22375 + priv->ieee80211->stats.tx_errors++;
22378 + if(inta & ISR_THPDOK){ //High priority tx ok
22380 + DMESG ("TX high priority OK");
22382 +// priv->NumTxOkTotal++;
22383 + //priv->NumTxOkInPeriod++; //YJ,del,080828
22384 + priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828
22385 + priv->stats.txhpokint++;
22386 + rtl8180_tx_isr(dev,HI_PRIORITY,0);
22389 + if(inta & ISR_RER) {
22390 + priv->stats.rxerr++;
22392 + DMESGW("RX error int");
22395 +#ifdef CONFIG_RTL8185B
22396 + if(inta & ISR_TBKDER){ //corresponding to BK_PRIORITY
22397 + priv->stats.txbkperr++;
22398 + priv->ieee80211->stats.tx_errors++;
22400 + DMESGW("TX bkp error int");
22402 + //tasklet_schedule(&priv->irq_tx_tasklet);
22403 + rtl8180_tx_isr(dev,BK_PRIORITY,1);
22404 + rtl8180_try_wake_queue(dev, BE_PRIORITY);
22407 + if(inta & ISR_TBEDER){ //corresponding to BE_PRIORITY
22408 + priv->stats.txbeperr++;
22409 + priv->ieee80211->stats.tx_errors++;
22411 + DMESGW("TX bep error int");
22413 + rtl8180_tx_isr(dev,BE_PRIORITY,1);
22414 + //tasklet_schedule(&priv->irq_tx_tasklet);
22415 + rtl8180_try_wake_queue(dev, BE_PRIORITY);
22418 + if(inta & ISR_TNPDER){ //corresponding to VO_PRIORITY
22419 + priv->stats.txnperr++;
22420 + priv->ieee80211->stats.tx_errors++;
22422 + DMESGW("TX np error int");
22424 + //tasklet_schedule(&priv->irq_tx_tasklet);
22425 + rtl8180_tx_isr(dev,NORM_PRIORITY,1);
22426 +#ifdef CONFIG_RTL8185B
22427 + rtl8180_try_wake_queue(dev, NORM_PRIORITY);
22431 + if(inta & ISR_TLPDER){ //corresponding to VI_PRIORITY
22432 + priv->stats.txlperr++;
22433 + priv->ieee80211->stats.tx_errors++;
22435 + DMESGW("TX lp error int");
22437 + rtl8180_tx_isr(dev,LOW_PRIORITY,1);
22438 + //tasklet_schedule(&priv->irq_tx_tasklet);
22439 + rtl8180_try_wake_queue(dev, LOW_PRIORITY);
22442 + if(inta & ISR_ROK){
22444 + DMESG("Frame arrived !");
22446 + //priv->NumRxOkInPeriod++; //YJ,del,080828
22447 + priv->stats.rxint++;
22448 + tasklet_schedule(&priv->irq_rx_tasklet);
22451 + if(inta & ISR_RQoSOK ){
22453 + DMESG("QoS Frame arrived !");
22455 + //priv->NumRxOkInPeriod++; //YJ,del,080828
22456 + priv->stats.rxint++;
22457 + tasklet_schedule(&priv->irq_rx_tasklet);
22459 + if(inta & ISR_BcnInt) {
22460 + //DMESG("Preparing Beacons");
22461 + rtl8180_prepare_beacon(dev);
22464 + if(inta & ISR_RDU){
22466 + DMESGW("No RX descriptor available");
22467 + priv->stats.rxrdu++;
22469 + tasklet_schedule(&priv->irq_rx_tasklet);
22470 + /*queue_work(priv->workqueue ,&priv->restart_work);*/
22473 + if(inta & ISR_RXFOVW){
22475 + DMESGW("RX fifo overflow");
22477 + priv->stats.rxoverflow++;
22478 + tasklet_schedule(&priv->irq_rx_tasklet);
22479 + //queue_work(priv->workqueue ,&priv->restart_work);
22482 + if(inta & ISR_TXFOVW) priv->stats.txoverflow++;
22484 + if(inta & ISR_TNPDOK){ //Normal priority tx ok
22486 + DMESG ("TX normal priority OK");
22488 +// priv->NumTxOkTotal++;
22489 + //priv->NumTxOkInPeriod++; //YJ,del,080828
22490 + priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828
22491 + // priv->ieee80211->stats.tx_packets++;
22492 + priv->stats.txnpokint++;
22493 + rtl8180_tx_isr(dev,NORM_PRIORITY,0);
22496 + if(inta & ISR_TLPDOK){ //Low priority tx ok
22498 + DMESG ("TX low priority OK");
22500 +// priv->NumTxOkTotal++;
22501 + //priv->NumTxOkInPeriod++; //YJ,del,080828
22502 + priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828
22503 + // priv->ieee80211->stats.tx_packets++;
22504 + priv->stats.txlpokint++;
22505 + rtl8180_tx_isr(dev,LOW_PRIORITY,0);
22506 + rtl8180_try_wake_queue(dev, LOW_PRIORITY);
22509 +#ifdef CONFIG_RTL8185B
22510 + if(inta & ISR_TBKDOK){ //corresponding to BK_PRIORITY
22511 + priv->stats.txbkpokint++;
22513 + DMESGW("TX bk priority ok");
22515 +// priv->NumTxOkTotal++;
22516 + //priv->NumTxOkInPeriod++; //YJ,del,080828
22517 + priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828
22518 + rtl8180_tx_isr(dev,BK_PRIORITY,0);
22519 + rtl8180_try_wake_queue(dev, BE_PRIORITY);
22522 + if(inta & ISR_TBEDOK){ //corresponding to BE_PRIORITY
22523 + priv->stats.txbeperr++;
22525 + DMESGW("TX be priority ok");
22527 +// priv->NumTxOkTotal++;
22528 + //priv->NumTxOkInPeriod++; //YJ,del,080828
22529 + priv->link_detect.NumTxOkInPeriod++; //YJ,add,080828
22530 + rtl8180_tx_isr(dev,BE_PRIORITY,0);
22531 + rtl8180_try_wake_queue(dev, BE_PRIORITY);
22534 + force_pci_posting(dev);
22535 + spin_unlock_irqrestore(&priv->irq_th_lock,flags);
22537 + return IRQ_HANDLED;
22541 +void rtl8180_irq_rx_tasklet(struct r8180_priv* priv)
22543 +// unsigned long flags;
22545 +/* spin_lock_irqsave(&priv->irq_lock, flags);
22546 + priv->irq_mask &=~IMR_ROK;
22547 + priv->irq_mask &=~IMR_RDU;
22549 + rtl8180_irq_enable(priv->dev);
22550 + spin_unlock_irqrestore(&priv->irq_lock, flags);
22552 + rtl8180_rx(priv->dev);
22554 +/* spin_lock_irqsave(&priv->irq_lock, flags);
22555 + priv->irq_mask |= IMR_ROK;
22556 + priv->irq_mask |= IMR_RDU;
22557 + rtl8180_irq_enable(priv->dev);
22558 + spin_unlock_irqrestore(&priv->irq_lock, flags);
22562 +/****************************************************************************
22563 +lizhaoming--------------------------- RF power on/power off -----------------
22564 +*****************************************************************************/
22566 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
22567 +void GPIOChangeRFWorkItemCallBack(struct work_struct *work)
22569 + //struct delayed_work *dwork = container_of(work, struct delayed_work, work);
22570 + struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, GPIOChangeRFWorkItem.work);
22571 + struct net_device *dev = ieee->dev;
22572 + struct r8180_priv *priv = ieee80211_priv(dev);
22574 +void GPIOChangeRFWorkItemCallBack(struct ieee80211_device *ieee)
22576 + struct net_device *dev = ieee->dev;
22577 + struct r8180_priv *priv = ieee80211_priv(dev);
22583 + RT_RF_POWER_STATE eRfPowerStateToSet;
22584 + bool bActuallySet=false;
22587 + static char *RadioPowerPath = "/etc/acpi/events/RadioPower.sh";
22588 + static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL};
22589 + static int readf_count = 0;
22590 + //printk("============>%s in \n", __func__);
22593 + if(readf_count % 10 == 0)
22594 + priv->PowerProfile = read_acadapter_file("/proc/acpi/ac_adapter/AC0/state");
22596 + readf_count = (readf_count+1)%0xffff;
22599 + if(priv->up == 0)//driver stopped
22601 + printk("\nDo nothing...");
22607 + // We should turn off LED before polling FF51[4].
22610 + btPSR = read_nic_byte(dev, PSR);
22611 + write_nic_byte(dev, PSR, (btPSR & ~BIT3));
22613 + //It need to delay 4us suggested by Jong, 2008-01-16
22616 + //HW radio On/Off according to the value of FF51[4](config0)
22617 + btConfig0 = btPSR = read_nic_byte(dev, CONFIG0);
22620 + write_nic_byte(dev, PSR, btPSR| BIT3);
22622 + eRfPowerStateToSet = (btConfig0 & BIT4) ? eRfOn : eRfOff;
22624 + if((priv->ieee80211->bHwRadioOff == true) && (eRfPowerStateToSet == eRfOn))
22626 + priv->ieee80211->bHwRadioOff = false;
22627 + bActuallySet = true;
22629 + else if((priv->ieee80211->bHwRadioOff == false) && (eRfPowerStateToSet == eRfOff))
22631 + priv->ieee80211->bHwRadioOff = true;
22632 + bActuallySet = true;
22637 + MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
22639 + /* To update the UI status for Power status changed */
22640 + if(priv->ieee80211->bHwRadioOff == true)
22641 + argv[1] = "RFOFF";
22643 + //if(!priv->RfOffReason)
22644 + argv[1] = "RFON";
22646 + // argv[1] = "RFOFF";
22648 + argv[0] = RadioPowerPath;
22651 + call_usermodehelper(RadioPowerPath,argv,envp,1);
22658 +static u8 read_acadapter_file(char *filename)
22660 +//#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21))
22667 + mm_segment_t old_fs = get_fs();
22668 + set_fs(KERNEL_DS);
22670 + fd = sys_open(filename, O_RDONLY, 0);
22672 + while (sys_read(fd, buf, 1) == 1)
22687 +// printk("%s \n", ret);
22690 + if(strncmp(ret, "off-line",8) == 0)
22698 +/***************************************************************************
22699 + ------------------- module init / exit stubs ----------------
22700 +****************************************************************************/
22701 +module_init(rtl8180_pci_module_init);
22702 +module_exit(rtl8180_pci_module_exit);
22705 +++ b/drivers/staging/rtl8187se/r8180_dm.c
22707 +//#include "r8180.h"
22708 +#include "r8180_dm.h"
22709 +#include "r8180_hw.h"
22710 +#include "r8180_93cx6.h"
22715 +// Return TRUE if we shall perform High Power Mecahnism, FALSE otherwise.
22718 +#define RATE_ADAPTIVE_TIMER_PERIOD 300
22720 +bool CheckHighPower(struct net_device *dev)
22722 + struct r8180_priv *priv = ieee80211_priv(dev);
22723 + struct ieee80211_device *ieee = priv->ieee80211;
22725 + if(!priv->bRegHighPowerMechanism)
22730 + if(ieee->state == IEEE80211_LINKED_SCANNING)
22740 +// Update Tx power level if necessary.
22741 +// See also DoRxHighPower() and SetTxPowerLevel8185() for reference.
22744 +// The reason why we udpate Tx power level here instead of DoRxHighPower()
22745 +// is the number of IO to change Tx power is much more than chane TR switch
22746 +// and they are related to OFDM and MAC registers.
22747 +// So, we don't want to update it so frequently in per-Rx packet base.
22751 + struct net_device *dev
22754 + struct r8180_priv *priv = ieee80211_priv(dev);
22755 + u16 HiPwrUpperTh = 0;
22756 + u16 HiPwrLowerTh = 0;
22757 + u8 RSSIHiPwrUpperTh;
22758 + u8 RSSIHiPwrLowerTh;
22760 + char OfdmTxPwrIdx, CckTxPwrIdx;
22762 + //printk("----> DoTxHighPower()\n");
22764 + HiPwrUpperTh = priv->RegHiPwrUpperTh;
22765 + HiPwrLowerTh = priv->RegHiPwrLowerTh;
22767 + HiPwrUpperTh = HiPwrUpperTh * 10;
22768 + HiPwrLowerTh = HiPwrLowerTh * 10;
22769 + RSSIHiPwrUpperTh = priv->RegRSSIHiPwrUpperTh;
22770 + RSSIHiPwrLowerTh = priv->RegRSSIHiPwrLowerTh;
22773 + OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
22774 + CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel];
22776 + // printk("DoTxHighPower() - UndecoratedSmoothedSS:%d, CurCCKRSSI = %d , bCurCCKPkt= %d \n", priv->UndecoratedSmoothedSS, priv->CurCCKRSSI, priv->bCurCCKPkt );
22778 + if((priv->UndecoratedSmoothedSS > HiPwrUpperTh) ||
22779 + (priv->bCurCCKPkt && (priv->CurCCKRSSI > RSSIHiPwrUpperTh)))
22781 + // Stevenl suggested that degrade 8dbm in high power sate. 2007-12-04 Isaiah
22783 + // printk("=====>DoTxHighPower() - High Power - UndecoratedSmoothedSS:%d, HiPwrUpperTh = %d \n", priv->UndecoratedSmoothedSS, HiPwrUpperTh );
22784 + priv->bToUpdateTxPwr = true;
22785 + u1bTmp= read_nic_byte(dev, CCK_TXAGC);
22787 + // If it never enter High Power.
22788 + if( CckTxPwrIdx == u1bTmp)
22790 + u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0; // 8dbm
22791 + write_nic_byte(dev, CCK_TXAGC, u1bTmp);
22793 + u1bTmp= read_nic_byte(dev, OFDM_TXAGC);
22794 + u1bTmp = (u1bTmp > 16) ? (u1bTmp -16): 0; // 8dbm
22795 + write_nic_byte(dev, OFDM_TXAGC, u1bTmp);
22799 + else if((priv->UndecoratedSmoothedSS < HiPwrLowerTh) &&
22800 + (!priv->bCurCCKPkt || priv->CurCCKRSSI < RSSIHiPwrLowerTh))
22802 + // printk("DoTxHighPower() - lower Power - UndecoratedSmoothedSS:%d, HiPwrUpperTh = %d \n", priv->UndecoratedSmoothedSS, HiPwrLowerTh );
22803 + if(priv->bToUpdateTxPwr)
22805 + priv->bToUpdateTxPwr = false;
22807 + u1bTmp= read_nic_byte(dev, CCK_TXAGC);
22808 + if(u1bTmp < CckTxPwrIdx)
22810 + //u1bTmp = ((u1bTmp+16) > 35) ? 35: (u1bTmp+16); // 8dbm
22811 + //write_nic_byte(dev, CCK_TXAGC, u1bTmp);
22812 + write_nic_byte(dev, CCK_TXAGC, CckTxPwrIdx);
22815 + u1bTmp= read_nic_byte(dev, OFDM_TXAGC);
22816 + if(u1bTmp < OfdmTxPwrIdx)
22818 + //u1bTmp = ((u1bTmp+16) > 35) ? 35: (u1bTmp+16); // 8dbm
22819 + //write_nic_byte(dev, OFDM_TXAGC, u1bTmp);
22820 + write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
22825 + //printk("<---- DoTxHighPower()\n");
22831 +// Callback function of UpdateTxPowerWorkItem.
22832 +// Because of some event happend, e.g. CCX TPC, High Power Mechanism,
22833 +// We update Tx power of current channel again.
22835 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
22836 +void rtl8180_tx_pw_wq (struct work_struct *work)
22838 +// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
22839 +// struct ieee80211_device * ieee = (struct ieee80211_device*)
22840 +// container_of(work, struct ieee80211_device, watch_dog_wq);
22841 + struct delayed_work *dwork = container_of(work,struct delayed_work,work);
22842 + struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,tx_pw_wq);
22843 + struct net_device *dev = ieee->dev;
22845 +void rtl8180_tx_pw_wq(struct net_device *dev)
22847 + // struct r8180_priv *priv = ieee80211_priv(dev);
22850 +// printk("----> UpdateTxPowerWorkItemCallback()\n");
22852 + DoTxHighPower(dev);
22854 +// printk("<---- UpdateTxPowerWorkItemCallback()\n");
22860 +// Return TRUE if we shall perform DIG Mecahnism, FALSE otherwise.
22864 + struct net_device *dev
22867 + struct r8180_priv *priv = ieee80211_priv(dev);
22868 + struct ieee80211_device *ieee = priv->ieee80211;
22870 + if(!priv->bDigMechanism)
22873 + if(ieee->state != IEEE80211_LINKED)
22876 + //if(priv->CurrentOperaRate < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01.
22877 + if((priv->ieee80211->rate/5) < 36) // Schedule Dig under all OFDM rates. By Bruce, 2007-06-01.
22883 +// Implementation of DIG for Zebra and Zebra2.
22887 + struct net_device *dev
22890 + struct r8180_priv *priv = ieee80211_priv(dev);
22891 + u16 CCKFalseAlarm, OFDMFalseAlarm;
22892 + u16 OfdmFA1, OfdmFA2;
22893 + int InitialGainStep = 7; // The number of initial gain stages.
22894 + int LowestGainStage = 4; // The capable lowest stage of performing dig workitem.
22895 + u32 AwakePeriodIn2Sec=0;
22897 + //printk("---------> DIG_Zebra()\n");
22899 + CCKFalseAlarm = (u16)(priv->FalseAlarmRegValue & 0x0000ffff);
22900 + OFDMFalseAlarm = (u16)((priv->FalseAlarmRegValue >> 16) & 0x0000ffff);
22902 + OfdmFA2 = ((u16)(priv->RegDigOfdmFaUpTh)) << 8;
22904 +// printk("DIG**********CCK False Alarm: %#X \n",CCKFalseAlarm);
22905 +// printk("DIG**********OFDM False Alarm: %#X \n",OFDMFalseAlarm);
22907 + // The number of initial gain steps is different, by Bruce, 2007-04-13.
22908 + if (priv->InitialGain == 0 ) //autoDIG
22909 + { // Advised from SD3 DZ
22910 + priv->InitialGain = 4; // In 87B, m74dBm means State 4 (m82dBm)
22912 + //if(pHalData->VersionID != VERSION_8187B_B)
22913 + { // Advised from SD3 DZ
22917 +#if 1 //lzm reserved 080826
22918 + AwakePeriodIn2Sec = (2000-priv ->DozePeriodInPast2Sec);
22919 + //printk("&&& DozePeriod=%d AwakePeriod=%d\n", priv->DozePeriodInPast2Sec, AwakePeriodIn2Sec);
22920 + priv ->DozePeriodInPast2Sec=0;
22922 + if(AwakePeriodIn2Sec)
22924 + //RT_TRACE(COMP_DIG, DBG_TRACE, ("DIG: AwakePeriodIn2Sec(%d) - FATh(0x%X , 0x%X) ->",AwakePeriodIn2Sec, OfdmFA1, OfdmFA2));
22925 + // adjuest DIG threshold.
22926 + OfdmFA1 = (u16)((OfdmFA1*AwakePeriodIn2Sec) / 2000) ;
22927 + OfdmFA2 = (u16)((OfdmFA2*AwakePeriodIn2Sec) / 2000) ;
22928 + //RT_TRACE(COMP_DIG, DBG_TRACE, ("( 0x%X , 0x%X)\n", OfdmFA1, OfdmFA2));
22932 + ;//RT_TRACE(COMP_DIG, DBG_WARNING, ("ERROR!! AwakePeriodIn2Sec should not be ZERO!!\n"));
22936 + InitialGainStep = 8;
22937 + LowestGainStage = priv->RegBModeGainStage; // Lowest gain stage.
22939 + if (OFDMFalseAlarm > OfdmFA1)
22941 + if (OFDMFalseAlarm > OfdmFA2)
22943 + priv->DIG_NumberFallbackVote++;
22944 + if (priv->DIG_NumberFallbackVote >1)
22946 + //serious OFDM False Alarm, need fallback
22947 + if (priv->InitialGain < InitialGainStep)
22949 + priv->InitialGainBackUp= priv->InitialGain;
22951 + priv->InitialGain = (priv->InitialGain + 1);
22952 +// printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
22953 +// printk("DIG+++++++ fallback OFDM:%d \n", priv->InitialGain);
22954 + UpdateInitialGain(dev);
22956 + priv->DIG_NumberFallbackVote = 0;
22957 + priv->DIG_NumberUpgradeVote=0;
22962 + if (priv->DIG_NumberFallbackVote)
22963 + priv->DIG_NumberFallbackVote--;
22965 + priv->DIG_NumberUpgradeVote=0;
22969 + if (priv->DIG_NumberFallbackVote)
22970 + priv->DIG_NumberFallbackVote--;
22971 + priv->DIG_NumberUpgradeVote++;
22973 + if (priv->DIG_NumberUpgradeVote>9)
22975 + if (priv->InitialGain > LowestGainStage) // In 87B, m78dBm means State 4 (m864dBm)
22977 + priv->InitialGainBackUp= priv->InitialGain;
22979 + priv->InitialGain = (priv->InitialGain - 1);
22980 +// printk("DIG**********OFDM False Alarm: %#X, OfdmFA1: %#X, OfdmFA2: %#X\n", OFDMFalseAlarm, OfdmFA1, OfdmFA2);
22981 +// printk("DIG--------- Upgrade OFDM:%d \n", priv->InitialGain);
22982 + UpdateInitialGain(dev);
22984 + priv->DIG_NumberFallbackVote = 0;
22985 + priv->DIG_NumberUpgradeVote=0;
22989 +// printk("DIG+++++++ OFDM:%d\n", priv->InitialGain);
22990 + //printk("<--------- DIG_Zebra()\n");
22995 +// Dispatch DIG implementation according to RF.
22999 + struct net_device *dev
23002 + struct r8180_priv *priv = ieee80211_priv(dev);
23004 + switch(priv->rf_chip)
23006 + case RF_ZEBRA2: // [AnnieWorkaround] For Zebra2, 2005-08-01.
23008 + DIG_Zebra( dev );
23012 + printk("DynamicInitGain(): unknown RFChipID(%d) !!!\n", priv->rf_chip);
23017 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
23018 +void rtl8180_hw_dig_wq (struct work_struct *work)
23020 +// struct r8180_priv *priv = container_of(work, struct r8180_priv, watch_dog_wq);
23021 +// struct ieee80211_device * ieee = (struct ieee80211_device*)
23022 +// container_of(work, struct ieee80211_device, watch_dog_wq);
23023 + struct delayed_work *dwork = container_of(work,struct delayed_work,work);
23024 + struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_dig_wq);
23025 + struct net_device *dev = ieee->dev;
23027 +void rtl8180_hw_dig_wq(struct net_device *dev)
23031 + struct r8180_priv *priv = ieee80211_priv(dev);
23033 + // Read CCK and OFDM False Alarm.
23034 + priv->FalseAlarmRegValue = read_nic_dword(dev, CCK_FALSE_ALARM);
23037 + // Adjust Initial Gain dynamically.
23038 + DynamicInitGain(dev);
23043 +IncludedInSupportedRates(
23044 + struct r8180_priv *priv,
23049 + u8 RateMask = 0x7F;
23051 + unsigned short Found = 0;
23052 + u8 NaiveTxRate = TxRate&RateMask;
23054 + rate_len = priv->ieee80211->current_network.rates_len;
23055 + rate_ex_len = priv->ieee80211->current_network.rates_ex_len;
23056 + for( idx=0; idx< rate_len; idx++ )
23058 + if( (priv->ieee80211->current_network.rates[idx] & RateMask) == NaiveTxRate )
23064 + for( idx=0; idx< rate_ex_len; idx++ )
23066 + if( (priv->ieee80211->current_network.rates_ex[idx] & RateMask) == NaiveTxRate )
23079 +// Get the Tx rate one degree up form the input rate in the supported rates.
23080 +// Return the upgrade rate if it is successed, otherwise return the input rate.
23081 +// By Bruce, 2007-06-05.
23085 + struct net_device *dev,
23089 + struct r8180_priv *priv = ieee80211_priv(dev);
23092 + // Upgrade 1 degree.
23095 + case 108: // Up to 54Mbps.
23099 + case 96: // Up to 54Mbps.
23103 + case 72: // Up to 48Mbps.
23107 + case 48: // Up to 36Mbps.
23111 + case 36: // Up to 24Mbps.
23115 + case 22: // Up to 18Mbps.
23119 + case 11: // Up to 11Mbps.
23123 + case 4: // Up to 5.5Mbps.
23127 + case 2: // Up to 2Mbps.
23132 + printk("GetUpgradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
23135 + // Check if the rate is valid.
23136 + if(IncludedInSupportedRates(priv, UpRate))
23138 +// printk("GetUpgradeTxRate(): GetUpgrade Tx rate(%d) from %d !\n", UpRate, priv->CurrentOperaRate);
23143 + //printk("GetUpgradeTxRate(): Tx rate (%d) is not in supported rates\n", UpRate);
23150 +// Get the Tx rate one degree down form the input rate in the supported rates.
23151 +// Return the degrade rate if it is successed, otherwise return the input rate.
23152 +// By Bruce, 2007-06-05.
23156 + struct net_device *dev,
23160 + struct r8180_priv *priv = ieee80211_priv(dev);
23163 + // Upgrade 1 degree.
23166 + case 108: // Down to 48Mbps.
23170 + case 96: // Down to 36Mbps.
23174 + case 72: // Down to 24Mbps.
23178 + case 48: // Down to 18Mbps.
23182 + case 36: // Down to 11Mbps.
23186 + case 22: // Down to 5.5Mbps.
23190 + case 11: // Down to 2Mbps.
23194 + case 4: // Down to 1Mbps.
23198 + case 2: // Down to 1Mbps.
23203 + printk("GetDegradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
23206 + // Check if the rate is valid.
23207 + if(IncludedInSupportedRates(priv, DownRate))
23209 +// printk("GetDegradeTxRate(): GetDegrade Tx rate(%d) from %d!\n", DownRate, priv->CurrentOperaRate);
23214 + //printk("GetDegradeTxRate(): Tx rate (%d) is not in supported rates\n", DownRate);
23220 +// Helper function to determine if specified data rate is
23222 +// 2005.01.25, by rcnjko.
23229 + bool bReturn = false;
23231 + if((rate <= 22) && (rate != 12) && (rate != 18))
23238 +#ifdef CONFIG_RTL818X_S
23241 +// Tx Power tracking mechanism routine on 87SE.
23242 +// Created by Roger, 2007.12.11.
23245 +TxPwrTracking87SE(
23246 + struct net_device *dev
23249 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
23250 + u8 tmpu1Byte, CurrentThermal, Idx;
23251 + char CckTxPwrIdx, OfdmTxPwrIdx;
23254 + tmpu1Byte = read_nic_byte(dev, EN_LPF_CAL);
23255 + CurrentThermal = (tmpu1Byte & 0xf0)>>4; //[ 7:4]: thermal meter indication.
23256 + CurrentThermal = (CurrentThermal>0x0c)? 0x0c:CurrentThermal;//lzm add 080826
23258 + //printk("TxPwrTracking87SE(): CurrentThermal(%d)\n", CurrentThermal);
23260 + if( CurrentThermal != priv->ThermalMeter)
23262 +// printk("TxPwrTracking87SE(): Thermal meter changed!!!\n");
23264 + // Update Tx Power level on each channel.
23265 + for(Idx = 1; Idx<15; Idx++)
23267 + CckTxPwrIdx = priv->chtxpwr[Idx];
23268 + OfdmTxPwrIdx = priv->chtxpwr_ofdm[Idx];
23270 + if( CurrentThermal > priv->ThermalMeter )
23271 + { // higher thermal meter.
23272 + CckTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2;
23273 + OfdmTxPwrIdx += (CurrentThermal - priv->ThermalMeter)*2;
23275 + if(CckTxPwrIdx >35)
23276 + CckTxPwrIdx = 35; // Force TxPower to maximal index.
23277 + if(OfdmTxPwrIdx >35)
23278 + OfdmTxPwrIdx = 35;
23281 + { // lower thermal meter.
23282 + CckTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2;
23283 + OfdmTxPwrIdx -= (priv->ThermalMeter - CurrentThermal)*2;
23285 + if(CckTxPwrIdx <0)
23287 + if(OfdmTxPwrIdx <0)
23288 + OfdmTxPwrIdx = 0;
23291 + // Update TxPower level on CCK and OFDM resp.
23292 + priv->chtxpwr[Idx] = CckTxPwrIdx;
23293 + priv->chtxpwr_ofdm[Idx] = OfdmTxPwrIdx;
23296 + // Update TxPower level immediately.
23297 + rtl8225z2_SetTXPowerLevel(dev, priv->ieee80211->current_network.channel);
23299 + priv->ThermalMeter = CurrentThermal;
23302 +StaRateAdaptive87SE(
23303 + struct net_device *dev
23306 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
23307 + unsigned long CurrTxokCnt;
23308 + u16 CurrRetryCnt;
23309 + u16 CurrRetryRate;
23311 + unsigned long CurrRxokCnt;
23312 + bool bTryUp = false;
23313 + bool bTryDown = false;
23315 + u8 TryDownTh = 2;
23316 + u32 TxThroughput;
23317 + long CurrSignalStrength;
23318 + bool bUpdateInitialGain = false;
23319 + u8 u1bOfdm=0, u1bCck = 0;
23320 + char OfdmTxPwrIdx, CckTxPwrIdx;
23322 + priv->RateAdaptivePeriod= RATE_ADAPTIVE_TIMER_PERIOD;
23325 + CurrRetryCnt = priv->CurrRetryCnt;
23326 + CurrTxokCnt = priv->NumTxOkTotal - priv->LastTxokCnt;
23327 + CurrRxokCnt = priv->ieee80211->NumRxOkTotal - priv->LastRxokCnt;
23328 + CurrSignalStrength = priv->Stats_RecvSignalPower;
23329 + TxThroughput = (u32)(priv->NumTxOkBytesTotal - priv->LastTxOKBytes);
23330 + priv->LastTxOKBytes = priv->NumTxOkBytesTotal;
23331 + priv->CurrentOperaRate = priv->ieee80211->rate/5;
23332 + //printk("priv->CurrentOperaRate is %d\n",priv->CurrentOperaRate);
23333 + //2 Compute retry ratio.
23334 + if (CurrTxokCnt>0)
23336 + CurrRetryRate = (u16)(CurrRetryCnt*100/CurrTxokCnt);
23339 + { // It may be serious retry. To distinguish serious retry or no packets modified by Bruce
23340 + CurrRetryRate = (u16)(CurrRetryCnt*100/1);
23345 + // Added by Roger, 2007.01.02.
23346 + // For debug information.
23348 + //printk("\n(1) pHalData->LastRetryRate: %d \n",priv->LastRetryRate);
23349 + //printk("(2) RetryCnt = %d \n", CurrRetryCnt);
23350 + //printk("(3) TxokCnt = %d \n", CurrTxokCnt);
23351 + //printk("(4) CurrRetryRate = %d \n", CurrRetryRate);
23352 + //printk("(5) CurrSignalStrength = %d \n",CurrSignalStrength);
23353 + //printk("(6) TxThroughput is %d\n",TxThroughput);
23354 + //printk("priv->NumTxOkBytesTotal is %d\n",priv->NumTxOkBytesTotal);
23356 + priv->LastRetryCnt = priv->CurrRetryCnt;
23357 + priv->LastTxokCnt = priv->NumTxOkTotal;
23358 + priv->LastRxokCnt = priv->ieee80211->NumRxOkTotal;
23359 + priv->CurrRetryCnt = 0;
23361 + //2No Tx packets, return to init_rate or not?
23362 + if (CurrRetryRate==0 && CurrTxokCnt == 0)
23365 + //After 9 (30*300ms) seconds in this condition, we try to raise rate.
23367 + priv->TryupingCountNoData++;
23369 +// printk("No Tx packets, TryupingCountNoData(%d)\n", priv->TryupingCountNoData);
23370 + //[TRC Dell Lab] Extend raised period from 4.5sec to 9sec, Isaiah 2008-02-15 18:00
23371 + if (priv->TryupingCountNoData>30)
23373 + priv->TryupingCountNoData = 0;
23374 + priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
23375 + // Reset Fail Record
23376 + priv->LastFailTxRate = 0;
23377 + priv->LastFailTxRateSS = -200;
23378 + priv->FailTxRateCount = 0;
23380 + goto SetInitialGain;
23384 + priv->TryupingCountNoData=0; //Reset trying up times.
23389 + // For Netgear case, I comment out the following signal strength estimation,
23390 + // which can results in lower rate to transmit when sample is NOT enough (e.g. PING request).
23391 + // 2007.04.09, by Roger.
23395 + // Restructure rate adaptive as the following main stages:
23396 + // (1) Add retry threshold in 54M upgrading condition with signal strength.
23397 + // (2) Add the mechanism to degrade to CCK rate according to signal strength
23398 + // and retry rate.
23399 + // (3) Remove all Initial Gain Updates over OFDM rate. To avoid the complicated
23400 + // situation, Initial Gain Update is upon on DIG mechanism except CCK rate.
23401 + // (4) Add the mehanism of trying to upgrade tx rate.
23402 + // (5) Record the information of upping tx rate to avoid trying upping tx rate constantly.
23403 + // By Bruce, 2007-06-05.
23407 + // 11Mbps or 36Mbps
23408 + // Check more times in these rate(key rates).
23410 + if(priv->CurrentOperaRate == 22 || priv->CurrentOperaRate == 72)
23415 + // Let these rates down more difficult.
23417 + if(MgntIsCckRate(priv->CurrentOperaRate) || priv->CurrentOperaRate == 36)
23423 + if (priv->bTryuping == true)
23425 + //2 For Test Upgrading mechanism
23427 + // Sometimes the throughput is upon on the capability bwtween the AP and NIC,
23428 + // thus the low data rate does not improve the performance.
23429 + // We randomly upgrade the data rate and check if the retry rate is improved.
23431 + // Upgrading rate did not improve the retry rate, fallback to the original rate.
23432 + if ( (CurrRetryRate > 25) && TxThroughput < priv->LastTxThroughput)
23434 + //Not necessary raising rate, fall back rate.
23436 + //printk("case1-1: Not necessary raising rate, fall back rate....\n");
23437 + //printk("case1-1: pMgntInfo->CurrentOperaRate =%d, TxThroughput = %d, LastThroughput = %d\n",
23438 + // priv->CurrentOperaRate, TxThroughput, priv->LastTxThroughput);
23442 + priv->bTryuping = false;
23445 + else if (CurrSignalStrength > -47 && (CurrRetryRate < 50))
23447 + //2For High Power
23449 + // Added by Roger, 2007.04.09.
23450 + // Return to highest data rate, if signal strength is good enough.
23451 + // SignalStrength threshold(-50dbm) is for RTL8186.
23452 + // Revise SignalStrength threshold to -51dbm.
23454 + // Also need to check retry rate for safety, by Bruce, 2007-06-05.
23455 + if(priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate )
23458 + // Upgrade Tx Rate directly.
23459 + priv->TryupingCount += TryUpTh;
23461 +// printk("case2: StaRateAdaptive87SE: Power(%d) is high enough!!. \n", CurrSignalStrength);
23464 + else if(CurrTxokCnt > 9 && CurrTxokCnt< 100 && CurrRetryRate >= 600)
23466 + //2 For Serious Retry
23468 + // Traffic is not busy but our Tx retry is serious.
23471 + // Let Rate Mechanism to degrade tx rate directly.
23472 + priv->TryDownCountLowData += TryDownTh;
23473 +// printk("case3: RA: Tx Retry is serious. Degrade Tx Rate to %d directly...\n", priv->CurrentOperaRate);
23475 + else if ( priv->CurrentOperaRate == 108 )
23479 + if ( (CurrRetryRate>26)&&(priv->LastRetryRate>25))
23480 +// if ( (CurrRetryRate>40)&&(priv->LastRetryRate>39))
23482 + //Down to rate 48Mbps.
23486 + else if ( (CurrRetryRate>17)&&(priv->LastRetryRate>16) && (CurrSignalStrength > -72))
23487 +// else if ( (CurrRetryRate>17)&&(priv->LastRetryRate>16) && (CurrSignalStrength > -72))
23489 + //Down to rate 48Mbps.
23493 + if(bTryDown && (CurrSignalStrength < -75)) //cable link
23495 + priv->TryDownCountLowData += TryDownTh;
23497 + //printk("case4---54M \n");
23500 + else if ( priv->CurrentOperaRate == 96 )
23504 + if ( ((CurrRetryRate>48) && (priv->LastRetryRate>47)))
23505 +// if ( ((CurrRetryRate>65) && (priv->LastRetryRate>64)))
23508 + //Down to rate 36Mbps.
23512 + else if ( ((CurrRetryRate>21) && (priv->LastRetryRate>20)) && (CurrSignalStrength > -74))
23514 + //Down to rate 36Mbps.
23517 + else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
23518 +// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
23521 + priv->TryDownCountLowData += TryDownTh;
23523 + else if ( (CurrRetryRate<8) && (priv->LastRetryRate<8) ) //TO DO: need to consider (RSSI)
23524 +// else if ( (CurrRetryRate<28) && (priv->LastRetryRate<8) )
23529 + if(bTryDown && (CurrSignalStrength < -75))
23531 + priv->TryDownCountLowData += TryDownTh;
23533 + //printk("case5---48M \n");
23535 + else if ( priv->CurrentOperaRate == 72 )
23538 + if ( (CurrRetryRate>43) && (priv->LastRetryRate>41))
23539 +// if ( (CurrRetryRate>60) && (priv->LastRetryRate>59))
23541 + //Down to rate 24Mbps.
23544 + else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
23545 +// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
23548 + priv->TryDownCountLowData += TryDownTh;
23550 + else if ( (CurrRetryRate<15) && (priv->LastRetryRate<16)) //TO DO: need to consider (RSSI)
23551 +// else if ( (CurrRetryRate<35) && (priv->LastRetryRate<36))
23556 + if(bTryDown && (CurrSignalStrength < -80))
23558 + priv->TryDownCountLowData += TryDownTh;
23560 + //printk("case6---36M \n");
23562 + else if ( priv->CurrentOperaRate == 48 )
23566 + if ( ((CurrRetryRate>63) && (priv->LastRetryRate>62)))
23567 +// if ( ((CurrRetryRate>83) && (priv->LastRetryRate>82)))
23569 + //Down to rate 18Mbps.
23573 + else if ( ((CurrRetryRate>33) && (priv->LastRetryRate>32)) && (CurrSignalStrength > -82) )
23574 +// else if ( ((CurrRetryRate>50) && (priv->LastRetryRate>49)) && (CurrSignalStrength > -82) )
23576 + //Down to rate 18Mbps.
23579 + else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
23580 +// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
23584 + priv->TryDownCountLowData += TryDownTh;
23586 + else if ( (CurrRetryRate<20) && (priv->LastRetryRate<21)) //TO DO: need to consider (RSSI)
23587 +// else if ( (CurrRetryRate<40) && (priv->LastRetryRate<41))
23592 + if(bTryDown && (CurrSignalStrength < -82))
23594 + priv->TryDownCountLowData += TryDownTh;
23596 + //printk("case7---24M \n");
23598 + else if ( priv->CurrentOperaRate == 36 )
23601 + // original (109, 109)
23602 + //[TRC Dell Lab] (90, 91), Isaiah 2008-02-18 23:24
23603 + // (85, 86), Isaiah 2008-02-18 24:00
23604 + if ( ((CurrRetryRate>85) && (priv->LastRetryRate>86)))
23605 +// if ( ((CurrRetryRate>115) && (priv->LastRetryRate>116)))
23607 + //Down to rate 11Mbps.
23610 + //[TRC Dell Lab] Isaiah 2008-02-18 23:24
23611 + else if((CurrRetryRate> (priv->LastRetryRate + 50 )) && (priv->FailTxRateCount >2 ))
23612 +// else if((CurrRetryRate> (priv->LastRetryRate + 70 )) && (priv->FailTxRateCount >2 ))
23615 + priv->TryDownCountLowData += TryDownTh;
23617 + else if ( (CurrRetryRate<22) && (priv->LastRetryRate<23)) //TO DO: need to consider (RSSI)
23618 +// else if ( (CurrRetryRate<42) && (priv->LastRetryRate<43))
23622 + //printk("case8---18M \n");
23624 + else if ( priv->CurrentOperaRate == 22 )
23627 + if (CurrRetryRate>95)
23628 +// if (CurrRetryRate>155)
23632 + else if ( (CurrRetryRate<29) && (priv->LastRetryRate <30) )//TO DO: need to consider (RSSI)
23633 +// else if ( (CurrRetryRate<49) && (priv->LastRetryRate <50) )
23637 + //printk("case9---11M \n");
23639 + else if ( priv->CurrentOperaRate == 11 )
23642 + if (CurrRetryRate>149)
23643 +// if (CurrRetryRate>189)
23647 + else if ( (CurrRetryRate<60) && (priv->LastRetryRate < 65))
23648 +// else if ( (CurrRetryRate<80) && (priv->LastRetryRate < 85))
23653 + //printk("case10---5.5M \n");
23655 + else if ( priv->CurrentOperaRate == 4 )
23658 + if((CurrRetryRate>99) && (priv->LastRetryRate>99))
23659 +// if((CurrRetryRate>199) && (priv->LastRetryRate>199))
23663 + else if ( (CurrRetryRate < 65) && (priv->LastRetryRate < 70))
23664 +// else if ( (CurrRetryRate < 85) && (priv->LastRetryRate < 90))
23668 + //printk("case11---2M \n");
23670 + else if ( priv->CurrentOperaRate == 2 )
23673 + if( (CurrRetryRate<70) && (priv->LastRetryRate<75))
23674 +// if( (CurrRetryRate<90) && (priv->LastRetryRate<95))
23678 + //printk("case12---1M \n");
23681 + if(bTryUp && bTryDown)
23682 + printk("StaRateAdaptive87B(): Tx Rate tried upping and downing simultaneously!\n");
23684 + //1 Test Upgrading Tx Rate
23685 + // Sometimes the cause of the low throughput (high retry rate) is the compatibility between the AP and NIC.
23686 + // To test if the upper rate may cause lower retry rate, this mechanism randomly occurs to test upgrading tx rate.
23687 + if(!bTryUp && !bTryDown && (priv->TryupingCount == 0) && (priv->TryDownCountLowData == 0)
23688 + && priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate && priv->FailTxRateCount < 2)
23690 + if(jiffies% (CurrRetryRate + 101) == 0)
23693 + priv->bTryuping = true;
23694 + //printk("StaRateAdaptive87SE(): Randomly try upgrading...\n");
23698 + //1 Rate Mechanism
23701 + priv->TryupingCount++;
23702 + priv->TryDownCountLowData = 0;
23705 +// printk("UP: pHalData->TryupingCount = %d\n", priv->TryupingCount);
23706 +// printk("UP: TryUpTh(%d)+ (FailTxRateCount(%d))^2 =%d\n",
23707 +// TryUpTh, priv->FailTxRateCount, (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount) );
23708 +// printk("UP: pHalData->bTryuping=%d\n", priv->bTryuping);
23713 + // Check more times if we need to upgrade indeed.
23714 + // Because the largest value of pHalData->TryupingCount is 0xFFFF and
23715 + // the largest value of pHalData->FailTxRateCount is 0x14,
23716 + // this condition will be satisfied at most every 2 min.
23719 + if((priv->TryupingCount > (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount)) ||
23720 + (CurrSignalStrength > priv->LastFailTxRateSS) || priv->bTryuping)
23722 + priv->TryupingCount = 0;
23724 + // When transfering from CCK to OFDM, DIG is an important issue.
23726 + if(priv->CurrentOperaRate == 22)
23727 + bUpdateInitialGain = true;
23729 + // The difference in throughput between 48Mbps and 36Mbps is 8M.
23730 + // So, we must be carefully in this rate scale. Isaiah 2008-02-15.
23732 + if( ((priv->CurrentOperaRate == 72) || (priv->CurrentOperaRate == 48) || (priv->CurrentOperaRate == 36)) &&
23733 + (priv->FailTxRateCount > 2) )
23734 + priv->RateAdaptivePeriod= (RATE_ADAPTIVE_TIMER_PERIOD/2);
23736 + // (1)To avoid upgrade frequently to the fail tx rate, add the FailTxRateCount into the threshold.
23737 + // (2)If the signal strength is increased, it may be able to upgrade.
23739 + priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
23740 +// printk("StaRateAdaptive87SE(): Upgrade Tx Rate to %d\n", priv->CurrentOperaRate);
23742 + //[TRC Dell Lab] Bypass 12/9/6, Isaiah 2008-02-18 20:00
23743 + if(priv->CurrentOperaRate ==36)
23745 + priv->bUpdateARFR=true;
23746 + write_nic_word(dev, ARFR, 0x0F8F); //bypass 12/9/6
23747 +// printk("UP: ARFR=0xF8F\n");
23749 + else if(priv->bUpdateARFR)
23751 + priv->bUpdateARFR=false;
23752 + write_nic_word(dev, ARFR, 0x0FFF); //set 1M ~ 54Mbps.
23753 +// printk("UP: ARFR=0xFFF\n");
23756 + // Update Fail Tx rate and count.
23757 + if(priv->LastFailTxRate != priv->CurrentOperaRate)
23759 + priv->LastFailTxRate = priv->CurrentOperaRate;
23760 + priv->FailTxRateCount = 0;
23761 + priv->LastFailTxRateSS = -200; // Set lowest power.
23767 + if(priv->TryupingCount > 0)
23768 + priv->TryupingCount --;
23773 + priv->TryDownCountLowData++;
23774 + priv->TryupingCount = 0;
23776 +// printk("DN: pHalData->TryDownCountLowData = %d\n",priv->TryDownCountLowData);
23777 +// printk("DN: TryDownTh =%d\n", TryDownTh);
23778 +// printk("DN: pHalData->bTryuping=%d\n", priv->bTryuping);
23781 + //Check if Tx rate can be degraded or Test trying upgrading should fallback.
23782 + if(priv->TryDownCountLowData > TryDownTh || priv->bTryuping)
23784 + priv->TryDownCountLowData = 0;
23785 + priv->bTryuping = false;
23786 + // Update fail information.
23787 + if(priv->LastFailTxRate == priv->CurrentOperaRate)
23789 + priv->FailTxRateCount ++;
23790 + // Record the Tx fail rate signal strength.
23791 + if(CurrSignalStrength > priv->LastFailTxRateSS)
23793 + priv->LastFailTxRateSS = CurrSignalStrength;
23798 + priv->LastFailTxRate = priv->CurrentOperaRate;
23799 + priv->FailTxRateCount = 1;
23800 + priv->LastFailTxRateSS = CurrSignalStrength;
23802 + priv->CurrentOperaRate = GetDegradeTxRate(dev, priv->CurrentOperaRate);
23804 + // Reduce chariot training time at weak signal strength situation. SD3 ED demand.
23805 + //[TRC Dell Lab] Revise Signal Threshold from -75 to -80 , Isaiah 2008-02-18 20:00
23806 + if( (CurrSignalStrength < -80) && (priv->CurrentOperaRate > 72 ))
23808 + priv->CurrentOperaRate = 72;
23809 +// printk("DN: weak signal strength (%d), degrade to 36Mbps\n", CurrSignalStrength);
23812 + //[TRC Dell Lab] Bypass 12/9/6, Isaiah 2008-02-18 20:00
23813 + if(priv->CurrentOperaRate ==36)
23815 + priv->bUpdateARFR=true;
23816 + write_nic_word(dev, ARFR, 0x0F8F); //bypass 12/9/6
23817 +// printk("DN: ARFR=0xF8F\n");
23819 + else if(priv->bUpdateARFR)
23821 + priv->bUpdateARFR=false;
23822 + write_nic_word(dev, ARFR, 0x0FFF); //set 1M ~ 54Mbps.
23823 +// printk("DN: ARFR=0xFFF\n");
23827 + // When it is CCK rate, it may need to update initial gain to receive lower power packets.
23829 + if(MgntIsCckRate(priv->CurrentOperaRate))
23831 + bUpdateInitialGain = true;
23833 +// printk("StaRateAdaptive87SE(): Degrade Tx Rate to %d\n", priv->CurrentOperaRate);
23838 + if(priv->TryDownCountLowData > 0)
23839 + priv->TryDownCountLowData --;
23842 + // Keep the Tx fail rate count to equal to 0x15 at most.
23843 + // Reduce the fail count at least to 10 sec if tx rate is tending stable.
23844 + if(priv->FailTxRateCount >= 0x15 ||
23845 + (!bTryUp && !bTryDown && priv->TryDownCountLowData == 0 && priv->TryupingCount && priv->FailTxRateCount > 0x6))
23847 + priv->FailTxRateCount --;
23851 + OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
23852 + CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel];
23854 + //[TRC Dell Lab] Mac0x9e increase 2 level in 36M~18M situation, Isaiah 2008-02-18 24:00
23855 + if((priv->CurrentOperaRate < 96) &&(priv->CurrentOperaRate > 22))
23857 + u1bCck = read_nic_byte(dev, CCK_TXAGC);
23858 + u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
23860 + // case 1: Never enter High power
23861 + if(u1bCck == CckTxPwrIdx )
23863 + if(u1bOfdm != (OfdmTxPwrIdx+2) )
23865 + priv->bEnhanceTxPwr= true;
23866 + u1bOfdm = ((u1bOfdm+2) > 35) ? 35: (u1bOfdm+2);
23867 + write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
23868 +// printk("Enhance OFDM_TXAGC : +++++ u1bOfdm= 0x%x\n", u1bOfdm);
23871 + // case 2: enter high power
23872 + else if(u1bCck < CckTxPwrIdx)
23874 + if(!priv->bEnhanceTxPwr)
23876 + priv->bEnhanceTxPwr= true;
23877 + u1bOfdm = ((u1bOfdm+2) > 35) ? 35: (u1bOfdm+2);
23878 + write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
23879 + //RT_TRACE(COMP_RATE, DBG_TRACE, ("Enhance OFDM_TXAGC(2) : +++++ u1bOfdm= 0x%x\n", u1bOfdm));
23883 + else if(priv->bEnhanceTxPwr) //54/48/11/5.5/2/1
23885 + u1bCck = read_nic_byte(dev, CCK_TXAGC);
23886 + u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
23888 + // case 1: Never enter High power
23889 + if(u1bCck == CckTxPwrIdx )
23891 + priv->bEnhanceTxPwr= false;
23892 + write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
23893 + //printk("Recover OFDM_TXAGC : ===== u1bOfdm= 0x%x\n", OfdmTxPwrIdx);
23895 + // case 2: enter high power
23896 + else if(u1bCck < CckTxPwrIdx)
23898 + priv->bEnhanceTxPwr= false;
23899 + u1bOfdm = ((u1bOfdm-2) > 0) ? (u1bOfdm-2): 0;
23900 + write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
23901 + //RT_TRACE(COMP_RATE, DBG_TRACE, ("Recover OFDM_TXAGC(2): ===== u1bOfdm= 0x%x\n", u1bOfdm));
23907 + // We need update initial gain when we set tx rate "from OFDM to CCK" or
23908 + // "from CCK to OFDM".
23911 + if(bUpdateInitialGain)
23913 + if(MgntIsCckRate(priv->CurrentOperaRate)) // CCK
23915 + if(priv->InitialGain > priv->RegBModeGainStage)
23917 + priv->InitialGainBackUp= priv->InitialGain;
23919 + if(CurrSignalStrength < -85) // Low power, OFDM [0x17] = 26.
23921 + //SD3 SYs suggest that CurrSignalStrength < -65, ofdm 0x17=26.
23922 + priv->InitialGain = priv->RegBModeGainStage;
23924 + else if(priv->InitialGain > priv->RegBModeGainStage + 1)
23926 + priv->InitialGain -= 2;
23930 + priv->InitialGain --;
23932 + printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
23933 + UpdateInitialGain(dev);
23938 + if(priv->InitialGain < 4)
23940 + priv->InitialGainBackUp= priv->InitialGain;
23942 + priv->InitialGain ++;
23943 + printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n",priv->InitialGain, priv->CurrentOperaRate);
23944 + UpdateInitialGain(dev);
23949 + //Record the related info
23950 + priv->LastRetryRate = CurrRetryRate;
23951 + priv->LastTxThroughput = TxThroughput;
23952 + priv->ieee80211->rate = priv->CurrentOperaRate * 5;
23956 +#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
23957 +void rtl8180_rate_adapter(struct work_struct * work)
23959 + struct delayed_work *dwork = container_of(work,struct delayed_work,work);
23960 + struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,rate_adapter_wq);
23961 + struct net_device *dev = ieee->dev;
23963 +void rtl8180_rate_adapter(struct net_device *dev)
23967 + //struct r8180_priv *priv = ieee80211_priv(dev);
23968 +// DMESG("---->rtl8180_rate_adapter");
23969 + StaRateAdaptive87SE(dev);
23970 +// DMESG("<----rtl8180_rate_adapter");
23972 +void timer_rate_adaptive(unsigned long data)
23974 + struct r8180_priv* priv = ieee80211_priv((struct net_device *)data);
23975 + //DMESG("---->timer_rate_adaptive()\n");
23978 +// DMESG("<----timer_rate_adaptive():driver is not up!\n");
23981 + if((priv->ieee80211->iw_mode != IW_MODE_MASTER)
23982 + && (priv->ieee80211->state == IEEE80211_LINKED) &&
23983 + (priv->ForcedDataRate == 0) )
23985 +// DMESG("timer_rate_adaptive():schedule rate_adapter_wq\n");
23986 +#ifdef CONFIG_RTL818X_S
23987 + queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->rate_adapter_wq);
23988 +// StaRateAdaptive87SE((struct net_device *)data);
23991 + priv->rateadapter_timer.expires = jiffies + MSECS(priv->RateAdaptivePeriod);
23992 + add_timer(&priv->rateadapter_timer);
23993 + //DMESG("<----timer_rate_adaptive()\n");
23997 +SwAntennaDiversityRxOk8185(
23998 + struct net_device *dev,
23999 + u8 SignalStrength
24002 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
24004 +// printk("+SwAntennaDiversityRxOk8185: RxSs: %d\n", SignalStrength);
24006 + priv->AdRxOkCnt++;
24008 + if( priv->AdRxSignalStrength != -1)
24010 + priv->AdRxSignalStrength = ((priv->AdRxSignalStrength*7) + (SignalStrength*3)) / 10;
24013 + { // Initialization case.
24014 + priv->AdRxSignalStrength = SignalStrength;
24017 + if( priv->LastRxPktAntenna ) //Main antenna.
24018 + priv->AdMainAntennaRxOkCnt++;
24019 + else // Aux antenna.
24020 + priv->AdAuxAntennaRxOkCnt++;
24022 +// printk("-SwAntennaDiversityRxOk8185: AdRxOkCnt: %d AdRxSignalStrength: %d\n", priv->AdRxOkCnt, priv->AdRxSignalStrength);
24026 +// Change Antenna Switch.
24030 + struct net_device *dev,
24031 + u8 u1bAntennaIndex
24034 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
24035 + bool bAntennaSwitched = false;
24037 +// printk("+SetAntenna8185(): Antenna is switching to: %d \n", u1bAntennaIndex);
24039 + switch(u1bAntennaIndex)
24042 + switch(priv->rf_chip)
24046 +#ifdef CONFIG_RTL8185B
24047 +#ifdef CONFIG_RTL818X_S
24048 + // Mac register, main antenna
24049 + write_nic_byte(dev, ANTSEL, 0x03);
24051 + write_phy_cck(dev,0x11, 0x9b); // Config CCK RX antenna.
24052 + write_phy_ofdm(dev, 0x0d, 0x5c); // Config OFDM RX antenna.
24055 + // Mac register, main antenna
24056 + write_nic_byte(dev, ANTSEL, 0x03);
24058 + write_phy_cck(dev, 0x10, 0x9b); // Config CCK RX antenna.
24059 + write_phy_ofdm(dev, 0x0d, 0x5c); // Config OFDM RX antenna.
24063 + bAntennaSwitched = true;
24067 + printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
24073 + switch(priv->rf_chip)
24077 +#ifdef CONFIG_RTL8185B
24078 +#ifdef CONFIG_RTL818X_S
24079 + // Mac register, aux antenna
24080 + write_nic_byte(dev, ANTSEL, 0x00);
24082 + write_phy_cck(dev, 0x11, 0xbb); // Config CCK RX antenna.
24083 + write_phy_ofdm(dev, 0x0d, 0x54); // Config OFDM RX antenna.
24085 + // Mac register, aux antenna
24086 + write_nic_byte(dev, ANTSEL, 0x00);
24088 + write_phy_cck(dev, 0x10, 0xbb); // Config CCK RX antenna.
24089 + write_phy_ofdm(dev, 0x0d, 0x54); // Config OFDM RX antenna.
24093 + bAntennaSwitched = true;
24097 + printk("SetAntenna8185: unkown RFChipID(%d)\n", priv->rf_chip);
24103 + printk("SetAntenna8185: unkown u1bAntennaIndex(%d)\n", u1bAntennaIndex);
24107 + if(bAntennaSwitched)
24109 + priv->CurrAntennaIndex = u1bAntennaIndex;
24112 +// printk("-SetAntenna8185(): return (%#X)\n", bAntennaSwitched);
24114 + return bAntennaSwitched;
24118 +// Toggle Antenna switch.
24122 + struct net_device *dev
24125 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
24129 + if(priv->CurrAntennaIndex == 0)
24131 +#if 0//lzm del 080826
24133 +#ifdef CONFIG_RTL818X_S
24134 + if(priv->bSwAntennaDiverity)
24135 + bResult = SetAntennaConfig87SE(dev, 1, true);
24139 + bResult = SetAntenna8185(dev, 1);
24141 +// printk("SwitchAntenna(): switching to antenna 1 ......\n");
24142 +// bResult = SetAntenna8185(dev, 1);//-by amy 080312
24146 +#if 0//lzm del 080826
24148 +#ifdef CONFIG_RTL818X_S
24149 + if(priv->bSwAntennaDiverity)
24150 + bResult = SetAntennaConfig87SE(dev, 0, true);
24154 + bResult = SetAntenna8185(dev, 0);
24156 +// printk("SwitchAntenna(): switching to antenna 0 ......\n");
24157 +// bResult = SetAntenna8185(dev, 0);//-by amy 080312
24164 +// Engine of SW Antenna Diversity mechanism.
24165 +// Since 8187 has no Tx part information,
24166 +// this implementation is only dependend on Rx part information.
24168 +// 2006.04.17, by rcnjko.
24171 +SwAntennaDiversity(
24172 + struct net_device *dev
24175 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
24176 + bool bSwCheckSS=false;
24177 +// printk("+SwAntennaDiversity(): CurrAntennaIndex: %d\n", priv->CurrAntennaIndex);
24178 +// printk("AdTickCount is %d\n",priv->AdTickCount);
24182 + priv->AdTickCount++;
24184 + printk("(1) AdTickCount: %d, AdCheckPeriod: %d\n",
24185 + priv->AdTickCount, priv->AdCheckPeriod);
24186 + printk("(2) AdRxSignalStrength: %ld, AdRxSsThreshold: %ld\n",
24187 + priv->AdRxSignalStrength, priv->AdRxSsThreshold);
24189 +// priv->AdTickCount++;//-by amy 080312
24191 + // Case 1. No Link.
24192 + if(priv->ieee80211->state != IEEE80211_LINKED)
24194 + // printk("SwAntennaDiversity(): Case 1. No Link.\n");
24196 + priv->bAdSwitchedChecking = false;
24197 + // I switch antenna here to prevent any one of antenna is broken before link established, 2006.04.18, by rcnjko..
24198 + SwitchAntenna(dev);
24200 + // Case 2. Linked but no packet received.
24201 + else if(priv->AdRxOkCnt == 0)
24203 + // printk("SwAntennaDiversity(): Case 2. Linked but no packet received.\n");
24205 + priv->bAdSwitchedChecking = false;
24206 + SwitchAntenna(dev);
24208 + // Case 3. Evaluate last antenna switch action and undo it if necessary.
24209 + else if(priv->bAdSwitchedChecking == true)
24211 + // printk("SwAntennaDiversity(): Case 3. Evaluate last antenna switch action.\n");
24213 + priv->bAdSwitchedChecking = false;
24215 + // Adjust Rx signal strength threashold.
24216 + priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2;
24218 + priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
24219 + priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;
24220 + if(priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched)
24221 + { // Rx signal strength is not improved after we swtiched antenna. => Swich back.
24222 +// printk("SwAntennaDiversity(): Rx Signal Strength is not improved, CurrRxSs: %d, LastRxSs: %d\n",
24223 +// priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
24225 + // Increase Antenna Diversity checking period due to bad decision.
24226 + priv->AdCheckPeriod *= 2;
24228 + // Increase Antenna Diversity checking period.
24229 + if(priv->AdCheckPeriod > priv->AdMaxCheckPeriod)
24230 + priv->AdCheckPeriod = priv->AdMaxCheckPeriod;
24232 + // Wrong deceision => switch back.
24233 + SwitchAntenna(dev);
24236 + { // Rx Signal Strength is improved.
24237 +// printk("SwAntennaDiversity(): Rx Signal Strength is improved, CurrRxSs: %d, LastRxSs: %d\n",
24238 +// priv->AdRxSignalStrength, priv->AdRxSsBeforeSwitched);
24240 + // Reset Antenna Diversity checking period to its min value.
24241 + priv->AdCheckPeriod = priv->AdMinCheckPeriod;
24244 +// printk("SwAntennaDiversity(): AdRxSsThreshold: %d, AdCheckPeriod: %d\n",
24245 +// priv->AdRxSsThreshold, priv->AdCheckPeriod);
24247 + // Case 4. Evaluate if we shall switch antenna now.
24248 + // Cause Table Speed is very fast in TRC Dell Lab, we check it every time.
24249 + else// if(priv->AdTickCount >= priv->AdCheckPeriod)//-by amy 080312
24251 +// printk("SwAntennaDiversity(): Case 4. Evaluate if we shall switch antenna now.\n");
24253 + priv->AdTickCount = 0;
24256 + // <Roger_Notes> We evaluate RxOk counts for each antenna first and than
24257 + // evaluate signal strength.
24258 + // The following operation can overcome the disability of CCA on both two antennas
24259 + // When signal strength was extremely low or high.
24264 + // Evaluate RxOk count from each antenna if we shall switch default antenna now.
24265 + // Added by Roger, 2008.02.21.
24267 + if((priv->AdMainAntennaRxOkCnt < priv->AdAuxAntennaRxOkCnt)
24268 + && (priv->CurrAntennaIndex == 0))
24269 + { // We set Main antenna as default but RxOk count was less than Aux ones.
24271 + // printk("SwAntennaDiversity(): Main antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
24272 + // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
24274 + // Switch to Aux antenna.
24275 + SwitchAntenna(dev);
24276 + priv->bHWAdSwitched = true;
24278 + else if((priv->AdAuxAntennaRxOkCnt < priv->AdMainAntennaRxOkCnt)
24279 + && (priv->CurrAntennaIndex == 1))
24280 + { // We set Aux antenna as default but RxOk count was less than Main ones.
24282 + // printk("SwAntennaDiversity(): Aux antenna RxOK is poor, AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
24283 + // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
24285 + // Switch to Main antenna.
24286 + SwitchAntenna(dev);
24287 + priv->bHWAdSwitched = true;
24290 + {// Default antenna is better.
24292 + // printk("SwAntennaDiversity(): Default antenna is better., AdMainAntennaRxOkCnt: %d, AdAuxAntennaRxOkCnt: %d\n",
24293 + // priv->AdMainAntennaRxOkCnt, priv->AdAuxAntennaRxOkCnt);
24295 + // Still need to check current signal strength.
24296 + priv->bHWAdSwitched = false;
24299 + // <Roger_Notes> We evaluate Rx signal strength ONLY when default antenna
24300 + // didn't changed by HW evaluation.
24303 + // [TRC Dell Lab] SignalStrength is inaccuracy. Isaiah 2008-03-05
24304 + // For example, Throughput of aux is better than main antenna(about 10M v.s 2M),
24305 + // but AdRxSignalStrength is less than main.
24306 + // Our guess is that main antenna have lower throughput and get many change
24307 + // to receive more CCK packets(ex.Beacon) which have stronger SignalStrength.
24309 + if( (!priv->bHWAdSwitched) && (bSwCheckSS))
24312 + // Evaluate Rx signal strength if we shall switch antenna now.
24313 + if(priv->AdRxSignalStrength < priv->AdRxSsThreshold)
24314 + { // Rx signal strength is weak => Switch Antenna.
24315 +// printk("SwAntennaDiversity(): Rx Signal Strength is weak, CurrRxSs: %d, RxSsThreshold: %d\n",
24316 +// priv->AdRxSignalStrength, priv->AdRxSsThreshold);
24318 + priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength;
24319 + priv->bAdSwitchedChecking = true;
24321 + SwitchAntenna(dev);
24324 + { // Rx signal strength is OK.
24325 +// printk("SwAntennaDiversity(): Rx Signal Strength is OK, CurrRxSs: %d, RxSsThreshold: %d\n",
24326 +// priv->AdRxSignalStrength, priv->AdRxSsThreshold);
24328 + priv->bAdSwitchedChecking = false;
24329 + // Increase Rx signal strength threashold if necessary.
24330 + if( (priv->AdRxSignalStrength > (priv->AdRxSsThreshold + 10)) && // Signal is much stronger than current threshold
24331 + priv->AdRxSsThreshold <= priv->AdMaxRxSsThreshold) // Current threhold is not yet reach upper limit.
24333 + priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2;
24334 + priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
24335 + priv->AdMaxRxSsThreshold: priv->AdRxSsThreshold;//+by amy 080312
24338 + // Reduce Antenna Diversity checking period if possible.
24339 + if( priv->AdCheckPeriod > priv->AdMinCheckPeriod )
24341 + priv->AdCheckPeriod /= 2;
24347 + // Reset antenna diversity Rx related statistics.
24348 + priv->AdRxOkCnt = 0;
24349 + priv->AdMainAntennaRxOkCnt = 0;
24350 + priv->AdAuxAntennaRxOkCnt = 0;
24353 +// priv->AdRxOkCnt = 0;//-by amy 080312
24355 +// printk("-SwAntennaDiversity()\n");
24360 +// Return TRUE if we shall perform Tx Power Tracking Mecahnism, FALSE otherwise.
24363 +CheckTxPwrTracking( struct net_device *dev)
24365 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
24367 + if(!priv->bTxPowerTrack)
24372 +//lzm reserved 080826
24373 + //if(priv->bScanInProgress)
24378 + //if 87SE is in High Power , don't do Tx Power Tracking. asked by SD3 ED. 2008-08-08 Isaiah
24379 + if(priv->bToUpdateTxPwr)
24390 +// Timer callback function of SW Antenna Diversity.
24393 +SwAntennaDiversityTimerCallback(
24394 + struct net_device *dev
24397 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
24398 + RT_RF_POWER_STATE rtState;
24400 + //printk("+SwAntennaDiversityTimerCallback()\n");
24403 + // We do NOT need to switch antenna while RF is off.
24404 + // 2007.05.09, added by Roger.
24406 + rtState = priv->eRFPowerState;
24408 + if (rtState == eRfOff)
24410 +// printk("SwAntennaDiversityTimer - RF is OFF.\n");
24413 + else if (rtState == eRfSleep)
24415 + // Don't access BB/RF under Disable PLL situation.
24416 + //RT_TRACE((COMP_RF|COMP_ANTENNA), DBG_LOUD, ("SwAntennaDiversityTimerCallback(): RF is Sleep => skip it\n"));
24419 + SwAntennaDiversity(dev);
24425 + priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD);
24426 + add_timer(&priv->SwAntennaDiversityTimer);
24429 + //printk("-SwAntennaDiversityTimerCallback()\n");
24433 +++ b/drivers/staging/rtl8187se/r8180_dm.h
24435 +#ifndef R8180_DM_H
24436 +#define R8180_DM_H
24438 +#include "r8180.h"
24439 +//#include "r8180_hw.h"
24440 +//#include "r8180_93cx6.h"
24441 +void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength);
24442 +bool SetAntenna8185(struct net_device *dev, u8 u1bAntennaIndex);
24443 +bool SwitchAntenna( struct net_device *dev);
24444 +void SwAntennaDiversity(struct net_device *dev );
24445 +void SwAntennaDiversityTimerCallback(struct net_device *dev);
24446 +bool CheckDig(struct net_device *dev);
24447 +bool CheckHighPower(struct net_device *dev);
24448 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
24449 +void rtl8180_hw_dig_wq (struct work_struct *work);
24451 +void rtl8180_hw_dig_wq(struct net_device *dev);
24453 +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20))
24454 +void rtl8180_tx_pw_wq (struct work_struct *work);
24456 +void rtl8180_tx_pw_wq(struct net_device *dev);
24458 +#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
24459 +void rtl8180_rate_adapter(struct work_struct * work);
24462 +void rtl8180_rate_adapter(struct net_device *dev);
24465 +void TxPwrTracking87SE(struct net_device *dev);
24466 +bool CheckTxPwrTracking(struct net_device *dev);
24467 +#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
24468 +void rtl8180_rate_adapter(struct work_struct * work);
24470 +void rtl8180_rate_adapter(struct net_device *dev);
24472 +void timer_rate_adaptive(unsigned long data);
24477 +++ b/drivers/staging/rtl8187se/r8180_gct.c
24480 + This files contains GCT radio frontend programming routines.
24482 + This is part of rtl8180 OpenSource driver
24483 + Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
24484 + Released under the terms of GPL (General Public Licence)
24486 + Parts of this driver are based on the GPL part of the
24487 + official realtek driver
24489 + Parts of this driver are based on the rtl8180 driver skeleton
24490 + from Patric Schenke & Andres Salomon
24492 + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
24494 + Code from Rtw8180 NetBSD driver by David Young has been really useful to
24495 + understand some things and gets some ideas
24497 + Code from rtl8181 project has been useful to me to understand some things.
24499 + Some code from 'Deuce' work
24501 + We want to tanks the Authors of such projects and the Ndiswrapper
24506 +#include "r8180.h"
24507 +#include "r8180_hw.h"
24508 +#include "r8180_gct.h"
24511 +//#define DEBUG_GCT
24513 +/* the following experiment are just experiments.
24514 + * this means if you enable them you can have every kind
24515 + * of result, included damage the RF chip, so don't
24516 + * touch them if you don't know what you are doing.
24517 + * In any case, if you do it, do at your own risk
24520 +//#define GCT_EXPERIMENT1 //improve RX sensivity
24522 +//#define GCT_EXPERIMENT2
24524 +//#define GCT_EXPERIMENT3 //iprove a bit RX signal quality ?
24526 +//#define GCT_EXPERIMENT4 //maybe solve some brokeness with experiment1 ?
24528 +//#define GCT_EXPERIMENT5
24530 +//#define GCT_EXPERIMENT6 //not good
24533 +u32 gct_chan[] = {
24534 + 0x0, //dummy channel 0
24551 +int gct_encode[16] = {
24558 +void gct_rf_stabilize(struct net_device *dev)
24560 + force_pci_posting(dev);
24561 + mdelay(3); //for now use a great value.. we may optimize in future
24565 +void write_gct(struct net_device *dev, u8 adr, u32 data)
24567 +// struct r8180_priv *priv = ieee80211_priv(dev);
24570 + phy_config = gct_encode[(data & 0xf00) >> 8];
24571 + phy_config |= gct_encode[(data & 0xf0) >> 4 ] << 4;
24572 + phy_config |= gct_encode[(data & 0xf) ] << 8;
24573 + phy_config |= gct_encode[(adr >> 1) & 0xf ] << 12;
24574 + phy_config |= (adr & 1 ) << 16;
24575 + phy_config |= gct_encode[(data & 0xf000)>>12] << 24;
24577 + phy_config |= 0x90000000; // MAC will bang bits to the chip
24580 + write_nic_dword(dev,PHY_CONFIG,phy_config);
24582 + DMESG("Writing GCT: %x (adr %x)",phy_config,adr);
24584 + gct_rf_stabilize(dev);
24589 +void gct_write_phy_antenna(struct net_device *dev,short ch)
24591 + struct r8180_priv *priv = ieee80211_priv(dev);
24594 + ant = GCT_ANTENNA;
24595 + if(priv->antb) /*default antenna is antenna B */
24596 + ant |= BB_ANTENNA_B;
24598 + ant |= BB_ANTATTEN_CHAN14;
24599 + write_phy(dev,0x10,ant);
24600 + //DMESG("BB antenna %x ",ant);
24604 +void gct_rf_set_chan(struct net_device *dev, short ch)
24606 + struct r8180_priv *priv = ieee80211_priv(dev);
24607 + u32 txpw = 0xff & priv->chtxpwr[ch];
24608 + u32 chan = gct_chan[ch];
24610 + //write_phy(dev,3,txpw);
24612 + DMESG("Gct set channel");
24614 + /* set TX power */
24615 + write_gct(dev,0x15,0);
24616 + write_gct(dev,6, txpw);
24617 + write_gct(dev,0x15, 0x10);
24618 + write_gct(dev,0x15,0);
24620 + /*set frequency*/
24621 + write_gct(dev,7, 0);
24622 + write_gct(dev,0xB, chan);
24623 + write_gct(dev,7, 0x1000);
24626 + DMESG("Gct set channel > write phy antenna");
24630 + gct_write_phy_antenna(dev,ch);
24635 +void gct_rf_close(struct net_device *dev)
24639 + anaparam = read_nic_dword(dev,ANAPARAM);
24640 + anaparam &= 0x000fffff;
24641 + anaparam |= 0x3f900000;
24642 + rtl8180_set_anaparam(dev, anaparam);
24644 + write_gct(dev, 0x7, 0);
24645 + write_gct(dev, 0x1f, 0x45);
24646 + write_gct(dev, 0x1f, 0x5);
24647 + write_gct(dev, 0x0, 0x8e4);
24651 +void gct_rf_init(struct net_device *dev)
24653 + struct r8180_priv *priv = ieee80211_priv(dev);
24657 + write_nic_byte(dev,PHY_DELAY,0x6); //this is general
24658 + write_nic_byte(dev,CARRIER_SENSE_COUNTER,0x4c); //this is general
24660 + //DMESG("%x", read_nic_dword(dev,ANAPARAM));
24661 + /* we should set anaparm here*/
24662 + //rtl8180_set_anaparam(dev,anaparam);
24664 + write_gct(dev,0x1f,0);
24665 + write_gct(dev,0x1f,0);
24666 + write_gct(dev,0x1f,0x40);
24667 + write_gct(dev,0x1f,0x60);
24668 + write_gct(dev,0x1f,0x61);
24669 + write_gct(dev,0x1f,0x61);
24670 + write_gct(dev,0x0,0xae4);
24671 + write_gct(dev,0x1f,0x1);
24672 + write_gct(dev,0x1f,0x41);
24673 + write_gct(dev,0x1f,0x61);
24674 + write_gct(dev,0x1,0x1a23);
24675 + write_gct(dev,0x2,0x4971);
24676 + write_gct(dev,0x3,0x41de);
24677 + write_gct(dev,0x4,0x2d80);
24678 +#ifdef GCT_EXPERIMENT1
24679 + //write_gct(dev,0x5,0x6810); // from zydas driver. sens+ but quite slow
24680 + //write_gct(dev,0x5,0x681f); //good+ (somewhat stable, better sens, performance decent)
24681 + write_gct(dev,0x5,0x685f); //good performances, not sure sens is really so beeter
24682 + //write_gct(dev,0x5,0x687f); //good performances, maybe sens is not improved
24683 + //write_gct(dev,0x5,0x689f); //like above
24684 + //write_gct(dev,0x5,0x685e); //bad
24685 + //write_gct(dev,0x5,0x68ff); //good+ (somewhat stable, better sens(?), performance decent)
24686 + //write_gct(dev,0x5,0x68f0); //bad
24687 + //write_gct(dev,0x5,0x6cff); //sens+ but not so good
24688 + //write_gct(dev,0x5,0x6dff); //sens+,apparentely very good but broken
24689 + //write_gct(dev,0x5,0x65ff); //sens+,good
24690 + //write_gct(dev,0x5,0x78ff); //sens + but almost broken
24691 + //write_gct(dev,0x5,0x7810); //- //snes + but broken
24692 + //write_gct(dev,0x5,0x781f); //-- //sens +
24693 + //write_gct(dev,0x5,0x78f0); //low sens
24695 + write_gct(dev,0x5,0x61ff); //best performance but weak sensitivity
24697 +#ifdef GCT_EXPERIMENT2
24698 + write_gct(dev,0x6,0xe);
24700 + write_gct(dev,0x6,0x0);
24702 + write_gct(dev,0x7,0x0);
24703 + write_gct(dev,0x8,0x7533);
24704 + write_gct(dev,0x9,0xc401);
24705 + write_gct(dev,0xa,0x0);
24706 + write_gct(dev,0xc,0x1c7);
24707 + write_gct(dev,0xd,0x29d3);
24708 + write_gct(dev,0xe,0x2e8);
24709 + write_gct(dev,0x10,0x192);
24710 +#ifdef GCT_EXPERIMENT3
24711 + write_gct(dev,0x11,0x246);
24713 + write_gct(dev,0x11,0x248);
24715 + write_gct(dev,0x12,0x0);
24716 + write_gct(dev,0x13,0x20c4);
24717 +#ifdef GCT_EXPERIMENT4
24718 + write_gct(dev,0x14,0xf488);
24720 + write_gct(dev,0x14,0xf4fc);
24722 +#ifdef GCT_EXPERIMENT5
24723 + write_gct(dev,0x15,0xb152);
24725 + write_gct(dev,0x15,0x0);
24727 +#ifdef GCT_EXPERIMENT6
24728 + write_gct(dev,0x1e,0x1);
24730 + write_gct(dev,0x16,0x1500);
24732 + write_gct(dev,0x7,0x1000);
24733 + /*write_gct(dev,0x15,0x0);
24734 + write_gct(dev,0x6,0x15);
24735 + write_gct(dev,0x15,0x8);
24736 + write_gct(dev,0x15,0x0);
24738 + write_phy(dev,0,0xa8);
24740 +/* write_gct(dev,0x15,0x0);
24741 + write_gct(dev,0x6,0x12);
24742 + write_gct(dev,0x15,0x8);
24743 + write_gct(dev,0x15,0x0);
24745 + write_phy(dev,3,0x0);
24746 + write_phy(dev,4,0xc0); /* lna det*/
24747 + write_phy(dev,5,0x90);
24748 + write_phy(dev,6,0x1e);
24749 + write_phy(dev,7,0x64);
24752 + DMESG("Gct init> write phy antenna");
24755 + gct_write_phy_antenna(dev,priv->chan);
24757 + write_phy(dev,0x11,0x88);
24758 + if(!priv->diversity)
24759 + write_phy(dev,0x12,0xc0);
24761 + write_phy(dev,0x12,0x40);
24763 + write_phy(dev,0x13,0x90 | priv->cs_treshold );
24765 + write_phy(dev,0x19,0x0);
24766 + write_phy(dev,0x1a,0xa0);
24767 + write_phy(dev,0x1b,0x44);
24770 + DMESG("Gct init > set channel2");
24773 + gct_rf_set_chan(dev,priv->chan);
24776 +++ b/drivers/staging/rtl8187se/r8180_gct.h
24779 + This is part of rtl8180 OpenSource driver - v 0.20
24780 + Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
24781 + Released under the terms of GPL (General Public Licence)
24783 + Parts of this driver are based on the GPL part of the official realtek driver
24784 + Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
24785 + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
24787 + We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
24790 +#define GCT_ANTENNA 0xA3
24793 +// we use the untouched eeprom value- cross your finger ;-)
24794 +#define GCT_ANAPARAM_PWR1_ON ??
24795 +#define GCT_ANAPARAM_PWR0_ON ??
24799 +void gct_rf_init(struct net_device *dev);
24800 +void gct_rf_set_chan(struct net_device *dev,short ch);
24802 +void gct_rf_close(struct net_device *dev);
24804 +++ b/drivers/staging/rtl8187se/r8180.h
24807 + This is part of rtl8180 OpenSource driver.
24808 + Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
24809 + Released under the terms of GPL (General Public Licence)
24811 + Parts of this driver are based on the GPL part of the
24812 + official realtek driver
24814 + Parts of this driver are based on the rtl8180 driver skeleton
24815 + from Patric Schenke & Andres Salomon
24817 + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
24819 + We want to tanks the Authors of those projects and the Ndiswrapper
24827 +#define RTL8180_MODULE_NAME "rtl8180"
24828 +#define DMESG(x,a...) printk(KERN_INFO RTL8180_MODULE_NAME ": " x "\n", ## a)
24829 +#define DMESGW(x,a...) printk(KERN_WARNING RTL8180_MODULE_NAME ": WW:" x "\n", ## a)
24830 +#define DMESGE(x,a...) printk(KERN_WARNING RTL8180_MODULE_NAME ": EE:" x "\n", ## a)
24832 +#include <linux/module.h>
24833 +#include <linux/kernel.h>
24834 +//#include <linux/config.h>
24835 +#include <linux/init.h>
24836 +#include <linux/ioport.h>
24837 +#include <linux/sched.h>
24838 +#include <linux/types.h>
24839 +#include <linux/slab.h>
24840 +#include <linux/netdevice.h>
24841 +#include <linux/pci.h>
24842 +#include <linux/etherdevice.h>
24843 +#include <linux/delay.h>
24844 +#include <linux/rtnetlink.h> //for rtnl_lock()
24845 +#include <linux/wireless.h>
24846 +#include <linux/timer.h>
24847 +#include <linux/proc_fs.h> // Necessary because we use the proc fs
24848 +#include <linux/if_arp.h>
24849 +#include "ieee80211.h"
24850 +#include <asm/io.h>
24851 +//#include <asm/semaphore.h>
24853 +#define EPROM_93c46 0
24854 +#define EPROM_93c56 1
24856 +#define RTL_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
24858 +#define DEFAULT_FRAG_THRESHOLD 2342U
24859 +#define MIN_FRAG_THRESHOLD 256U
24860 +//#define MAX_FRAG_THRESHOLD 2342U
24861 +#define DEFAULT_RTS_THRESHOLD 2342U
24862 +#define MIN_RTS_THRESHOLD 0U
24863 +#define MAX_RTS_THRESHOLD 2342U
24864 +#define DEFAULT_BEACONINTERVAL 0x64U
24865 +#define DEFAULT_BEACON_ESSID "Rtl8180"
24867 +#define DEFAULT_SSID ""
24868 +#define DEFAULT_RETRY_RTS 7
24869 +#define DEFAULT_RETRY_DATA 7
24870 +#define PRISM_HDR_SIZE 64
24872 +#ifdef CONFIG_RTL8185B
24874 +#define MGNT_QUEUE 0
24875 +#define BK_QUEUE 1
24876 +#define BE_QUEUE 2
24877 +#define VI_QUEUE 3
24878 +#define VO_QUEUE 4
24879 +#define HIGH_QUEUE 5
24880 +#define BEACON_QUEUE 6
24882 +#define LOW_QUEUE BE_QUEUE
24883 +#define NORMAL_QUEUE MGNT_QUEUE
24885 +#define aSifsTime 10
24888 +#define sAckCtsLng 112 // bits in ACK and CTS frames
24890 +#define RATE_ADAPTIVE_TIMER_PERIOD 300
24892 +typedef enum _WIRELESS_MODE {
24893 + WIRELESS_MODE_UNKNOWN = 0x00,
24894 + WIRELESS_MODE_A = 0x01,
24895 + WIRELESS_MODE_B = 0x02,
24896 + WIRELESS_MODE_G = 0x04,
24897 + WIRELESS_MODE_AUTO = 0x08,
24900 +typedef enum _VERSION_8185{
24902 + VERSION_8185_UNKNOWN,
24903 + VERSION_8185_C, // C-cut
24904 + VERSION_8185_D, // D-cut
24906 + VERSION_8185B_B, // B-cut
24907 + VERSION_8185B_D, // D-cut
24908 + VERSION_8185B_E, // E-cut
24910 + VERSION_8187S_B, // B-cut
24911 + VERSION_8187S_C, // C-cut
24912 + VERSION_8187S_D, // D-cut
24914 +}VERSION_8185,*PVERSION_8185;
24915 +typedef struct ChnlAccessSetting {
24918 + u16 SlotTimeTimer;
24922 +}*PCHANNEL_ACCESS_SETTING,CHANNEL_ACCESS_SETTING;
24929 +typedef u32 AC_CODING;
24930 +#define AC0_BE 0 // ACI: 0x00 // Best Effort
24931 +#define AC1_BK 1 // ACI: 0x01 // Background
24932 +#define AC2_VI 2 // ACI: 0x10 // Video
24933 +#define AC3_VO 3 // ACI: 0x11 // Voice
24934 +#define AC_MAX 4 // Max: define total number; Should not to be used as a real enum.
24937 +// ECWmin/ECWmax field.
24938 +// Ref: WMM spec 2.2.2: WME Parameter Element, p.13.
24940 +typedef union _ECW{
24950 +// ACI/AIFSN Field.
24951 +// Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
24953 +typedef union _ACI_AIFSN{
24963 +}ACI_AIFSN, *PACI_AIFSN;
24966 +// AC Parameters Record Format.
24967 +// Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
24969 +typedef union _AC_PARAM{
24975 + ACI_AIFSN AciAifsn;
24979 +}AC_PARAM, *PAC_PARAM;
24981 +/* it is a wrong definition. -xiong-2006-11-17
24982 +typedef struct ThreeWireReg {
24993 +typedef union _ThreeWire{
24994 + struct _ThreeWireStruc{
24998 + u16 read_write:1;
25000 +// u2Byte resv2:14;
25001 +// u2Byte ThreeWireEnable:1;
25002 +// u2Byte resv3:1;
25009 +typedef struct buffer
25011 + struct buffer *next;
25016 +//YJ,modified,080828
25017 +typedef struct Stats
25019 + unsigned long txrdu;
25020 + unsigned long rxrdu;
25021 + unsigned long rxnolast;
25022 + unsigned long rxnodata;
25023 +// unsigned long rxreset;
25024 +// unsigned long rxwrkaround;
25025 + unsigned long rxnopointer;
25026 + unsigned long txnperr;
25027 + unsigned long txresumed;
25028 + unsigned long rxerr;
25029 + unsigned long rxoverflow;
25030 + unsigned long rxint;
25031 + unsigned long txbkpokint;
25032 + unsigned long txbepoking;
25033 + unsigned long txbkperr;
25034 + unsigned long txbeperr;
25035 + unsigned long txnpokint;
25036 + unsigned long txhpokint;
25037 + unsigned long txhperr;
25038 + unsigned long ints;
25039 + unsigned long shints;
25040 + unsigned long txoverflow;
25041 + unsigned long rxdmafail;
25042 + unsigned long txbeacon;
25043 + unsigned long txbeaconerr;
25044 + unsigned long txlpokint;
25045 + unsigned long txlperr;
25046 + unsigned long txretry;//retry number tony 20060601
25047 + unsigned long rxcrcerrmin;//crc error (0-500)
25048 + unsigned long rxcrcerrmid;//crc error (500-1000)
25049 + unsigned long rxcrcerrmax;//crc error (>1000)
25050 + unsigned long rxicverr;//ICV error
25053 +#define MAX_LD_SLOT_NUM 10
25054 +#define KEEP_ALIVE_INTERVAL 20 // in seconds.
25055 +#define CHECK_FOR_HANG_PERIOD 2 //be equal to watchdog check time
25056 +#define DEFAULT_KEEP_ALIVE_LEVEL 1
25057 +#define DEFAULT_SLOT_NUM 2
25058 +#define POWER_PROFILE_AC 0
25059 +#define POWER_PROFILE_BATTERY 1
25061 +typedef struct _link_detect_t
25063 + u32 RxFrameNum[MAX_LD_SLOT_NUM]; // number of Rx Frame / CheckForHang_period to determine link status
25064 + u16 SlotNum; // number of CheckForHang period to determine link status, default is 2
25067 + u32 NumTxOkInPeriod; //number of packet transmitted during CheckForHang
25068 + u32 NumRxOkInPeriod; //number of packet received during CheckForHang
25070 + u8 IdleCount; // (KEEP_ALIVE_INTERVAL / CHECK_FOR_HANG_PERIOD)
25071 + u32 LastNumTxUnicast;
25072 + u32 LastNumRxUnicast;
25074 + bool bBusyTraffic; //when it is set to 1, UI cann't scan at will.
25075 +}link_detect_t, *plink_detect_t;
25077 +//YJ,modified,080828,end
25080 +//================================================================================
25081 +// LED customization.
25082 +//================================================================================
25084 +typedef enum _LED_STRATEGY_8185{
25087 + HW_LED, // HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes)
25088 +}LED_STRATEGY_8185, *PLED_STRATEGY_8185;
25090 +//by amy for power save
25091 +typedef enum _LED_CTL_MODE{
25092 + LED_CTL_POWER_ON = 1,
25093 + LED_CTL_LINK = 2,
25094 + LED_CTL_NO_LINK = 3,
25097 + LED_CTL_SITE_SURVEY = 6,
25098 + LED_CTL_POWER_OFF = 7
25101 +typedef enum _RT_RF_POWER_STATE
25106 +}RT_RF_POWER_STATE;
25109 + unspec_reason = 0x1,
25110 + auth_not_valid = 0x2,
25111 + deauth_lv_ss = 0x3,
25112 + inactivity = 0x4,
25113 + ap_overload = 0x5,
25114 + class2_err = 0x6,
25115 + class3_err = 0x7,
25116 + disas_lv_ss = 0x8,
25117 + asoc_not_auth = 0x9,
25120 + mic_failure = 0xe,
25121 + //----END MIC_CHECK
25123 + // Reason code defined in 802.11i D10.0 p.28.
25124 + invalid_IE = 0x0d,
25125 + four_way_tmout = 0x0f,
25126 + two_way_tmout = 0x10,
25127 + IE_dismatch = 0x11,
25128 + invalid_Gcipher = 0x12,
25129 + invalid_Pcipher = 0x13,
25130 + invalid_AKMP = 0x14,
25131 + unsup_RSNIEver = 0x15,
25132 + invalid_RSNIE = 0x16,
25133 + auth_802_1x_fail= 0x17,
25134 + ciper_reject = 0x18,
25136 + // Reason code defined in 7.3.1.7, 802.1e D13.0, p.42. Added by Annie, 2005-11-15.
25137 + QoS_unspec = 0x20, // 32
25138 + QAP_bandwidth = 0x21, // 33
25139 + poor_condition = 0x22, // 34
25140 + no_facility = 0x23, // 35
25141 + // Where is 36???
25142 + req_declined = 0x25, // 37
25143 + invalid_param = 0x26, // 38
25144 + req_not_honored= 0x27, // 39
25145 + TS_not_created = 0x2F, // 47
25146 + DL_not_allowed = 0x30, // 48
25147 + dest_not_exist = 0x31, // 49
25148 + dest_not_QSTA = 0x32, // 50
25150 +typedef enum _RT_PS_MODE
25152 + eActive, // Active/Continuous access.
25153 + eMaxPs, // Max power save mode.
25154 + eFastPs // Fast power save mode.
25156 +//by amy for power save
25157 +typedef struct r8180_priv
25159 + struct pci_dev *pdev;
25163 + struct ieee80211_device *ieee80211;
25165 + short card_8185; /* O: rtl8180, 1:rtl8185 V B/C, 2:rtl8185 V D, 3:rtl8185B */
25166 + short card_8185_Bversion; /* if TCR reports card V B/C this discriminates */
25167 + short phy_ver; /* meaningful for rtl8225 1:A 2:B 3:C */
25168 + short enable_gpio0;
25169 + enum card_type {PCI,MINIPCI,CARDBUS,USB/*rtl8187*/}card_type;
25170 + short hw_plcp_len;
25171 + short plcp_preamble_mode; // 0:auto 1:short 2:long
25173 + spinlock_t irq_lock;
25174 + spinlock_t irq_th_lock;
25175 + spinlock_t tx_lock;
25176 + spinlock_t ps_lock;
25177 + spinlock_t rf_ps_lock;
25180 + short irq_enabled;
25181 + struct net_device *dev;
25185 + u8 chtxpwr[15]; //channels from 1 to 14, 0 not used
25186 + u8 chtxpwr_ofdm[15]; //channels from 1 to 14, 0 not used
25187 + //u8 challow[15]; //channels from 1 to 14, 0 not used
25188 + u8 channel_plan; // it's the channel plan index
25190 + short crcmon; //if 1 allow bad crc frame reception in monitor mode
25193 + struct timer_list scan_timer;
25194 + /*short scanpending;
25195 + short stopscan;*/
25196 + spinlock_t scan_lock;
25198 + //u8 active_scan_num;
25199 + struct semaphore wx_sem;
25200 + struct semaphore rf_state;
25207 + short rcr_csense;
25210 + short (*rf_set_sens)(struct net_device *dev,short sens);
25211 + void (*rf_set_chan)(struct net_device *dev,short ch);
25212 + void (*rf_close)(struct net_device *dev);
25213 + void (*rf_init)(struct net_device *dev);
25214 + void (*rf_sleep)(struct net_device *dev);
25215 + void (*rf_wakeup)(struct net_device *dev);
25219 + struct Stats stats;
25220 + struct _link_detect_t link_detect; //YJ,add,080828
25221 + struct iw_statistics wstats;
25222 + struct proc_dir_entry *dir_dev;
25227 + dma_addr_t rxringdma;
25228 + struct buffer *rxbuffer;
25229 + struct buffer *rxbufferhead;
25231 + u16 rxbuffersize;
25233 + struct sk_buff *rx_skb;
25235 + short rx_skb_complete;
25244 + dma_addr_t txlpringdma;
25245 + dma_addr_t txhpringdma;
25246 + dma_addr_t txnpringdma;
25247 + u32 *txlpringtail;
25248 + u32 *txhpringtail;
25249 + u32 *txnpringtail;
25250 + u32 *txlpringhead;
25251 + u32 *txhpringhead;
25252 + u32 *txnpringhead;
25253 + struct buffer *txlpbufs;
25254 + struct buffer *txhpbufs;
25255 + struct buffer *txnpbufs;
25256 + struct buffer *txlpbufstail;
25257 + struct buffer *txhpbufstail;
25258 + struct buffer *txnpbufstail;
25266 + dma_addr_t txmapringdma;
25267 + dma_addr_t txbkpringdma;
25268 + dma_addr_t txbepringdma;
25269 + dma_addr_t txvipringdma;
25270 + dma_addr_t txvopringdma;
25271 + dma_addr_t txhpringdma;
25272 + u32 *txmapringtail;
25273 + u32 *txbkpringtail;
25274 + u32 *txbepringtail;
25275 + u32 *txvipringtail;
25276 + u32 *txvopringtail;
25277 + u32 *txhpringtail;
25278 + u32 *txmapringhead;
25279 + u32 *txbkpringhead;
25280 + u32 *txbepringhead;
25281 + u32 *txvipringhead;
25282 + u32 *txvopringhead;
25283 + u32 *txhpringhead;
25284 + struct buffer *txmapbufs;
25285 + struct buffer *txbkpbufs;
25286 + struct buffer *txbepbufs;
25287 + struct buffer *txvipbufs;
25288 + struct buffer *txvopbufs;
25289 + struct buffer *txhpbufs;
25290 + struct buffer *txmapbufstail;
25291 + struct buffer *txbkpbufstail;
25292 + struct buffer *txbepbufstail;
25293 + struct buffer *txvipbufstail;
25294 + struct buffer *txvopbufstail;
25295 + struct buffer *txhpbufstail;
25299 + //struct tx_pendingbuf txnp_pending;
25300 + //struct tasklet_struct irq_tx_tasklet;
25301 + struct tasklet_struct irq_rx_tasklet;
25302 + u8 dma_poll_mask;
25303 + //short tx_suspend;
25305 + /* adhoc/master mode stuff */
25306 + u32 *txbeaconringtail;
25307 + dma_addr_t txbeaconringdma;
25308 + u32 *txbeaconring;
25309 + int txbeaconcount;
25310 + struct buffer *txbeaconbufs;
25311 + struct buffer *txbeaconbufstail;
25312 + //char *master_essid;
25313 + //u16 master_beaconinterval;
25314 + //u32 master_beaconsize;
25315 + //u16 beacon_interval;
25321 +//add for RF power on power off by lizhaoming 080512
25322 + u8 RegThreeWireMode; // See "Three wire mode" defined above, 2006.05.31, by rcnjko.
25325 + LED_STRATEGY_8185 LedStrategy;
25328 +//by amy for power save
25329 + struct timer_list watch_dog_timer;
25330 + bool bInactivePs;
25331 + bool bSwRfProcessing;
25332 + RT_RF_POWER_STATE eInactivePowerState;
25333 + RT_RF_POWER_STATE eRFPowerState;
25335 + bool RFChangeInProgress;
25337 + bool SetRFPowerStateInProgress;
25340 + RT_PS_MODE dot11PowerSaveMode;
25341 + //u32 NumRxOkInPeriod; //YJ,del,080828
25342 + //u32 NumTxOkInPeriod; //YJ,del,080828
25343 + u8 TxPollingTimes;
25345 + bool bApBufOurFrame;// TRUE if AP buffer our unicast data , we will keep eAwake untill receive data or timeout.
25346 + u8 WaitBufDataBcnCount;
25347 + u8 WaitBufDataTimeOut;
25349 +//by amy for power save
25350 +//by amy for antenna
25351 + u8 EEPROMSwAntennaDiversity;
25352 + bool EEPROMDefaultAntenna1;
25353 + u8 RegSwAntennaDiversityMechanism;
25354 + bool bSwAntennaDiverity;
25355 + u8 RegDefaultAntenna;
25356 + bool bDefaultAntenna1;
25357 + u8 SignalStrength;
25358 + long Stats_SignalStrength;
25359 + long LastSignalStrengthInPercent; // In percentange, used for smoothing, e.g. Moving Average.
25360 + u8 SignalQuality; // in 0-100 index.
25361 + long Stats_SignalQuality;
25362 + long RecvSignalPower; // in dBm.
25363 + long Stats_RecvSignalPower;
25364 + u8 LastRxPktAntenna; // +by amy 080312 Antenn which received the lasted packet. 0: Aux, 1:Main. Added by Roger, 2008.01.25.
25366 + long AdRxSignalStrength;
25367 + u8 CurrAntennaIndex; // Index to current Antenna (both Tx and Rx).
25368 + u8 AdTickCount; // Times of SwAntennaDiversityTimer happened.
25369 + u8 AdCheckPeriod; // # of period SwAntennaDiversityTimer to check Rx signal strength for SW Antenna Diversity.
25370 + u8 AdMinCheckPeriod; // Min value of AdCheckPeriod.
25371 + u8 AdMaxCheckPeriod; // Max value of AdCheckPeriod.
25372 + long AdRxSsThreshold; // Signal strength threshold to switch antenna.
25373 + long AdMaxRxSsThreshold; // Max value of AdRxSsThreshold.
25374 + bool bAdSwitchedChecking; // TRUE if we shall shall check Rx signal strength for last time switching antenna.
25375 + long AdRxSsBeforeSwitched; // Rx signal strength before we swithed antenna.
25376 + struct timer_list SwAntennaDiversityTimer;
25377 +//by amy for antenna
25380 + // Crystal calibration.
25381 + // Added by Roger, 2007.12.11.
25383 + bool bXtalCalibration; // Crystal calibration.
25384 + u8 XtalCal_Xin; // Crystal calibration for Xin. 0~7.5pF
25385 + u8 XtalCal_Xout; // Crystal calibration for Xout. 0~7.5pF
25387 + // Tx power tracking with thermal meter indication.
25388 + // Added by Roger, 2007.12.11.
25390 + bool bTxPowerTrack; // Tx Power tracking.
25391 + u8 ThermalMeter; // Thermal meter reference indication.
25393 + // Dynamic Initial Gain Adjustment Mechanism. Added by Bruce, 2007-02-14.
25395 + bool bDigMechanism; // TRUE if DIG is enabled, FALSE ow.
25396 + bool bRegHighPowerMechanism; // For High Power Mechanism. 061010, by rcnjko.
25397 + u32 FalseAlarmRegValue;
25398 + u8 RegDigOfdmFaUpTh; // Upper threhold of OFDM false alarm, which is used in DIG.
25399 + u8 DIG_NumberFallbackVote;
25400 + u8 DIG_NumberUpgradeVote;
25401 + // For HW antenna diversity, added by Roger, 2008.01.30.
25402 + u32 AdMainAntennaRxOkCnt; // Main antenna Rx OK count.
25403 + u32 AdAuxAntennaRxOkCnt; // Aux antenna Rx OK count.
25404 + bool bHWAdSwitched; // TRUE if we has switched default antenna by HW evaluation.
25405 + // RF High Power upper/lower threshold.
25406 + u8 RegHiPwrUpperTh;
25407 + u8 RegHiPwrLowerTh;
25408 + // RF RSSI High Power upper/lower Threshold.
25409 + u8 RegRSSIHiPwrUpperTh;
25410 + u8 RegRSSIHiPwrLowerTh;
25411 + // Current CCK RSSI value to determine CCK high power, asked by SD3 DZ, by Bruce, 2007-04-12.
25415 + // High Power Mechanism. Added by amy, 080312.
25417 + bool bToUpdateTxPwr;
25418 + long UndecoratedSmoothedSS;
25419 + long UndercorateSmoothedRxPower;
25423 + //For adjust Dig Threshhold during Legacy/Leisure Power Save Mode
25424 + u32 DozePeriodInPast2Sec;
25425 + // Don't access BB/RF under disable PLL situation.
25426 + u8 InitialGainBackUp;
25427 + u8 RegBModeGainStage;
25428 +//by amy for rate adaptive
25429 + struct timer_list rateadapter_timer;
25430 + u32 RateAdaptivePeriod;
25431 + bool bEnhanceTxPwr;
25432 + bool bUpdateARFR;
25433 + int ForcedDataRate; // Force Data Rate. 0: Auto, 0x02: 1M ~ 0x6C: 54M.)
25434 + u32 NumTxUnicast; //YJ,add,080828,for keep alive
25435 + u8 keepAliveLevel; //YJ,add,080828,for KeepAlive
25436 + unsigned long NumTxOkTotal;
25437 + u16 LastRetryCnt;
25438 + u16 LastRetryRate;
25439 + unsigned long LastTxokCnt;
25440 + unsigned long LastRxokCnt;
25441 + u16 CurrRetryCnt;
25442 + unsigned long LastTxOKBytes;
25443 + unsigned long NumTxOkBytesTotal;
25444 + u8 LastFailTxRate;
25445 + long LastFailTxRateSS;
25446 + u8 FailTxRateCount;
25447 + u32 LastTxThroughput;
25449 + unsigned short bTryuping;
25450 + u8 CurrTxRate; //the rate before up
25451 + u16 CurrRetryRate;
25452 + u16 TryupingCount;
25453 + u8 TryDownCountLowData;
25454 + u8 TryupingCountNoData;
25456 + u8 CurrentOperaRate;
25457 +//by amy for rate adaptive
25459 +// short wq_hurryup;
25460 +// struct workqueue_struct *workqueue;
25461 + struct work_struct reset_wq;
25462 + struct work_struct watch_dog_wq;
25463 + struct work_struct tx_irq_wq;
25464 + short ack_tx_to_ieee;
25467 +#ifdef CONFIG_RTL8185B
25469 + u8 cck_txpwr_base;
25470 + u8 ofdm_txpwr_base;
25471 + u8 dma_poll_stop_mask;
25473 + //u8 RegThreeWireMode;
25475 + u16 ShortRetryLimit;
25476 + u16 LongRetryLimit;
25477 + u16 EarlyRxThreshold;
25478 + u32 TransmitConfig;
25479 + u32 ReceiveConfig;
25482 + struct ChnlAccessSetting ChannelAccessSetting;
25486 +#define MANAGE_PRIORITY 0
25487 +#define BK_PRIORITY 1
25488 +#define BE_PRIORITY 2
25489 +#define VI_PRIORITY 3
25490 +#define VO_PRIORITY 4
25491 +#define HI_PRIORITY 5
25492 +#define BEACON_PRIORITY 6
25494 +#define LOW_PRIORITY VI_PRIORITY
25495 +#define NORM_PRIORITY VO_PRIORITY
25496 +//AC2Queue mapping
25497 +#define AC2Q(_ac) (((_ac) == WME_AC_VO) ? VO_PRIORITY : \
25498 + ((_ac) == WME_AC_VI) ? VI_PRIORITY : \
25499 + ((_ac) == WME_AC_BK) ? BK_PRIORITY : \
25502 +short rtl8180_tx(struct net_device *dev,u8* skbuf, int len,int priority,
25503 + short morefrag,short fragdesc,int rate);
25505 +u8 read_nic_byte(struct net_device *dev, int x);
25506 +u32 read_nic_dword(struct net_device *dev, int x);
25507 +u16 read_nic_word(struct net_device *dev, int x) ;
25508 +void write_nic_byte(struct net_device *dev, int x,u8 y);
25509 +void write_nic_word(struct net_device *dev, int x,u16 y);
25510 +void write_nic_dword(struct net_device *dev, int x,u32 y);
25511 +void force_pci_posting(struct net_device *dev);
25513 +void rtl8180_rtx_disable(struct net_device *);
25514 +void rtl8180_rx_enable(struct net_device *);
25515 +void rtl8180_tx_enable(struct net_device *);
25516 +void rtl8180_start_scanning(struct net_device *dev);
25517 +void rtl8180_start_scanning_s(struct net_device *dev);
25518 +void rtl8180_stop_scanning(struct net_device *dev);
25519 +void rtl8180_disassociate(struct net_device *dev);
25520 +//void fix_rx_fifo(struct net_device *dev);
25521 +void rtl8180_set_anaparam(struct net_device *dev,u32 a);
25522 +void rtl8185_set_anaparam2(struct net_device *dev,u32 a);
25523 +void rtl8180_set_hw_wep(struct net_device *dev);
25524 +void rtl8180_no_hw_wep(struct net_device *dev);
25525 +void rtl8180_update_msr(struct net_device *dev);
25526 +//void rtl8180_BSS_create(struct net_device *dev);
25527 +void rtl8180_beacon_tx_disable(struct net_device *dev);
25528 +void rtl8180_beacon_rx_disable(struct net_device *dev);
25529 +void rtl8180_conttx_enable(struct net_device *dev);
25530 +void rtl8180_conttx_disable(struct net_device *dev);
25531 +int rtl8180_down(struct net_device *dev);
25532 +int rtl8180_up(struct net_device *dev);
25533 +void rtl8180_commit(struct net_device *dev);
25534 +void rtl8180_set_chan(struct net_device *dev,short ch);
25535 +void rtl8180_set_master_essid(struct net_device *dev,char *essid);
25536 +void rtl8180_update_beacon_security(struct net_device *dev);
25537 +void write_phy(struct net_device *dev, u8 adr, u8 data);
25538 +void write_phy_cck(struct net_device *dev, u8 adr, u32 data);
25539 +void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data);
25540 +void rtl8185_tx_antenna(struct net_device *dev, u8 ant);
25541 +void rtl8185_rf_pins_enable(struct net_device *dev);
25542 +void IBSS_randomize_cell(struct net_device *dev);
25543 +void IPSEnter(struct net_device *dev);
25544 +void IPSLeave(struct net_device *dev);
25545 +int get_curr_tx_free_desc(struct net_device *dev, int priority);
25546 +void UpdateInitialGain(struct net_device *dev);
25547 +bool SetAntennaConfig87SE(struct net_device *dev, u8 DefaultAnt, bool bAntDiversity);
25549 +//#ifdef CONFIG_RTL8185B
25550 +void rtl8185b_adapter_start(struct net_device *dev);
25551 +void rtl8185b_rx_enable(struct net_device *dev);
25552 +void rtl8185b_tx_enable(struct net_device *dev);
25553 +void rtl8180_reset(struct net_device *dev);
25554 +void rtl8185b_irq_enable(struct net_device *dev);
25555 +void fix_rx_fifo(struct net_device *dev);
25556 +void fix_tx_fifo(struct net_device *dev);
25557 +void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch);
25558 +#if LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,20)
25559 +void rtl8180_rate_adapter(struct work_struct * work);
25561 +void rtl8180_rate_adapter(struct net_device *dev);
25564 +bool MgntActSet_RF_State(struct net_device *dev, RT_RF_POWER_STATE StateToSet, u32 ChangeSource);
25568 +++ b/drivers/staging/rtl8187se/r8180_hw.h
25571 + This is part of rtl8180 OpenSource driver.
25572 + Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
25573 + Released under the terms of GPL (General Public Licence)
25575 + Parts of this driver are based on the GPL part of the
25576 + official Realtek driver.
25577 + Parts of this driver are based on the rtl8180 driver skeleton
25578 + from Patric Schenke & Andres Salomon.
25579 + Parts of this driver are based on the Intel Pro Wireless
25582 + We want to tanks the Authors of those projects
25583 + and the Ndiswrapper project Authors.
25586 +/* Mariusz Matuszek added full registers definition with Realtek's name */
25588 +/* this file contains register definitions for the rtl8180 MAC controller */
25592 +#define CONFIG_RTL8185B //support for rtl8185B, xiong-2006-11-15
25593 +#define CONFIG_RTL818X_S
25595 +#define BIT0 0x00000001
25596 +#define BIT1 0x00000002
25597 +#define BIT2 0x00000004
25598 +#define BIT3 0x00000008
25599 +#define BIT4 0x00000010
25600 +#define BIT5 0x00000020
25601 +#define BIT6 0x00000040
25602 +#define BIT7 0x00000080
25603 +#define BIT8 0x00000100
25604 +#define BIT9 0x00000200
25605 +#define BIT10 0x00000400
25606 +#define BIT11 0x00000800
25607 +#define BIT12 0x00001000
25608 +#define BIT13 0x00002000
25609 +#define BIT14 0x00004000
25610 +#define BIT15 0x00008000
25611 +#define BIT16 0x00010000
25612 +#define BIT17 0x00020000
25613 +#define BIT18 0x00040000
25614 +#define BIT19 0x00080000
25615 +#define BIT20 0x00100000
25616 +#define BIT21 0x00200000
25617 +#define BIT22 0x00400000
25618 +#define BIT23 0x00800000
25619 +#define BIT24 0x01000000
25620 +#define BIT25 0x02000000
25621 +#define BIT26 0x04000000
25622 +#define BIT27 0x08000000
25623 +#define BIT28 0x10000000
25624 +#define BIT29 0x20000000
25625 +#define BIT30 0x40000000
25626 +#define BIT31 0x80000000
25628 +#define MAX_SLEEP_TIME (10000)
25629 +#define MIN_SLEEP_TIME (50)
25631 +#define BB_ANTATTEN_CHAN14 0x0c
25632 +#define BB_ANTENNA_B 0x40
25634 +#define BB_HOST_BANG (1<<30)
25635 +#define BB_HOST_BANG_EN (1<<2)
25636 +#define BB_HOST_BANG_CLK (1<<1)
25637 +#define BB_HOST_BANG_DATA 1
25639 +#define ANAPARAM_TXDACOFF_SHIFT 27
25640 +#define ANAPARAM_PWR0_MASK ((1<<30)|(1<<29)|(1<<28))
25641 +#define ANAPARAM_PWR0_SHIFT 28
25642 +#define ANAPARAM_PWR1_MASK ((1<<26)|(1<<25)|(1<<24)|(1<<23)|(1<<22)|(1<<21)|(1<<20))
25643 +#define ANAPARAM_PWR1_SHIFT 20
25652 +#define CMD_RST_SHIFT 4
25653 +#define CMD_RESERVED_MASK ((1<<1) | (1<<5) | (1<<6) | (1<<7))
25654 +#define CMD_RX_ENABLE_SHIFT 3
25655 +#define CMD_TX_ENABLE_SHIFT 2
25657 +#define EPROM_CMD 0x50
25658 +#define EPROM_CMD_RESERVED_MASK ((1<<5)|(1<<4))
25659 +#define EPROM_CMD_OPERATING_MODE_SHIFT 6
25660 +#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6))
25661 +#define EPROM_CMD_CONFIG 0x3
25662 +#define EPROM_CMD_NORMAL 0
25663 +#define EPROM_CMD_LOAD 1
25664 +#define EPROM_CMD_PROGRAM 2
25665 +#define EPROM_CS_SHIFT 3
25666 +#define EPROM_CK_SHIFT 2
25667 +#define EPROM_W_SHIFT 1
25668 +#define EPROM_R_SHIFT 0
25669 +#define CONFIG2_DMA_POLLING_MODE_SHIFT 3
25671 +#define INTA_TXOVERFLOW (1<<15)
25672 +#define INTA_TIMEOUT (1<<14)
25673 +#define INTA_BEACONTIMEOUT (1<<13)
25674 +#define INTA_ATIM (1<<12)
25675 +#define INTA_BEACONDESCERR (1<<11)
25676 +#define INTA_BEACONDESCOK (1<<10)
25677 +#define INTA_HIPRIORITYDESCERR (1<<9)
25678 +#define INTA_HIPRIORITYDESCOK (1<<8)
25679 +#define INTA_NORMPRIORITYDESCERR (1<<7)
25680 +#define INTA_NORMPRIORITYDESCOK (1<<6)
25681 +#define INTA_RXOVERFLOW (1<<5)
25682 +#define INTA_RXDESCERR (1<<4)
25683 +#define INTA_LOWPRIORITYDESCERR (1<<3)
25684 +#define INTA_LOWPRIORITYDESCOK (1<<2)
25685 +#define INTA_RXCRCERR (1<<1)
25686 +#define INTA_RXOK (1)
25687 +#define INTA_MASK 0x3c
25688 +#define RXRING_ADDR 0xe4 // page 0
25689 +#define PGSELECT 0x5e
25690 +#define PGSELECT_PG_SHIFT 0
25691 +#define RX_CONF 0x44
25692 +#define MAC_FILTER_MASK ((1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<5) | \
25693 +(1<<12) | (1<<18) | (1<<19) | (1<<20) | (1<<21) | (1<<22) | (1<<23))
25694 +#define RX_CHECK_BSSID_SHIFT 23
25695 +#define ACCEPT_PWR_FRAME_SHIFT 22
25696 +#define ACCEPT_MNG_FRAME_SHIFT 20
25697 +#define ACCEPT_CTL_FRAME_SHIFT 19
25698 +#define ACCEPT_DATA_FRAME_SHIFT 18
25699 +#define ACCEPT_ICVERR_FRAME_SHIFT 12
25700 +#define ACCEPT_CRCERR_FRAME_SHIFT 5
25701 +#define ACCEPT_BCAST_FRAME_SHIFT 3
25702 +#define ACCEPT_MCAST_FRAME_SHIFT 2
25703 +#define ACCEPT_ALLMAC_FRAME_SHIFT 0
25704 +#define ACCEPT_NICMAC_FRAME_SHIFT 1
25705 +#define RX_FIFO_THRESHOLD_MASK ((1<<13) | (1<<14) | (1<<15))
25706 +#define RX_FIFO_THRESHOLD_SHIFT 13
25707 +#define RX_FIFO_THRESHOLD_128 3
25708 +#define RX_FIFO_THRESHOLD_256 4
25709 +#define RX_FIFO_THRESHOLD_512 5
25710 +#define RX_FIFO_THRESHOLD_1024 6
25711 +#define RX_FIFO_THRESHOLD_NONE 7
25712 +#define RX_AUTORESETPHY_SHIFT 28
25713 +#define EPROM_TYPE_SHIFT 6
25714 +#define TX_CONF 0x40
25715 +#define TX_CONF_HEADER_AUTOICREMENT_SHIFT 30
25716 +#define TX_LOOPBACK_SHIFT 17
25717 +#define TX_LOOPBACK_MAC 1
25718 +#define TX_LOOPBACK_BASEBAND 2
25719 +#define TX_LOOPBACK_NONE 0
25720 +#define TX_LOOPBACK_CONTINUE 3
25721 +#define TX_LOOPBACK_MASK ((1<<17)|(1<<18))
25722 +#define TX_DPRETRY_SHIFT 0
25723 +#define R8180_MAX_RETRY 255
25724 +#define TX_RTSRETRY_SHIFT 8
25725 +#define TX_NOICV_SHIFT 19
25726 +#define TX_NOCRC_SHIFT 16
25727 +#define TX_DMA_POLLING 0xd9
25728 +#define TX_DMA_POLLING_BEACON_SHIFT 7
25729 +#define TX_DMA_POLLING_HIPRIORITY_SHIFT 6
25730 +#define TX_DMA_POLLING_NORMPRIORITY_SHIFT 5
25731 +#define TX_DMA_POLLING_LOWPRIORITY_SHIFT 4
25732 +#define TX_DMA_STOP_BEACON_SHIFT 3
25733 +#define TX_DMA_STOP_HIPRIORITY_SHIFT 2
25734 +#define TX_DMA_STOP_NORMPRIORITY_SHIFT 1
25735 +#define TX_DMA_STOP_LOWPRIORITY_SHIFT 0
25736 +#define TX_MANAGEPRIORITY_RING_ADDR 0x0C
25737 +#define TX_BKPRIORITY_RING_ADDR 0x10
25738 +#define TX_BEPRIORITY_RING_ADDR 0x14
25739 +#define TX_VIPRIORITY_RING_ADDR 0x20
25740 +#define TX_VOPRIORITY_RING_ADDR 0x24
25741 +#define TX_HIGHPRIORITY_RING_ADDR 0x28
25742 +//AC_VI and Low priority share the sane queue
25743 +#define TX_LOWPRIORITY_RING_ADDR TX_VIPRIORITY_RING_ADDR
25744 +//AC_VO and Norm priority share the same queue
25745 +#define TX_NORMPRIORITY_RING_ADDR TX_VOPRIORITY_RING_ADDR
25747 +#define MAX_RX_DMA_MASK ((1<<8) | (1<<9) | (1<<10))
25748 +#define MAX_RX_DMA_2048 7
25749 +#define MAX_RX_DMA_1024 6
25750 +#define MAX_RX_DMA_SHIFT 10
25751 +#define INT_TIMEOUT 0x48
25752 +#define CONFIG3_CLKRUN_SHIFT 2
25753 +#define CONFIG3_ANAPARAM_W_SHIFT 6
25754 +#define ANAPARAM 0x54
25755 +#define BEACON_INTERVAL 0x70
25756 +#define BEACON_INTERVAL_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)| \
25757 +(1<<6)|(1<<7)|(1<<8)|(1<<9))
25758 +#define ATIM_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)| \
25761 +#define EPROM_CS_SHIFT 3
25762 +#define EPROM_CK_SHIFT 2
25763 +#define PHY_DELAY 0x78
25764 +#define PHY_CONFIG 0x80
25765 +#define PHY_ADR 0x7c
25766 +#define PHY_READ 0x7e
25767 +#define CARRIER_SENSE_COUNTER 0x79 //byte
25768 +#define SECURITY 0x5f //1209 this is sth wrong
25769 +#define SECURITY_WEP_TX_ENABLE_SHIFT 1
25770 +#define SECURITY_WEP_RX_ENABLE_SHIFT 0
25771 +#define SECURITY_ENCRYP_104 1
25772 +#define SECURITY_ENCRYP_SHIFT 4
25773 +#define SECURITY_ENCRYP_MASK ((1<<4)|(1<<5))
25774 +#define KEY0 0x90 //1209 this is sth wrong
25775 +#define CONFIG2_ANTENNA_SHIFT 6
25776 +#define TX_BEACON_RING_ADDR 0x4c
25777 +#define CONFIG0_WEP40_SHIFT 7
25778 +#define CONFIG0_WEP104_SHIFT 6
25779 +#define AGCRESET_SHIFT 5
25784 + * Operational registers offsets in PCI (I/O) space.
25785 + * RealTek names are used.
25788 +#define IDR0 0x0000
25789 +#define IDR1 0x0001
25790 +#define IDR2 0x0002
25791 +#define IDR3 0x0003
25792 +#define IDR4 0x0004
25793 +#define IDR5 0x0005
25795 +/* 0x0006 - 0x0007 - reserved */
25797 +#define MAR0 0x0008
25798 +#define MAR1 0x0009
25799 +#define MAR2 0x000A
25800 +#define MAR3 0x000B
25801 +#define MAR4 0x000C
25802 +#define MAR5 0x000D
25803 +#define MAR6 0x000E
25804 +#define MAR7 0x000F
25806 +/* 0x0010 - 0x0017 - reserved */
25808 +#define TSFTR 0x0018
25809 +#define TSFTR_END 0x001F
25811 +#define TLPDA 0x0020
25812 +#define TLPDA_END 0x0023
25813 +#define TNPDA 0x0024
25814 +#define TNPDA_END 0x0027
25815 +#define THPDA 0x0028
25816 +#define THPDA_END 0x002B
25818 +#define BSSID 0x002E
25819 +#define BSSID_END 0x0033
25823 +#ifdef CONFIG_RTL8185B
25824 +#define RF_SW_CONFIG 0x8 // store data which is transmitted to RF for driver
25825 +#define RF_SW_CFG_SI BIT1
25826 +#define PIFS 0x2C // PCF InterFrame Spacing Timer Setting.
25827 +#define EIFS 0x2D // Extended InterFrame Space Timer, in unit of 4 us.
25829 +#define BRSR 0x34 // Basic rate set
25831 +#define IMR 0x006C
25832 +#define ISR 0x003C
25834 +#define BRSR 0x002C
25835 +#define BRSR_END 0x002D
25837 +/* 0x0034 - 0x0034 - reserved */
25838 +#define EIFS 0x0035
25840 +#define IMR 0x003C
25841 +#define IMR_END 0x003D
25842 +#define ISR 0x003E
25843 +#define ISR_END 0x003F
25846 +#define TCR 0x0040
25847 +#define TCR_END 0x0043
25849 +#define RCR 0x0044
25850 +#define RCR_END 0x0047
25852 +#define TimerInt 0x0048
25853 +#define TimerInt_END 0x004B
25855 +#define TBDA 0x004C
25856 +#define TBDA_END 0x004F
25858 +#define CR9346 0x0050
25860 +#define CONFIG0 0x0051
25861 +#define CONFIG1 0x0052
25862 +#define CONFIG2 0x0053
25864 +#define ANA_PARM 0x0054
25865 +#define ANA_PARM_END 0x0x0057
25867 +#define MSR 0x0058
25869 +#define CONFIG3 0x0059
25870 +#define CONFIG4 0x005A
25871 +#ifdef CONFIG_RTL8185B
25872 +#ifdef CONFIG_RTL818X_S
25873 + // SD3 szuyitasi: Mac0x57= CC -> B0 Mac0x60= D1 -> C6
25874 + // Mac0x60 = 0x000004C6 power save parameters
25875 + #define ANAPARM_ASIC_ON 0xB0054D00
25876 + #define ANAPARM2_ASIC_ON 0x000004C6
25878 + #define ANAPARM_ON ANAPARM_ASIC_ON
25879 + #define ANAPARM2_ON ANAPARM2_ASIC_ON
25882 + #define ANAPARM_ASIC_ON 0x45090658
25883 + #define ANAPARM2_ASIC_ON 0x727f3f52
25885 + #define ANAPARM_ON ANAPARM_ASIC_ON
25886 + #define ANAPARM2_ON ANAPARM2_ASIC_ON
25890 +#define TESTR 0x005B
25892 +/* 0x005C - 0x005D - reserved */
25894 +#define PSR 0x005E
25896 +/* 0x0060 - 0x006F - reserved */
25898 +#define BcnItv 0x0070
25899 +#define BcnItv_END 0x0071
25901 +#define AtimWnd 0x0072
25902 +#define AtimWnd_END 0x0073
25904 +#define BintrItv 0x0074
25905 +#define BintrItv_END 0x0075
25907 +#define AtimtrItv 0x0076
25908 +#define AtimtrItv_END 0x0077
25910 +#define PhyDelay 0x0078
25912 +#define CRCount 0x0079
25914 +/* 0x007A - 0x007B - reserved */
25916 +#define PhyAddr 0x007C
25917 +#define PhyDataW 0x007D
25918 +#define PhyDataR 0x007E
25920 +#define PhyCFG 0x0080
25921 +#define PhyCFG_END 0x0083
25923 +/* following are for rtl8185 */
25924 +#define RFPinsOutput 0x80
25925 +#define RFPinsEnable 0x82
25926 +#define RF_TIMING 0x8c
25927 +#define RFPinsSelect 0x84
25928 +#define ANAPARAM2 0x60
25929 +#define RF_PARA 0x88
25930 +#define RFPinsInput 0x86
25931 +#define GP_ENABLE 0x90
25933 +#define SW_CONTROL_GPIO 0x400
25934 +#define TX_ANTENNA 0x9f
25935 +#define TX_GAIN_OFDM 0x9e
25936 +#define TX_GAIN_CCK 0x9d
25937 +#define WPA_CONFIG 0xb0
25938 +#define TX_AGC_CTL 0x9c
25939 +#define TX_AGC_CTL_PERPACKET_GAIN_SHIFT 0
25940 +#define TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT 1
25941 +#define TX_AGC_CTL_FEEDBACK_ANT 2
25942 +#define RESP_RATE 0x34
25947 +#define CW_CONF 0xbc
25948 +#define CW_CONF_PERPACKET_RETRY_SHIFT 1
25949 +#define CW_CONF_PERPACKET_CW_SHIFT 0
25950 +#define CW_VAL 0xbd
25951 +#define MAX_RESP_RATE_SHIFT 4
25952 +#define MIN_RESP_RATE_SHIFT 0
25953 +#define RATE_FALLBACK 0xbe
25955 + * 0x0084 - 0x00D3 is selected to page 1 when PSEn bit (bit0, PSR)
25959 +#define Wakeup0 0x0084
25960 +#define Wakeup0_END 0x008B
25962 +#define Wakeup1 0x008C
25963 +#define Wakeup1_END 0x0093
25965 +#define Wakeup2LD 0x0094
25966 +#define Wakeup2LD_END 0x009B
25967 +#define Wakeup2HD 0x009C
25968 +#define Wakeup2HD_END 0x00A3
25970 +#define Wakeup3LD 0x00A4
25971 +#define Wakeup3LD_END 0x00AB
25972 +#define Wakeup3HD 0x00AC
25973 +#define Wakeup3HD_END 0x00B3
25975 +#define Wakeup4LD 0x00B4
25976 +#define Wakeup4LD_END 0x00BB
25977 +#define Wakeup4HD 0x00BC
25978 +#define Wakeup4HD_END 0x00C3
25980 +#define CRC0 0x00C4
25981 +#define CRC0_END 0x00C5
25982 +#define CRC1 0x00C6
25983 +#define CRC1_END 0x00C7
25984 +#define CRC2 0x00C8
25985 +#define CRC2_END 0x00C9
25986 +#define CRC3 0x00CA
25987 +#define CRC3_END 0x00CB
25988 +#define CRC4 0x00CC
25989 +#define CRC4_END 0x00CD
25991 +/* 0x00CE - 0x00D3 - reserved */
25996 + * 0x0084 - 0x00D3 is selected to page 0 when PSEn bit (bit0, PSR)
26000 +/* 0x0084 - 0x008F - reserved */
26002 +#define DK0 0x0090
26003 +#define DK0_END 0x009F
26004 +#define DK1 0x00A0
26005 +#define DK1_END 0x00AF
26006 +#define DK2 0x00B0
26007 +#define DK2_END 0x00BF
26008 +#define DK3 0x00C0
26009 +#define DK3_END 0x00CF
26011 +/* 0x00D0 - 0x00D3 - reserved */
26017 +/* 0x00D4 - 0x00D7 - reserved */
26019 +#define CONFIG5 0x00D8
26021 +#define TPPoll 0x00D9
26023 +/* 0x00DA - 0x00DB - reserved */
26025 +#ifdef CONFIG_RTL818X_S
26026 +#define PHYPR 0xDA //0xDA - 0x0B PHY Parameter Register.
26029 +#define CWR 0x00DC
26030 +#define CWR_END 0x00DD
26032 +#define RetryCTR 0x00DE
26034 +/* 0x00DF - 0x00E3 - reserved */
26036 +#define RDSAR 0x00E4
26037 +#define RDSAR_END 0x00E7
26039 +/* 0x00E8 - 0x00EF - reserved */
26040 +#ifdef CONFIG_RTL818X_S
26041 +#define LED_CONTROL 0xED
26044 +#define FER 0x00F0
26045 +#define FER_END 0x00F3
26047 +#ifdef CONFIG_RTL8185B
26048 +#define FEMR 0x1D4 // Function Event Mask register
26050 +#define FEMR 0x00F4
26051 +#define FEMR_END 0x00F7
26054 +#define FPSR 0x00F8
26055 +#define FPSR_END 0x00FB
26057 +#define FFER 0x00FC
26058 +#define FFER_END 0x00FF
26063 + * Bitmasks for specific register functions.
26064 + * Names are derived from the register name and function name.
26066 + * <REGISTER>_<FUNCTION>[<bit>]
26068 + * this leads to some awkward names...
26071 +#define BRSR_BPLCP ((1<< 8))
26072 +#define BRSR_MBR ((1<< 1)|(1<< 0))
26073 +#define BRSR_MBR_8185 ((1<< 11)|(1<< 10)|(1<< 9)|(1<< 8)|(1<< 7)|(1<< 6)|(1<< 5)|(1<< 4)|(1<< 3)|(1<< 2)|(1<< 1)|(1<< 0))
26074 +#define BRSR_MBR0 ((1<< 0))
26075 +#define BRSR_MBR1 ((1<< 1))
26077 +#define CR_RST ((1<< 4))
26078 +#define CR_RE ((1<< 3))
26079 +#define CR_TE ((1<< 2))
26080 +#define CR_MulRW ((1<< 0))
26082 +#ifdef CONFIG_RTL8185B
26083 +#define IMR_Dot11hInt ((1<< 25)) // 802.11h Measurement Interrupt
26084 +#define IMR_BcnDmaInt ((1<< 24)) // Beacon DMA Interrupt // What differenct between BcnDmaInt and BcnInt???
26085 +#define IMR_WakeInt ((1<< 23)) // Wake Up Interrupt
26086 +#define IMR_TXFOVW ((1<< 22)) // Tx FIFO Overflow Interrupt
26087 +#define IMR_TimeOut1 ((1<< 21)) // Time Out Interrupt 1
26088 +#define IMR_BcnInt ((1<< 20)) // Beacon Time out Interrupt
26089 +#define IMR_ATIMInt ((1<< 19)) // ATIM Time Out Interrupt
26090 +#define IMR_TBDER ((1<< 18)) // Tx Beacon Descriptor Error Interrupt
26091 +#define IMR_TBDOK ((1<< 17)) // Tx Beacon Descriptor OK Interrupt
26092 +#define IMR_THPDER ((1<< 16)) // Tx High Priority Descriptor Error Interrupt
26093 +#define IMR_THPDOK ((1<< 15)) // Tx High Priority Descriptor OK Interrupt
26094 +#define IMR_TVODER ((1<< 14)) // Tx AC_VO Descriptor Error Interrupt
26095 +#define IMR_TVODOK ((1<< 13)) // Tx AC_VO Descriptor OK Interrupt
26096 +#define IMR_FOVW ((1<< 12)) // Rx FIFO Overflow Interrupt
26097 +#define IMR_RDU ((1<< 11)) // Rx Descriptor Unavailable Interrupt
26098 +#define IMR_TVIDER ((1<< 10)) // Tx AC_VI Descriptor Error Interrupt
26099 +#define IMR_TVIDOK ((1<< 9)) // Tx AC_VI Descriptor OK Interrupt
26100 +#define IMR_RER ((1<< 8)) // Rx Error Interrupt
26101 +#define IMR_ROK ((1<< 7)) // Receive OK Interrupt
26102 +#define IMR_TBEDER ((1<< 6)) // Tx AC_BE Descriptor Error Interrupt
26103 +#define IMR_TBEDOK ((1<< 5)) // Tx AC_BE Descriptor OK Interrupt
26104 +#define IMR_TBKDER ((1<< 4)) // Tx AC_BK Descriptor Error Interrupt
26105 +#define IMR_TBKDOK ((1<< 3)) // Tx AC_BK Descriptor OK Interrupt
26106 +#define IMR_RQoSOK ((1<< 2)) // Rx QoS OK Interrupt
26107 +#define IMR_TimeOut2 ((1<< 1)) // Time Out Interrupt 2
26108 +#define IMR_TimeOut3 ((1<< 0)) // Time Out Interrupt 3
26109 +#define IMR_TMGDOK ((1<<30))
26110 +#define ISR_Dot11hInt ((1<< 25)) // 802.11h Measurement Interrupt
26111 +#define ISR_BcnDmaInt ((1<< 24)) // Beacon DMA Interrupt // What differenct between BcnDmaInt and BcnInt???
26112 +#define ISR_WakeInt ((1<< 23)) // Wake Up Interrupt
26113 +#define ISR_TXFOVW ((1<< 22)) // Tx FIFO Overflow Interrupt
26114 +#define ISR_TimeOut1 ((1<< 21)) // Time Out Interrupt 1
26115 +#define ISR_BcnInt ((1<< 20)) // Beacon Time out Interrupt
26116 +#define ISR_ATIMInt ((1<< 19)) // ATIM Time Out Interrupt
26117 +#define ISR_TBDER ((1<< 18)) // Tx Beacon Descriptor Error Interrupt
26118 +#define ISR_TBDOK ((1<< 17)) // Tx Beacon Descriptor OK Interrupt
26119 +#define ISR_THPDER ((1<< 16)) // Tx High Priority Descriptor Error Interrupt
26120 +#define ISR_THPDOK ((1<< 15)) // Tx High Priority Descriptor OK Interrupt
26121 +#define ISR_TVODER ((1<< 14)) // Tx AC_VO Descriptor Error Interrupt
26122 +#define ISR_TVODOK ((1<< 13)) // Tx AC_VO Descriptor OK Interrupt
26123 +#define ISR_FOVW ((1<< 12)) // Rx FIFO Overflow Interrupt
26124 +#define ISR_RDU ((1<< 11)) // Rx Descriptor Unavailable Interrupt
26125 +#define ISR_TVIDER ((1<< 10)) // Tx AC_VI Descriptor Error Interrupt
26126 +#define ISR_TVIDOK ((1<< 9)) // Tx AC_VI Descriptor OK Interrupt
26127 +#define ISR_RER ((1<< 8)) // Rx Error Interrupt
26128 +#define ISR_ROK ((1<< 7)) // Receive OK Interrupt
26129 +#define ISR_TBEDER ((1<< 6)) // Tx AC_BE Descriptor Error Interrupt
26130 +#define ISR_TBEDOK ((1<< 5)) // Tx AC_BE Descriptor OK Interrupt
26131 +#define ISR_TBKDER ((1<< 4)) // Tx AC_BK Descriptor Error Interrupt
26132 +#define ISR_TBKDOK ((1<< 3)) // Tx AC_BK Descriptor OK Interrupt
26133 +#define ISR_RQoSOK ((1<< 2)) // Rx QoS OK Interrupt
26134 +#define ISR_TimeOut2 ((1<< 1)) // Time Out Interrupt 2
26135 +#define ISR_TimeOut3 ((1<< 0)) // Time Out Interrupt 3
26137 +//these definition is used for Tx/Rx test temporarily
26138 +#define ISR_TLPDER ISR_TVIDER
26139 +#define ISR_TLPDOK ISR_TVIDOK
26140 +#define ISR_TNPDER ISR_TVODER
26141 +#define ISR_TNPDOK ISR_TVODOK
26142 +#define ISR_TimeOut ISR_TimeOut1
26143 +#define ISR_RXFOVW ISR_FOVW
26146 +#define IMR_TXFOVW ((1<<15))
26147 +#define IMR_TimeOut ((1<<14))
26148 +#define IMR_BcnInt ((1<<13))
26149 +#define IMR_ATIMInt ((1<<12))
26150 +#define IMR_TBDER ((1<<11))
26151 +#define IMR_TBDOK ((1<<10))
26152 +#define IMR_THPDER ((1<< 9))
26153 +#define IMR_THPDOK ((1<< 8))
26154 +#define IMR_TNPDER ((1<< 7))
26155 +#define IMR_TNPDOK ((1<< 6))
26156 +#define IMR_RXFOVW ((1<< 5))
26157 +#define IMR_RDU ((1<< 4))
26158 +#define IMR_TLPDER ((1<< 3))
26159 +#define IMR_TLPDOK ((1<< 2))
26160 +#define IMR_RER ((1<< 1))
26161 +#define IMR_ROK ((1<< 0))
26163 +#define ISR_TXFOVW ((1<<15))
26164 +#define ISR_TimeOut ((1<<14))
26165 +#define ISR_BcnInt ((1<<13))
26166 +#define ISR_ATIMInt ((1<<12))
26167 +#define ISR_TBDER ((1<<11))
26168 +#define ISR_TBDOK ((1<<10))
26169 +#define ISR_THPDER ((1<< 9))
26170 +#define ISR_THPDOK ((1<< 8))
26171 +#define ISR_TNPDER ((1<< 7))
26172 +#define ISR_TNPDOK ((1<< 6))
26173 +#define ISR_RXFOVW ((1<< 5))
26174 +#define ISR_RDU ((1<< 4))
26175 +#define ISR_TLPDER ((1<< 3))
26176 +#define ISR_TLPDOK ((1<< 2))
26177 +#define ISR_RER ((1<< 1))
26178 +#define ISR_ROK ((1<< 0))
26181 +#define HW_VERID_R8180_F 3
26182 +#define HW_VERID_R8180_ABCD 2
26183 +#define HW_VERID_R8185_ABC 4
26184 +#define HW_VERID_R8185_D 5
26185 +#ifdef CONFIG_RTL8185B
26186 +#define HW_VERID_R8185B_B 6
26189 +#define TCR_CWMIN ((1<<31))
26190 +#define TCR_SWSEQ ((1<<30))
26191 +#define TCR_HWVERID_MASK ((1<<27)|(1<<26)|(1<<25))
26192 +#define TCR_HWVERID_SHIFT 25
26193 +#define TCR_SAT ((1<<24))
26194 +#define TCR_PLCP_LEN TCR_SAT // rtl8180
26195 +#define TCR_MXDMA_MASK ((1<<23)|(1<<22)|(1<<21))
26196 +#define TCR_MXDMA_1024 6
26197 +#define TCR_MXDMA_2048 7
26198 +#define TCR_MXDMA_SHIFT 21
26199 +#define TCR_DISCW ((1<<20))
26200 +#define TCR_ICV ((1<<19))
26201 +#define TCR_LBK ((1<<18)|(1<<17))
26202 +#define TCR_LBK1 ((1<<18))
26203 +#define TCR_LBK0 ((1<<17))
26204 +#define TCR_CRC ((1<<16))
26205 +#define TCR_DPRETRY_MASK ((1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8))
26206 +#define TCR_RTSRETRY_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7))
26207 +#define TCR_PROBE_NOTIMESTAMP_SHIFT 29 //rtl8185
26209 +#define RCR_ONLYERLPKT ((1<<31))
26210 +#define RCR_CS_SHIFT 29
26211 +#define RCR_CS_MASK ((1<<30) | (1<<29))
26212 +#define RCR_ENMARP ((1<<28))
26213 +#define RCR_CBSSID ((1<<23))
26214 +#define RCR_APWRMGT ((1<<22))
26215 +#define RCR_ADD3 ((1<<21))
26216 +#define RCR_AMF ((1<<20))
26217 +#define RCR_ACF ((1<<19))
26218 +#define RCR_ADF ((1<<18))
26219 +#define RCR_RXFTH ((1<<15)|(1<<14)|(1<<13))
26220 +#define RCR_RXFTH2 ((1<<15))
26221 +#define RCR_RXFTH1 ((1<<14))
26222 +#define RCR_RXFTH0 ((1<<13))
26223 +#define RCR_AICV ((1<<12))
26224 +#define RCR_MXDMA ((1<<10)|(1<< 9)|(1<< 8))
26225 +#define RCR_MXDMA2 ((1<<10))
26226 +#define RCR_MXDMA1 ((1<< 9))
26227 +#define RCR_MXDMA0 ((1<< 8))
26228 +#define RCR_9356SEL ((1<< 6))
26229 +#define RCR_ACRC32 ((1<< 5))
26230 +#define RCR_AB ((1<< 3))
26231 +#define RCR_AM ((1<< 2))
26232 +#define RCR_APM ((1<< 1))
26233 +#define RCR_AAP ((1<< 0))
26235 +#define CR9346_EEM ((1<<7)|(1<<6))
26236 +#define CR9346_EEM1 ((1<<7))
26237 +#define CR9346_EEM0 ((1<<6))
26238 +#define CR9346_EECS ((1<<3))
26239 +#define CR9346_EESK ((1<<2))
26240 +#define CR9346_EED1 ((1<<1))
26241 +#define CR9346_EED0 ((1<<0))
26243 +#define CONFIG0_WEP104 ((1<<6))
26244 +#define CONFIG0_LEDGPO_En ((1<<4))
26245 +#define CONFIG0_Aux_Status ((1<<3))
26246 +#define CONFIG0_GL ((1<<1)|(1<<0))
26247 +#define CONFIG0_GL1 ((1<<1))
26248 +#define CONFIG0_GL0 ((1<<0))
26250 +#define CONFIG1_LEDS ((1<<7)|(1<<6))
26251 +#define CONFIG1_LEDS1 ((1<<7))
26252 +#define CONFIG1_LEDS0 ((1<<6))
26253 +#define CONFIG1_LWACT ((1<<4))
26254 +#define CONFIG1_MEMMAP ((1<<3))
26255 +#define CONFIG1_IOMAP ((1<<2))
26256 +#define CONFIG1_VPD ((1<<1))
26257 +#define CONFIG1_PMEn ((1<<0))
26259 +#define CONFIG2_LCK ((1<<7))
26260 +#define CONFIG2_ANT ((1<<6))
26261 +#define CONFIG2_DPS ((1<<3))
26262 +#define CONFIG2_PAPE_sign ((1<<2))
26263 +#define CONFIG2_PAPE_time ((1<<1)|(1<<0))
26264 +#define CONFIG2_PAPE_time1 ((1<<1))
26265 +#define CONFIG2_PAPE_time0 ((1<<0))
26267 +#define CONFIG3_GNTSel ((1<<7))
26268 +#define CONFIG3_PARM_En ((1<<6))
26269 +#define CONFIG3_Magic ((1<<5))
26270 +#define CONFIG3_CardB_En ((1<<3))
26271 +#define CONFIG3_CLKRUN_En ((1<<2))
26272 +#define CONFIG3_FuncRegEn ((1<<1))
26273 +#define CONFIG3_FBtbEn ((1<<0))
26275 +#define CONFIG4_VCOPDN ((1<<7))
26276 +#define CONFIG4_PWROFF ((1<<6))
26277 +#define CONFIG4_PWRMGT ((1<<5))
26278 +#define CONFIG4_LWPME ((1<<4))
26279 +#define CONFIG4_LWPTN ((1<<2))
26280 +#define CONFIG4_RFTYPE ((1<<1)|(1<<0))
26281 +#define CONFIG4_RFTYPE1 ((1<<1))
26282 +#define CONFIG4_RFTYPE0 ((1<<0))
26284 +#define CONFIG5_TX_FIFO_OK ((1<<7))
26285 +#define CONFIG5_RX_FIFO_OK ((1<<6))
26286 +#define CONFIG5_CALON ((1<<5))
26287 +#define CONFIG5_EACPI ((1<<2))
26288 +#define CONFIG5_LANWake ((1<<1))
26289 +#define CONFIG5_PME_STS ((1<<0))
26291 +#define MSR_LINK_MASK ((1<<2)|(1<<3))
26292 +#define MSR_LINK_MANAGED 2
26293 +#define MSR_LINK_NONE 0
26294 +#define MSR_LINK_SHIFT 2
26295 +#define MSR_LINK_ADHOC 1
26296 +#define MSR_LINK_MASTER 3
26298 +#define PSR_GPO ((1<<7))
26299 +#define PSR_GPI ((1<<6))
26300 +#define PSR_LEDGPO1 ((1<<5))
26301 +#define PSR_LEDGPO0 ((1<<4))
26302 +#define PSR_UWF ((1<<1))
26303 +#define PSR_PSEn ((1<<0))
26305 +#define SCR_KM ((1<<5)|(1<<4))
26306 +#define SCR_KM1 ((1<<5))
26307 +#define SCR_KM0 ((1<<4))
26308 +#define SCR_TXSECON ((1<<1))
26309 +#define SCR_RXSECON ((1<<0))
26311 +#define BcnItv_BcnItv (0x01FF)
26313 +#define AtimWnd_AtimWnd (0x01FF)
26315 +#define BintrItv_BintrItv (0x01FF)
26317 +#define AtimtrItv_AtimtrItv (0x01FF)
26319 +#define PhyDelay_PhyDelay ((1<<2)|(1<<1)|(1<<0))
26321 +#define TPPoll_BQ ((1<<7))
26322 +#define TPPoll_HPQ ((1<<6))
26323 +#define TPPoll_NPQ ((1<<5))
26324 +#define TPPoll_LPQ ((1<<4))
26325 +#define TPPoll_SBQ ((1<<3))
26326 +#define TPPoll_SHPQ ((1<<2))
26327 +#define TPPoll_SNPQ ((1<<1))
26328 +#define TPPoll_SLPQ ((1<<0))
26330 +#define CWR_CW (0x01FF)
26332 +#define FER_INTR ((1<<15))
26333 +#define FER_GWAKE ((1<< 4))
26335 +#define FEMR_INTR ((1<<15))
26336 +#define FEMR_WKUP ((1<<14))
26337 +#define FEMR_GWAKE ((1<< 4))
26339 +#define FPSR_INTR ((1<<15))
26340 +#define FPSR_GWAKE ((1<< 4))
26342 +#define FFER_INTR ((1<<15))
26343 +#define FFER_GWAKE ((1<< 4))
26345 +#ifdef CONFIG_RTL8185B
26346 +// Three wire mode.
26347 +#define SW_THREE_WIRE 0
26348 +#define HW_THREE_WIRE 2
26350 +#define HW_THREE_WIRE_PI 5
26351 +#define HW_THREE_WIRE_SI 6
26353 +#define TCR_LRL_OFFSET 0
26354 +#define TCR_SRL_OFFSET 8
26355 +#define TCR_MXDMA_OFFSET 21
26356 +#define TCR_DISReqQsize_OFFSET 28
26357 +#define TCR_DurProcMode_OFFSET 30
26359 +#define RCR_MXDMA_OFFSET 8
26360 +#define RCR_FIFO_OFFSET 13
26362 +#define TMGDS 0x0C // Tx Management Descriptor Address
26363 +#define TBKDS 0x10 // Tx AC_BK Descriptor Address
26364 +#define TBEDS 0x14 // Tx AC_BE Descriptor Address
26365 +#define TLPDS 0x20 // Tx AC_VI Descriptor Address
26366 +#define TNPDS 0x24 // Tx AC_VO Descriptor Address
26367 +#define THPDS 0x28 // Tx Hign Priority Descriptor Address
26369 +#define TBDS 0x4c // Beacon descriptor queue start address
26371 +#define RDSA 0xE4 // Receive descriptor queue start address
26373 +#define AckTimeOutReg 0x79 // ACK timeout register, in unit of 4 us.
26375 +#define RFTiming 0x8C
26377 +#define TPPollStop 0x93
26379 +#define TXAGC_CTL 0x9C // <RJ_TODO_8185B> TX_AGC_CONTROL (0x9C seems be removed at 8185B, see p37).
26380 +#define CCK_TXAGC 0x9D
26381 +#define OFDM_TXAGC 0x9E
26382 +#define ANTSEL 0x9F
26384 +#define ACM_CONTROL 0x00BF // ACM Control Registe
26386 +#define RTL8185B_VER_REG 0xE1
26388 +#define IntMig 0xE2 // Interrupt Migration (0xE2 ~ 0xE3)
26390 +#define TID_AC_MAP 0xE8 // TID to AC Mapping Register
26392 +#define ANAPARAM3 0xEE // <RJ_TODO_8185B> How to use it?
26394 +#define AC_VO_PARAM 0xF0 // AC_VO Parameters Record
26395 +#define AC_VI_PARAM 0xF4 // AC_VI Parameters Record
26396 +#define AC_BE_PARAM 0xF8 // AC_BE Parameters Record
26397 +#define AC_BK_PARAM 0xFC // AC_BK Parameters Record
26399 +#ifdef CONFIG_RTL818X_S
26400 +#define BcnTimingAdjust 0x16A // Beacon Timing Adjust Register.
26401 +#define GPIOCtrl 0x16B // GPIO Control Register.
26402 +#define PSByGC 0x180 // 0x180 - 0x183 Power Saving by Gated Clock.
26404 +#define ARFR 0x1E0 // Auto Rate Fallback Register (0x1e0 ~ 0x1e2)
26406 +#define RFSW_CTRL 0x272 // 0x272-0x273.
26407 +#define SW_3W_DB0 0x274 // Software 3-wire data buffer bit 31~0.
26408 +#define SW_3W_DB1 0x278 // Software 3-wire data buffer bit 63~32.
26409 +#define SW_3W_CMD0 0x27C // Software 3-wire Control/Status Register.
26410 +#define SW_3W_CMD1 0x27D // Software 3-wire Control/Status Register.
26412 +#ifdef CONFIG_RTL818X_S
26413 +#define PI_DATA_READ 0X360 // 0x360 - 0x361 Parallel Interface Data Register.
26414 +#define SI_DATA_READ 0x362 // 0x362 - 0x363 Serial Interface Data Register.
26417 +//----------------------------------------------------------------------------
26418 +// 8185B TPPoll bits (offset 0xd9, 1 byte)
26419 +//----------------------------------------------------------------------------
26420 +#define TPPOLL_BQ (0x01 << 7)
26421 +#define TPPOLL_HPQ (0x01 << 6)
26422 +#define TPPOLL_AC_VOQ (0x01 << 5)
26423 +#define TPPOLL_AC_VIQ (0x01 << 4)
26424 +#define TPPOLL_AC_BEQ (0x01 << 3)
26425 +#define TPPOLL_AC_BKQ (0x01 << 2)
26426 +#define TPPOLL_AC_MGQ (0x01 << 1)
26428 +//----------------------------------------------------------------------------
26429 +// 8185B TPPollStop bits (offset 0x93, 1 byte)
26430 +//----------------------------------------------------------------------------
26431 +#define TPPOLLSTOP_BQ (0x01 << 7)
26432 +#define TPPOLLSTOP_HPQ (0x01 << 6)
26433 +#define TPPOLLSTOP_AC_VOQ (0x01 << 5)
26434 +#define TPPOLLSTOP_AC_VIQ (0x01 << 4)
26435 +#define TPPOLLSTOP_AC_BEQ (0x01 << 3)
26436 +#define TPPOLLSTOP_AC_BKQ (0x01 << 2)
26437 +#define TPPOLLSTOP_AC_MGQ (0x01 << 1)
26440 +#define MSR_LINK_ENEDCA (1<<4)
26442 +//----------------------------------------------------------------------------
26443 +// 8187B AC_XX_PARAM bits
26444 +//----------------------------------------------------------------------------
26445 +#define AC_PARAM_TXOP_LIMIT_OFFSET 16
26446 +#define AC_PARAM_ECW_MAX_OFFSET 12
26447 +#define AC_PARAM_ECW_MIN_OFFSET 8
26448 +#define AC_PARAM_AIFS_OFFSET 0
26450 +//----------------------------------------------------------------------------
26451 +// 8187B ACM_CONTROL bits (Offset 0xBF, 1 Byte)
26452 +//----------------------------------------------------------------------------
26453 +#define VOQ_ACM_EN (0x01 << 7) //BIT7
26454 +#define VIQ_ACM_EN (0x01 << 6) //BIT6
26455 +#define BEQ_ACM_EN (0x01 << 5) //BIT5
26456 +#define ACM_HW_EN (0x01 << 4) //BIT4
26457 +#define TXOPSEL (0x01 << 3) //BIT3
26458 +#define VOQ_ACM_CTL (0x01 << 2) //BIT2 // Set to 1 when AC_VO used time reaches or exceeds the admitted time
26459 +#define VIQ_ACM_CTL (0x01 << 1) //BIT1 // Set to 1 when AC_VI used time reaches or exceeds the admitted time
26460 +#define BEQ_ACM_CTL (0x01 << 0) //BIT0 // Set to 1 when AC_BE used time reaches or exceeds the admitted time
26463 +//----------------------------------------------------------------------------
26464 +// 8185B SW_3W_CMD bits (Offset 0x27C-0x27D, 16bit)
26465 +//----------------------------------------------------------------------------
26466 +#define SW_3W_CMD0_HOLD ((1<< 7))
26467 +#define SW_3W_CMD1_RE ((1<< 0)) // BIT8
26468 +#define SW_3W_CMD1_WE ((1<< 1)) // BIT9
26469 +#define SW_3W_CMD1_DONE ((1<< 2)) // BIT10
26471 +#define BB_HOST_BANG_RW (1<<3)
26473 +//----------------------------------------------------------------------------
26474 +// 8185B RATE_FALLBACK_CTL bits (Offset 0xBE, 8bit)
26475 +//----------------------------------------------------------------------------
26476 +#define RATE_FALLBACK_CTL_ENABLE ((1<< 7))
26477 +#define RATE_FALLBACK_CTL_ENABLE_RTSCTS ((1<< 6))
26478 +// Auto rate fallback per 2^n retry.
26479 +#define RATE_FALLBACK_CTL_AUTO_STEP0 0x00
26480 +#define RATE_FALLBACK_CTL_AUTO_STEP1 0x01
26481 +#define RATE_FALLBACK_CTL_AUTO_STEP2 0x02
26482 +#define RATE_FALLBACK_CTL_AUTO_STEP3 0x03
26485 +#define RTL8225z2_ANAPARAM_OFF 0x55480658
26486 +#define RTL8225z2_ANAPARAM2_OFF 0x72003f70
26487 +//by amy for power save
26488 +#define RF_CHANGE_BY_SW BIT31
26489 +#define RF_CHANGE_BY_HW BIT30
26490 +#define RF_CHANGE_BY_PS BIT29
26491 +#define RF_CHANGE_BY_IPS BIT28
26492 +//by amy for power save
26493 +//by amy for antenna
26494 +#define EEPROM_SW_REVD_OFFSET 0x3f
26495 +// BIT[8-9] is for SW Antenna Diversity. Only the value EEPROM_SW_AD_ENABLE means enable, other values are diable.
26496 +#define EEPROM_SW_AD_MASK 0x0300
26497 +#define EEPROM_SW_AD_ENABLE 0x0100
26499 +// BIT[10-11] determine if Antenna 1 is the Default Antenna. Only the value EEPROM_DEF_ANT_1 means TRUE, other values are FALSE.
26500 +#define EEPROM_DEF_ANT_MASK 0x0C00
26501 +#define EEPROM_DEF_ANT_1 0x0400
26502 +//by amy for antenna
26504 +//0x7C, 0x7D Crystal calibration and Tx Power tracking mechanism. Added by Roger. 2007.12.10.
26505 +#define EEPROM_RSV 0x7C
26506 +#define EEPROM_XTAL_CAL_MASK 0x00FF // 0x7C[7:0], Crystal calibration mask.
26507 +#define EEPROM_XTAL_CAL_XOUT_MASK 0x0F // 0x7C[3:0], Crystal calibration for Xout.
26508 +#define EEPROM_XTAL_CAL_XIN_MASK 0xF0 // 0x7C[7:4], Crystal calibration for Xin.
26509 +#define EEPROM_THERMAL_METER_MASK 0x0F00 // 0x7D[3:0], Thermal meter reference level.
26510 +#define EEPROM_XTAL_CAL_ENABLE 0x1000 // 0x7D[4], Crystal calibration enabled/disabled BIT.
26511 +#define EEPROM_THERMAL_METER_ENABLE 0x2000 // 0x7D[5], Thermal meter enabled/disabled BIT.
26512 +#define EEPROM_CID_RSVD1 0x3F
26513 +#define EN_LPF_CAL 0x238 // Enable LPF Calibration.
26514 +#define PWR_METER_EN BIT1
26515 +// <RJ_TODO_8185B> where are false alarm counters in 8185B?
26516 +#define CCK_FALSE_ALARM 0xD0
26517 +#define OFDM_FALSE_ALARM 0xD2
26520 +//YJ,add for Country IE, 080630
26521 +#define EEPROM_COUNTRY_CODE 0x2E
26522 +//YJ,add,080630,end
26527 +++ b/drivers/staging/rtl8187se/r8180_max2820.c
26530 + This files contains MAXIM MAX2820 radio frontend programming routines.
26532 + This is part of rtl8180 OpenSource driver
26533 + Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
26534 + Released under the terms of GPL (General Public Licence)
26536 + Parts of this driver are based on the GPL part of the
26537 + official realtek driver
26539 + Parts of this driver are based on the rtl8180 driver skeleton
26540 + from Patric Schenke & Andres Salomon
26542 + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
26544 + NetBSD rtl8180 driver from Dave Young has been really useful to
26545 + understand how to program the MAXIM radio. Thanks a lot!!!
26547 + 'The Deuce' tested this and fixed some bugs.
26549 + Code from rtl8181 project has been useful to me to understand some things.
26551 + We want to tanks the Authors of such projects and the Ndiswrapper
26556 +#include "r8180.h"
26557 +#include "r8180_hw.h"
26558 +#include "r8180_max2820.h"
26561 +//#define DEBUG_MAXIM
26563 +u32 maxim_chan[] = {
26564 + 0, //dummy channel 0
26582 +/* maxim expects 4 bit address MSF, then 12 bit data MSF*/
26583 +void write_maxim(struct net_device *dev,u8 adr, u32 data)
26591 + word = (u16)data & 0xfff;
26592 + word |= (adr<<12);
26593 + /*write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | BB_HOST_BANG_EN);
26594 + read_nic_dword(dev,PHY_CONFIG);
26597 + write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | BB_HOST_BANG_EN | BB_HOST_BANG_CLK);
26598 + read_nic_dword(dev,PHY_CONFIG);
26602 + /* MAX2820 will sample data on rising edge of clock */
26603 + for(shift = 15;shift >=0; shift--){
26604 + bit = word>>shift & 1;
26606 + write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | (bit<<BB_HOST_BANG_DATA));
26608 + read_nic_dword(dev,PHY_CONFIG);
26611 + write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG |
26612 + (bit<<BB_HOST_BANG_DATA) | BB_HOST_BANG_CLK); /* sample data */
26614 + read_nic_dword(dev,PHY_CONFIG);
26617 + write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG |
26618 + (bit<<BB_HOST_BANG_DATA));
26620 + read_nic_dword(dev,PHY_CONFIG);
26624 + write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | (bit<<BB_HOST_BANG_DATA)|
26625 + BB_HOST_BANG_EN);
26626 + read_nic_dword(dev,PHY_CONFIG);
26629 + /* The shift register fill flush to the requested register the
26630 + * last 12 bits data shifted in
26632 + write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | (bit<<BB_HOST_BANG_DATA)|
26633 + BB_HOST_BANG_EN | BB_HOST_BANG_CLK);
26634 + read_nic_dword(dev,PHY_CONFIG);
26637 + write_nic_dword(dev,PHY_CONFIG,BB_HOST_BANG | (bit<<BB_HOST_BANG_DATA)|
26638 + BB_HOST_BANG_EN);
26639 + read_nic_dword(dev,PHY_CONFIG);
26643 +#ifdef DEBUG_MAXIM
26644 + DMESG("Writing maxim: %x (adr %x)",phy_config,adr);
26650 +void write_maxim(struct net_device *dev,u8 adr, u32 data) {
26652 + temp = 0x90 + (data & 0xf);
26656 + temp += (data >> 4) & 0xff;
26657 +#ifdef DEBUG_MAXIM
26658 + DMESG("write_maxim: %08x", temp);
26660 + write_nic_dword(dev, PHY_CONFIG, temp);
26661 + force_pci_posting(dev);
26666 +void maxim_write_phy_antenna(struct net_device *dev,short ch)
26668 + struct r8180_priv *priv = ieee80211_priv(dev);
26671 + ant = MAXIM_ANTENNA;
26672 + if(priv->antb) /*default antenna is antenna B */
26673 + ant |= BB_ANTENNA_B;
26675 + ant |= BB_ANTATTEN_CHAN14;
26676 + write_phy(dev,0x10,ant);
26677 + //DMESG("BB antenna %x ",ant);
26681 +void maxim_rf_set_chan(struct net_device *dev, short ch)
26683 + struct r8180_priv *priv = ieee80211_priv(dev);
26684 + u32 txpw = 0xff & priv->chtxpwr[ch];
26685 + u32 chan = maxim_chan[ch];
26687 + /*While philips SA2400 drive the PA bias
26688 + *seems that for MAXIM we delegate this
26692 + //write_maxim(dev,5,txpw);
26693 + write_phy(dev,3,txpw);
26695 + maxim_write_phy_antenna(dev,ch);
26696 + write_maxim(dev,3,chan);
26700 +void maxim_rf_close(struct net_device *dev)
26702 + write_phy(dev, 3, 0x8);
26703 + write_maxim(dev, 1, 0);
26707 +void maxim_rf_init(struct net_device *dev)
26709 + struct r8180_priv *priv = ieee80211_priv(dev);
26712 + write_nic_byte(dev,PHY_DELAY,0x6); //this is general
26713 + write_nic_byte(dev,CARRIER_SENSE_COUNTER,0x4c); //this is general
26715 + /*these are maxim specific*/
26716 + anaparam = read_nic_dword(dev,ANAPARAM);
26717 + anaparam = anaparam &~ (ANAPARAM_TXDACOFF_SHIFT);
26718 + anaparam = anaparam &~ANAPARAM_PWR1_MASK;
26719 + anaparam = anaparam &~ANAPARAM_PWR0_MASK;
26720 + anaparam |= (MAXIM_ANAPARAM_PWR1_ON<<ANAPARAM_PWR1_SHIFT);
26721 + anaparam |= (MAXIM_ANAPARAM_PWR0_ON<<ANAPARAM_PWR0_SHIFT);
26723 + //rtl8180_set_anaparam(dev,anaparam);
26725 + /* MAXIM from netbsd driver */
26727 + write_maxim(dev,0, 7); /* test mode as indicated in datasheet*/
26728 + write_maxim(dev,1, 0x1e); /* enable register*/
26729 + write_maxim(dev,2, 1); /* synt register */
26732 + maxim_rf_set_chan(dev,priv->chan);
26734 + write_maxim(dev,4, 0x313); /* rx register*/
26736 + /* PA is driven directly by the BB, we keep the MAXIM bias
26737 + * at the highest value in the boubt tha pleacing it to lower
26738 + * values may introduce some further attenuation somewhere..
26741 + write_maxim(dev,5, 0xf);
26744 + /*baseband configuration*/
26745 + write_phy(dev,0,0x88); //sys1
26746 + write_phy(dev,3,0x8); //txagc
26747 + write_phy(dev,4,0xf8); // lnadet
26748 + write_phy(dev,5,0x90); // ifagcinit
26749 + write_phy(dev,6,0x1a); // ifagclimit
26750 + write_phy(dev,7,0x64); // ifagcdet
26752 + /*Should be done something more here??*/
26754 + maxim_write_phy_antenna(dev,priv->chan);
26756 + write_phy(dev,0x11,0x88); //trl
26757 + if(priv->diversity)
26758 + write_phy(dev,0x12,0xc7);
26760 + write_phy(dev,0x12,0x47);
26762 + write_phy(dev,0x13,0x9b);
26764 + write_phy(dev,0x19,0x0); //CHESTLIM
26765 + write_phy(dev,0x1a,0x9f); //CHSQLIM
26767 + maxim_rf_set_chan(dev,priv->chan);
26770 +++ b/drivers/staging/rtl8187se/r8180_max2820.h
26773 + This is part of rtl8180 OpenSource driver
26774 + Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
26775 + Released under the terms of GPL (General Public Licence)
26777 + Parts of this driver are based on the GPL part of the official realtek driver
26778 + Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
26779 + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
26781 + We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
26784 +#define MAXIM_ANTENNA 0xb3
26785 +#define MAXIM_ANAPARAM_PWR1_ON 0x8
26786 +#define MAXIM_ANAPARAM_PWR0_ON 0x0
26789 +void maxim_rf_init(struct net_device *dev);
26790 +void maxim_rf_set_chan(struct net_device *dev,short ch);
26792 +void maxim_rf_close(struct net_device *dev);
26794 +++ b/drivers/staging/rtl8187se/r8180_pm.c
26797 + Power management interface routines.
26798 + Written by Mariusz Matuszek.
26799 + This code is currently just a placeholder for later work and
26800 + does not do anything useful.
26802 + This is part of rtl8180 OpenSource driver.
26803 + Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
26804 + Released under the terms of GPL (General Public Licence)
26807 +#ifdef CONFIG_RTL8180_PM
26810 +#include "r8180_hw.h"
26811 +#include "r8180_pm.h"
26812 +#include "r8180.h"
26814 +int rtl8180_save_state (struct pci_dev *dev, u32 state)
26816 + printk(KERN_NOTICE "r8180 save state call (state %u).\n", state);
26820 +int rtl8180_suspend (struct pci_dev *pdev, pm_message_t state)
26822 + struct net_device *dev = pci_get_drvdata(pdev);
26823 +// struct r8180_priv *priv = ieee80211_priv(dev);
26825 + if (!netif_running(dev))
26826 + goto out_pci_suspend;
26830 + netif_device_detach(dev);
26833 + pci_save_state(pdev);
26834 + pci_disable_device(pdev);
26835 + pci_set_power_state(pdev,pci_choose_state(pdev,state));
26839 +int rtl8180_resume (struct pci_dev *pdev)
26841 + struct net_device *dev = pci_get_drvdata(pdev);
26842 +// struct r8180_priv *priv = ieee80211_priv(dev);
26846 + pci_set_power_state(pdev, PCI_D0);
26848 + err = pci_enable_device(pdev);
26850 + printk(KERN_ERR "%s: pci_enable_device failed on resume\n",
26855 + pci_restore_state(pdev);
26857 + * Suspend/Resume resets the PCI configuration space, so we have to
26858 + * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
26859 + * from interfering with C3 CPU state. pci_restore_state won't help
26860 + * here since it only restores the first 64 bytes pci config header.
26862 + pci_read_config_dword(pdev, 0x40, &val);
26863 + if ((val & 0x0000ff00) != 0)
26864 + pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
26866 + if(!netif_running(dev))
26870 + netif_device_attach(dev);
26876 +int rtl8180_enable_wake (struct pci_dev *dev, u32 state, int enable)
26878 + printk(KERN_NOTICE "r8180 enable wake call (state %u, enable %d).\n",
26885 +#endif //CONFIG_RTL8180_PM
26887 +++ b/drivers/staging/rtl8187se/r8180_pm.h
26890 + Power management interface routines.
26891 + Written by Mariusz Matuszek.
26892 + This code is currently just a placeholder for later work and
26893 + does not do anything useful.
26895 + This is part of rtl8180 OpenSource driver.
26896 + Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
26897 + Released under the terms of GPL (General Public Licence)
26901 +#ifdef CONFIG_RTL8180_PM
26903 +#ifndef R8180_PM_H
26904 +#define R8180_PM_H
26906 +#include <linux/types.h>
26907 +#include <linux/pci.h>
26909 +int rtl8180_save_state (struct pci_dev *dev, u32 state);
26910 +int rtl8180_suspend (struct pci_dev *pdev, pm_message_t state);
26911 +int rtl8180_resume (struct pci_dev *pdev);
26912 +int rtl8180_enable_wake (struct pci_dev *dev, u32 state, int enable);
26914 +#endif //R8180_PM_H
26916 +#endif // CONFIG_RTL8180_PM
26918 +++ b/drivers/staging/rtl8187se/r8180_rtl8225.c
26921 + This is part of the rtl8180-sa2400 driver
26922 + released under the GPL (See file COPYING for details).
26923 + Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
26925 + This files contains programming code for the rtl8225
26928 + *Many* thanks to Realtek Corp. for their great support!
26934 +#include "r8180_hw.h"
26935 +#include "r8180_rtl8225.h"
26938 +u8 rtl8225_gain[]={
26939 + 0x23,0x88,0x7c,0xa5,// -82dbm
26940 + 0x23,0x88,0x7c,0xb5,// -82dbm
26941 + 0x23,0x88,0x7c,0xc5,// -82dbm
26942 + 0x33,0x80,0x79,0xc5,// -78dbm
26943 + 0x43,0x78,0x76,0xc5,// -74dbm
26944 + 0x53,0x60,0x73,0xc5,// -70dbm
26945 + 0x63,0x58,0x70,0xc5,// -66dbm
26949 +u8 rtl8225_init_gain[]={
26950 + //0x00,0x00,0x00,0x00,//0x00,0x00,0x00,0x00,
26951 + 0x33,0x80,0x6c,0xc5,//0x00,0x49,0x06,0xb5,//Gain = 0 ~ -78dbm
26952 + 0x43,0x78,0x69,0xc5,//0x00,0x45,0x06,0xb1,//Gain = 1 ~ -74dbm
26953 + 0x53,0x60,0x66,0xc5,//0x00,0x41,0x06,0xab,//Gain = 2 ~ -70dbm
26954 + 0x63,0x58,0x63,0xc5,//0x00,0x3d,0x06,0xa5,//Gain = 3 ~ -66dbm
26955 + 0x73,0x50,0x62,0xc5,//0x00,0x39,0x06,0xa1,//Gain = 4 ~ -62dbm
26956 + 0x83,0x43,0x61,0xc5,//0x00,0x35,0x06,0x9b,//Gain = 5 ~ -58dbm
26957 + 0x93,0x38,0x5a,0xc5,//0x00,0x31,0x06,0x99,//Gain = 6 ~ -54dbm
26960 +#ifdef CONFIG_RTL818X_S
26961 +u32 rtl8225_chan[] ={
26979 +u32 rtl8225_chan[] = {
26980 + 0, //dummy channel 0
26999 +u16 rtl8225bcd_rxgain[]={
27000 + 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
27001 + 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
27002 + 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
27003 + 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
27004 + 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
27005 + 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
27006 + 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
27007 + 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
27008 + 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
27009 + 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
27010 + 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07b0, 0x07b1, 0x07b2, 0x07b3,
27011 + 0x07b4, 0x07b5, 0x07b8, 0x07b9, 0x07ba, 0x07bb, 0x07bb
27017 +u16 rtl8225bc_rxgain[]={
27018 + 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
27019 + 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
27020 + 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
27021 + 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
27022 + 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
27023 + 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
27024 + 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
27025 + 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
27026 + 0x0794, 0x0795, 0x0798, 0x0799, 0x039a, 0x039b, 0x039c, 0x039d,
27027 + 0x03a0, 0x03a1, 0x03a2, 0x03a3, 0x03a4, 0x03a5, 0x03a8, 0x03a9,
27028 + 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
27029 + 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
27034 +u16 rtl8225a_rxgain[]={
27035 + 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
27036 + 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
27037 + 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
27038 + 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
27039 + 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
27040 + 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
27041 + 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
27042 + 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
27043 + 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
27044 + 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
27045 + 0x07aa, 0x07ab, 0x07ac, 0x07ad, 0x07ad, 0x07ad, 0x07ad, 0x07ad,
27046 + 0x07ad, 0x07ad, 0x07ad, 0x07ad, 0x07ad, 0x07ad, 0x07ad
27050 +u8 rtl8225_agc[]={
27051 + 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9d,0x9c,0x9b,0x9a,0x99,0x98,0x97,0x96,
27052 + 0x95,0x94,0x93,0x92,0x91,0x90,0x8f,0x8e,0x8d,0x8c,0x8b,0x8a,0x89,0x88,0x87,0x86,
27053 + 0x85,0x84,0x83,0x82,0x81,0x80,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,
27054 + 0x35,0x34,0x33,0x32,0x31,0x30,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,
27055 + 0x25,0x24,0x23,0x22,0x21,0x20,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,
27056 + 0x15,0x14,0x13,0x12,0x11,0x10,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,
27057 + 0x05,0x04,0x03,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
27058 + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
27062 +u8 rtl8225_tx_gain_cck_ofdm[]={
27063 + 0x02,0x06,0x0e,0x1e,0x3e,0x7e
27067 +u8 rtl8225_tx_power_ofdm[]={
27068 + 0x80,0x90,0xa2,0xb5,0xcb,0xe4
27072 +u8 rtl8225_tx_power_cck_ch14[]={
27073 + 0x18,0x17,0x15,0x0c,0x00,0x00,0x00,0x00,
27074 + 0x1b,0x1a,0x17,0x0e,0x00,0x00,0x00,0x00,
27075 + 0x1f,0x1e,0x1a,0x0f,0x00,0x00,0x00,0x00,
27076 + 0x22,0x21,0x1d,0x11,0x00,0x00,0x00,0x00,
27077 + 0x26,0x25,0x21,0x13,0x00,0x00,0x00,0x00,
27078 + 0x2b,0x2a,0x25,0x15,0x00,0x00,0x00,0x00
27082 +u8 rtl8225_tx_power_cck[]={
27083 + 0x18,0x17,0x15,0x11,0x0c,0x08,0x04,0x02,
27084 + 0x1b,0x1a,0x17,0x13,0x0e,0x09,0x04,0x02,
27085 + 0x1f,0x1e,0x1a,0x15,0x10,0x0a,0x05,0x02,
27086 + 0x22,0x21,0x1d,0x18,0x11,0x0b,0x06,0x02,
27087 + 0x26,0x25,0x21,0x1b,0x14,0x0d,0x06,0x03,
27088 + 0x2b,0x2a,0x25,0x1e,0x16,0x0e,0x07,0x03
27092 +void rtl8225_set_gain(struct net_device *dev, short gain)
27094 + write_phy_ofdm(dev, 0x0d, rtl8225_gain[gain * 4]);
27095 + write_phy_ofdm(dev, 0x23, rtl8225_gain[gain * 4 + 1]);
27096 + write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 4 + 2]);
27097 + write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 4 + 3]);
27101 +void rtl8225_set_gain(struct net_device *dev, short gain)
27103 + struct r8180_priv *priv = ieee80211_priv(dev);
27105 + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
27107 + if(priv->card_8185 == 2)
27108 + write_phy_ofdm(dev, 0x21, 0x27);
27110 + write_phy_ofdm(dev, 0x21, 0x37);
27112 + write_phy_ofdm(dev, 0x25, 0x20);
27113 + write_phy_ofdm(dev, 0x11, 0x6);
27115 + if(priv->card_8185 == 1 && priv->card_8185_Bversion)
27116 + write_phy_ofdm(dev, 0x27, 0x8);
27118 + write_phy_ofdm(dev, 0x27, 0x88);
27120 + write_phy_ofdm(dev, 0x14, 0);
27121 + write_phy_ofdm(dev, 0x16, 0);
27122 + write_phy_ofdm(dev, 0x15, 0x40);
27123 + write_phy_ofdm(dev, 0x17, 0x40);
27125 + write_phy_ofdm(dev, 0x0d, rtl8225_gain[gain * 4]);
27126 + write_phy_ofdm(dev, 0x23, rtl8225_gain[gain * 4 + 1]);
27127 + write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 4 + 2]);
27128 + write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 4 + 3]);
27129 + //rtl8225_set_gain_usb(dev, gain);
27134 +void write_rtl8225(struct net_device *dev, u8 adr, u16 data)
27139 + u32 bangdata = (data << 4) | (adr & 0xf);
27140 + struct r8180_priv *priv = ieee80211_priv(dev);
27142 + out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
27144 + write_nic_word(dev,RFPinsEnable,
27145 + (read_nic_word(dev,RFPinsEnable) | 0x7));
27147 + select = read_nic_word(dev, RFPinsSelect);
27149 + write_nic_word(dev, RFPinsSelect, select | 0x7 |
27150 + ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
27152 + force_pci_posting(dev);
27155 + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
27157 + force_pci_posting(dev);
27160 + write_nic_word(dev, RFPinsOutput, out);
27162 + force_pci_posting(dev);
27166 + for(i=15; i>=0;i--){
27168 + bit = (bangdata & (1<<i)) >> i;
27170 + write_nic_word(dev, RFPinsOutput, bit | out);
27172 + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
27173 + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
27176 + bit = (bangdata & (1<<i)) >> i;
27178 + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
27179 + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
27181 + write_nic_word(dev, RFPinsOutput, bit | out);
27185 + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
27187 + force_pci_posting(dev);
27190 + write_nic_word(dev, RFPinsOutput, out |
27191 + ((priv->card_type == USB) ? 4 : BB_HOST_BANG_EN));
27193 + write_nic_word(dev, RFPinsSelect, select |
27194 + ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
27196 + if(priv->card_type == USB)
27199 + rtl8185_rf_pins_enable(dev);
27202 +void rtl8225_rf_close(struct net_device *dev)
27204 + write_rtl8225(dev, 0x4, 0x1f);
27206 + force_pci_posting(dev);
27209 + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_OFF);
27210 + rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_OFF);
27213 +void rtl8225_SetTXPowerLevel(struct net_device *dev, short ch)
27215 + struct r8180_priv *priv = ieee80211_priv(dev);
27221 + u8 *cck_power_table;
27222 + u8 max_cck_power_level;
27223 + u8 max_ofdm_power_level;
27224 + u8 min_ofdm_power_level;
27225 + u8 cck_power_level = 0xff & priv->chtxpwr[ch];
27226 + u8 ofdm_power_level = 0xff & priv->chtxpwr_ofdm[ch];
27228 + if(priv->card_type == USB){
27229 + max_cck_power_level = 11;
27230 + max_ofdm_power_level = 25; // 12 -> 25
27231 + min_ofdm_power_level = 10;
27233 + max_cck_power_level = 35;
27234 + max_ofdm_power_level = 35;
27235 + min_ofdm_power_level = 0;
27237 + /* CCK power setting */
27238 + if(cck_power_level > max_cck_power_level)
27239 + cck_power_level = max_cck_power_level;
27240 + GainIdx=cck_power_level % 6;
27241 + GainSetting=cck_power_level / 6;
27244 + cck_power_table = rtl8225_tx_power_cck_ch14;
27246 + cck_power_table = rtl8225_tx_power_cck;
27248 +// if(priv->card_8185 == 1 && priv->card_8185_Bversion ){
27250 +// write_nic_byte(dev, TX_GAIN_CCK, rtl8225_tx_gain_cck_ofdm[GainSetting]);
27253 + write_nic_byte(dev, TX_GAIN_CCK, rtl8225_tx_gain_cck_ofdm[GainSetting]>>1);
27256 + for(i=0;i<8;i++){
27258 + power = cck_power_table[GainIdx * 8 + i];
27259 + write_phy_cck(dev, 0x44 + i, power);
27262 + /* FIXME Is this delay really needeed ? */
27263 + force_pci_posting(dev);
27266 + /* OFDM power setting */
27268 +// if(ofdm_power_level > max_ofdm_power_level)
27269 +// ofdm_power_level = 35;
27270 +// ofdm_power_level += min_ofdm_power_level;
27272 + if(ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level))
27273 + ofdm_power_level = max_ofdm_power_level;
27275 + ofdm_power_level += min_ofdm_power_level;
27276 + if(ofdm_power_level > 35)
27277 + ofdm_power_level = 35;
27280 + GainIdx=ofdm_power_level % 6;
27281 + GainSetting=ofdm_power_level / 6;
27283 +// if(priv->card_type == USB){
27284 + rtl8185_set_anaparam2(dev,RTL8225_ANAPARAM2_ON);
27286 + write_phy_ofdm(dev,2,0x42);
27287 + write_phy_ofdm(dev,6,0);
27288 + write_phy_ofdm(dev,8,0);
27291 +// if(priv->card_8185 == 1 && priv->card_8185_Bversion){
27293 +// write_nic_byte(dev, TX_GAIN_OFDM, rtl8225_tx_gain_cck_ofdm[GainSetting]);
27296 + write_nic_byte(dev, TX_GAIN_OFDM, rtl8225_tx_gain_cck_ofdm[GainSetting]>>1);
27300 + power = rtl8225_tx_power_ofdm[GainIdx];
27302 + write_phy_ofdm(dev, 0x5, power);
27303 + write_phy_ofdm(dev, 0x7, power);
27305 + force_pci_posting(dev);
27307 + //write_nic_byte(dev, TX_AGC_CONTROL,4);
27310 +/* switch between mode B and G */
27311 +void rtl8225_set_mode(struct net_device *dev, short modeb)
27313 + write_phy_ofdm(dev, 0x15, (modeb ? 0x0 : 0x40));
27314 + write_phy_ofdm(dev, 0x17, (modeb ? 0x0 : 0x40));
27317 +void rtl8225_rf_set_chan(struct net_device *dev, short ch)
27319 + struct r8180_priv *priv = ieee80211_priv(dev);
27320 + short gset = (priv->ieee80211->state == IEEE80211_LINKED &&
27321 + ieee80211_is_54g(priv->ieee80211->current_network)) ||
27322 + priv->ieee80211->iw_mode == IW_MODE_MONITOR;
27324 + rtl8225_SetTXPowerLevel(dev, ch);
27326 + write_rtl8225(dev, 0x7, rtl8225_chan[ch]);
27328 + force_pci_posting(dev);
27331 + // A mode sifs 0x44, difs 34-14, slot 9, eifs 23, cwm 3, cwM 7, ctstoself 0x10
27333 + write_nic_byte(dev,SIFS,0x22);// SIFS: 0x22
27334 + write_nic_byte(dev,DIFS,0x14); //DIFS: 20
27335 + //write_nic_byte(dev,DIFS,20); //DIFS: 20
27337 + write_nic_byte(dev,SIFS,0x44);// SIFS: 0x22
27338 + write_nic_byte(dev,DIFS,50 - 14); //DIFS: 36
27340 + if(priv->ieee80211->state == IEEE80211_LINKED &&
27341 + ieee80211_is_shortslot(priv->ieee80211->current_network))
27342 + write_nic_byte(dev,SLOT,0x9); //SLOT: 9
27345 + write_nic_byte(dev,SLOT,0x14); //SLOT: 20 (0x14)
27349 + write_nic_byte(dev,EIFS,81);//91 - 20); // EIFS: 91 (0x5B)
27350 + write_nic_byte(dev,CW_VAL,0x73); //CW VALUE: 0x37
27351 + //DMESG("using G net params");
27353 + write_nic_byte(dev,EIFS,81); // EIFS: 91 (0x5B)
27354 + write_nic_byte(dev,CW_VAL,0xa5); //CW VALUE: 0x37
27355 + //DMESG("using B net params");
27361 +void rtl8225_host_pci_init(struct net_device *dev)
27363 + write_nic_word(dev, RFPinsOutput, 0x480);
27365 + rtl8185_rf_pins_enable(dev);
27367 + //if(priv->card_8185 == 2 && priv->enable_gpio0 ) /* version D */
27368 + //write_nic_word(dev, RFPinsSelect, 0x88);
27370 + write_nic_word(dev, RFPinsSelect, 0x88 | SW_CONTROL_GPIO); /* 0x488 | SW_CONTROL_GPIO */
27372 + write_nic_byte(dev, GP_ENABLE, 0);
27374 + force_pci_posting(dev);
27377 + write_nic_word(dev, GP_ENABLE, 0xff & (~(1<<6))); /* bit 6 is for RF on/off detection */
27382 +void rtl8225_host_usb_init(struct net_device *dev)
27385 + write_nic_byte(dev,RFPinsSelect+1,0);
27387 + write_nic_byte(dev,GPIO,0);
27389 + write_nic_byte_E(dev,0x53,read_nic_byte_E(dev,0x53) | (1<<7));
27391 + write_nic_byte(dev,RFPinsSelect+1,4);
27393 + write_nic_byte(dev,GPIO,0x20);
27395 + write_nic_byte(dev,GP_ENABLE,0);
27398 + /* Config BB & RF */
27399 + write_nic_word(dev, RFPinsOutput, 0x80);
27401 + write_nic_word(dev, RFPinsSelect, 0x80);
27403 + write_nic_word(dev, RFPinsEnable, 0x80);
27413 +void rtl8225_rf_sleep(struct net_device *dev)
27415 + write_rtl8225(dev,0x4,0xdff);
27416 + force_pci_posting(dev);
27418 + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_SLEEP);
27419 + rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_SLEEP);
27420 + force_pci_posting(dev);
27423 +void rtl8225_rf_wakeup(struct net_device *dev)
27425 + write_rtl8225(dev,0x4,0x9ff);
27426 + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
27427 + rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
27428 + force_pci_posting(dev);
27431 +void rtl8225_rf_init(struct net_device *dev)
27433 + struct r8180_priv *priv = ieee80211_priv(dev);
27435 + short channel = 1;
27438 + priv->chan = channel;
27440 + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
27443 + if(priv->card_type == USB)
27444 + rtl8225_host_usb_init(dev);
27446 + rtl8225_host_pci_init(dev);
27448 + write_nic_dword(dev, RF_TIMING, 0x000a8008);
27450 + brsr = read_nic_word(dev, BRSR);
27452 + write_nic_word(dev, BRSR, 0xffff);
27455 + if(priv->card_8185 == 1){/* version C or B */
27456 + if(priv->card_8185_Bversion) /* version B*/
27457 + write_nic_dword(dev, RF_PARA, 0x44);
27458 + else /* version C */
27459 + write_nic_dword(dev, RF_PARA, 0x100044);
27460 + }else{ /* version D */
27461 + if(priv->enable_gpio0)
27462 + write_nic_dword(dev, RF_PARA, 0x20100044);
27463 + else /* also USB */
27464 + write_nic_dword(dev, RF_PARA, 0x100044);
27468 + write_nic_dword(dev, RF_PARA, 0x100044);
27471 + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
27472 + write_nic_byte(dev, CONFIG3, 0x44);
27473 + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
27476 + if(priv->card_type == USB){
27477 + rtl8185_rf_pins_enable(dev);
27482 + write_rtl8225(dev, 0x0, 0x67); mdelay(1);
27485 + write_rtl8225(dev, 0x1, 0xfe0); mdelay(1);
27487 + write_rtl8225(dev, 0x2, 0x44d); mdelay(1);
27489 + write_rtl8225(dev, 0x3, 0x441); mdelay(1);
27491 + if(priv->card_type == USB)
27492 + write_rtl8225(dev, 0x4, 0x486);
27494 + write_rtl8225(dev, 0x4, 0x8be);
27500 + }else if(priv->phy_ver == 1){
27502 + write_rtl8225(dev, 0x5, 0xbc0 + 2);
27505 + /* version B & C */
27507 + if(priv->card_type == USB)
27508 + write_rtl8225(dev, 0x5, 0xbc0);
27509 + else if(priv->card_type == MINIPCI)
27510 + write_rtl8225(dev, 0x5, 0xbc0 + 3 +(6<<3));
27512 + write_rtl8225(dev, 0x5, 0xbc0 + (6<<3));
27517 + write_rtl8225(dev, 0x6, 0xae6); mdelay(1);
27519 + write_rtl8225(dev, 0x7, ((priv->card_type == USB)? 0x82a : rtl8225_chan[channel])); mdelay(1);
27521 + write_rtl8225(dev, 0x8, 0x1f); mdelay(1);
27523 + write_rtl8225(dev, 0x9, 0x334); mdelay(1);
27525 + write_rtl8225(dev, 0xa, 0xfd4); mdelay(1);
27527 + write_rtl8225(dev, 0xb, 0x391); mdelay(1);
27529 + write_rtl8225(dev, 0xc, 0x50); mdelay(1);
27532 + write_rtl8225(dev, 0xd, 0x6db); mdelay(1);
27534 + write_rtl8225(dev, 0xe, 0x29); mdelay(1);
27536 + write_rtl8225(dev, 0xf, 0x914);
27538 + if(priv->card_type == USB){
27539 + //force_pci_posting(dev);
27543 + write_rtl8225(dev, 0x2, 0xc4d);
27545 + if(priv->card_type == USB){
27546 + // force_pci_posting(dev);
27549 + write_rtl8225(dev, 0x2, 0x44d);
27551 + // force_pci_posting(dev);
27554 + }//End of if(priv->card_type == USB)
27555 + /* FIXME!! rtl8187 we have to check if calibrarion
27556 + * is successful and eventually cal. again (repeat
27557 + * the two write on reg 2)
27559 + force_pci_posting(dev);
27561 + mdelay(100); //200 for 8187
27563 + //if(priv->card_type != USB) /* maybe not needed even for 8185 */
27564 +// write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
27566 + write_rtl8225(dev, 0x0, 0x127);
27568 + for(i=0;i<95;i++){
27569 + write_rtl8225(dev, 0x1, (u8)(i+1));
27572 + if(priv->phy_ver == 1)
27574 + write_rtl8225(dev, 0x2, rtl8225a_rxgain[i]);
27577 + /* version B & C & D*/
27579 + write_rtl8225(dev, 0x2, rtl8225bcd_rxgain[i]);
27582 + write_rtl8225(dev, 0x0, 0x27);
27585 +// //if(priv->card_type != USB){
27586 +// write_rtl8225(dev, 0x2, 0x44d);
27587 +// write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
27588 +// write_rtl8225(dev, 0x2, 0x47d);
27590 +// force_pci_posting(dev);
27593 +// write_rtl8225(dev, 0x2, 0x44d);
27596 + write_rtl8225(dev, 0x0, 0x22f);
27598 + if(priv->card_type != USB)
27599 + rtl8185_rf_pins_enable(dev);
27601 + for(i=0;i<128;i++){
27602 + write_phy_ofdm(dev, 0xb, rtl8225_agc[i]);
27605 + write_phy_ofdm(dev, 0xa, (u8)i+ 0x80);
27610 + force_pci_posting(dev);
27613 + write_phy_ofdm(dev, 0x0, 0x1); mdelay(1);
27614 + write_phy_ofdm(dev, 0x1, 0x2); mdelay(1);
27615 + write_phy_ofdm(dev, 0x2, ((priv->card_type == USB)? 0x42 : 0x62)); mdelay(1);
27616 + write_phy_ofdm(dev, 0x3, 0x0); mdelay(1);
27617 + write_phy_ofdm(dev, 0x4, 0x0); mdelay(1);
27618 + write_phy_ofdm(dev, 0x5, 0x0); mdelay(1);
27619 + write_phy_ofdm(dev, 0x6, 0x40); mdelay(1);
27620 + write_phy_ofdm(dev, 0x7, 0x0); mdelay(1);
27621 + write_phy_ofdm(dev, 0x8, 0x40); mdelay(1);
27622 + write_phy_ofdm(dev, 0x9, 0xfe); mdelay(1);
27625 + if(priv->card_type == USB){
27626 + write_phy_ofdm(dev, 0xa, 0x9);
27628 + if(priv->card_8185 == 1 && priv->card_8185_Bversion){
27630 + * maybe later version can accept this also?
27632 + write_phy_ofdm(dev, 0xa, 0x6);
27633 + write_phy_ofdm(dev, 0x18, 0x6f);
27637 + write_phy_ofdm(dev, 0xa, 0x9); mdelay(1);
27639 + //write_phy_ofdm(dev, 0x18, 0xef);
27642 + write_phy_ofdm(dev, 0xb, 0x80); mdelay(1);
27644 + write_phy_ofdm(dev, 0xc, 0x1);mdelay(1);
27647 + //if(priv->card_type != USB)
27648 + //write_phy_ofdm(dev, 0xd, 0x33); // <>
27650 + write_phy_ofdm(dev, 0xe, 0xd3);mdelay(1);
27654 + if(priv->card_8185 == 1){
27655 + if(priv->card_8185_Bversion)
27656 + write_phy_ofdm(dev, 0xf, 0x20);/*ver B*/
27658 + write_phy_ofdm(dev, 0xf, 0x28);/*ver C*/
27661 + write_phy_ofdm(dev, 0xf, 0x38);mdelay(1);
27665 +// if(priv->card_8185 == 1 && priv->card_8185_Bversion)
27666 +// write_phy_ofdm(dev, 0x10, 0x04);/*ver B*/
27668 + write_phy_ofdm(dev, 0x10, 0x84);mdelay(1);
27669 +/*ver C & D & 8187*/
27671 + write_phy_ofdm(dev, 0x11, 0x06);mdelay(1);
27672 +/*agc resp time 700*/
27675 +// if(priv->card_8185 == 2){
27676 + /* Ver D & 8187*/
27677 + write_phy_ofdm(dev, 0x12, 0x20);mdelay(1);
27679 + write_phy_ofdm(dev, 0x13, 0x20);mdelay(1);
27684 + write_phy_ofdm(dev, 0x12, 0x0);
27685 + write_phy_ofdm(dev, 0x13, 0x0);
27688 + write_phy_ofdm(dev, 0x14, 0x0); mdelay(1);
27689 + write_phy_ofdm(dev, 0x15, 0x40); mdelay(1);
27690 + write_phy_ofdm(dev, 0x16, 0x0); mdelay(1);
27691 + write_phy_ofdm(dev, 0x17, 0x40); mdelay(1);
27693 +// if (priv->card_type == USB)
27694 +// write_phy_ofdm(dev, 0x18, 0xef);
27696 + write_phy_ofdm(dev, 0x18, 0xef);mdelay(1);
27699 + write_phy_ofdm(dev, 0x19, 0x19); mdelay(1);
27700 + write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1);
27702 +// if (priv->card_type != USB){
27703 +// if(priv->card_8185 == 1 && priv->card_8185_Bversion)
27704 +// write_phy_ofdm(dev, 0x1b, 0x66); /* Ver B */
27706 + write_phy_ofdm(dev, 0x1b, 0x76);mdelay(1);
27707 + /* Ver C & D */ //FIXME:MAYBE not needed
27710 + write_phy_ofdm(dev, 0x1c, 0x4);mdelay(1);
27713 + if(priv->card_8185 == 1){
27714 + if(priv->card_8185_Bversion){
27716 + write_phy_ofdm(dev, 0x1e, 0x95);
27717 + write_phy_ofdm(dev, 0x1f, 0x55);
27720 + write_phy_ofdm(dev, 0x1e, 0x90);
27721 + write_phy_ofdm(dev, 0x1f, 0x34);
27727 + write_phy_ofdm(dev, 0x1e, 0x95);mdelay(1);
27729 + write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1);
27733 + write_phy_ofdm(dev, 0x20, 0x1f);mdelay(1);
27735 + write_phy_ofdm(dev, 0x21, 0x27);mdelay(1);
27737 + write_phy_ofdm(dev, 0x22, 0x16);mdelay(1);
27739 +// if(priv->card_type != USB)
27740 + //write_phy_ofdm(dev, 0x23, 0x43); //FIXME maybe not needed // <>
27742 + write_phy_ofdm(dev, 0x24, 0x46); mdelay(1);
27743 + write_phy_ofdm(dev, 0x25, 0x20); mdelay(1);
27744 + write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);
27746 + if(priv->card_8185 == 1 && priv->card_8185_Bversion)
27747 + write_phy_ofdm(dev, 0x27, 0x08); /* Ver B. might work also fo ver C&D ?*/
27750 + write_phy_ofdm(dev, 0x27, 0x88); mdelay(1);
27751 +/* Ver C & D & 8187*/
27753 + // <> Set init. gain to m74dBm.
27754 + write_phy_ofdm(dev, 0x0d, 0x43); mdelay(1);
27755 + write_phy_ofdm(dev, 0x1b, 0x76); mdelay(1);
27756 + write_phy_ofdm(dev, 0x1d, 0xc5); mdelay(1);
27757 + write_phy_ofdm(dev, 0x23, 0x78); mdelay(1);
27759 + //if(priv->card_type == USB);
27760 + // rtl8225_set_gain_usb(dev, 1); /* FIXME this '2' is random */
27762 + write_phy_cck(dev, 0x0, 0x98); mdelay(1);
27763 + write_phy_cck(dev, 0x3, 0x20); mdelay(1);
27764 + write_phy_cck(dev, 0x4, 0x7e); mdelay(1);
27765 + write_phy_cck(dev, 0x5, 0x12); mdelay(1);
27766 + write_phy_cck(dev, 0x6, 0xfc); mdelay(1);
27768 + if(priv->card_8185 == 1 && priv->card_8185_Bversion)
27769 + write_phy_cck(dev, 0x7, 0xd8); /* Ver B */
27772 + write_phy_cck(dev, 0x7, 0x78);mdelay(1);
27773 + /* Ver C & D & 8187*/
27775 + write_phy_cck(dev, 0x8, 0x2e);mdelay(1);
27777 + write_phy_cck(dev, 0x10, ((priv->card_type == USB) ? 0x9b: 0x93)); mdelay(1);
27778 + write_phy_cck(dev, 0x11, 0x88); mdelay(1);
27779 + write_phy_cck(dev, 0x12, 0x47); mdelay(1);
27781 + if(priv->card_8185 == 1 && priv->card_8185_Bversion)
27782 + write_phy_cck(dev, 0x13, 0x98); /* Ver B */
27785 + write_phy_cck(dev, 0x13, 0xd0); /* Ver C & D & 8187*/
27787 + write_phy_cck(dev, 0x19, 0x0);
27788 + write_phy_cck(dev, 0x1a, 0xa0);
27789 + write_phy_cck(dev, 0x1b, 0x8);
27790 + write_phy_cck(dev, 0x40, 0x86); /* CCK Carrier Sense Threshold */
27792 + write_phy_cck(dev, 0x41, 0x8d);mdelay(1);
27795 + write_phy_cck(dev, 0x42, 0x15); mdelay(1);
27796 + write_phy_cck(dev, 0x43, 0x18); mdelay(1);
27797 + write_phy_cck(dev, 0x44, 0x1f); mdelay(1);
27798 + write_phy_cck(dev, 0x45, 0x1e); mdelay(1);
27799 + write_phy_cck(dev, 0x46, 0x1a); mdelay(1);
27800 + write_phy_cck(dev, 0x47, 0x15); mdelay(1);
27801 + write_phy_cck(dev, 0x48, 0x10); mdelay(1);
27802 + write_phy_cck(dev, 0x49, 0xa); mdelay(1);
27803 + write_phy_cck(dev, 0x4a, 0x5); mdelay(1);
27804 + write_phy_cck(dev, 0x4b, 0x2); mdelay(1);
27805 + write_phy_cck(dev, 0x4c, 0x5);mdelay(1);
27808 + write_nic_byte(dev, 0x5b, 0x0d); mdelay(1);
27813 +// // TESTR 0xb 8187
27814 +// write_phy_cck(dev, 0x10, 0x93);// & 0xfb);
27816 +// //if(priv->card_type != USB){
27817 +// write_phy_ofdm(dev, 0x2, 0x62);
27818 +// write_phy_ofdm(dev, 0x6, 0x0);
27819 +// write_phy_ofdm(dev, 0x8, 0x0);
27822 + rtl8225_SetTXPowerLevel(dev, channel);
27824 + write_phy_cck(dev, 0x10, 0x9b); mdelay(1); /* Rx ant A, 0xdb for B */
27825 + write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); /* Rx ant A, 0x10 for B */
27827 + rtl8185_tx_antenna(dev, 0x3); /* TX ant A, 0x0 for B */
27829 + /* switch to high-speed 3-wire
27830 + * last digit. 2 for both cck and ofdm
27832 + if(priv->card_type == USB)
27833 + write_nic_dword(dev, 0x94, 0x3dc00002);
27835 + write_nic_dword(dev, 0x94, 0x15c00002);
27836 + rtl8185_rf_pins_enable(dev);
27839 +// if(priv->card_type != USB)
27840 +// rtl8225_set_gain(dev, 4); /* FIXME this '1' is random */ // <>
27841 +// rtl8225_set_mode(dev, 1); /* FIXME start in B mode */ // <>
27843 +// /* make sure is waken up! */
27844 +// write_rtl8225(dev,0x4, 0x9ff);
27845 +// rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
27846 +// rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
27848 + rtl8225_rf_set_chan(dev, priv->chan);
27850 + write_nic_word(dev,BRSR,brsr);
27854 +++ b/drivers/staging/rtl8187se/r8180_rtl8225.h
27857 + This is part of the rtl8180-sa2400 driver
27858 + released under the GPL (See file COPYING for details).
27859 + Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
27861 + This files contains programming code for the rtl8225
27864 + *Many* thanks to Realtek Corp. for their great support!
27868 +#include "r8180.h"
27870 +#define RTL8225_ANAPARAM_ON 0xa0000b59
27871 +#define RTL8225_ANAPARAM_OFF 0xa00beb59
27872 +#define RTL8225_ANAPARAM2_OFF 0x840dec11
27873 +#define RTL8225_ANAPARAM2_ON 0x860dec11
27874 +#define RTL8225_ANAPARAM_SLEEP 0xa00bab59
27875 +#define RTL8225_ANAPARAM2_SLEEP 0x840dec11
27877 +#ifdef CONFIG_RTL8185B
27878 +void rtl8225z2_rf_init(struct net_device *dev);
27879 +void rtl8225z2_rf_set_chan(struct net_device *dev,short ch);
27880 +void rtl8225z2_rf_close(struct net_device *dev);
27882 +void rtl8225_host_pci_init(struct net_device *dev);
27883 +void rtl8225_host_usb_init(struct net_device *dev);
27885 +void write_rtl8225(struct net_device *dev, u8 adr, u16 data);
27886 +void RF_WriteReg(struct net_device *dev, u8 offset, u32 data);
27887 +u32 RF_ReadReg(struct net_device *dev, u8 offset);
27889 +void rtl8225_rf_init(struct net_device *dev);
27890 +void rtl8225_rf_set_chan(struct net_device *dev,short ch);
27891 +void rtl8225_rf_close(struct net_device *dev);
27892 +void rtl8225_rf_sleep(struct net_device *dev);
27893 +void rtl8225_rf_wakeup(struct net_device *dev);
27894 +void rtl8180_set_mode(struct net_device *dev,int mode);
27895 +void rtl8180_set_mode(struct net_device *dev,int mode);
27896 +bool SetZebraRFPowerState8185(struct net_device *dev,RT_RF_POWER_STATE eRFPowerState);
27897 +void rtl8225z4_rf_sleep(struct net_device *dev);
27898 +void rtl8225z4_rf_wakeup(struct net_device *dev);
27901 +++ b/drivers/staging/rtl8187se/r8180_rtl8225z2.c
27904 + This is part of the rtl8180-sa2400 driver
27905 + released under the GPL (See file COPYING for details).
27906 + Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
27908 + This files contains programming code for the rtl8225
27911 + *Many* thanks to Realtek Corp. for their great support!
27915 +#include "r8180_hw.h"
27916 +#include "r8180_rtl8225.h"
27917 +#include "r8180_93cx6.h"
27919 +#ifdef ENABLE_DOT11D
27920 +#include "dot11d.h"
27923 +#ifdef CONFIG_RTL8185B
27925 +extern u8 rtl8225_agc[];
27927 +extern u32 rtl8225_chan[];
27930 +u8 rtl8225z2_threshold[]={
27931 + 0x8d, 0x8d, 0x8d, 0x8d, 0x9d, 0xad, 0xbd,
27934 +// 0xd 0x19 0x1b 0x21
27935 +u8 rtl8225z2_gain_bg[]={
27936 + 0x23, 0x15, 0xa5, // -82-1dbm
27937 + 0x23, 0x15, 0xb5, // -82-2dbm
27938 + 0x23, 0x15, 0xc5, // -82-3dbm
27939 + 0x33, 0x15, 0xc5, // -78dbm
27940 + 0x43, 0x15, 0xc5, // -74dbm
27941 + 0x53, 0x15, 0xc5, // -70dbm
27942 + 0x63, 0x15, 0xc5, // -66dbm
27945 +u8 rtl8225z2_gain_a[]={
27946 + 0x13,0x27,0x5a,//,0x37,// -82dbm
27947 + 0x23,0x23,0x58,//,0x37,// -82dbm
27948 + 0x33,0x1f,0x56,//,0x37,// -82dbm
27949 + 0x43,0x1b,0x54,//,0x37,// -78dbm
27950 + 0x53,0x17,0x51,//,0x37,// -74dbm
27951 + 0x63,0x24,0x4f,//,0x37,// -70dbm
27952 + 0x73,0x0f,0x4c,//,0x37,// -66dbm
27955 +u32 rtl8225_chan[] = {
27956 + 0, //dummy channel 0
27976 +u16 rtl8225z2_rxgain[]={
27977 + 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
27978 + 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
27979 + 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
27980 + 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
27981 + 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
27982 + 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
27983 + 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
27984 + 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
27985 + 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
27986 + 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
27987 + 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
27988 + 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bb
27993 +u8 ZEBRA2_CCK_OFDM_GAIN_SETTING[]={
27994 + 0x00,0x01,0x02,0x03,0x04,0x05,
27995 + 0x06,0x07,0x08,0x09,0x0a,0x0b,
27996 + 0x0c,0x0d,0x0e,0x0f,0x10,0x11,
27997 + 0x12,0x13,0x14,0x15,0x16,0x17,
27998 + 0x18,0x19,0x1a,0x1b,0x1c,0x1d,
27999 + 0x1e,0x1f,0x20,0x21,0x22,0x23,
28004 +u8 rtl8225_agc[]={
28005 + 0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9e,0x9d,0x9c,0x9b,0x9a,0x99,0x98,0x97,0x96,
28006 + 0x95,0x94,0x93,0x92,0x91,0x90,0x8f,0x8e,0x8d,0x8c,0x8b,0x8a,0x89,0x88,0x87,0x86,
28007 + 0x85,0x84,0x83,0x82,0x81,0x80,0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,
28008 + 0x35,0x34,0x33,0x32,0x31,0x30,0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,
28009 + 0x25,0x24,0x23,0x22,0x21,0x20,0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,
28010 + 0x15,0x14,0x13,0x12,0x11,0x10,0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,
28011 + 0x05,0x04,0x03,0x02,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
28012 + 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
28017 +u8 rtl8225_tx_gain_cck_ofdm[]={
28018 + 0x02,0x06,0x0e,0x1e,0x3e,0x7e
28023 +u8 rtl8225z2_tx_power_ofdm[]={
28024 + 0x42,0x00,0x40,0x00,0x40
28029 +u8 rtl8225z2_tx_power_cck_ch14[]={
28030 + 0x36,0x35,0x2e,0x1b,0x00,0x00,0x00,0x00
28035 +u8 rtl8225z2_tx_power_cck[]={
28036 + 0x36,0x35,0x2e,0x25,0x1c,0x12,0x09,0x04
28040 +void rtl8225z2_set_gain(struct net_device *dev, short gain)
28042 + u8* rtl8225_gain;
28043 + struct r8180_priv *priv = ieee80211_priv(dev);
28045 + u8 mode = priv->ieee80211->mode;
28047 + if(mode == IEEE_B || mode == IEEE_G)
28048 + rtl8225_gain = rtl8225z2_gain_bg;
28050 + rtl8225_gain = rtl8225z2_gain_a;
28052 + //write_phy_ofdm(dev, 0x0d, rtl8225_gain[gain * 3]);
28053 + //write_phy_ofdm(dev, 0x19, rtl8225_gain[gain * 3 + 1]);
28054 + //write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 3 + 2]);
28055 + //2005.11.17, by ch-hsu
28056 + write_phy_ofdm(dev, 0x0b, rtl8225_gain[gain * 3]);
28057 + write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 3 + 1]);
28058 + write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 3 + 2]);
28059 + write_phy_ofdm(dev, 0x21, 0x37);
28065 +void rtl8225_set_gain(struct net_device *dev, short gain)
28067 + struct r8180_priv *priv = ieee80211_priv(dev);
28069 + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
28071 + if(priv->card_8185 == 2)
28072 + write_phy_ofdm(dev, 0x21, 0x27);
28074 + write_phy_ofdm(dev, 0x21, 0x37);
28076 + write_phy_ofdm(dev, 0x25, 0x20);
28077 + write_phy_ofdm(dev, 0x11, 0x6);
28079 + if(priv->card_8185 == 1 && priv->card_8185_Bversion)
28080 + write_phy_ofdm(dev, 0x27, 0x8);
28082 + write_phy_ofdm(dev, 0x27, 0x88);
28084 + write_phy_ofdm(dev, 0x14, 0);
28085 + write_phy_ofdm(dev, 0x16, 0);
28086 + write_phy_ofdm(dev, 0x15, 0x40);
28087 + write_phy_ofdm(dev, 0x17, 0x40);
28089 + write_phy_ofdm(dev, 0x0d, rtl8225_gain[gain * 4]);
28090 + write_phy_ofdm(dev, 0x23, rtl8225_gain[gain * 4 + 1]);
28091 + write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 4 + 2]);
28092 + write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 4 + 3]);
28093 + //rtl8225_set_gain_usb(dev, gain);
28097 +u32 read_rtl8225(struct net_device *dev, u8 adr)
28099 + u32 data2Write = ((u32)(adr & 0x1f)) << 27;
28102 + u16 oval,oval2,oval3,tmp;
28103 +// ThreeWireReg twreg;
28104 +// ThreeWireReg tdata;
28112 + oval = read_nic_word(dev, RFPinsOutput);
28113 + oval2 = read_nic_word(dev, RFPinsEnable);
28114 + oval3 = read_nic_word(dev, RFPinsSelect);
28116 + write_nic_word(dev, RFPinsEnable, (oval2|0xf));
28117 + write_nic_word(dev, RFPinsSelect, (oval3|0xf));
28123 + write_nic_word(dev, RFPinsOutput, oval | BB_HOST_BANG_EN ); udelay(4);
28125 + write_nic_word(dev, RFPinsOutput, oval ); udelay(5);
28129 + mask = (low2high) ? 0x01 : (((u32)0x01)<<(32-1));
28130 + for(i = 0; i < wLength/2; i++)
28132 + bit = ((data2Write&mask) != 0) ? 1 : 0;
28133 + write_nic_word(dev, RFPinsOutput, bit|oval | rw); udelay(1);
28135 + write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2);
28136 + write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2);
28138 + mask = (low2high) ? (mask<<1): (mask>>1);
28142 + rw = BB_HOST_BANG_RW;
28143 + write_nic_word(dev, RFPinsOutput, bit|oval | BB_HOST_BANG_CLK | rw); udelay(2);
28144 + write_nic_word(dev, RFPinsOutput, bit|oval | rw); udelay(2);
28148 + bit = ((data2Write&mask) != 0) ? 1: 0;
28150 + write_nic_word(dev, RFPinsOutput, oval|bit|rw| BB_HOST_BANG_CLK); udelay(2);
28151 + write_nic_word(dev, RFPinsOutput, oval|bit|rw| BB_HOST_BANG_CLK); udelay(2);
28153 + write_nic_word(dev, RFPinsOutput, oval| bit |rw); udelay(1);
28155 + mask = (low2high) ? (mask<<1) : (mask>>1);
28158 + //twreg.struc.clk = 0;
28159 + //twreg.struc.data = 0;
28160 + write_nic_word(dev, RFPinsOutput, rw|oval); udelay(2);
28161 + mask = (low2high) ? 0x01 : (((u32)0x01) << (12-1));
28163 + // We must set data pin to HW controled, otherwise RF can't driver it and
28164 + // value RF register won't be able to read back properly. 2006.06.13, by rcnjko.
28165 + write_nic_word(dev, RFPinsEnable, (oval2 & (~0x01)));
28167 + for(i = 0; i < rLength; i++)
28169 + write_nic_word(dev, RFPinsOutput, rw|oval); udelay(1);
28171 + write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2);
28172 + write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2);
28173 + write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK); udelay(2);
28174 + tmp = read_nic_word(dev, RFPinsInput);
28176 + dataRead |= (tmp & BB_HOST_BANG_CLK ? mask : 0);
28178 + write_nic_word(dev, RFPinsOutput, (rw|oval)); udelay(2);
28180 + mask = (low2high) ? (mask<<1) : (mask>>1);
28183 + write_nic_word(dev, RFPinsOutput, BB_HOST_BANG_EN|BB_HOST_BANG_RW|oval); udelay(2);
28185 + write_nic_word(dev, RFPinsEnable, oval2);
28186 + write_nic_word(dev, RFPinsSelect, oval3); // Set To SW Switch
28187 + write_nic_word(dev, RFPinsOutput, 0x3a0);
28193 +void write_rtl8225(struct net_device *dev, u8 adr, u16 data)
28198 + u32 bangdata = (data << 4) | (adr & 0xf);
28199 + struct r8180_priv *priv = ieee80211_priv(dev);
28201 + out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
28203 + write_nic_word(dev,RFPinsEnable,
28204 + (read_nic_word(dev,RFPinsEnable) | 0x7));
28206 + select = read_nic_word(dev, RFPinsSelect);
28208 + write_nic_word(dev, RFPinsSelect, select | 0x7 |
28209 + ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
28211 + force_pci_posting(dev);
28214 + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
28216 + force_pci_posting(dev);
28219 + write_nic_word(dev, RFPinsOutput, out);
28221 + force_pci_posting(dev);
28225 + for(i=15; i>=0;i--){
28227 + bit = (bangdata & (1<<i)) >> i;
28229 + write_nic_word(dev, RFPinsOutput, bit | out);
28231 + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
28232 + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
28235 + bit = (bangdata & (1<<i)) >> i;
28237 + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
28238 + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
28240 + write_nic_word(dev, RFPinsOutput, bit | out);
28244 + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
28246 + force_pci_posting(dev);
28249 + write_nic_word(dev, RFPinsOutput, out |
28250 + ((priv->card_type == USB) ? 4 : BB_HOST_BANG_EN));
28252 + write_nic_word(dev, RFPinsSelect, select |
28253 + ((priv->card_type == USB) ? 0 : SW_CONTROL_GPIO));
28255 + if(priv->card_type == USB)
28258 + rtl8185_rf_pins_enable(dev);
28262 +short rtl8225_is_V_z2(struct net_device *dev)
28266 + /* sw to reg pg 1 */
28267 + //write_rtl8225(dev, 0, 0x1b7);
28268 + //write_rtl8225(dev, 0, 0x0b7);
28270 + /* reg 8 pg 1 = 23*/
28271 + //printk(KERN_WARNING "RF Rigisters:\n");
28273 + for(i = 0; i <= 0xf; i++)
28274 + printk(KERN_WARNING "%08x,", read_rtl8225(dev, i));
28275 + //printk(KERN_WARNING "reg[9]@pg1 = 0x%x\n", read_rtl8225(dev, 0x0F));
28277 +// printk(KERN_WARNING "RF:\n");
28279 + if( read_rtl8225(dev, 8) != 0x588)
28282 + else /* reg 9 pg 1 = 24 */
28283 + if( read_rtl8225(dev, 9) != 0x700)
28286 + /* sw back to pg 0 */
28287 + write_rtl8225(dev, 0, 0xb7);
28294 +void rtl8225_rf_close(struct net_device *dev)
28296 + write_rtl8225(dev, 0x4, 0x1f);
28298 + force_pci_posting(dev);
28301 + rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_OFF);
28302 + rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_OFF);
28306 +short rtl8225_rf_set_sens(struct net_device *dev, short sens)
28308 + if (sens <0 || sens > 6) return -1;
28311 + write_rtl8225(dev, 0x0c, 0x850);
28313 + write_rtl8225(dev, 0x0c, 0x50);
28316 + rtl8225_set_gain(dev, sens);
28318 + write_phy_cck(dev, 0x41, rtl8225_threshold[sens]);
28325 +void rtl8225z2_rf_close(struct net_device *dev)
28327 + RF_WriteReg(dev, 0x4, 0x1f);
28329 + force_pci_posting(dev);
28332 + rtl8180_set_anaparam(dev, RTL8225z2_ANAPARAM_OFF);
28333 + rtl8185_set_anaparam2(dev, RTL8225z2_ANAPARAM2_OFF);
28336 +#ifdef ENABLE_DOT11D
28339 +// Map dBm into Tx power index according to
28340 +// current HW model, for example, RF and PA, and
28341 +// current wireless mode.
28345 + struct r8180_priv *priv,
28346 + WIRELESS_MODE WirelessMode,
28350 + bool bUseDefault = true;
28353 +#ifdef CONFIG_RTL818X_S
28355 + // 071011, SD3 SY:
28356 + // OFDM Power in dBm = Index * 0.5 + 0
28357 + // CCK Power in dBm = Index * 0.25 + 13
28359 + if(priv->card_8185 >= VERSION_8187S_B)
28363 + if(WirelessMode == WIRELESS_MODE_G)
28365 + bUseDefault = false;
28366 + tmp = (2 * PowerInDbm);
28370 + else if(tmp > 40) // 40 means 20 dBm.
28373 + TxPwrIdx = (s8)tmp;
28375 + else if(WirelessMode == WIRELESS_MODE_B)
28377 + bUseDefault = false;
28378 + tmp = (4 * PowerInDbm) - 52;
28382 + else if(tmp > 28) // 28 means 20 dBm.
28385 + TxPwrIdx = (s8)tmp;
28391 + // TRUE if we want to use a default implementation.
28392 + // We shall set it to FALSE when we have exact translation formular
28393 + // for target IC. 070622, by rcnjko.
28397 + if(PowerInDbm < 0)
28399 + else if(PowerInDbm > 35)
28402 + TxPwrIdx = (u8)PowerInDbm;
28409 +void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch)
28411 + struct r8180_priv *priv = ieee80211_priv(dev);
28414 +// int GainSetting;
28417 + //u8 *cck_power_table;
28418 + u8 max_cck_power_level;
28419 + //u8 min_cck_power_level;
28420 + u8 max_ofdm_power_level;
28421 + u8 min_ofdm_power_level;
28422 +// u8 cck_power_level = 0xff & priv->chtxpwr[ch];//-by amy 080312
28423 +// u8 ofdm_power_level = 0xff & priv->chtxpwr_ofdm[ch];//-by amy 080312
28424 + char cck_power_level = (char)(0xff & priv->chtxpwr[ch]);//+by amy 080312
28425 + char ofdm_power_level = (char)(0xff & priv->chtxpwr_ofdm[ch]);//+by amy 080312
28428 + // CCX 2 S31, AP control of client transmit power:
28429 + // 1. We shall not exceed Cell Power Limit as possible as we can.
28430 + // 2. Tolerance is +/- 5dB.
28431 + // 3. 802.11h Power Contraint takes higher precedence over CCX Cell Power Limit.
28434 + // 1. 802.11h power contraint
28436 + // 071011, by rcnjko.
28438 + if( priv->OpMode == RT_OP_MODE_INFRASTRUCTURE &&
28439 + priv->bWithCcxCellPwr &&
28440 + ch == priv->dot11CurrentChannelNumber)
28442 + u8 CckCellPwrIdx = DbmToTxPwrIdx(dev, WIRELESS_MODE_B, pMgntInfo->CcxCellPwr);
28443 + u8 OfdmCellPwrIdx = DbmToTxPwrIdx(dev, WIRELESS_MODE_G, pMgntInfo->CcxCellPwr);
28445 + printk("CCX Cell Limit: %d dBm => CCK Tx power index : %d, OFDM Tx power index: %d\n",
28446 + priv->CcxCellPwr, CckCellPwrIdx, OfdmCellPwrIdx);
28447 + printk("EEPROM channel(%d) => CCK Tx power index: %d, OFDM Tx power index: %d\n",
28448 + channel, CckTxPwrIdx, OfdmTxPwrIdx);
28450 + if(cck_power_level > CckCellPwrIdx)
28451 + cck_power_level = CckCellPwrIdx;
28452 + if(ofdm_power_level > OfdmCellPwrIdx)
28453 + ofdm_power_level = OfdmCellPwrIdx;
28455 + printk("Altered CCK Tx power index : %d, OFDM Tx power index: %d\n",
28456 + CckTxPwrIdx, OfdmTxPwrIdx);
28459 +#ifdef ENABLE_DOT11D
28460 + if(IS_DOT11D_ENABLE(priv->ieee80211) &&
28461 + IS_DOT11D_STATE_DONE(priv->ieee80211) )
28463 + //PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(priv->ieee80211);
28464 + u8 MaxTxPwrInDbm = DOT11D_GetMaxTxPwrInDbm(priv->ieee80211, ch);
28465 + u8 CckMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_B, MaxTxPwrInDbm);
28466 + u8 OfdmMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_G, MaxTxPwrInDbm);
28468 + //printk("Max Tx Power dBm (%d) => CCK Tx power index : %d, OFDM Tx power index: %d\n", MaxTxPwrInDbm, CckMaxPwrIdx, OfdmMaxPwrIdx);
28470 + //printk("EEPROM channel(%d) => CCK Tx power index: %d, OFDM Tx power index: %d\n",
28471 + // ch, cck_power_level, ofdm_power_level);
28473 + if(cck_power_level > CckMaxPwrIdx)
28474 + cck_power_level = CckMaxPwrIdx;
28475 + if(ofdm_power_level > OfdmMaxPwrIdx)
28476 + ofdm_power_level = OfdmMaxPwrIdx;
28479 + //priv->CurrentCckTxPwrIdx = cck_power_level;
28480 + //priv->CurrentOfdmTxPwrIdx = ofdm_power_level;
28483 + max_cck_power_level = 15;
28484 + max_ofdm_power_level = 25; // 12 -> 25
28485 + min_ofdm_power_level = 10;
28487 +#ifdef CONFIG_RTL8185B
28488 +#ifdef CONFIG_RTL818X_S
28490 + if(cck_power_level > 35)
28492 + cck_power_level = 35;
28495 + // Set up CCK TXAGC. suggested by SD3 SY.
28497 + write_nic_byte(dev, CCK_TXAGC, (ZEBRA2_CCK_OFDM_GAIN_SETTING[(u8)cck_power_level]) );
28498 + //printk("CCK TX power is %x\n", (ZEBRA2_CCK_OFDM_GAIN_SETTING[cck_power_level]));
28499 + force_pci_posting(dev);
28503 + /* CCK power setting */
28504 + if(cck_power_level > max_cck_power_level)
28505 + cck_power_level = max_cck_power_level;
28507 + cck_power_level += priv->cck_txpwr_base;
28509 + if(cck_power_level > 35)
28510 + cck_power_level = 35;
28513 + cck_power_table = rtl8225z2_tx_power_cck_ch14;
28515 + cck_power_table = rtl8225z2_tx_power_cck;
28518 + for(i=0;i<8;i++){
28520 + power = cck_power_table[i];
28521 + write_phy_cck(dev, 0x44 + i, power);
28524 + //write_nic_byte(dev, TX_GAIN_CCK, power);
28526 + write_nic_byte(dev, CCK_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[(u8)cck_power_level]);
28528 + force_pci_posting(dev);
28532 + /* OFDM power setting */
28534 +// if(ofdm_power_level > max_ofdm_power_level)
28535 +// ofdm_power_level = 35;
28536 +// ofdm_power_level += min_ofdm_power_level;
28538 +/* if(ofdm_power_level > (max_ofdm_power_level - min_ofdm_power_level))
28539 + ofdm_power_level = max_ofdm_power_level;
28541 + ofdm_power_level += min_ofdm_power_level;
28543 + ofdm_power_level += priv->ofdm_txpwr_base;
28545 + if(ofdm_power_level > 35)
28546 + ofdm_power_level = 35;
28548 +// rtl8185_set_anaparam2(dev,RTL8225_ANAPARAM2_ON);
28550 + //rtl8185_set_anaparam2(dev, ANAPARM2_ASIC_ON);
28552 + if (priv->up == 0) {
28553 + //must add these for rtl8185B down, xiong-2006-11-21
28554 + write_phy_ofdm(dev,2,0x42);
28555 + write_phy_ofdm(dev,5,0);
28556 + write_phy_ofdm(dev,6,0x40);
28557 + write_phy_ofdm(dev,7,0);
28558 + write_phy_ofdm(dev,8,0x40);
28561 + //write_nic_byte(dev, TX_GAIN_OFDM, ofdm_power_level);
28563 +#ifdef CONFIG_RTL818X_S
28564 + write_nic_byte(dev, OFDM_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[(u8)ofdm_power_level]);
28566 + write_nic_byte(dev, OFDM_TXAGC, ZEBRA2_CCK_OFDM_GAIN_SETTING[(u8)ofdm_power_level]*2);
28568 + if(ofdm_power_level<=11)
28570 +// write_nic_dword(dev,PHY_ADR,0x00005c87);
28571 +// write_nic_dword(dev,PHY_ADR,0x00005c89);
28572 + write_phy_ofdm(dev,0x07,0x5c);
28573 + write_phy_ofdm(dev,0x09,0x5c);
28575 + if(ofdm_power_level<=17)
28577 +// write_nic_dword(dev,PHY_ADR,0x00005487);
28578 +// write_nic_dword(dev,PHY_ADR,0x00005489);
28579 + write_phy_ofdm(dev,0x07,0x54);
28580 + write_phy_ofdm(dev,0x09,0x54);
28584 +// write_nic_dword(dev,PHY_ADR,0x00005087);
28585 +// write_nic_dword(dev,PHY_ADR,0x00005089);
28586 + write_phy_ofdm(dev,0x07,0x50);
28587 + write_phy_ofdm(dev,0x09,0x50);
28589 + force_pci_posting(dev);
28594 +/* switch between mode B and G */
28595 +void rtl8225_set_mode(struct net_device *dev, short modeb)
28597 + write_phy_ofdm(dev, 0x15, (modeb ? 0x0 : 0x40));
28598 + write_phy_ofdm(dev, 0x17, (modeb ? 0x0 : 0x40));
28602 +void rtl8225z2_rf_set_chan(struct net_device *dev, short ch)
28605 + short gset = (priv->ieee80211->state == IEEE80211_LINKED &&
28606 + ieee80211_is_54g(priv->ieee80211->current_network)) ||
28607 + priv->ieee80211->iw_mode == IW_MODE_MONITOR;
28609 + rtl8225z2_SetTXPowerLevel(dev, ch);
28611 + RF_WriteReg(dev, 0x7, rtl8225_chan[ch]);
28613 + //YJ,add,080828, if set channel failed, write again
28614 + if((RF_ReadReg(dev, 0x7) & 0x0F80) != rtl8225_chan[ch])
28616 + RF_WriteReg(dev, 0x7, rtl8225_chan[ch]);
28621 + force_pci_posting(dev);
28623 +//deleted by David : 2006/8/9
28625 + write_nic_byte(dev,SIFS,0x22);// SIFS: 0x22
28628 + write_nic_byte(dev,DIFS,20); //DIFS: 20
28630 + write_nic_byte(dev,DIFS,0x24); //DIFS: 36
28632 + if(priv->ieee80211->state == IEEE80211_LINKED &&
28633 + ieee80211_is_shortslot(priv->ieee80211->current_network))
28634 + write_nic_byte(dev,SLOT,0x9); //SLOT: 9
28637 + write_nic_byte(dev,SLOT,0x14); //SLOT: 20 (0x14)
28641 + write_nic_byte(dev,EIFS,91 - 20); // EIFS: 91 (0x5B)
28642 + write_nic_byte(dev,CW_VAL,0x73); //CW VALUE: 0x37
28643 + //DMESG("using G net params");
28645 + write_nic_byte(dev,EIFS,91 - 0x24); // EIFS: 91 (0x5B)
28646 + write_nic_byte(dev,CW_VAL,0xa5); //CW VALUE: 0x37
28647 + //DMESG("using B net params");
28653 +void rtl8225_host_pci_init(struct net_device *dev)
28655 + write_nic_word(dev, RFPinsOutput, 0x480);
28657 + rtl8185_rf_pins_enable(dev);
28659 + //if(priv->card_8185 == 2 && priv->enable_gpio0 ) /* version D */
28660 + //write_nic_word(dev, RFPinsSelect, 0x88);
28662 + write_nic_word(dev, RFPinsSelect, 0x88 | SW_CONTROL_GPIO); /* 0x488 | SW_CONTROL_GPIO */
28664 + write_nic_byte(dev, GP_ENABLE, 0);
28666 + force_pci_posting(dev);
28669 + write_nic_word(dev, GP_ENABLE, 0xff & (~(1<<6))); /* bit 6 is for RF on/off detection */
28674 +void rtl8225_host_usb_init(struct net_device *dev)
28676 + write_nic_byte(dev,RFPinsSelect+1,0);
28678 + write_nic_byte(dev,GPIO,0);
28680 + write_nic_byte_E(dev,0x53,read_nic_byte_E(dev,0x53) | (1<<7));
28682 + write_nic_byte(dev,RFPinsSelect+1,4);
28684 + write_nic_byte(dev,GPIO,0x20);
28686 + write_nic_byte(dev,GP_ENABLE,0);
28689 + /* Config BB & RF */
28690 + write_nic_word(dev, RFPinsOutput, 0x80);
28692 + write_nic_word(dev, RFPinsSelect, 0x80);
28694 + write_nic_word(dev, RFPinsEnable, 0x80);
28703 +void rtl8225z2_rf_init(struct net_device *dev)
28705 + struct r8180_priv *priv = ieee80211_priv(dev);
28707 + short channel = 1;
28711 + priv->chan = channel;
28713 +// rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
28716 + if(priv->card_type == USB)
28717 + rtl8225_host_usb_init(dev);
28719 + rtl8225_host_pci_init(dev);
28721 + write_nic_dword(dev, RF_TIMING, 0x000a8008);
28723 + brsr = read_nic_word(dev, BRSR);
28725 + write_nic_word(dev, BRSR, 0xffff);
28728 + write_nic_dword(dev, RF_PARA, 0x100044);
28731 + rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
28732 + write_nic_byte(dev, CONFIG3, 0x44);
28733 + rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
28737 + rtl8185_rf_pins_enable(dev);
28741 + write_rtl8225(dev, 0x0, 0x2bf); mdelay(1);
28744 + write_rtl8225(dev, 0x1, 0xee0); mdelay(1);
28746 + write_rtl8225(dev, 0x2, 0x44d); mdelay(1);
28748 + write_rtl8225(dev, 0x3, 0x441); mdelay(1);
28751 + write_rtl8225(dev, 0x4, 0x8c3);mdelay(1);
28755 + write_rtl8225(dev, 0x5, 0xc72);mdelay(1);
28758 + write_rtl8225(dev, 0x6, 0xe6); mdelay(1);
28760 + write_rtl8225(dev, 0x7, ((priv->card_type == USB)? 0x82a : rtl8225_chan[channel])); mdelay(1);
28762 + write_rtl8225(dev, 0x8, 0x3f); mdelay(1);
28764 + write_rtl8225(dev, 0x9, 0x335); mdelay(1);
28766 + write_rtl8225(dev, 0xa, 0x9d4); mdelay(1);
28768 + write_rtl8225(dev, 0xb, 0x7bb); mdelay(1);
28770 + write_rtl8225(dev, 0xc, 0x850); mdelay(1);
28773 + write_rtl8225(dev, 0xd, 0xcdf); mdelay(1);
28775 + write_rtl8225(dev, 0xe, 0x2b); mdelay(1);
28777 + write_rtl8225(dev, 0xf, 0x114);
28783 + //if(priv->card_type != USB) /* maybe not needed even for 8185 */
28784 +// write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
28786 + write_rtl8225(dev, 0x0, 0x1b7);
28788 + for(i=0;i<95;i++){
28789 + write_rtl8225(dev, 0x1, (u8)(i+1));
28792 + if(priv->phy_ver == 1)
28794 + write_rtl8225(dev, 0x2, rtl8225a_rxgain[i]);
28797 + /* version B & C & D*/
28799 + write_rtl8225(dev, 0x2, rtl8225z2_rxgain[i]);
28801 + write_rtl8225(dev, 0x3, 0x80);
28802 + write_rtl8225(dev, 0x5, 0x4);
28804 + write_rtl8225(dev, 0x0, 0xb7);
28806 + write_rtl8225(dev, 0x2, 0xc4d);
28808 + if(priv->card_type == USB){
28809 + // force_pci_posting(dev);
28812 + write_rtl8225(dev, 0x2, 0x44d);
28814 + // force_pci_posting(dev);
28817 + }//End of if(priv->card_type == USB)
28818 + /* FIXME!! rtl8187 we have to check if calibrarion
28819 + * is successful and eventually cal. again (repeat
28820 + * the two write on reg 2)
28822 + // Check for calibration status, 2005.11.17,
28823 + data = read_rtl8225(dev, 6);
28824 + if (!(data&0x00000080))
28826 + write_rtl8225(dev, 0x02, 0x0c4d);
28827 + force_pci_posting(dev); mdelay(200);
28828 + write_rtl8225(dev, 0x02, 0x044d);
28829 + force_pci_posting(dev); mdelay(100);
28830 + data = read_rtl8225(dev, 6);
28831 + if (!(data&0x00000080))
28833 + DMESGW("RF Calibration Failed!!!!\n");
28836 + //force_pci_posting(dev);
28838 + mdelay(200); //200 for 8187
28841 +// //if(priv->card_type != USB){
28842 +// write_rtl8225(dev, 0x2, 0x44d);
28843 +// write_rtl8225(dev, 0x7, rtl8225_chan[channel]);
28844 +// write_rtl8225(dev, 0x2, 0x47d);
28846 +// force_pci_posting(dev);
28849 +// write_rtl8225(dev, 0x2, 0x44d);
28852 + write_rtl8225(dev, 0x0, 0x2bf);
28854 + if(priv->card_type != USB)
28855 + rtl8185_rf_pins_enable(dev);
28856 + //set up ZEBRA AGC table, 2005.11.17,
28857 + for(i=0;i<128;i++){
28858 + data = rtl8225_agc[i];
28860 + addr = i + 0x80; //enable writing AGC table
28861 + write_phy_ofdm(dev, 0xb, data);
28864 + write_phy_ofdm(dev, 0xa, addr);
28869 + for(i=0;i<128;i++){
28870 + write_phy_ofdm(dev, 0xb, rtl8225_agc[i]);
28873 + write_phy_ofdm(dev, 0xa, (u8)i+ 0x80);
28879 + force_pci_posting(dev);
28882 + write_phy_ofdm(dev, 0x0, 0x1); mdelay(1);
28883 + write_phy_ofdm(dev, 0x1, 0x2); mdelay(1);
28884 + write_phy_ofdm(dev, 0x2, ((priv->card_type == USB)? 0x42 : 0x62)); mdelay(1);
28885 + write_phy_ofdm(dev, 0x3, 0x0); mdelay(1);
28886 + write_phy_ofdm(dev, 0x4, 0x0); mdelay(1);
28887 + write_phy_ofdm(dev, 0x5, 0x0); mdelay(1);
28888 + write_phy_ofdm(dev, 0x6, 0x40); mdelay(1);
28889 + write_phy_ofdm(dev, 0x7, 0x0); mdelay(1);
28890 + write_phy_ofdm(dev, 0x8, 0x40); mdelay(1);
28891 + write_phy_ofdm(dev, 0x9, 0xfe); mdelay(1);
28893 + write_phy_ofdm(dev, 0xa, 0x8); mdelay(1);
28895 + //write_phy_ofdm(dev, 0x18, 0xef);
28898 + write_phy_ofdm(dev, 0xb, 0x80); mdelay(1);
28900 + write_phy_ofdm(dev, 0xc, 0x1);mdelay(1);
28903 + //if(priv->card_type != USB)
28904 + write_phy_ofdm(dev, 0xd, 0x43);
28906 + write_phy_ofdm(dev, 0xe, 0xd3);mdelay(1);
28910 + if(priv->card_8185 == 1){
28911 + if(priv->card_8185_Bversion)
28912 + write_phy_ofdm(dev, 0xf, 0x20);/*ver B*/
28914 + write_phy_ofdm(dev, 0xf, 0x28);/*ver C*/
28917 + write_phy_ofdm(dev, 0xf, 0x38);mdelay(1);
28921 +// if(priv->card_8185 == 1 && priv->card_8185_Bversion)
28922 +// write_phy_ofdm(dev, 0x10, 0x04);/*ver B*/
28924 + write_phy_ofdm(dev, 0x10, 0x84);mdelay(1);
28925 +/*ver C & D & 8187*/
28927 + write_phy_ofdm(dev, 0x11, 0x07);mdelay(1);
28928 +/*agc resp time 700*/
28931 +// if(priv->card_8185 == 2){
28932 + /* Ver D & 8187*/
28933 + write_phy_ofdm(dev, 0x12, 0x20);mdelay(1);
28935 + write_phy_ofdm(dev, 0x13, 0x20);mdelay(1);
28940 + write_phy_ofdm(dev, 0x12, 0x0);
28941 + write_phy_ofdm(dev, 0x13, 0x0);
28944 + write_phy_ofdm(dev, 0x14, 0x0); mdelay(1);
28945 + write_phy_ofdm(dev, 0x15, 0x40); mdelay(1);
28946 + write_phy_ofdm(dev, 0x16, 0x0); mdelay(1);
28947 + write_phy_ofdm(dev, 0x17, 0x40); mdelay(1);
28949 +// if (priv->card_type == USB)
28950 +// write_phy_ofdm(dev, 0x18, 0xef);
28952 + write_phy_ofdm(dev, 0x18, 0xef);mdelay(1);
28955 + write_phy_ofdm(dev, 0x19, 0x19); mdelay(1);
28956 + write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1);
28957 + write_phy_ofdm(dev, 0x1b, 0x15);mdelay(1);
28959 + write_phy_ofdm(dev, 0x1c, 0x4);mdelay(1);
28961 + write_phy_ofdm(dev, 0x1d, 0xc5);mdelay(1); //2005.11.17,
28963 + write_phy_ofdm(dev, 0x1e, 0x95);mdelay(1);
28965 + write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1);
28969 + write_phy_ofdm(dev, 0x20, 0x1f);mdelay(1);
28971 + write_phy_ofdm(dev, 0x21, 0x17);mdelay(1);
28973 + write_phy_ofdm(dev, 0x22, 0x16);mdelay(1);
28975 +// if(priv->card_type != USB)
28976 + write_phy_ofdm(dev, 0x23, 0x80);mdelay(1); //FIXME maybe not needed // <>
28978 + write_phy_ofdm(dev, 0x24, 0x46); mdelay(1);
28979 + write_phy_ofdm(dev, 0x25, 0x00); mdelay(1);
28980 + write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);
28982 + write_phy_ofdm(dev, 0x27, 0x88); mdelay(1);
28985 + // <> Set init. gain to m74dBm.
28987 + rtl8225z2_set_gain(dev,4);
28989 + write_phy_cck(dev, 0x0, 0x98); mdelay(1);
28990 + write_phy_cck(dev, 0x3, 0x20); mdelay(1);
28991 + write_phy_cck(dev, 0x4, 0x7e); mdelay(1);
28992 + write_phy_cck(dev, 0x5, 0x12); mdelay(1);
28993 + write_phy_cck(dev, 0x6, 0xfc); mdelay(1);
28995 + write_phy_cck(dev, 0x7, 0x78);mdelay(1);
28996 + /* Ver C & D & 8187*/
28998 + write_phy_cck(dev, 0x8, 0x2e);mdelay(1);
29000 + write_phy_cck(dev, 0x10, ((priv->card_type == USB) ? 0x9b: 0x93)); mdelay(1);
29001 + write_phy_cck(dev, 0x11, 0x88); mdelay(1);
29002 + write_phy_cck(dev, 0x12, 0x47); mdelay(1);
29004 + if(priv->card_8185 == 1 && priv->card_8185_Bversion)
29005 + write_phy_cck(dev, 0x13, 0x98); /* Ver B */
29008 + write_phy_cck(dev, 0x13, 0xd0); /* Ver C & D & 8187*/
29010 + write_phy_cck(dev, 0x19, 0x0);
29011 + write_phy_cck(dev, 0x1a, 0xa0);
29012 + write_phy_cck(dev, 0x1b, 0x8);
29013 + write_phy_cck(dev, 0x40, 0x86); /* CCK Carrier Sense Threshold */
29015 + write_phy_cck(dev, 0x41, 0x8d);mdelay(1);
29018 + write_phy_cck(dev, 0x42, 0x15); mdelay(1);
29019 + write_phy_cck(dev, 0x43, 0x18); mdelay(1);
29022 + write_phy_cck(dev, 0x44, 0x36); mdelay(1);
29023 + write_phy_cck(dev, 0x45, 0x35); mdelay(1);
29024 + write_phy_cck(dev, 0x46, 0x2e); mdelay(1);
29025 + write_phy_cck(dev, 0x47, 0x25); mdelay(1);
29026 + write_phy_cck(dev, 0x48, 0x1c); mdelay(1);
29027 + write_phy_cck(dev, 0x49, 0x12); mdelay(1);
29028 + write_phy_cck(dev, 0x4a, 0x9); mdelay(1);
29029 + write_phy_cck(dev, 0x4b, 0x4); mdelay(1);
29030 + write_phy_cck(dev, 0x4c, 0x5);mdelay(1);
29033 + write_nic_byte(dev, 0x5b, 0x0d); mdelay(1);
29038 +// // TESTR 0xb 8187
29039 +// write_phy_cck(dev, 0x10, 0x93);// & 0xfb);
29041 +// //if(priv->card_type != USB){
29042 +// write_phy_ofdm(dev, 0x2, 0x62);
29043 +// write_phy_ofdm(dev, 0x6, 0x0);
29044 +// write_phy_ofdm(dev, 0x8, 0x0);
29047 + rtl8225z2_SetTXPowerLevel(dev, channel);
29048 +#ifdef CONFIG_RTL818X_S
29049 + write_phy_cck(dev, 0x11, 0x9b); mdelay(1); /* Rx ant A, 0xdb for B */
29051 + write_phy_cck(dev, 0x10, 0x9b); mdelay(1); /* Rx ant A, 0xdb for B */
29053 + write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); /* Rx ant A, 0x10 for B */
29055 + rtl8185_tx_antenna(dev, 0x3); /* TX ant A, 0x0 for B */
29057 + /* switch to high-speed 3-wire
29058 + * last digit. 2 for both cck and ofdm
29060 + if(priv->card_type == USB)
29061 + write_nic_dword(dev, 0x94, 0x3dc00002);
29063 + write_nic_dword(dev, 0x94, 0x15c00002);
29064 + rtl8185_rf_pins_enable(dev);
29067 +// if(priv->card_type != USB)
29068 +// rtl8225_set_gain(dev, 4); /* FIXME this '1' is random */ // <>
29069 +// rtl8225_set_mode(dev, 1); /* FIXME start in B mode */ // <>
29071 +// /* make sure is waken up! */
29072 +// write_rtl8225(dev,0x4, 0x9ff);
29073 +// rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_ON);
29074 +// rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_ON);
29076 + rtl8225_rf_set_chan(dev, priv->chan);
29078 + //write_nic_word(dev,BRSR,brsr);
29080 + //rtl8225z2_rf_set_mode(dev);
29083 +void rtl8225z2_rf_set_mode(struct net_device *dev)
29085 + struct r8180_priv *priv = ieee80211_priv(dev);
29087 + if(priv->ieee80211->mode == IEEE_A)
29089 + write_rtl8225(dev, 0x5, 0x1865);
29090 + write_nic_dword(dev, RF_PARA, 0x10084);
29091 + write_nic_dword(dev, RF_TIMING, 0xa8008);
29092 + write_phy_ofdm(dev, 0x0, 0x0);
29093 + write_phy_ofdm(dev, 0xa, 0x6);
29094 + write_phy_ofdm(dev, 0xb, 0x99);
29095 + write_phy_ofdm(dev, 0xf, 0x20);
29096 + write_phy_ofdm(dev, 0x11, 0x7);
29098 + rtl8225z2_set_gain(dev,4);
29100 + write_phy_ofdm(dev,0x15, 0x40);
29101 + write_phy_ofdm(dev,0x17, 0x40);
29103 + write_nic_dword(dev, 0x94,0x10000000);
29106 + write_rtl8225(dev, 0x5, 0x1864);
29107 + write_nic_dword(dev, RF_PARA, 0x10044);
29108 + write_nic_dword(dev, RF_TIMING, 0xa8008);
29109 + write_phy_ofdm(dev, 0x0, 0x1);
29110 + write_phy_ofdm(dev, 0xa, 0x6);
29111 + write_phy_ofdm(dev, 0xb, 0x99);
29112 + write_phy_ofdm(dev, 0xf, 0x20);
29113 + write_phy_ofdm(dev, 0x11, 0x7);
29115 + rtl8225z2_set_gain(dev,4);
29117 + write_phy_ofdm(dev,0x15, 0x40);
29118 + write_phy_ofdm(dev,0x17, 0x40);
29120 + write_nic_dword(dev, 0x94,0x04000002);
29125 +//#define MAX_DOZE_WAITING_TIMES_85B 64
29126 +//#define MAX_POLLING_24F_TIMES_87SE 5
29127 +#define MAX_DOZE_WAITING_TIMES_85B 20
29128 +#define MAX_POLLING_24F_TIMES_87SE 10
29129 +#define LPS_MAX_SLEEP_WAITING_TIMES_87SE 5
29132 +SetZebraRFPowerState8185(
29133 + struct net_device *dev,
29134 + RT_RF_POWER_STATE eRFPowerState
29137 + struct r8180_priv *priv = ieee80211_priv(dev);
29138 + u8 btCR9346, btConfig3;
29139 + bool bActionAllowed= true, bTurnOffBB = true;//lzm mod 080826
29140 + //u32 DWordContent;
29143 + //u16 u2bTFPC = 0;
29144 + bool bResult = true;
29147 + if(priv->SetRFPowerStateInProgress == true)
29150 + priv->SetRFPowerStateInProgress = true;
29152 + // enable EEM0 and EEM1 in 9346CR
29153 + btCR9346 = read_nic_byte(dev, CR9346);
29154 + write_nic_byte(dev, CR9346, (btCR9346|0xC0) );
29155 + // enable PARM_En in Config3
29156 + btConfig3 = read_nic_byte(dev, CONFIG3);
29157 + write_nic_byte(dev, CONFIG3, (btConfig3|CONFIG3_PARM_En) );
29159 + switch( priv->rf_chip )
29162 + switch( eRFPowerState )
29165 + RF_WriteReg(dev,0x4,0x9FF);
29167 + write_nic_dword(dev, ANAPARAM, ANAPARM_ON);
29168 + write_nic_dword(dev, ANAPARAM2, ANAPARM2_ON);
29170 + write_nic_byte(dev, CONFIG4, priv->RFProgType);
29172 + //Follow 87B, Isaiah 2007-04-27
29173 + u1bTmp = read_nic_byte(dev, 0x24E);
29174 + write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5|BIT6))) );// 070124 SD1 Alex: turn on CCK and OFDM.
29190 + switch( eRFPowerState )
29193 + //printk("===================================power on@jiffies:%d\n",jiffies);
29194 + write_nic_word(dev, 0x37C, 0x00EC);
29197 + write_nic_byte(dev, 0x54, 0x00);
29198 + write_nic_byte(dev, 0x62, 0x00);
29202 + //RF_WriteReg(dev, 0x0, 0x009f); //mdelay(1);
29203 + //RF_WriteReg(dev, 0x4, 0x0972); //mdelay(1);
29204 + RF_WriteReg(dev, 0x0, 0x009f); udelay(500);
29205 + RF_WriteReg(dev, 0x4, 0x0972); udelay(500);
29206 + //turn on RF again, suggested by SD3 stevenl.
29207 + RF_WriteReg(dev, 0x0, 0x009f); udelay(500);
29208 + RF_WriteReg(dev, 0x4, 0x0972); udelay(500);
29211 +// write_nic_dword(dev, PhyAddr, 0x4090); //ofdm 10=00
29212 +// write_nic_dword(dev, PhyAddr, 0x4092); //ofdm 12=00
29213 + write_phy_ofdm(dev,0x10,0x40);
29214 + write_phy_ofdm(dev,0x12,0x40);
29215 + //Avoid power down at init time.
29216 + write_nic_byte(dev, CONFIG4, priv->RFProgType);
29218 + u1bTmp = read_nic_byte(dev, 0x24E);
29219 + write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5|BIT6))) );
29224 + // Make sure BusyQueue is empty befor turn off RFE pwoer.
29225 + //printk("===================================power sleep@jiffies:%d\n",jiffies);
29227 + for(QueueID = 0, i = 0; QueueID < 6; )
29229 + if(get_curr_tx_free_desc(dev,QueueID) == priv->txringcount)
29234 +#if 0 //reserved amy
29235 + else if(priv->NdisAdapter.CurrentPowerState != NdisDeviceStateD0)
29237 + RT_TRACE(COMP_POWER, DBG_LOUD, ("eRfSleep: %d times TcbBusyQueue[%d] !=0 but lower power state!\n", (pMgntInfo->TxPollingTimes+1), QueueID));
29241 + else//lzm mod 080826
29243 + priv->TxPollingTimes ++;
29244 + if(priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE)
29246 + //RT_TRACE(COMP_POWER, DBG_WARNING, ("\n\n\n SetZebraRFPowerState8185B():eRfSleep: %d times TcbBusyQueue[%d] != 0 !!!\n\n\n", LPS_MAX_SLEEP_WAITING_TIMES_87SE, QueueID));
29247 + bActionAllowed=false;
29252 + udelay(10); // Windows may delay 3~16ms actually.
29253 + //RT_TRACE(COMP_POWER, DBG_LOUD, ("eRfSleep: %d times TcbBusyQueue[%d] !=0 before doze!\n", (pMgntInfo->TxPollingTimes), QueueID));
29258 + //if(i >= MAX_DOZE_WAITING_TIMES_85B)
29260 + //printk("\n\n\n SetZebraRFPowerState8185B(): %d times BusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_85B, QueueID);
29265 + if(bActionAllowed)//lzm add 080826
29267 + //turn off BB RXIQ matrix to cut off rx signal
29268 +// write_nic_dword(dev, PhyAddr, 0x0090); //ofdm 10=00
29269 +// write_nic_dword(dev, PhyAddr, 0x0092); //ofdm 12=00
29270 + write_phy_ofdm(dev,0x10,0x00);
29271 + write_phy_ofdm(dev,0x12,0x00);
29273 + RF_WriteReg(dev, 0x4, 0x0000); //mdelay(1);
29274 + RF_WriteReg(dev, 0x0, 0x0000); //mdelay(1);
29275 + //turn off AFE except PLL
29276 + write_nic_byte(dev, 0x62, 0xff);
29277 + write_nic_byte(dev, 0x54, 0xec);
29286 + u8 tmp24F = read_nic_byte(dev, 0x24f);
29287 + if ((tmp24F == 0x01) || (tmp24F == 0x09))
29289 + bTurnOffBB = true;
29292 + else//lzm mod 080826
29296 + priv->TxPollingTimes++;
29298 + if(priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE)
29300 + //RT_TRACE(COMP_POWER, DBG_WARNING, ("\n\n\n SetZebraRFPowerState8185B(): eRfOff: %d times Rx Mac0x24F=0x%x !!!\n\n\n", i, u1bTmp24F));
29301 + bTurnOffBB=false;
29306 + udelay(10);// Windows may delay 3~16ms actually.
29307 + //RT_TRACE(COMP_POWER, DBG_LOUD,("(%d)eRfSleep- u1bTmp24F= 0x%X\n", i, u1bTmp24F));
29313 + //if (i > MAX_POLLING_24F_TIMES_87SE)
29318 + if (bTurnOffBB)//lzm mod 080826
29321 + u1bTmp = read_nic_byte(dev, 0x24E);
29322 + write_nic_byte(dev, 0x24E, (u1bTmp|BIT5|BIT6));
29324 + //turn off AFE PLL
29325 + //write_nic_byte(dev, 0x54, 0xec);
29326 + //write_nic_word(dev, 0x37C, 0x00ec);
29327 + write_nic_byte(dev, 0x54, 0xFC); //[ECS] FC-> EC->FC, asked by SD3 Stevenl
29328 + write_nic_word(dev, 0x37C, 0x00FC);//[ECS] FC-> EC->FC, asked by SD3 Stevenl
29334 + // Make sure BusyQueue is empty befor turn off RFE pwoer.
29335 + //printk("===================================power off@jiffies:%d\n",jiffies);
29336 + for(QueueID = 0, i = 0; QueueID < 6; )
29338 + if(get_curr_tx_free_desc(dev,QueueID) == priv->txringcount)
29344 + else if(Adapter->NdisAdapter.CurrentPowerState != NdisDeviceStateD0)
29346 + RT_TRACE(COMP_POWER, DBG_LOUD, ("%d times TcbBusyQueue[%d] !=0 but lower power state!\n", (i+1), QueueID));
29356 + if(i >= MAX_DOZE_WAITING_TIMES_85B)
29358 + //printk("\n\n\n SetZebraRFPowerState8185B(): %d times BusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_85B, QueueID);
29363 + //turn off BB RXIQ matrix to cut off rx signal
29364 +// write_nic_dword(dev, PhyAddr, 0x0090); //ofdm 10=00
29365 +// write_nic_dword(dev, PhyAddr, 0x0092); //ofdm 12=00
29366 + write_phy_ofdm(dev,0x10,0x00);
29367 + write_phy_ofdm(dev,0x12,0x00);
29369 + RF_WriteReg(dev, 0x4, 0x0000); //mdelay(1);
29370 + RF_WriteReg(dev, 0x0, 0x0000); //mdelay(1);
29371 + //turn off AFE except PLL
29372 + write_nic_byte(dev, 0x62, 0xff);
29373 + write_nic_byte(dev, 0x54, 0xec);
29381 + u8 tmp24F = read_nic_byte(dev, 0x24f);
29382 + if ((tmp24F == 0x01) || (tmp24F == 0x09))
29384 + bTurnOffBB = true;
29389 + bTurnOffBB = false;
29393 + if (i > MAX_POLLING_24F_TIMES_87SE)
29398 + if (bTurnOffBB)//lzm mod 080826
29402 + u1bTmp = read_nic_byte(dev, 0x24E);
29403 + write_nic_byte(dev, 0x24E, (u1bTmp|BIT5|BIT6));
29404 + //turn off AFE PLL (80M)
29405 + //write_nic_byte(dev, 0x54, 0xec);
29406 + //write_nic_word(dev, 0x37C, 0x00ec);
29407 + write_nic_byte(dev, 0x54, 0xFC); //[ECS] FC-> EC->FC, asked by SD3 Stevenl
29408 + write_nic_word(dev, 0x37C, 0x00FC); //[ECS] FC-> EC->FC, asked by SD3 Stevenl
29415 + printk("SetZebraRFPowerState8185(): unknow state to set: 0x%X!!!\n", eRFPowerState);
29421 + // disable PARM_En in Config3
29422 + btConfig3 &= ~(CONFIG3_PARM_En);
29423 + write_nic_byte(dev, CONFIG3, btConfig3);
29424 + // disable EEM0 and EEM1 in 9346CR
29425 + btCR9346 &= ~(0xC0);
29426 + write_nic_byte(dev, CR9346, btCR9346);
29428 + if(bResult && bActionAllowed)//lzm mod 080826
29430 + // Update current RF state variable.
29431 + priv->eRFPowerState = eRFPowerState;
29433 + switch(priv->eRFPowerState)
29437 + //If Rf off reason is from IPS, Led should blink with no link, by Maddest 071015
29439 + if(priv->RfOffReason==RF_CHANGE_BY_IPS )
29441 + Adapter->HalFunc.LedControlHandler(Adapter,LED_CTL_NO_LINK);
29445 + // Turn off LED if RF is not ON.
29446 + Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_OFF);
29451 + // Turn on RF we are still linked, which might happen when
29452 + // we quickly turn off and on HW RF. 2006.05.12, by rcnjko.
29453 + if( pMgntInfo->bMediaConnect == TRUE )
29455 + Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_LINK);
29467 + priv->SetRFPowerStateInProgress = false;
29469 + return (bResult && bActionAllowed) ;
29471 +void rtl8225z4_rf_sleep(struct net_device *dev)
29474 + // Turn off RF power.
29476 + //printk("=========>%s()\n", __FUNCTION__);
29477 + MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS);
29478 + //mdelay(2); //FIXME
29480 +void rtl8225z4_rf_wakeup(struct net_device *dev)
29483 + // Turn on RF power.
29485 + //printk("=========>%s()\n", __FUNCTION__);
29486 + MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS);
29491 +++ b/drivers/staging/rtl8187se/r8180_rtl8255.c
29494 + This is part of the rtl8180-sa2400 driver
29495 + released under the GPL (See file COPYING for details).
29496 + Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
29498 + This files contains programming code for the rtl8255
29501 + *Many* thanks to Realtek Corp. for their great support!
29508 +#include "r8180.h"
29509 +#include "r8180_hw.h"
29510 +#include "r8180_rtl8255.h"
29512 +u32 rtl8255_chan[] = {
29513 + 0, //dummy channel 0
29530 +static short rtl8255_gain_2G[]={
29531 + 0x33, 0x17, 0x7c, 0xc5,//-78
29532 + 0x43, 0x17, 0x7a, 0xc5,//-74
29533 + 0x53, 0x17, 0x78, 0xc5,//-70
29534 + 0x63, 0x17, 0x76, 0xc5,//-66
29538 +static short rtl8255_agc[]={
29539 + 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1,
29541 + 0x1, 0x1, 0x2, 0x2, 0x3, 0x3, 0x4, 0x4, 0x5, 0x5,
29542 + 0x6, 0x6, 0x7, 0x7, 0x8, 0x8, 0x9, 0x9, 0xa, 0xa,
29543 + 0xb, 0xb, 0xc, 0xc, 0xd, 0xd, 0xe, 0xe, 0xf, 0xf,
29545 + 0x10, 0x10, 0x11, 0x11, 0x12, 0x12, 0x13, 0x13, 0x14, 0x14,
29546 + 0x15, 0x15, 0x16, 0x16, 0x17, 0x17, 0x18, 0x18, 0x19, 0x19,
29547 + 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1e, 0x1e,
29550 + 0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23, 0x24, 0x24,
29551 + 0x25, 0x25, 0x26, 0x26, 0x27, 0x27, 0x28, 0x28, 0x29, 0x29,
29554 + 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
29555 + 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
29556 + 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
29557 + 0x2a, 0x2a, 0x2a, 0x2a
29561 +void rtl8255_set_gain(struct net_device *dev, short gain)
29564 +// struct r8180_priv *priv = ieee80211_priv(dev);
29566 + write_phy_ofdm(dev, 0x0d, rtl8255_gain_2G[gain * 4]);
29567 + write_phy_ofdm(dev, 0x23, rtl8255_gain_2G[gain * 4 + 1]);
29568 + write_phy_ofdm(dev, 0x1b, rtl8255_gain_2G[gain * 4 + 2]);
29569 + write_phy_ofdm(dev, 0x1d, rtl8255_gain_2G[gain * 4 + 3]);
29570 + //rtl8225_set_gain_usb(dev, gain);
29573 +void write_rtl8255_reg0c(struct net_device *dev, u32 d1, u32 d2, u32 d3, u32 d4,
29574 +u32 d5, u32 d6, u32 d7, u32 d8, u32 d9, u32 d10)
29580 +// struct r8180_priv *priv = ieee80211_priv(dev);
29582 + write_nic_word(dev,RFPinsEnable,
29583 + (read_nic_word(dev,RFPinsEnable) | 0x7));
29585 + select = read_nic_word(dev, RFPinsSelect);
29587 + write_nic_word(dev, RFPinsSelect, select | 0x7 | SW_CONTROL_GPIO);
29589 + out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
29591 + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
29593 + force_pci_posting(dev);
29596 + write_nic_word(dev, RFPinsOutput, out);
29598 + force_pci_posting(dev);
29601 + for(j=0;j<10;j++)
29606 + bangdata = d10 | 0x0c;
29636 + bangdata=0xbadc0de; /* avoid gcc complaints */
29640 + for(i=31; i>=0;i--){
29642 + bit = (bangdata & (1<<i)) >> i;
29644 + write_nic_word(dev, RFPinsOutput, bit | out);
29645 + force_pci_posting(dev);
29647 + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
29648 + force_pci_posting(dev);
29650 + // write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
29652 + bit = (bangdata & (1<<i)) >> i;
29654 + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
29655 + force_pci_posting(dev);
29657 + // write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
29658 + write_nic_word(dev, RFPinsOutput, bit | out);
29659 + force_pci_posting(dev);
29664 + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
29665 + force_pci_posting(dev);
29668 +// write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
29669 + write_nic_word(dev, RFPinsSelect, select | SW_CONTROL_GPIO);
29670 +// rtl8185_rf_pins_enable(dev);
29674 +void write_rtl8255(struct net_device *dev, u8 adr, u16 data)
29679 + u32 bangdata = (data << 4) | (adr & 0xf);
29680 +// struct r8180_priv *priv = ieee80211_priv(dev);
29682 + out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
29684 + write_nic_word(dev,RFPinsEnable,
29685 + (read_nic_word(dev,RFPinsEnable) | 0x7));
29687 + select = read_nic_word(dev, RFPinsSelect);
29689 + write_nic_word(dev, RFPinsSelect, select | 0x7 | SW_CONTROL_GPIO);
29691 + force_pci_posting(dev);
29694 + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN );//| 0x1fff);
29696 + force_pci_posting(dev);
29699 + write_nic_word(dev, RFPinsOutput, out);
29701 + force_pci_posting(dev);
29705 + for(i=15; i>=0;i--){
29707 + bit = (bangdata & (1<<i)) >> i;
29709 + write_nic_word(dev, RFPinsOutput, bit | out);
29710 + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
29711 + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
29713 + bit = (bangdata & (1<<i)) >> i;
29715 + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
29716 + write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
29717 + write_nic_word(dev, RFPinsOutput, bit | out);
29721 + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
29723 + force_pci_posting(dev);
29726 + write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
29727 + write_nic_word(dev, RFPinsSelect, select | SW_CONTROL_GPIO);
29729 + rtl8185_rf_pins_enable(dev);
29732 +void rtl8255_rf_close(struct net_device *dev)
29735 +// rtl8180_set_anaparam(dev, RTL8225_ANAPARAM_OFF);
29736 +// rtl8185_set_anaparam2(dev, RTL8225_ANAPARAM2_OFF);
29739 +void rtl8255_SetTXPowerLevel(struct net_device *dev, short ch)
29741 + struct r8180_priv *priv = ieee80211_priv(dev);
29743 + u8 cck_power_level = 0xff & priv->chtxpwr[ch];
29744 + u8 ofdm_power_level = 0xff & priv->chtxpwr_ofdm[ch];
29745 + write_nic_byte(dev, TX_GAIN_OFDM, ofdm_power_level);
29746 + write_nic_byte(dev, TX_GAIN_CCK, cck_power_level);
29747 + force_pci_posting(dev);
29749 + //write_nic_byte(dev, TX_AGC_CONTROL,4);
29752 +/* switch between mode B and G */
29753 +void rtl8255_set_mode(struct net_device *dev, short modeb)
29755 + write_phy_ofdm(dev, 0x15, (modeb ? 0x0 : 0x40));
29756 + write_phy_ofdm(dev, 0x17, (modeb ? 0x0 : 0x40));
29760 +void rtl8255_rf_set_chan(struct net_device *dev, short ch)
29762 + //write_rtl8225(dev, 0x7, rtl8225_chan[1]);
29763 + write_rtl8255(dev, 0x5, 0x65);
29764 + write_rtl8255(dev, 0x6, rtl8255_chan[ch]);
29765 + write_rtl8255(dev, 0x7, 0x7c);
29766 + write_rtl8255(dev, 0x8, 0x6);
29769 + force_pci_posting(dev);
29770 + set_current_state(TASK_INTERRUPTIBLE);
29771 + schedule_timeout(HZ);
29772 +// rtl8225_set_mode_B(dev);
29774 + rtl8255_SetTXPowerLevel(dev, ch);
29775 + /* FIXME FIXME FIXME */
29778 + write_nic_byte(dev,DIFS,0xe); //DIFS
29779 + write_nic_byte(dev,SLOT,0x14); //SLOT
29780 + write_nic_byte(dev,EIFS,0x5b); // EIFS
29781 + //write_nic_byte(dev,0xbc,0); //CW CONFIG
29782 + write_nic_byte(dev,0xbd,0xa4); //CW VALUE
29783 + //write_nic_byte(dev,TX_AGC_CONTROL,4);
29784 + //write_nic_byte(dev, 0x9d,7);
29785 +//Apr 20 13:25:03 localhost kernel: w8. 409d<-7 // CCK AGC
29786 + /*write_nic_word(dev,0x84,0x488);
29787 + write_nic_byte(dev,0x91,0x3e);
29788 + write_nic_byte(dev,0x90,0x30);
29789 + write_nic_word(dev,0x84,0x488);
29790 + write_nic_byte(dev,0x91,0x3e);
29791 + write_nic_byte(dev,0x90,0x20);
29797 +void rtl8255_init_BGband(struct net_device *dev)
29799 + write_rtl8255(dev, 0x3, 0x0);
29800 + write_rtl8255(dev, 0x1, 0x807);
29801 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804187cf, 0x40000027,
29802 + 0x92402ac0, 0xf0009, 0x28000, 0xc00, 0x0);
29803 + write_rtl8255(dev, 0x1, 0x807);
29804 + write_rtl8255(dev, 0x4, 0xc00);
29805 + write_rtl8255(dev, 0x4, 0xe00);
29806 + write_rtl8255(dev, 0x4, 0xc00);
29807 + write_rtl8255(dev, 0x1, 0x0);
29808 + write_rtl8255(dev, 0x4, 0x800);
29809 + write_rtl8255(dev, 0x3, 0x0);
29810 + write_rtl8255(dev, 0x2, 0x0);
29811 + write_rtl8255(dev, 0x4, 0xa00);
29812 + write_rtl8255(dev, 0x4, 0x800);
29813 + write_rtl8255(dev, 0x4, 0x400);
29814 + write_rtl8255(dev, 0x3, 0x26);
29815 + write_rtl8255(dev, 0x2, 0x27);
29816 + write_rtl8255(dev, 0x4, 0x600);
29817 + write_rtl8255(dev, 0x4, 0x400);
29818 + write_rtl8255(dev, 0x4, 0x400);
29819 + write_rtl8255(dev, 0x3, 0x100);
29820 + write_rtl8255(dev, 0x4, 0x600);
29821 + write_rtl8255(dev, 0x4, 0x400);
29822 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804187ce, 0x80000027,
29823 + 0x92402ac0, 0xf0009, 0x28000, 0xc00, 0x0);
29824 + write_rtl8255(dev, 0x1, 0x807);
29825 + write_rtl8255(dev, 0x4, 0xc01);
29826 + write_rtl8255(dev, 0x4, 0xe01);
29827 + write_rtl8255(dev, 0x4, 0xc01);
29828 + write_rtl8255(dev, 0x1, 0x0);
29829 + write_rtl8255(dev, 0x4, 0x801);
29830 + write_rtl8255(dev, 0x3, 0x0);
29831 + write_rtl8255(dev, 0x2, 0x0);
29832 + write_rtl8255(dev, 0x4, 0xa01);
29833 + write_rtl8255(dev, 0x4, 0x801);
29834 + write_rtl8255(dev, 0x4, 0x401);
29835 + write_rtl8255(dev, 0x3, 0x26);
29836 + write_rtl8255(dev, 0x2, 0x27);
29837 + write_rtl8255(dev, 0x4, 0x601);
29838 + write_rtl8255(dev, 0x4, 0x401);
29839 + write_rtl8255(dev, 0x4, 0x401);
29840 + write_rtl8255(dev, 0x3, 0x100);
29841 + write_rtl8255(dev, 0x4, 0x601);
29842 + write_rtl8255(dev, 0x4, 0x401);
29843 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80418bdf, 0x40000027,
29844 + 0x92402ac4, 0xf0009, 0x28000, 0xc00, 0x0);
29845 + write_rtl8255(dev, 0x1, 0x807);
29846 + write_rtl8255(dev, 0x4, 0xc02);
29847 + write_rtl8255(dev, 0x4, 0xe02);
29848 + write_rtl8255(dev, 0x4, 0xc02);
29849 + write_rtl8255(dev, 0x1, 0x0);
29850 + write_rtl8255(dev, 0x4, 0x802);
29851 + write_rtl8255(dev, 0x3, 0x0);
29852 + write_rtl8255(dev, 0x2, 0x0);
29853 + write_rtl8255(dev, 0x4, 0xa02);
29854 + write_rtl8255(dev, 0x4, 0x802);
29855 + write_rtl8255(dev, 0x4, 0x402);
29856 + write_rtl8255(dev, 0x3, 0x26);
29857 + write_rtl8255(dev, 0x2, 0x26);
29858 + write_rtl8255(dev, 0x4, 0x602);
29859 + write_rtl8255(dev, 0x4, 0x402);
29860 + write_rtl8255(dev, 0x4, 0x402);
29861 + write_rtl8255(dev, 0x3, 0x100);
29862 + write_rtl8255(dev, 0x4, 0x602);
29863 + write_rtl8255(dev, 0x4, 0x402);
29864 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80418bbf, 0x40000027,
29865 + 0x92402ac4, 0xf0009, 0x28000, 0xc00, 0x0);
29866 + write_rtl8255(dev, 0x1, 0x807);
29867 + write_rtl8255(dev, 0x4, 0xc03);
29868 + write_rtl8255(dev, 0x4, 0xe03);
29869 + write_rtl8255(dev, 0x4, 0xc03);
29870 + write_rtl8255(dev, 0x1, 0x0);
29871 + write_rtl8255(dev, 0x4, 0x803);
29872 + write_rtl8255(dev, 0x3, 0x0);
29873 + write_rtl8255(dev, 0x2, 0x0);
29874 + write_rtl8255(dev, 0x4, 0xa03);
29875 + write_rtl8255(dev, 0x4, 0x803);
29876 + write_rtl8255(dev, 0x4, 0x403);
29877 + write_rtl8255(dev, 0x3, 0x26);
29878 + write_rtl8255(dev, 0x2, 0x26);
29879 + write_rtl8255(dev, 0x4, 0x603);
29880 + write_rtl8255(dev, 0x4, 0x403);
29881 + write_rtl8255(dev, 0x4, 0x403);
29882 + write_rtl8255(dev, 0x3, 0x100);
29883 + write_rtl8255(dev, 0x4, 0x603);
29884 + write_rtl8255(dev, 0x4, 0x403);
29885 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80418b9f, 0x40000027,
29886 + 0x92402ac8, 0xf0009, 0x28000, 0xc00, 0x0);
29887 + write_rtl8255(dev, 0x1, 0x807);
29888 + write_rtl8255(dev, 0x4, 0xc04);
29889 + write_rtl8255(dev, 0x4, 0xe04);
29890 + write_rtl8255(dev, 0x4, 0xc04);
29891 + write_rtl8255(dev, 0x1, 0x0);
29892 + write_rtl8255(dev, 0x4, 0x804);
29893 + write_rtl8255(dev, 0x3, 0x0);
29894 + write_rtl8255(dev, 0x2, 0x0);
29895 + write_rtl8255(dev, 0x4, 0xa04);
29896 + write_rtl8255(dev, 0x4, 0x804);
29897 + write_rtl8255(dev, 0x4, 0x404);
29898 + write_rtl8255(dev, 0x3, 0x26);
29899 + write_rtl8255(dev, 0x2, 0x26);
29900 + write_rtl8255(dev, 0x4, 0x604);
29901 + write_rtl8255(dev, 0x4, 0x404);
29902 + write_rtl8255(dev, 0x4, 0x404);
29903 + write_rtl8255(dev, 0x3, 0x100);
29904 + write_rtl8255(dev, 0x4, 0x604);
29905 + write_rtl8255(dev, 0x4, 0x404);
29906 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804183df, 0x40000027,
29907 + 0x92402ac8, 0xf0009, 0x28000, 0xc00, 0x0);
29908 + write_rtl8255(dev, 0x1, 0x807);
29909 + write_rtl8255(dev, 0x4, 0xc05);
29910 + write_rtl8255(dev, 0x4, 0xe05);
29911 + write_rtl8255(dev, 0x4, 0xc05);
29912 + write_rtl8255(dev, 0x1, 0x0);
29913 + write_rtl8255(dev, 0x4, 0x805);
29914 + write_rtl8255(dev, 0x3, 0x0);
29915 + write_rtl8255(dev, 0x2, 0x0);
29916 + write_rtl8255(dev, 0x4, 0xa05);
29917 + write_rtl8255(dev, 0x4, 0x805);
29918 + write_rtl8255(dev, 0x4, 0x405);
29919 + write_rtl8255(dev, 0x3, 0x26);
29920 + write_rtl8255(dev, 0x2, 0x26);
29921 + write_rtl8255(dev, 0x4, 0x605);
29922 + write_rtl8255(dev, 0x4, 0x405);
29923 + write_rtl8255(dev, 0x4, 0x405);
29924 + write_rtl8255(dev, 0x3, 0x100);
29925 + write_rtl8255(dev, 0x4, 0x605);
29926 + write_rtl8255(dev, 0x4, 0x405);
29927 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804183cf, 0x27,
29928 + 0x92402acc, 0xf0009, 0x28000, 0xc00, 0x0);
29929 + write_rtl8255(dev, 0x1, 0x807);
29930 + write_rtl8255(dev, 0x4, 0xc06);
29931 + write_rtl8255(dev, 0x4, 0xe06);
29932 + write_rtl8255(dev, 0x4, 0xc06);
29933 + write_rtl8255(dev, 0x1, 0x0);
29934 + write_rtl8255(dev, 0x4, 0x806);
29935 + write_rtl8255(dev, 0x3, 0x0);
29936 + write_rtl8255(dev, 0x2, 0x0);
29937 + write_rtl8255(dev, 0x4, 0xa06);
29938 + write_rtl8255(dev, 0x4, 0x806);
29939 + write_rtl8255(dev, 0x4, 0x406);
29940 + write_rtl8255(dev, 0x3, 0x25);
29941 + write_rtl8255(dev, 0x2, 0x26);
29942 + write_rtl8255(dev, 0x4, 0x606);
29943 + write_rtl8255(dev, 0x4, 0x406);
29944 + write_rtl8255(dev, 0x4, 0x406);
29945 + write_rtl8255(dev, 0x3, 0x100);
29946 + write_rtl8255(dev, 0x4, 0x606);
29947 + write_rtl8255(dev, 0x4, 0x406);
29948 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804183af, 0x27,
29949 + 0x92402acc, 0xf0009, 0x28000, 0xc00, 0x0);
29950 + write_rtl8255(dev, 0x1, 0x807);
29951 + write_rtl8255(dev, 0x4, 0xc07);
29952 + write_rtl8255(dev, 0x4, 0xe07);
29953 + write_rtl8255(dev, 0x4, 0xc07);
29954 + write_rtl8255(dev, 0x1, 0x0);
29955 + write_rtl8255(dev, 0x4, 0x807);
29956 + write_rtl8255(dev, 0x3, 0x0);
29957 + write_rtl8255(dev, 0x2, 0x0);
29958 + write_rtl8255(dev, 0x4, 0xa07);
29959 + write_rtl8255(dev, 0x4, 0x807);
29960 + write_rtl8255(dev, 0x4, 0x407);
29961 + write_rtl8255(dev, 0x3, 0x25);
29962 + write_rtl8255(dev, 0x2, 0x26);
29963 + write_rtl8255(dev, 0x4, 0x607);
29964 + write_rtl8255(dev, 0x4, 0x407);
29965 + write_rtl8255(dev, 0x4, 0x407);
29966 + write_rtl8255(dev, 0x3, 0x100);
29967 + write_rtl8255(dev, 0x4, 0x607);
29968 + write_rtl8255(dev, 0x4, 0x407);
29969 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804083d7, 0x40000027,
29970 + 0x92402ad0, 0xf0009, 0x28000, 0xc00, 0x0);
29971 + write_rtl8255(dev, 0x1, 0x807);
29972 + write_rtl8255(dev, 0x4, 0xc08);
29973 + write_rtl8255(dev, 0x4, 0xe08);
29974 + write_rtl8255(dev, 0x4, 0xc08);
29975 + write_rtl8255(dev, 0x1, 0x0);
29976 + write_rtl8255(dev, 0x4, 0x808);
29977 + write_rtl8255(dev, 0x3, 0x0);
29978 + write_rtl8255(dev, 0x2, 0x0);
29979 + write_rtl8255(dev, 0x4, 0xa08);
29980 + write_rtl8255(dev, 0x4, 0x808);
29981 + write_rtl8255(dev, 0x4, 0x408);
29982 + write_rtl8255(dev, 0x3, 0x25);
29983 + write_rtl8255(dev, 0x2, 0x26);
29984 + write_rtl8255(dev, 0x4, 0x608);
29985 + write_rtl8255(dev, 0x4, 0x408);
29986 + write_rtl8255(dev, 0x4, 0x408);
29987 + write_rtl8255(dev, 0x3, 0x100);
29988 + write_rtl8255(dev, 0x4, 0x608);
29989 + write_rtl8255(dev, 0x4, 0x408);
29990 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804083c7, 0x27,
29991 + 0x92402ad0, 0xf0009, 0x28000, 0xc00, 0x0);
29992 + write_rtl8255(dev, 0x1, 0x807);
29993 + write_rtl8255(dev, 0x4, 0xc09);
29994 + write_rtl8255(dev, 0x4, 0xe09);
29995 + write_rtl8255(dev, 0x4, 0xc09);
29996 + write_rtl8255(dev, 0x1, 0x0);
29997 + write_rtl8255(dev, 0x4, 0x809);
29998 + write_rtl8255(dev, 0x3, 0x0);
29999 + write_rtl8255(dev, 0x2, 0x0);
30000 + write_rtl8255(dev, 0x4, 0xa09);
30001 + write_rtl8255(dev, 0x4, 0x809);
30002 + write_rtl8255(dev, 0x4, 0x409);
30003 + write_rtl8255(dev, 0x3, 0x25);
30004 + write_rtl8255(dev, 0x2, 0x26);
30005 + write_rtl8255(dev, 0x4, 0x609);
30006 + write_rtl8255(dev, 0x4, 0x409);
30007 + write_rtl8255(dev, 0x4, 0x409);
30008 + write_rtl8255(dev, 0x3, 0x100);
30009 + write_rtl8255(dev, 0x4, 0x609);
30010 + write_rtl8255(dev, 0x4, 0x409);
30011 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804043d7, 0x40000027,
30012 + 0x92402ad4, 0xf0009, 0x28000, 0xc00, 0x0);
30013 + write_rtl8255(dev, 0x1, 0x807);
30014 + write_rtl8255(dev, 0x4, 0xc0a);
30015 + write_rtl8255(dev, 0x4, 0xe0a);
30016 + write_rtl8255(dev, 0x4, 0xc0a);
30017 + write_rtl8255(dev, 0x1, 0x0);
30018 + write_rtl8255(dev, 0x4, 0x80a);
30019 + write_rtl8255(dev, 0x3, 0x0);
30020 + write_rtl8255(dev, 0x2, 0x0);
30021 + write_rtl8255(dev, 0x4, 0xa0a);
30022 + write_rtl8255(dev, 0x4, 0x80a);
30023 + write_rtl8255(dev, 0x4, 0x40a);
30024 + write_rtl8255(dev, 0x3, 0x25);
30025 + write_rtl8255(dev, 0x2, 0x26);
30026 + write_rtl8255(dev, 0x4, 0x60a);
30027 + write_rtl8255(dev, 0x4, 0x40a);
30028 + write_rtl8255(dev, 0x4, 0x40a);
30029 + write_rtl8255(dev, 0x3, 0x100);
30030 + write_rtl8255(dev, 0x4, 0x60a);
30031 + write_rtl8255(dev, 0x4, 0x40a);
30032 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804043d7, 0x40000027,
30033 + 0x92402ad4, 0xf0009, 0x28000, 0xc00, 0x0);
30034 + write_rtl8255(dev, 0x1, 0x807);
30035 + write_rtl8255(dev, 0x4, 0xc0b);
30036 + write_rtl8255(dev, 0x4, 0xe0b);
30037 + write_rtl8255(dev, 0x4, 0xc0b);
30038 + write_rtl8255(dev, 0x1, 0x0);
30039 + write_rtl8255(dev, 0x4, 0x80b);
30040 + write_rtl8255(dev, 0x3, 0x0);
30041 + write_rtl8255(dev, 0x2, 0x0);
30042 + write_rtl8255(dev, 0x4, 0xa0b);
30043 + write_rtl8255(dev, 0x4, 0x80b);
30044 + write_rtl8255(dev, 0x4, 0x40b);
30045 + write_rtl8255(dev, 0x3, 0x25);
30046 + write_rtl8255(dev, 0x2, 0x26);
30047 + write_rtl8255(dev, 0x4, 0x60b);
30048 + write_rtl8255(dev, 0x4, 0x40b);
30049 + write_rtl8255(dev, 0x4, 0x40b);
30050 + write_rtl8255(dev, 0x3, 0x100);
30051 + write_rtl8255(dev, 0x4, 0x60b);
30052 + write_rtl8255(dev, 0x4, 0x40b);
30053 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804043c7, 0x27,
30054 + 0x92402ad8, 0xf0009, 0x28000, 0xc00, 0x0);
30055 + write_rtl8255(dev, 0x1, 0x807);
30056 + write_rtl8255(dev, 0x4, 0xc0c);
30057 + write_rtl8255(dev, 0x4, 0xe0c);
30058 + write_rtl8255(dev, 0x4, 0xc0c);
30059 + write_rtl8255(dev, 0x1, 0x0);
30060 + write_rtl8255(dev, 0x4, 0x80c);
30061 + write_rtl8255(dev, 0x3, 0x0);
30062 + write_rtl8255(dev, 0x2, 0x0);
30063 + write_rtl8255(dev, 0x4, 0xa0c);
30064 + write_rtl8255(dev, 0x4, 0x80c);
30065 + write_rtl8255(dev, 0x4, 0x40c);
30066 + write_rtl8255(dev, 0x3, 0x25);
30067 + write_rtl8255(dev, 0x2, 0x26);
30068 + write_rtl8255(dev, 0x4, 0x60c);
30069 + write_rtl8255(dev, 0x4, 0x40c);
30070 + write_rtl8255(dev, 0x4, 0x40c);
30071 + write_rtl8255(dev, 0x3, 0x100);
30072 + write_rtl8255(dev, 0x4, 0x60c);
30073 + write_rtl8255(dev, 0x4, 0x40c);
30074 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804043a7, 0x27,
30075 + 0x92402ad8, 0xf0009, 0x28000, 0xc00, 0x0);
30076 + write_rtl8255(dev, 0x1, 0x807);
30077 + write_rtl8255(dev, 0x4, 0xc0d);
30078 + write_rtl8255(dev, 0x4, 0xe0d);
30079 + write_rtl8255(dev, 0x4, 0xc0d);
30080 + write_rtl8255(dev, 0x1, 0x0);
30081 + write_rtl8255(dev, 0x4, 0x80d);
30082 + write_rtl8255(dev, 0x3, 0x0);
30083 + write_rtl8255(dev, 0x2, 0x0);
30084 + write_rtl8255(dev, 0x4, 0xa0d);
30085 + write_rtl8255(dev, 0x4, 0x80d);
30086 + write_rtl8255(dev, 0x4, 0x40d);
30087 + write_rtl8255(dev, 0x3, 0x25);
30088 + write_rtl8255(dev, 0x2, 0x26);
30089 + write_rtl8255(dev, 0x4, 0x60d);
30090 + write_rtl8255(dev, 0x4, 0x40d);
30091 + write_rtl8255(dev, 0x4, 0x40d);
30092 + write_rtl8255(dev, 0x3, 0x100);
30093 + write_rtl8255(dev, 0x4, 0x60d);
30094 + write_rtl8255(dev, 0x4, 0x40d);
30095 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404387, 0x27,
30096 + 0x92402aa8, 0xf0009, 0x28000, 0xc00, 0x0);
30097 + write_rtl8255(dev, 0x1, 0x807);
30098 + write_rtl8255(dev, 0x4, 0xc0e);
30099 + write_rtl8255(dev, 0x4, 0xe0e);
30100 + write_rtl8255(dev, 0x4, 0xc0e);
30101 + write_rtl8255(dev, 0x1, 0x0);
30102 + write_rtl8255(dev, 0x4, 0x80e);
30103 + write_rtl8255(dev, 0x3, 0x0);
30104 + write_rtl8255(dev, 0x2, 0x0);
30105 + write_rtl8255(dev, 0x4, 0xa0e);
30106 + write_rtl8255(dev, 0x4, 0x80e);
30107 + write_rtl8255(dev, 0x4, 0x40e);
30108 + write_rtl8255(dev, 0x3, 0x25);
30109 + write_rtl8255(dev, 0x2, 0x26);
30110 + write_rtl8255(dev, 0x4, 0x60e);
30111 + write_rtl8255(dev, 0x4, 0x40e);
30112 + write_rtl8255(dev, 0x4, 0x40e);
30113 + write_rtl8255(dev, 0x3, 0x100);
30114 + write_rtl8255(dev, 0x4, 0x60e);
30115 + write_rtl8255(dev, 0x4, 0x40e);
30116 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804041c7, 0x27,
30117 + 0x92402aa8, 0xf0009, 0x28000, 0xc00, 0x0);
30118 + write_rtl8255(dev, 0x1, 0x807);
30119 + write_rtl8255(dev, 0x4, 0xc0f);
30120 + write_rtl8255(dev, 0x4, 0xe0f);
30121 + write_rtl8255(dev, 0x4, 0xc0f);
30122 + write_rtl8255(dev, 0x1, 0x0);
30123 + write_rtl8255(dev, 0x4, 0x80f);
30124 + write_rtl8255(dev, 0x3, 0x0);
30125 + write_rtl8255(dev, 0x2, 0x0);
30126 + write_rtl8255(dev, 0x4, 0xa0f);
30127 + write_rtl8255(dev, 0x4, 0x80f);
30128 + write_rtl8255(dev, 0x4, 0x40f);
30129 + write_rtl8255(dev, 0x3, 0x25);
30130 + write_rtl8255(dev, 0x2, 0x26);
30131 + write_rtl8255(dev, 0x4, 0x60f);
30132 + write_rtl8255(dev, 0x4, 0x40f);
30133 + write_rtl8255(dev, 0x4, 0x40f);
30134 + write_rtl8255(dev, 0x3, 0x100);
30135 + write_rtl8255(dev, 0x4, 0x60f);
30136 + write_rtl8255(dev, 0x4, 0x40f);
30137 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x804041a7, 0x27,
30138 + 0x92402aac, 0xf0009, 0x28000, 0xc00, 0x0);
30139 + write_rtl8255(dev, 0x1, 0x807);
30140 + write_rtl8255(dev, 0x4, 0xc10);
30141 + write_rtl8255(dev, 0x4, 0xe10);
30142 + write_rtl8255(dev, 0x4, 0xc10);
30143 + write_rtl8255(dev, 0x1, 0x0);
30144 + write_rtl8255(dev, 0x4, 0x810);
30145 + write_rtl8255(dev, 0x3, 0x0);
30146 + write_rtl8255(dev, 0x2, 0x0);
30147 + write_rtl8255(dev, 0x4, 0xa10);
30148 + write_rtl8255(dev, 0x4, 0x810);
30149 + write_rtl8255(dev, 0x4, 0x410);
30150 + write_rtl8255(dev, 0x3, 0x25);
30151 + write_rtl8255(dev, 0x2, 0x26);
30152 + write_rtl8255(dev, 0x4, 0x610);
30153 + write_rtl8255(dev, 0x4, 0x410);
30154 + write_rtl8255(dev, 0x4, 0x410);
30155 + write_rtl8255(dev, 0x3, 0x100);
30156 + write_rtl8255(dev, 0x4, 0x610);
30157 + write_rtl8255(dev, 0x4, 0x410);
30158 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404187, 0x27,
30159 + 0x92402aac, 0xf0009, 0x28000, 0xc00, 0x0);
30160 + write_rtl8255(dev, 0x1, 0x807);
30161 + write_rtl8255(dev, 0x4, 0xc11);
30162 + write_rtl8255(dev, 0x4, 0xe11);
30163 + write_rtl8255(dev, 0x4, 0xc11);
30164 + write_rtl8255(dev, 0x1, 0x0);
30165 + write_rtl8255(dev, 0x4, 0x811);
30166 + write_rtl8255(dev, 0x3, 0x0);
30167 + write_rtl8255(dev, 0x2, 0x0);
30168 + write_rtl8255(dev, 0x4, 0xa11);
30169 + write_rtl8255(dev, 0x4, 0x811);
30170 + write_rtl8255(dev, 0x4, 0x411);
30171 + write_rtl8255(dev, 0x3, 0x25);
30172 + write_rtl8255(dev, 0x2, 0x26);
30173 + write_rtl8255(dev, 0x4, 0x611);
30174 + write_rtl8255(dev, 0x4, 0x411);
30175 + write_rtl8255(dev, 0x4, 0x411);
30176 + write_rtl8255(dev, 0x3, 0x100);
30177 + write_rtl8255(dev, 0x4, 0x611);
30178 + write_rtl8255(dev, 0x4, 0x411);
30179 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404186, 0x80000027,
30180 + 0x92402ab0, 0xf0009, 0x28000, 0xc00, 0x0);
30181 + write_rtl8255(dev, 0x1, 0x807);
30182 + write_rtl8255(dev, 0x4, 0xc12);
30183 + write_rtl8255(dev, 0x4, 0xe12);
30184 + write_rtl8255(dev, 0x4, 0xc12);
30185 + write_rtl8255(dev, 0x1, 0x0);
30186 + write_rtl8255(dev, 0x4, 0x812);
30187 + write_rtl8255(dev, 0x3, 0x0);
30188 + write_rtl8255(dev, 0x2, 0x0);
30189 + write_rtl8255(dev, 0x4, 0xa12);
30190 + write_rtl8255(dev, 0x4, 0x812);
30191 + write_rtl8255(dev, 0x4, 0x412);
30192 + write_rtl8255(dev, 0x3, 0x25);
30193 + write_rtl8255(dev, 0x2, 0x26);
30194 + write_rtl8255(dev, 0x4, 0x612);
30195 + write_rtl8255(dev, 0x4, 0x412);
30196 + write_rtl8255(dev, 0x4, 0x412);
30197 + write_rtl8255(dev, 0x3, 0x100);
30198 + write_rtl8255(dev, 0x4, 0x612);
30199 + write_rtl8255(dev, 0x4, 0x412);
30200 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404186, 0x27,
30201 + 0x92402ab0, 0xf0009, 0x28000, 0xc00, 0x0);
30202 + write_rtl8255(dev, 0x1, 0x807);
30203 + write_rtl8255(dev, 0x4, 0xc13);
30204 + write_rtl8255(dev, 0x4, 0xe13);
30205 + write_rtl8255(dev, 0x4, 0xc13);
30206 + write_rtl8255(dev, 0x1, 0x0);
30207 + write_rtl8255(dev, 0x4, 0x813);
30208 + write_rtl8255(dev, 0x3, 0x0);
30209 + write_rtl8255(dev, 0x2, 0x0);
30210 + write_rtl8255(dev, 0x4, 0xa13);
30211 + write_rtl8255(dev, 0x4, 0x813);
30212 + write_rtl8255(dev, 0x4, 0x413);
30213 + write_rtl8255(dev, 0x3, 0x25);
30214 + write_rtl8255(dev, 0x2, 0x26);
30215 + write_rtl8255(dev, 0x4, 0x613);
30216 + write_rtl8255(dev, 0x4, 0x413);
30217 + write_rtl8255(dev, 0x4, 0x413);
30218 + write_rtl8255(dev, 0x3, 0x100);
30219 + write_rtl8255(dev, 0x4, 0x613);
30220 + write_rtl8255(dev, 0x4, 0x413);
30221 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404146, 0x27,
30222 + 0x92402ab4, 0xf0009, 0x28000, 0xc00, 0x0);
30223 + write_rtl8255(dev, 0x1, 0x807);
30224 + write_rtl8255(dev, 0x4, 0xc14);
30225 + write_rtl8255(dev, 0x4, 0xe14);
30226 + write_rtl8255(dev, 0x4, 0xc14);
30227 + write_rtl8255(dev, 0x1, 0x0);
30228 + write_rtl8255(dev, 0x4, 0x814);
30229 + write_rtl8255(dev, 0x3, 0x0);
30230 + write_rtl8255(dev, 0x2, 0x0);
30231 + write_rtl8255(dev, 0x4, 0xa14);
30232 + write_rtl8255(dev, 0x4, 0x814);
30233 + write_rtl8255(dev, 0x4, 0x414);
30234 + write_rtl8255(dev, 0x3, 0x25);
30235 + write_rtl8255(dev, 0x2, 0x26);
30236 + write_rtl8255(dev, 0x4, 0x614);
30237 + write_rtl8255(dev, 0x4, 0x414);
30238 + write_rtl8255(dev, 0x4, 0x414);
30239 + write_rtl8255(dev, 0x3, 0x100);
30240 + write_rtl8255(dev, 0x4, 0x614);
30241 + write_rtl8255(dev, 0x4, 0x414);
30242 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404126, 0x27,
30243 + 0x92402ab4, 0xf0009, 0x28000, 0xc00, 0x0);
30244 + write_rtl8255(dev, 0x1, 0x807);
30245 + write_rtl8255(dev, 0x4, 0xc15);
30246 + write_rtl8255(dev, 0x4, 0xe15);
30247 + write_rtl8255(dev, 0x4, 0xc15);
30248 + write_rtl8255(dev, 0x1, 0x0);
30249 + write_rtl8255(dev, 0x4, 0x815);
30250 + write_rtl8255(dev, 0x3, 0x0);
30251 + write_rtl8255(dev, 0x2, 0x0);
30252 + write_rtl8255(dev, 0x4, 0xa15);
30253 + write_rtl8255(dev, 0x4, 0x815);
30254 + write_rtl8255(dev, 0x4, 0x415);
30255 + write_rtl8255(dev, 0x3, 0x25);
30256 + write_rtl8255(dev, 0x2, 0x26);
30257 + write_rtl8255(dev, 0x4, 0x615);
30258 + write_rtl8255(dev, 0x4, 0x415);
30259 + write_rtl8255(dev, 0x4, 0x415);
30260 + write_rtl8255(dev, 0x3, 0x100);
30261 + write_rtl8255(dev, 0x4, 0x615);
30262 + write_rtl8255(dev, 0x4, 0x415);
30263 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404106, 0x27,
30264 + 0x92402ab8, 0xf0009, 0x28000, 0xc00, 0x0);
30265 + write_rtl8255(dev, 0x1, 0x807);
30266 + write_rtl8255(dev, 0x4, 0xc16);
30267 + write_rtl8255(dev, 0x4, 0xe16);
30268 + write_rtl8255(dev, 0x4, 0xc16);
30269 + write_rtl8255(dev, 0x1, 0x0);
30270 + write_rtl8255(dev, 0x4, 0x816);
30271 + write_rtl8255(dev, 0x3, 0x0);
30272 + write_rtl8255(dev, 0x2, 0x0);
30273 + write_rtl8255(dev, 0x4, 0xa16);
30274 + write_rtl8255(dev, 0x4, 0x816);
30275 + write_rtl8255(dev, 0x4, 0x416);
30276 + write_rtl8255(dev, 0x3, 0x25);
30277 + write_rtl8255(dev, 0x2, 0x26);
30278 + write_rtl8255(dev, 0x4, 0x616);
30279 + write_rtl8255(dev, 0x4, 0x416);
30280 + write_rtl8255(dev, 0x4, 0x416);
30281 + write_rtl8255(dev, 0x3, 0x100);
30282 + write_rtl8255(dev, 0x4, 0x616);
30283 + write_rtl8255(dev, 0x4, 0x416);
30284 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404105, 0x27,
30285 + 0x92402ab8, 0xf0009, 0x28000, 0xc00, 0x0);
30286 + write_rtl8255(dev, 0x1, 0x807);
30287 + write_rtl8255(dev, 0x4, 0xc17);
30288 + write_rtl8255(dev, 0x4, 0xe17);
30289 + write_rtl8255(dev, 0x4, 0xc17);
30290 + write_rtl8255(dev, 0x1, 0x0);
30291 + write_rtl8255(dev, 0x4, 0x817);
30292 + write_rtl8255(dev, 0x3, 0x0);
30293 + write_rtl8255(dev, 0x2, 0x0);
30294 + write_rtl8255(dev, 0x4, 0xa17);
30295 + write_rtl8255(dev, 0x4, 0x817);
30296 + write_rtl8255(dev, 0x4, 0x417);
30297 + write_rtl8255(dev, 0x3, 0x25);
30298 + write_rtl8255(dev, 0x2, 0x26);
30299 + write_rtl8255(dev, 0x4, 0x617);
30300 + write_rtl8255(dev, 0x4, 0x417);
30301 + write_rtl8255(dev, 0x4, 0x417);
30302 + write_rtl8255(dev, 0x3, 0x100);
30303 + write_rtl8255(dev, 0x4, 0x617);
30304 + write_rtl8255(dev, 0x4, 0x417);
30305 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404104, 0x80000027,
30306 + 0x92402a88, 0xf0009, 0x28000, 0xc00, 0x0);
30307 + write_rtl8255(dev, 0x1, 0x807);
30308 + write_rtl8255(dev, 0x4, 0xc18);
30309 + write_rtl8255(dev, 0x4, 0xe18);
30310 + write_rtl8255(dev, 0x4, 0xc18);
30311 + write_rtl8255(dev, 0x1, 0x0);
30312 + write_rtl8255(dev, 0x4, 0x818);
30313 + write_rtl8255(dev, 0x3, 0x0);
30314 + write_rtl8255(dev, 0x2, 0x0);
30315 + write_rtl8255(dev, 0x4, 0xa18);
30316 + write_rtl8255(dev, 0x4, 0x818);
30317 + write_rtl8255(dev, 0x4, 0x418);
30318 + write_rtl8255(dev, 0x3, 0x25);
30319 + write_rtl8255(dev, 0x2, 0x26);
30320 + write_rtl8255(dev, 0x4, 0x618);
30321 + write_rtl8255(dev, 0x4, 0x418);
30322 + write_rtl8255(dev, 0x4, 0x418);
30323 + write_rtl8255(dev, 0x3, 0x100);
30324 + write_rtl8255(dev, 0x4, 0x618);
30325 + write_rtl8255(dev, 0x4, 0x418);
30326 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404104, 0x27,
30327 + 0x92402a88, 0xf0009, 0x28000, 0xc00, 0x0);
30328 + write_rtl8255(dev, 0x1, 0x807);
30329 + write_rtl8255(dev, 0x4, 0xc19);
30330 + write_rtl8255(dev, 0x4, 0xe19);
30331 + write_rtl8255(dev, 0x4, 0xc19);
30332 + write_rtl8255(dev, 0x1, 0x0);
30333 + write_rtl8255(dev, 0x4, 0x819);
30334 + write_rtl8255(dev, 0x3, 0x0);
30335 + write_rtl8255(dev, 0x2, 0x0);
30336 + write_rtl8255(dev, 0x4, 0xa19);
30337 + write_rtl8255(dev, 0x4, 0x819);
30338 + write_rtl8255(dev, 0x4, 0x419);
30339 + write_rtl8255(dev, 0x3, 0x25);
30340 + write_rtl8255(dev, 0x2, 0x26);
30341 + write_rtl8255(dev, 0x4, 0x619);
30342 + write_rtl8255(dev, 0x4, 0x419);
30343 + write_rtl8255(dev, 0x4, 0x419);
30344 + write_rtl8255(dev, 0x3, 0x100);
30345 + write_rtl8255(dev, 0x4, 0x619);
30346 + write_rtl8255(dev, 0x4, 0x419);
30347 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404044, 0x27,
30348 + 0x92402a8c, 0xf0009, 0x28000, 0xc00, 0x0);
30349 + write_rtl8255(dev, 0x1, 0x807);
30350 + write_rtl8255(dev, 0x4, 0xc1a);
30351 + write_rtl8255(dev, 0x4, 0xe1a);
30352 + write_rtl8255(dev, 0x4, 0xc1a);
30353 + write_rtl8255(dev, 0x1, 0x0);
30354 + write_rtl8255(dev, 0x4, 0x81a);
30355 + write_rtl8255(dev, 0x3, 0x0);
30356 + write_rtl8255(dev, 0x2, 0x0);
30357 + write_rtl8255(dev, 0x4, 0xa1a);
30358 + write_rtl8255(dev, 0x4, 0x81a);
30359 + write_rtl8255(dev, 0x4, 0x41a);
30360 + write_rtl8255(dev, 0x3, 0x25);
30361 + write_rtl8255(dev, 0x2, 0x26);
30362 + write_rtl8255(dev, 0x4, 0x61a);
30363 + write_rtl8255(dev, 0x4, 0x41a);
30364 + write_rtl8255(dev, 0x4, 0x41a);
30365 + write_rtl8255(dev, 0x3, 0x100);
30366 + write_rtl8255(dev, 0x4, 0x61a);
30367 + write_rtl8255(dev, 0x4, 0x41a);
30368 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404024, 0x27,
30369 + 0x92402a8c, 0xf0009, 0x28000, 0xc00, 0x0);
30370 + write_rtl8255(dev, 0x1, 0x807);
30371 + write_rtl8255(dev, 0x4, 0xc1b);
30372 + write_rtl8255(dev, 0x4, 0xe1b);
30373 + write_rtl8255(dev, 0x4, 0xc1b);
30374 + write_rtl8255(dev, 0x1, 0x0);
30375 + write_rtl8255(dev, 0x4, 0x81b);
30376 + write_rtl8255(dev, 0x3, 0x0);
30377 + write_rtl8255(dev, 0x2, 0x0);
30378 + write_rtl8255(dev, 0x4, 0xa1b);
30379 + write_rtl8255(dev, 0x4, 0x81b);
30380 + write_rtl8255(dev, 0x4, 0x41b);
30381 + write_rtl8255(dev, 0x3, 0x25);
30382 + write_rtl8255(dev, 0x2, 0x26);
30383 + write_rtl8255(dev, 0x4, 0x61b);
30384 + write_rtl8255(dev, 0x4, 0x41b);
30385 + write_rtl8255(dev, 0x4, 0x41b);
30386 + write_rtl8255(dev, 0x3, 0x100);
30387 + write_rtl8255(dev, 0x4, 0x61b);
30388 + write_rtl8255(dev, 0x4, 0x41b);
30389 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404004, 0x27,
30390 + 0x92402a90, 0xf0009, 0x28000, 0xc00, 0x0);
30391 + write_rtl8255(dev, 0x1, 0x807);
30392 + write_rtl8255(dev, 0x4, 0xc1c);
30393 + write_rtl8255(dev, 0x4, 0xe1c);
30394 + write_rtl8255(dev, 0x4, 0xc1c);
30395 + write_rtl8255(dev, 0x1, 0x0);
30396 + write_rtl8255(dev, 0x4, 0x81c);
30397 + write_rtl8255(dev, 0x3, 0x0);
30398 + write_rtl8255(dev, 0x2, 0x0);
30399 + write_rtl8255(dev, 0x4, 0xa1c);
30400 + write_rtl8255(dev, 0x4, 0x81c);
30401 + write_rtl8255(dev, 0x4, 0x41c);
30402 + write_rtl8255(dev, 0x3, 0x25);
30403 + write_rtl8255(dev, 0x2, 0x26);
30404 + write_rtl8255(dev, 0x4, 0x61c);
30405 + write_rtl8255(dev, 0x4, 0x41c);
30406 + write_rtl8255(dev, 0x4, 0x41c);
30407 + write_rtl8255(dev, 0x3, 0x100);
30408 + write_rtl8255(dev, 0x4, 0x61c);
30409 + write_rtl8255(dev, 0x4, 0x41c);
30410 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404001, 0x27,
30411 + 0x92402a90, 0xf0009, 0x28000, 0xc00, 0x0);
30412 + write_rtl8255(dev, 0x1, 0x807);
30413 + write_rtl8255(dev, 0x4, 0xc1d);
30414 + write_rtl8255(dev, 0x4, 0xe1d);
30415 + write_rtl8255(dev, 0x4, 0xc1d);
30416 + write_rtl8255(dev, 0x1, 0x0);
30417 + write_rtl8255(dev, 0x4, 0x81d);
30418 + write_rtl8255(dev, 0x3, 0x0);
30419 + write_rtl8255(dev, 0x2, 0x0);
30420 + write_rtl8255(dev, 0x4, 0xa1d);
30421 + write_rtl8255(dev, 0x4, 0x81d);
30422 + write_rtl8255(dev, 0x4, 0x41d);
30423 + write_rtl8255(dev, 0x3, 0x25);
30424 + write_rtl8255(dev, 0x2, 0x26);
30425 + write_rtl8255(dev, 0x4, 0x61d);
30426 + write_rtl8255(dev, 0x4, 0x41d);
30427 + write_rtl8255(dev, 0x4, 0x41d);
30428 + write_rtl8255(dev, 0x3, 0x100);
30429 + write_rtl8255(dev, 0x4, 0x61d);
30430 + write_rtl8255(dev, 0x4, 0x41d);
30431 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
30432 + 0x92402a94, 0xf0009, 0x28000, 0xc00, 0x0);
30433 + write_rtl8255(dev, 0x1, 0x807);
30434 + write_rtl8255(dev, 0x4, 0xc1e);
30435 + write_rtl8255(dev, 0x4, 0xe1e);
30436 + write_rtl8255(dev, 0x4, 0xc1e);
30437 + write_rtl8255(dev, 0x1, 0x0);
30438 + write_rtl8255(dev, 0x4, 0x81e);
30439 + write_rtl8255(dev, 0x3, 0x0);
30440 + write_rtl8255(dev, 0x2, 0x0);
30441 + write_rtl8255(dev, 0x4, 0xa1e);
30442 + write_rtl8255(dev, 0x4, 0x81e);
30443 + write_rtl8255(dev, 0x4, 0x41e);
30444 + write_rtl8255(dev, 0x3, 0x25);
30445 + write_rtl8255(dev, 0x2, 0x26);
30446 + write_rtl8255(dev, 0x4, 0x61e);
30447 + write_rtl8255(dev, 0x4, 0x41e);
30448 + write_rtl8255(dev, 0x4, 0x41e);
30449 + write_rtl8255(dev, 0x3, 0x100);
30450 + write_rtl8255(dev, 0x4, 0x61e);
30451 + write_rtl8255(dev, 0x4, 0x41e);
30452 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x27,
30453 + 0x92402a94, 0xf0009, 0x28000, 0xc00, 0x0);
30454 + write_rtl8255(dev, 0x1, 0x807);
30455 + write_rtl8255(dev, 0x4, 0xc1f);
30456 + write_rtl8255(dev, 0x4, 0xe1f);
30457 + write_rtl8255(dev, 0x4, 0xc1f);
30458 + write_rtl8255(dev, 0x1, 0x0);
30459 + write_rtl8255(dev, 0x4, 0x81f);
30460 + write_rtl8255(dev, 0x3, 0x0);
30461 + write_rtl8255(dev, 0x2, 0x0);
30462 + write_rtl8255(dev, 0x4, 0xa1f);
30463 + write_rtl8255(dev, 0x4, 0x81f);
30464 + write_rtl8255(dev, 0x4, 0x41f);
30465 + write_rtl8255(dev, 0x3, 0x25);
30466 + write_rtl8255(dev, 0x2, 0x26);
30467 + write_rtl8255(dev, 0x4, 0x61f);
30468 + write_rtl8255(dev, 0x4, 0x41f);
30469 + write_rtl8255(dev, 0x4, 0x41f);
30470 + write_rtl8255(dev, 0x3, 0x100);
30471 + write_rtl8255(dev, 0x4, 0x61f);
30472 + write_rtl8255(dev, 0x4, 0x41f);
30473 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404020, 0x80000027,
30474 + 0x92402a98, 0xf8009, 0x28000, 0xc00, 0x0);
30475 + write_rtl8255(dev, 0x1, 0x807);
30476 + write_rtl8255(dev, 0x4, 0xc20);
30477 + write_rtl8255(dev, 0x4, 0xe20);
30478 + write_rtl8255(dev, 0x4, 0xc20);
30479 + write_rtl8255(dev, 0x1, 0x0);
30480 + write_rtl8255(dev, 0x4, 0x820);
30481 + write_rtl8255(dev, 0x3, 0x0);
30482 + write_rtl8255(dev, 0x2, 0x0);
30483 + write_rtl8255(dev, 0x4, 0xa20);
30484 + write_rtl8255(dev, 0x4, 0x820);
30485 + write_rtl8255(dev, 0x4, 0x420);
30486 + write_rtl8255(dev, 0x3, 0x25);
30487 + write_rtl8255(dev, 0x2, 0x26);
30488 + write_rtl8255(dev, 0x4, 0x620);
30489 + write_rtl8255(dev, 0x4, 0x420);
30490 + write_rtl8255(dev, 0x4, 0x420);
30491 + write_rtl8255(dev, 0x3, 0x100);
30492 + write_rtl8255(dev, 0x4, 0x620);
30493 + write_rtl8255(dev, 0x4, 0x420);
30494 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404020, 0x27,
30495 + 0x92402a98, 0xf8009, 0x28000, 0xc00, 0x0);
30496 + write_rtl8255(dev, 0x1, 0x807);
30497 + write_rtl8255(dev, 0x4, 0xc21);
30498 + write_rtl8255(dev, 0x4, 0xe21);
30499 + write_rtl8255(dev, 0x4, 0xc21);
30500 + write_rtl8255(dev, 0x1, 0x0);
30501 + write_rtl8255(dev, 0x4, 0x821);
30502 + write_rtl8255(dev, 0x3, 0x0);
30503 + write_rtl8255(dev, 0x2, 0x0);
30504 + write_rtl8255(dev, 0x4, 0xa21);
30505 + write_rtl8255(dev, 0x4, 0x821);
30506 + write_rtl8255(dev, 0x4, 0x421);
30507 + write_rtl8255(dev, 0x3, 0x25);
30508 + write_rtl8255(dev, 0x2, 0x26);
30509 + write_rtl8255(dev, 0x4, 0x621);
30510 + write_rtl8255(dev, 0x4, 0x421);
30511 + write_rtl8255(dev, 0x4, 0x421);
30512 + write_rtl8255(dev, 0x3, 0x100);
30513 + write_rtl8255(dev, 0x4, 0x621);
30514 + write_rtl8255(dev, 0x4, 0x421);
30515 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
30516 + 0x92402a68, 0xf0009, 0x10028000, 0xc00, 0x0);
30517 + write_rtl8255(dev, 0x1, 0x807);
30518 + write_rtl8255(dev, 0x4, 0xc22);
30519 + write_rtl8255(dev, 0x4, 0xe22);
30520 + write_rtl8255(dev, 0x4, 0xc22);
30521 + write_rtl8255(dev, 0x1, 0x0);
30522 + write_rtl8255(dev, 0x4, 0x822);
30523 + write_rtl8255(dev, 0x3, 0x0);
30524 + write_rtl8255(dev, 0x2, 0x0);
30525 + write_rtl8255(dev, 0x4, 0xa22);
30526 + write_rtl8255(dev, 0x4, 0x822);
30527 + write_rtl8255(dev, 0x4, 0x422);
30528 + write_rtl8255(dev, 0x3, 0x25);
30529 + write_rtl8255(dev, 0x2, 0x26);
30530 + write_rtl8255(dev, 0x4, 0x622);
30531 + write_rtl8255(dev, 0x4, 0x422);
30532 + write_rtl8255(dev, 0x4, 0x422);
30533 + write_rtl8255(dev, 0x3, 0x100);
30534 + write_rtl8255(dev, 0x4, 0x622);
30535 + write_rtl8255(dev, 0x4, 0x422);
30536 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404010, 0x80000027,
30537 + 0x92402a68, 0xf0009, 0x20028000, 0xc00, 0x0);
30538 + write_rtl8255(dev, 0x1, 0x807);
30539 + write_rtl8255(dev, 0x4, 0xc23);
30540 + write_rtl8255(dev, 0x4, 0xe23);
30541 + write_rtl8255(dev, 0x4, 0xc23);
30542 + write_rtl8255(dev, 0x1, 0x0);
30543 + write_rtl8255(dev, 0x4, 0x823);
30544 + write_rtl8255(dev, 0x3, 0x0);
30545 + write_rtl8255(dev, 0x2, 0x0);
30546 + write_rtl8255(dev, 0x4, 0xa23);
30547 + write_rtl8255(dev, 0x4, 0x823);
30548 + write_rtl8255(dev, 0x4, 0x423);
30549 + write_rtl8255(dev, 0x3, 0x25);
30550 + write_rtl8255(dev, 0x2, 0x26);
30551 + write_rtl8255(dev, 0x4, 0x623);
30552 + write_rtl8255(dev, 0x4, 0x423);
30553 + write_rtl8255(dev, 0x4, 0x423);
30554 + write_rtl8255(dev, 0x3, 0x100);
30555 + write_rtl8255(dev, 0x4, 0x623);
30556 + write_rtl8255(dev, 0x4, 0x423);
30557 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404010, 0x80000027,
30558 + 0x92402a6c, 0xf0009, 0x30028000, 0xc00, 0x0);
30559 + write_rtl8255(dev, 0x1, 0x807);
30560 + write_rtl8255(dev, 0x4, 0xc24);
30561 + write_rtl8255(dev, 0x4, 0xe24);
30562 + write_rtl8255(dev, 0x4, 0xc24);
30563 + write_rtl8255(dev, 0x1, 0x0);
30564 + write_rtl8255(dev, 0x4, 0x824);
30565 + write_rtl8255(dev, 0x3, 0x0);
30566 + write_rtl8255(dev, 0x2, 0x0);
30567 + write_rtl8255(dev, 0x4, 0xa24);
30568 + write_rtl8255(dev, 0x4, 0x824);
30569 + write_rtl8255(dev, 0x4, 0x424);
30570 + write_rtl8255(dev, 0x3, 0x25);
30571 + write_rtl8255(dev, 0x2, 0x26);
30572 + write_rtl8255(dev, 0x4, 0x624);
30573 + write_rtl8255(dev, 0x4, 0x424);
30574 + write_rtl8255(dev, 0x4, 0x424);
30575 + write_rtl8255(dev, 0x3, 0x100);
30576 + write_rtl8255(dev, 0x4, 0x624);
30577 + write_rtl8255(dev, 0x4, 0x424);
30578 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404010, 0x80000027,
30579 + 0x92402a6c, 0xf0009, 0x40028000, 0xc00, 0x0);
30580 + write_rtl8255(dev, 0x1, 0x807);
30581 + write_rtl8255(dev, 0x4, 0xc25);
30582 + write_rtl8255(dev, 0x4, 0xe25);
30583 + write_rtl8255(dev, 0x4, 0xc25);
30584 + write_rtl8255(dev, 0x1, 0x0);
30585 + write_rtl8255(dev, 0x4, 0x825);
30586 + write_rtl8255(dev, 0x3, 0x0);
30587 + write_rtl8255(dev, 0x2, 0x0);
30588 + write_rtl8255(dev, 0x4, 0xa25);
30589 + write_rtl8255(dev, 0x4, 0x825);
30590 + write_rtl8255(dev, 0x4, 0x425);
30591 + write_rtl8255(dev, 0x3, 0x25);
30592 + write_rtl8255(dev, 0x2, 0x26);
30593 + write_rtl8255(dev, 0x4, 0x625);
30594 + write_rtl8255(dev, 0x4, 0x425);
30595 + write_rtl8255(dev, 0x4, 0x425);
30596 + write_rtl8255(dev, 0x3, 0x100);
30597 + write_rtl8255(dev, 0x4, 0x625);
30598 + write_rtl8255(dev, 0x4, 0x425);
30599 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
30600 + 0x92402a70, 0xf0009, 0x60028000, 0xc00, 0x0);
30601 + write_rtl8255(dev, 0x1, 0x807);
30602 + write_rtl8255(dev, 0x4, 0xc26);
30603 + write_rtl8255(dev, 0x4, 0xe26);
30604 + write_rtl8255(dev, 0x4, 0xc26);
30605 + write_rtl8255(dev, 0x1, 0x0);
30606 + write_rtl8255(dev, 0x4, 0x826);
30607 + write_rtl8255(dev, 0x3, 0x0);
30608 + write_rtl8255(dev, 0x2, 0x0);
30609 + write_rtl8255(dev, 0x4, 0xa26);
30610 + write_rtl8255(dev, 0x4, 0x826);
30611 + write_rtl8255(dev, 0x4, 0x426);
30612 + write_rtl8255(dev, 0x3, 0x25);
30613 + write_rtl8255(dev, 0x2, 0x26);
30614 + write_rtl8255(dev, 0x4, 0x626);
30615 + write_rtl8255(dev, 0x4, 0x426);
30616 + write_rtl8255(dev, 0x4, 0x426);
30617 + write_rtl8255(dev, 0x3, 0x100);
30618 + write_rtl8255(dev, 0x4, 0x626);
30619 + write_rtl8255(dev, 0x4, 0x426);
30620 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404031, 0x40000027,
30621 + 0x92402a70, 0xf0011, 0x60028000, 0xc00, 0x0);
30622 + write_rtl8255(dev, 0x1, 0x807);
30623 + write_rtl8255(dev, 0x4, 0xc27);
30624 + write_rtl8255(dev, 0x4, 0xe27);
30625 + write_rtl8255(dev, 0x4, 0xc27);
30626 + write_rtl8255(dev, 0x1, 0x0);
30627 + write_rtl8255(dev, 0x4, 0x827);
30628 + write_rtl8255(dev, 0x3, 0x0);
30629 + write_rtl8255(dev, 0x2, 0x0);
30630 + write_rtl8255(dev, 0x4, 0xa27);
30631 + write_rtl8255(dev, 0x4, 0x827);
30632 + write_rtl8255(dev, 0x4, 0x427);
30633 + write_rtl8255(dev, 0x3, 0x25);
30634 + write_rtl8255(dev, 0x2, 0x26);
30635 + write_rtl8255(dev, 0x4, 0x627);
30636 + write_rtl8255(dev, 0x4, 0x427);
30637 + write_rtl8255(dev, 0x4, 0x427);
30638 + write_rtl8255(dev, 0x3, 0x100);
30639 + write_rtl8255(dev, 0x4, 0x627);
30640 + write_rtl8255(dev, 0x4, 0x427);
30641 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404011, 0x40000027,
30642 + 0x92402a74, 0xf0011, 0x60028000, 0xc00, 0x0);
30643 + write_rtl8255(dev, 0x1, 0x807);
30644 + write_rtl8255(dev, 0x4, 0xc28);
30645 + write_rtl8255(dev, 0x4, 0xe28);
30646 + write_rtl8255(dev, 0x4, 0xc28);
30647 + write_rtl8255(dev, 0x1, 0x0);
30648 + write_rtl8255(dev, 0x4, 0x828);
30649 + write_rtl8255(dev, 0x3, 0x0);
30650 + write_rtl8255(dev, 0x2, 0x0);
30651 + write_rtl8255(dev, 0x4, 0xa28);
30652 + write_rtl8255(dev, 0x4, 0x828);
30653 + write_rtl8255(dev, 0x4, 0x428);
30654 + write_rtl8255(dev, 0x3, 0x25);
30655 + write_rtl8255(dev, 0x2, 0x26);
30656 + write_rtl8255(dev, 0x4, 0x628);
30657 + write_rtl8255(dev, 0x4, 0x428);
30658 + write_rtl8255(dev, 0x4, 0x428);
30659 + write_rtl8255(dev, 0x3, 0x100);
30660 + write_rtl8255(dev, 0x4, 0x628);
30661 + write_rtl8255(dev, 0x4, 0x428);
30662 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404010, 0xc0000027,
30663 + 0x92402a74, 0xf0011, 0x60028000, 0xc00, 0x0);
30664 + write_rtl8255(dev, 0x1, 0x807);
30665 + write_rtl8255(dev, 0x4, 0xc29);
30666 + write_rtl8255(dev, 0x4, 0xe29);
30667 + write_rtl8255(dev, 0x4, 0xc29);
30668 + write_rtl8255(dev, 0x1, 0x0);
30669 + write_rtl8255(dev, 0x4, 0x829);
30670 + write_rtl8255(dev, 0x3, 0x0);
30671 + write_rtl8255(dev, 0x2, 0x0);
30672 + write_rtl8255(dev, 0x4, 0xa29);
30673 + write_rtl8255(dev, 0x4, 0x829);
30674 + write_rtl8255(dev, 0x4, 0x429);
30675 + write_rtl8255(dev, 0x3, 0x25);
30676 + write_rtl8255(dev, 0x2, 0x26);
30677 + write_rtl8255(dev, 0x4, 0x629);
30678 + write_rtl8255(dev, 0x4, 0x429);
30679 + write_rtl8255(dev, 0x4, 0x429);
30680 + write_rtl8255(dev, 0x3, 0x100);
30681 + write_rtl8255(dev, 0x4, 0x629);
30682 + write_rtl8255(dev, 0x4, 0x429);
30683 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
30684 + 0x92402a78, 0xf0011, 0x60028000, 0xc00, 0x0);
30685 + write_rtl8255(dev, 0x1, 0x807);
30686 + write_rtl8255(dev, 0x4, 0xc2a);
30687 + write_rtl8255(dev, 0x4, 0xe2a);
30688 + write_rtl8255(dev, 0x4, 0xc2a);
30689 + write_rtl8255(dev, 0x1, 0x0);
30690 + write_rtl8255(dev, 0x4, 0x82a);
30691 + write_rtl8255(dev, 0x3, 0x0);
30692 + write_rtl8255(dev, 0x2, 0x0);
30693 + write_rtl8255(dev, 0x4, 0xa2a);
30694 + write_rtl8255(dev, 0x4, 0x82a);
30695 + write_rtl8255(dev, 0x4, 0x42a);
30696 + write_rtl8255(dev, 0x3, 0x24);
30697 + write_rtl8255(dev, 0x2, 0x26);
30698 + write_rtl8255(dev, 0x4, 0x62a);
30699 + write_rtl8255(dev, 0x4, 0x42a);
30700 + write_rtl8255(dev, 0x4, 0x42a);
30701 + write_rtl8255(dev, 0x3, 0x100);
30702 + write_rtl8255(dev, 0x4, 0x62a);
30703 + write_rtl8255(dev, 0x4, 0x42a);
30704 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
30705 + 0x92402a78, 0xf0011, 0x70028000, 0xc00, 0x0);
30706 + write_rtl8255(dev, 0x1, 0x807);
30707 + write_rtl8255(dev, 0x4, 0xc2b);
30708 + write_rtl8255(dev, 0x4, 0xe2b);
30709 + write_rtl8255(dev, 0x4, 0xc2b);
30710 + write_rtl8255(dev, 0x1, 0x0);
30711 + write_rtl8255(dev, 0x4, 0x82b);
30712 + write_rtl8255(dev, 0x3, 0x0);
30713 + write_rtl8255(dev, 0x2, 0x0);
30714 + write_rtl8255(dev, 0x4, 0xa2b);
30715 + write_rtl8255(dev, 0x4, 0x82b);
30716 + write_rtl8255(dev, 0x4, 0x42b);
30717 + write_rtl8255(dev, 0x3, 0x24);
30718 + write_rtl8255(dev, 0x2, 0x26);
30719 + write_rtl8255(dev, 0x4, 0x62b);
30720 + write_rtl8255(dev, 0x4, 0x42b);
30721 + write_rtl8255(dev, 0x4, 0x42b);
30722 + write_rtl8255(dev, 0x3, 0x100);
30723 + write_rtl8255(dev, 0x4, 0x62b);
30724 + write_rtl8255(dev, 0x4, 0x42b);
30725 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
30726 + 0x92402a48, 0xf0019, 0x70028000, 0xc00, 0x0);
30727 + write_rtl8255(dev, 0x1, 0x807);
30728 + write_rtl8255(dev, 0x4, 0xc2c);
30729 + write_rtl8255(dev, 0x4, 0xe2c);
30730 + write_rtl8255(dev, 0x4, 0xc2c);
30731 + write_rtl8255(dev, 0x1, 0x0);
30732 + write_rtl8255(dev, 0x4, 0x82c);
30733 + write_rtl8255(dev, 0x3, 0x0);
30734 + write_rtl8255(dev, 0x2, 0x0);
30735 + write_rtl8255(dev, 0x4, 0xa2c);
30736 + write_rtl8255(dev, 0x4, 0x82c);
30737 + write_rtl8255(dev, 0x4, 0x42c);
30738 + write_rtl8255(dev, 0x3, 0x24);
30739 + write_rtl8255(dev, 0x2, 0x26);
30740 + write_rtl8255(dev, 0x4, 0x62c);
30741 + write_rtl8255(dev, 0x4, 0x42c);
30742 + write_rtl8255(dev, 0x4, 0x42c);
30743 + write_rtl8255(dev, 0x3, 0x100);
30744 + write_rtl8255(dev, 0x4, 0x62c);
30745 + write_rtl8255(dev, 0x4, 0x42c);
30746 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
30747 + 0x92402a48, 0xf8019, 0x70028000, 0xc00, 0x0);
30748 + write_rtl8255(dev, 0x1, 0x807);
30749 + write_rtl8255(dev, 0x4, 0xc2d);
30750 + write_rtl8255(dev, 0x4, 0xe2d);
30751 + write_rtl8255(dev, 0x4, 0xc2d);
30752 + write_rtl8255(dev, 0x1, 0x0);
30753 + write_rtl8255(dev, 0x4, 0x82d);
30754 + write_rtl8255(dev, 0x3, 0x0);
30755 + write_rtl8255(dev, 0x2, 0x0);
30756 + write_rtl8255(dev, 0x4, 0xa2d);
30757 + write_rtl8255(dev, 0x4, 0x82d);
30758 + write_rtl8255(dev, 0x4, 0x42d);
30759 + write_rtl8255(dev, 0x3, 0x24);
30760 + write_rtl8255(dev, 0x2, 0x26);
30761 + write_rtl8255(dev, 0x4, 0x62d);
30762 + write_rtl8255(dev, 0x4, 0x42d);
30763 + write_rtl8255(dev, 0x4, 0x42d);
30764 + write_rtl8255(dev, 0x3, 0x100);
30765 + write_rtl8255(dev, 0x4, 0x62d);
30766 + write_rtl8255(dev, 0x4, 0x42d);
30767 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
30768 + 0x92402a4c, 0xf8019, 0x70028000, 0xc00, 0x0);
30769 + write_rtl8255(dev, 0x1, 0x807);
30770 + write_rtl8255(dev, 0x4, 0xc2e);
30771 + write_rtl8255(dev, 0x4, 0xe2e);
30772 + write_rtl8255(dev, 0x4, 0xc2e);
30773 + write_rtl8255(dev, 0x1, 0x0);
30774 + write_rtl8255(dev, 0x4, 0x82e);
30775 + write_rtl8255(dev, 0x3, 0x0);
30776 + write_rtl8255(dev, 0x2, 0x0);
30777 + write_rtl8255(dev, 0x4, 0xa2e);
30778 + write_rtl8255(dev, 0x4, 0x82e);
30779 + write_rtl8255(dev, 0x4, 0x42e);
30780 + write_rtl8255(dev, 0x3, 0x24);
30781 + write_rtl8255(dev, 0x2, 0x26);
30782 + write_rtl8255(dev, 0x4, 0x62e);
30783 + write_rtl8255(dev, 0x4, 0x42e);
30784 + write_rtl8255(dev, 0x4, 0x42e);
30785 + write_rtl8255(dev, 0x3, 0x100);
30786 + write_rtl8255(dev, 0x4, 0x62e);
30787 + write_rtl8255(dev, 0x4, 0x42e);
30788 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
30789 + 0x92402a4c, 0xf8019, 0x70028000, 0xc00, 0x0);
30790 + write_rtl8255(dev, 0x1, 0x807);
30791 + write_rtl8255(dev, 0x4, 0xc2f);
30792 + write_rtl8255(dev, 0x4, 0xe2f);
30793 + write_rtl8255(dev, 0x4, 0xc2f);
30794 + write_rtl8255(dev, 0x1, 0x0);
30795 + write_rtl8255(dev, 0x4, 0x82f);
30796 + write_rtl8255(dev, 0x3, 0x0);
30797 + write_rtl8255(dev, 0x2, 0x0);
30798 + write_rtl8255(dev, 0x4, 0xa2f);
30799 + write_rtl8255(dev, 0x4, 0x82f);
30800 + write_rtl8255(dev, 0x4, 0x42f);
30801 + write_rtl8255(dev, 0x3, 0x24);
30802 + write_rtl8255(dev, 0x2, 0x26);
30803 + write_rtl8255(dev, 0x4, 0x62f);
30804 + write_rtl8255(dev, 0x4, 0x42f);
30805 + write_rtl8255(dev, 0x4, 0x42f);
30806 + write_rtl8255(dev, 0x3, 0x100);
30807 + write_rtl8255(dev, 0x4, 0x62f);
30808 + write_rtl8255(dev, 0x4, 0x42f);
30809 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
30810 + 0x92402a50, 0xf8019, 0x70028000, 0xc00, 0x0);
30811 + write_rtl8255(dev, 0x1, 0x807);
30812 + write_rtl8255(dev, 0x4, 0xc30);
30813 + write_rtl8255(dev, 0x4, 0xe30);
30814 + write_rtl8255(dev, 0x4, 0xc30);
30815 + write_rtl8255(dev, 0x1, 0x0);
30816 + write_rtl8255(dev, 0x4, 0x830);
30817 + write_rtl8255(dev, 0x3, 0x0);
30818 + write_rtl8255(dev, 0x2, 0x0);
30819 + write_rtl8255(dev, 0x4, 0xa30);
30820 + write_rtl8255(dev, 0x4, 0x830);
30821 + write_rtl8255(dev, 0x4, 0x430);
30822 + write_rtl8255(dev, 0x3, 0x24);
30823 + write_rtl8255(dev, 0x2, 0x26);
30824 + write_rtl8255(dev, 0x4, 0x630);
30825 + write_rtl8255(dev, 0x4, 0x430);
30826 + write_rtl8255(dev, 0x4, 0x430);
30827 + write_rtl8255(dev, 0x3, 0x100);
30828 + write_rtl8255(dev, 0x4, 0x630);
30829 + write_rtl8255(dev, 0x4, 0x430);
30830 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
30831 + 0x92402a50, 0xf8019, 0x70028000, 0xc00, 0x0);
30832 + write_rtl8255(dev, 0x1, 0x807);
30833 + write_rtl8255(dev, 0x4, 0xc31);
30834 + write_rtl8255(dev, 0x4, 0xe31);
30835 + write_rtl8255(dev, 0x4, 0xc31);
30836 + write_rtl8255(dev, 0x1, 0x0);
30837 + write_rtl8255(dev, 0x4, 0x831);
30838 + write_rtl8255(dev, 0x3, 0x0);
30839 + write_rtl8255(dev, 0x2, 0x0);
30840 + write_rtl8255(dev, 0x4, 0xa31);
30841 + write_rtl8255(dev, 0x4, 0x831);
30842 + write_rtl8255(dev, 0x4, 0x431);
30843 + write_rtl8255(dev, 0x3, 0x24);
30844 + write_rtl8255(dev, 0x2, 0x26);
30845 + write_rtl8255(dev, 0x4, 0x631);
30846 + write_rtl8255(dev, 0x4, 0x431);
30847 + write_rtl8255(dev, 0x4, 0x431);
30848 + write_rtl8255(dev, 0x3, 0x100);
30849 + write_rtl8255(dev, 0x4, 0x631);
30850 + write_rtl8255(dev, 0x4, 0x431);
30851 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
30852 + 0x92402a54, 0xf8019, 0x70028000, 0xc00, 0x0);
30853 + write_rtl8255(dev, 0x1, 0x807);
30854 + write_rtl8255(dev, 0x4, 0xc32);
30855 + write_rtl8255(dev, 0x4, 0xe32);
30856 + write_rtl8255(dev, 0x4, 0xc32);
30857 + write_rtl8255(dev, 0x1, 0x0);
30858 + write_rtl8255(dev, 0x4, 0x832);
30859 + write_rtl8255(dev, 0x3, 0x0);
30860 + write_rtl8255(dev, 0x2, 0x0);
30861 + write_rtl8255(dev, 0x4, 0xa32);
30862 + write_rtl8255(dev, 0x4, 0x832);
30863 + write_rtl8255(dev, 0x4, 0x432);
30864 + write_rtl8255(dev, 0x3, 0x24);
30865 + write_rtl8255(dev, 0x2, 0x26);
30866 + write_rtl8255(dev, 0x4, 0x632);
30867 + write_rtl8255(dev, 0x4, 0x432);
30868 + write_rtl8255(dev, 0x4, 0x432);
30869 + write_rtl8255(dev, 0x3, 0x100);
30870 + write_rtl8255(dev, 0x4, 0x632);
30871 + write_rtl8255(dev, 0x4, 0x432);
30872 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
30873 + 0x92402a54, 0xf8019, 0x70028000, 0xc00, 0x0);
30874 + write_rtl8255(dev, 0x1, 0x807);
30875 + write_rtl8255(dev, 0x4, 0xc33);
30876 + write_rtl8255(dev, 0x4, 0xe33);
30877 + write_rtl8255(dev, 0x4, 0xc33);
30878 + write_rtl8255(dev, 0x1, 0x0);
30879 + write_rtl8255(dev, 0x4, 0x833);
30880 + write_rtl8255(dev, 0x3, 0x0);
30881 + write_rtl8255(dev, 0x2, 0x0);
30882 + write_rtl8255(dev, 0x4, 0xa33);
30883 + write_rtl8255(dev, 0x4, 0x833);
30884 + write_rtl8255(dev, 0x4, 0x433);
30885 + write_rtl8255(dev, 0x3, 0x24);
30886 + write_rtl8255(dev, 0x2, 0x26);
30887 + write_rtl8255(dev, 0x4, 0x633);
30888 + write_rtl8255(dev, 0x4, 0x433);
30889 + write_rtl8255(dev, 0x4, 0x433);
30890 + write_rtl8255(dev, 0x3, 0x100);
30891 + write_rtl8255(dev, 0x4, 0x633);
30892 + write_rtl8255(dev, 0x4, 0x433);
30893 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
30894 + 0x92402a58, 0xf8019, 0x70028000, 0xc00, 0x0);
30895 + write_rtl8255(dev, 0x1, 0x807);
30896 + write_rtl8255(dev, 0x4, 0xc34);
30897 + write_rtl8255(dev, 0x4, 0xe34);
30898 + write_rtl8255(dev, 0x4, 0xc34);
30899 + write_rtl8255(dev, 0x1, 0x0);
30900 + write_rtl8255(dev, 0x4, 0x834);
30901 + write_rtl8255(dev, 0x3, 0x0);
30902 + write_rtl8255(dev, 0x2, 0x0);
30903 + write_rtl8255(dev, 0x4, 0xa34);
30904 + write_rtl8255(dev, 0x4, 0x834);
30905 + write_rtl8255(dev, 0x4, 0x434);
30906 + write_rtl8255(dev, 0x3, 0x24);
30907 + write_rtl8255(dev, 0x2, 0x26);
30908 + write_rtl8255(dev, 0x4, 0x634);
30909 + write_rtl8255(dev, 0x4, 0x434);
30910 + write_rtl8255(dev, 0x4, 0x434);
30911 + write_rtl8255(dev, 0x3, 0x100);
30912 + write_rtl8255(dev, 0x4, 0x634);
30913 + write_rtl8255(dev, 0x4, 0x434);
30914 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
30915 + 0x92402a58, 0xf8019, 0x70028000, 0xc00, 0x0);
30916 + write_rtl8255(dev, 0x1, 0x807);
30917 + write_rtl8255(dev, 0x4, 0xc35);
30918 + write_rtl8255(dev, 0x4, 0xe35);
30919 + write_rtl8255(dev, 0x4, 0xc35);
30920 + write_rtl8255(dev, 0x1, 0x0);
30921 + write_rtl8255(dev, 0x4, 0x835);
30922 + write_rtl8255(dev, 0x3, 0x0);
30923 + write_rtl8255(dev, 0x2, 0x0);
30924 + write_rtl8255(dev, 0x4, 0xa35);
30925 + write_rtl8255(dev, 0x4, 0x835);
30926 + write_rtl8255(dev, 0x4, 0x435);
30927 + write_rtl8255(dev, 0x3, 0x24);
30928 + write_rtl8255(dev, 0x2, 0x26);
30929 + write_rtl8255(dev, 0x4, 0x635);
30930 + write_rtl8255(dev, 0x4, 0x435);
30931 + write_rtl8255(dev, 0x4, 0x435);
30932 + write_rtl8255(dev, 0x3, 0x100);
30933 + write_rtl8255(dev, 0x4, 0x635);
30934 + write_rtl8255(dev, 0x4, 0x435);
30935 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
30936 + 0x92402a24, 0xf8019, 0x70028000, 0xc00, 0x0);
30937 + write_rtl8255(dev, 0x1, 0x807);
30938 + write_rtl8255(dev, 0x4, 0xc36);
30939 + write_rtl8255(dev, 0x4, 0xe36);
30940 + write_rtl8255(dev, 0x4, 0xc36);
30941 + write_rtl8255(dev, 0x1, 0x0);
30942 + write_rtl8255(dev, 0x4, 0x836);
30943 + write_rtl8255(dev, 0x3, 0x0);
30944 + write_rtl8255(dev, 0x2, 0x0);
30945 + write_rtl8255(dev, 0x4, 0xa36);
30946 + write_rtl8255(dev, 0x4, 0x836);
30947 + write_rtl8255(dev, 0x4, 0x436);
30948 + write_rtl8255(dev, 0x3, 0x24);
30949 + write_rtl8255(dev, 0x2, 0x25);
30950 + write_rtl8255(dev, 0x4, 0x636);
30951 + write_rtl8255(dev, 0x4, 0x436);
30952 + write_rtl8255(dev, 0x4, 0x436);
30953 + write_rtl8255(dev, 0x3, 0x100);
30954 + write_rtl8255(dev, 0x4, 0x636);
30955 + write_rtl8255(dev, 0x4, 0x436);
30956 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
30957 + 0x92402a24, 0xf8019, 0x70028000, 0xc00, 0x0);
30958 + write_rtl8255(dev, 0x1, 0x807);
30959 + write_rtl8255(dev, 0x4, 0xc37);
30960 + write_rtl8255(dev, 0x4, 0xe37);
30961 + write_rtl8255(dev, 0x4, 0xc37);
30962 + write_rtl8255(dev, 0x1, 0x0);
30963 + write_rtl8255(dev, 0x4, 0x837);
30964 + write_rtl8255(dev, 0x3, 0x0);
30965 + write_rtl8255(dev, 0x2, 0x0);
30966 + write_rtl8255(dev, 0x4, 0xa37);
30967 + write_rtl8255(dev, 0x4, 0x837);
30968 + write_rtl8255(dev, 0x4, 0x437);
30969 + write_rtl8255(dev, 0x3, 0x24);
30970 + write_rtl8255(dev, 0x2, 0x25);
30971 + write_rtl8255(dev, 0x4, 0x637);
30972 + write_rtl8255(dev, 0x4, 0x437);
30973 + write_rtl8255(dev, 0x4, 0x437);
30974 + write_rtl8255(dev, 0x3, 0x100);
30975 + write_rtl8255(dev, 0x4, 0x637);
30976 + write_rtl8255(dev, 0x4, 0x437);
30977 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
30978 + 0x92402a28, 0xf8019, 0x70028000, 0xc00, 0x0);
30979 + write_rtl8255(dev, 0x1, 0x807);
30980 + write_rtl8255(dev, 0x4, 0xc38);
30981 + write_rtl8255(dev, 0x4, 0xe38);
30982 + write_rtl8255(dev, 0x4, 0xc38);
30983 + write_rtl8255(dev, 0x1, 0x0);
30984 + write_rtl8255(dev, 0x4, 0x838);
30985 + write_rtl8255(dev, 0x3, 0x0);
30986 + write_rtl8255(dev, 0x2, 0x0);
30987 + write_rtl8255(dev, 0x4, 0xa38);
30988 + write_rtl8255(dev, 0x4, 0x838);
30989 + write_rtl8255(dev, 0x4, 0x438);
30990 + write_rtl8255(dev, 0x3, 0x24);
30991 + write_rtl8255(dev, 0x2, 0x25);
30992 + write_rtl8255(dev, 0x4, 0x638);
30993 + write_rtl8255(dev, 0x4, 0x438);
30994 + write_rtl8255(dev, 0x4, 0x438);
30995 + write_rtl8255(dev, 0x3, 0x100);
30996 + write_rtl8255(dev, 0x4, 0x638);
30997 + write_rtl8255(dev, 0x4, 0x438);
30998 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
30999 + 0x92402a28, 0xf8019, 0x70028000, 0xc00, 0x0);
31000 + write_rtl8255(dev, 0x1, 0x807);
31001 + write_rtl8255(dev, 0x4, 0xc39);
31002 + write_rtl8255(dev, 0x4, 0xe39);
31003 + write_rtl8255(dev, 0x4, 0xc39);
31004 + write_rtl8255(dev, 0x1, 0x0);
31005 + write_rtl8255(dev, 0x4, 0x839);
31006 + write_rtl8255(dev, 0x3, 0x0);
31007 + write_rtl8255(dev, 0x2, 0x0);
31008 + write_rtl8255(dev, 0x4, 0xa39);
31009 + write_rtl8255(dev, 0x4, 0x839);
31010 + write_rtl8255(dev, 0x4, 0x439);
31011 + write_rtl8255(dev, 0x3, 0x24);
31012 + write_rtl8255(dev, 0x2, 0x25);
31013 + write_rtl8255(dev, 0x4, 0x639);
31014 + write_rtl8255(dev, 0x4, 0x439);
31015 + write_rtl8255(dev, 0x4, 0x439);
31016 + write_rtl8255(dev, 0x3, 0x100);
31017 + write_rtl8255(dev, 0x4, 0x639);
31018 + write_rtl8255(dev, 0x4, 0x439);
31019 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
31020 + 0x92402a00, 0xf8019, 0x70028000, 0xc00, 0x0);
31021 + write_rtl8255(dev, 0x1, 0x807);
31022 + write_rtl8255(dev, 0x4, 0xc3a);
31023 + write_rtl8255(dev, 0x4, 0xe3a);
31024 + write_rtl8255(dev, 0x4, 0xc3a);
31025 + write_rtl8255(dev, 0x1, 0x0);
31026 + write_rtl8255(dev, 0x4, 0x83a);
31027 + write_rtl8255(dev, 0x3, 0x0);
31028 + write_rtl8255(dev, 0x2, 0x0);
31029 + write_rtl8255(dev, 0x4, 0xa3a);
31030 + write_rtl8255(dev, 0x4, 0x83a);
31031 + write_rtl8255(dev, 0x4, 0x43a);
31032 + write_rtl8255(dev, 0x3, 0x0);
31033 + write_rtl8255(dev, 0x2, 0x0);
31034 + write_rtl8255(dev, 0x4, 0x63a);
31035 + write_rtl8255(dev, 0x4, 0x43a);
31036 + write_rtl8255(dev, 0x4, 0x43a);
31037 + write_rtl8255(dev, 0x3, 0x100);
31038 + write_rtl8255(dev, 0x4, 0x63a);
31039 + write_rtl8255(dev, 0x4, 0x43a);
31040 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
31041 + 0x92402a00, 0xf8019, 0x70028000, 0xc00, 0x0);
31042 + write_rtl8255(dev, 0x1, 0x807);
31043 + write_rtl8255(dev, 0x4, 0xc3b);
31044 + write_rtl8255(dev, 0x4, 0xe3b);
31045 + write_rtl8255(dev, 0x4, 0xc3b);
31046 + write_rtl8255(dev, 0x1, 0x0);
31047 + write_rtl8255(dev, 0x4, 0x83b);
31048 + write_rtl8255(dev, 0x3, 0x0);
31049 + write_rtl8255(dev, 0x2, 0x0);
31050 + write_rtl8255(dev, 0x4, 0xa3b);
31051 + write_rtl8255(dev, 0x4, 0x83b);
31052 + write_rtl8255(dev, 0x4, 0x43b);
31053 + write_rtl8255(dev, 0x3, 0x0);
31054 + write_rtl8255(dev, 0x2, 0x0);
31055 + write_rtl8255(dev, 0x4, 0x63b);
31056 + write_rtl8255(dev, 0x4, 0x43b);
31057 + write_rtl8255(dev, 0x4, 0x43b);
31058 + write_rtl8255(dev, 0x3, 0x100);
31059 + write_rtl8255(dev, 0x4, 0x63b);
31060 + write_rtl8255(dev, 0x4, 0x43b);
31061 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
31062 + 0x92402a00, 0xf8019, 0x70028000, 0xc00, 0x0);
31063 + write_rtl8255(dev, 0x1, 0x807);
31064 + write_rtl8255(dev, 0x4, 0xc3c);
31065 + write_rtl8255(dev, 0x4, 0xe3c);
31066 + write_rtl8255(dev, 0x4, 0xc3c);
31067 + write_rtl8255(dev, 0x1, 0x0);
31068 + write_rtl8255(dev, 0x4, 0x83c);
31069 + write_rtl8255(dev, 0x3, 0x0);
31070 + write_rtl8255(dev, 0x2, 0x0);
31071 + write_rtl8255(dev, 0x4, 0xa3c);
31072 + write_rtl8255(dev, 0x4, 0x83c);
31073 + write_rtl8255(dev, 0x4, 0x43c);
31074 + write_rtl8255(dev, 0x3, 0x0);
31075 + write_rtl8255(dev, 0x2, 0x0);
31076 + write_rtl8255(dev, 0x4, 0x63c);
31077 + write_rtl8255(dev, 0x4, 0x43c);
31078 + write_rtl8255(dev, 0x4, 0x43c);
31079 + write_rtl8255(dev, 0x3, 0x100);
31080 + write_rtl8255(dev, 0x4, 0x63c);
31081 + write_rtl8255(dev, 0x4, 0x43c);
31082 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
31083 + 0x92402a00, 0xf8019, 0x70028000, 0xc00, 0x0);
31084 + write_rtl8255(dev, 0x1, 0x807);
31085 + write_rtl8255(dev, 0x4, 0xc3d);
31086 + write_rtl8255(dev, 0x4, 0xe3d);
31087 + write_rtl8255(dev, 0x4, 0xc3d);
31088 + write_rtl8255(dev, 0x1, 0x0);
31089 + write_rtl8255(dev, 0x4, 0x83d);
31090 + write_rtl8255(dev, 0x3, 0x0);
31091 + write_rtl8255(dev, 0x2, 0x0);
31092 + write_rtl8255(dev, 0x4, 0xa3d);
31093 + write_rtl8255(dev, 0x4, 0x83d);
31094 + write_rtl8255(dev, 0x4, 0x43d);
31095 + write_rtl8255(dev, 0x3, 0x0);
31096 + write_rtl8255(dev, 0x2, 0x0);
31097 + write_rtl8255(dev, 0x4, 0x63d);
31098 + write_rtl8255(dev, 0x4, 0x43d);
31099 + write_rtl8255(dev, 0x4, 0x43d);
31100 + write_rtl8255(dev, 0x3, 0x100);
31101 + write_rtl8255(dev, 0x4, 0x63d);
31102 + write_rtl8255(dev, 0x4, 0x43d);
31103 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
31104 + 0x92402a00, 0xf8019, 0x70028000, 0xc00, 0x0);
31105 + write_rtl8255(dev, 0x1, 0x807);
31106 + write_rtl8255(dev, 0x4, 0xc3e);
31107 + write_rtl8255(dev, 0x4, 0xe3e);
31108 + write_rtl8255(dev, 0x4, 0xc3e);
31109 + write_rtl8255(dev, 0x1, 0x0);
31110 + write_rtl8255(dev, 0x4, 0x83e);
31111 + write_rtl8255(dev, 0x3, 0x0);
31112 + write_rtl8255(dev, 0x2, 0x0);
31113 + write_rtl8255(dev, 0x4, 0xa3e);
31114 + write_rtl8255(dev, 0x4, 0x83e);
31115 + write_rtl8255(dev, 0x4, 0x43e);
31116 + write_rtl8255(dev, 0x3, 0x0);
31117 + write_rtl8255(dev, 0x2, 0x0);
31118 + write_rtl8255(dev, 0x4, 0x63e);
31119 + write_rtl8255(dev, 0x4, 0x43e);
31120 + write_rtl8255(dev, 0x4, 0x43e);
31121 + write_rtl8255(dev, 0x3, 0x100);
31122 + write_rtl8255(dev, 0x4, 0x63e);
31123 + write_rtl8255(dev, 0x4, 0x43e);
31124 + write_rtl8255_reg0c(dev, 0x1554, 0xa800403b, 0xf6d44278, 0x80404000, 0x80000027,
31125 + 0x92402a00, 0xf8011, 0x70028000, 0xc00, 0x0);
31126 + write_rtl8255(dev, 0x1, 0x807);
31127 + write_rtl8255(dev, 0x4, 0xc3f);
31128 + write_rtl8255(dev, 0x4, 0xe3f);
31129 + write_rtl8255(dev, 0x4, 0xc3f);
31130 + write_rtl8255(dev, 0x1, 0x0);
31131 + write_rtl8255(dev, 0x4, 0x83f);
31132 + write_rtl8255(dev, 0x3, 0x0);
31133 + write_rtl8255(dev, 0x2, 0x0);
31134 + write_rtl8255(dev, 0x4, 0xa3f);
31135 + write_rtl8255(dev, 0x4, 0x83f);
31136 + write_rtl8255(dev, 0x4, 0x43f);
31137 + write_rtl8255(dev, 0x3, 0x0);
31138 + write_rtl8255(dev, 0x2, 0x0);
31139 + write_rtl8255(dev, 0x4, 0x63f);
31140 + write_rtl8255(dev, 0x4, 0x43f);
31141 + write_rtl8255(dev, 0x4, 0x43f);
31142 + write_rtl8255(dev, 0x3, 0x100);
31143 + write_rtl8255(dev, 0x4, 0x63f);
31144 + write_rtl8255(dev, 0x4, 0x43f);
31145 + write_rtl8255(dev, 0x4, 0x0);
31146 + write_rtl8255(dev, 0x1, 0x0);
31147 + write_rtl8255_reg0c(dev, 0x3539, 0x70000c03, 0xfef46178, 0x408000, 0x403307,
31148 + 0x924f80c0, 0xf955c, 0x8400, 0x429200, 0x1ce20);
31149 + write_rtl8255(dev, 0x1, 0x1c7);
31150 + write_rtl8255(dev, 0x2, 0x26);
31151 + write_rtl8255(dev, 0x3, 0x27);
31152 + write_rtl8255(dev, 0x1, 0x47);
31153 + write_rtl8255(dev, 0x4, 0x98c);
31154 + write_rtl8255(dev, 0x5, 0x65);
31155 + write_rtl8255(dev, 0x6, 0x13);
31156 + write_rtl8255(dev, 0x7, 0x7c);
31157 + write_rtl8255(dev, 0x8, 0x6);
31158 + write_rtl8255(dev, 0x8, 0x7);
31159 + write_rtl8255(dev, 0x8, 0x6);
31160 + write_rtl8255(dev, 0x9, 0xce2);
31161 + write_rtl8255(dev, 0xb, 0x1c5);
31162 + write_rtl8255(dev, 0xd, 0xd7f);
31163 + write_rtl8255(dev, 0xe, 0x369);
31164 + write_rtl8255(dev, 0xa, 0xd56);
31165 + write_rtl8255(dev, 0xa, 0xd57);
31167 + write_rtl8255(dev, 0xd, 0xd7e);
31172 +void rtl8255_set_band_param(struct net_device *dev, short band)
31174 + if(band != BAND_A){
31175 + write_nic_dword(dev, 0x94, 0x3dc00002);
31176 + write_nic_dword(dev, 0x88, 0x00100040);
31178 + write_phy_cck(dev, 0x13, 0xd0);
31180 + write_phy_cck(dev, 0x41, 0x9d);
31181 + write_nic_dword(dev, 0x8c, 0x00082205);
31182 + write_nic_byte(dev, 0xb4, 0x66);
31186 +void rtl8255_rf_init(struct net_device *dev)
31188 + struct r8180_priv *priv = ieee80211_priv(dev);
31191 +// short channel /*= priv->chan*/ = 1;
31194 + write_nic_word(dev, RFPinsOutput, 0x80);
31195 + write_nic_word(dev, RFPinsSelect, 0x80 | SW_CONTROL_GPIO);
31196 + write_nic_word(dev, RFPinsEnable, 0x80);
31197 + write_nic_word(dev, RFPinsSelect, SW_CONTROL_GPIO);
31199 + write_nic_dword(dev, RF_TIMING, 0x000f800f);
31201 + brsr = read_nic_word(dev, BRSR);
31203 + write_nic_word(dev, 0x2c, 0xffff);
31206 + rtl8180_set_anaparam(dev, RTL8255_ANAPARAM_ON);
31207 + rtl8185_set_anaparam2(dev, RTL8255_ANAPARAM2_ON);
31209 + write_nic_dword(dev, 0x94, 0x11c00002);
31211 + write_nic_dword(dev, RF_PARA, 0x100040);
31213 + rtl8185_rf_pins_enable(dev);
31215 + rtl8255_init_BGband(dev);
31216 + rtl8255_set_band_param(dev,BAND_BG);
31218 + write_phy_cck(dev, 0x0, 0x98);
31219 + write_phy_cck(dev, 0x3, 0x20);
31220 + write_phy_cck(dev, 0x4, 0x2e);
31221 + write_phy_cck(dev, 0x5, 0x12);
31222 + write_phy_cck(dev, 0x6, 0xfc);
31223 + write_phy_cck(dev, 0x7, 0xd8);
31224 + write_phy_cck(dev, 0x8, 0x2e);
31225 + write_phy_cck(dev, 0x10, 0xd3);
31226 + write_phy_cck(dev, 0x11, 0x88);
31227 + write_phy_cck(dev, 0x12, 0x47);
31228 + write_phy_cck(dev, 0x13, 0xd0); /* Ver C & D & 8187*/
31230 + write_phy_cck(dev, 0x19, 0x0);
31231 + write_phy_cck(dev, 0x1a, 0xa0);
31232 + write_phy_cck(dev, 0x1b, 0x8);
31233 + write_phy_cck(dev, 0x40, 0x86); /* CCK Carrier Sense Threshold */
31234 + write_phy_cck(dev, 0x41, 0x9d); /* Energy Threshold */
31235 + //write_phy_cck(dev, 0x42, 0x0);
31236 + write_phy_cck(dev, 0x43, 0x8);
31238 + write_nic_byte(dev, TESTR,0x8);
31240 + for(i=0;i<128;i++){
31241 + write_phy_ofdm(dev, 0x4b, rtl8255_agc[i]);
31242 + write_phy_ofdm(dev, 0x4a, (u8)i+ 0x80);
31246 + write_phy_ofdm(dev, 0x0, 0x1);
31247 + write_phy_ofdm(dev, 0x1, 0x2);
31248 + write_phy_ofdm(dev, 0x2, 0x43);
31249 + write_phy_ofdm(dev, 0x3, 0x0);
31250 + write_phy_ofdm(dev, 0x4, 0x0);
31251 + write_phy_ofdm(dev, 0x5, 0x0);
31252 + write_phy_ofdm(dev, 0x6, 0x40);
31253 + write_phy_ofdm(dev, 0x7, 0x0);
31254 + write_phy_ofdm(dev, 0x8, 0x40);
31255 + write_phy_ofdm(dev, 0x9, 0xfe);
31256 + write_phy_ofdm(dev, 0xa, 0x9);
31257 + write_phy_ofdm(dev, 0xb, 0x80);
31258 + write_phy_ofdm(dev, 0xc, 0x1);
31259 + write_phy_ofdm(dev, 0xd, 0x43);
31260 + write_phy_ofdm(dev, 0xe, 0xd3);
31261 + write_phy_ofdm(dev, 0xf, 0x38);
31262 + write_phy_ofdm(dev, 0x10, 0x4);
31263 + write_phy_ofdm(dev, 0x11, 0x06);/*agc resp time 700*/
31264 + write_phy_ofdm(dev, 0x12, 0x20);
31265 + write_phy_ofdm(dev, 0x13, 0x20);
31266 + write_phy_ofdm(dev, 0x14, 0x0);
31267 + write_phy_ofdm(dev, 0x15, 0x40);
31268 + write_phy_ofdm(dev, 0x16, 0x0);
31269 + write_phy_ofdm(dev, 0x17, 0x40);
31270 + write_phy_ofdm(dev, 0x18, 0xef);
31271 + write_phy_ofdm(dev, 0x19, 0x25);
31272 + write_phy_ofdm(dev, 0x1a, 0x20);
31273 + write_phy_ofdm(dev, 0x1b, 0x7a);
31274 + write_phy_ofdm(dev, 0x1c, 0x84);
31275 + write_phy_ofdm(dev, 0x1e, 0x95);
31276 + write_phy_ofdm(dev, 0x1f, 0x75);
31277 + write_phy_ofdm(dev, 0x20, 0x1f);
31278 + write_phy_ofdm(dev, 0x21, 0x17);
31279 + write_phy_ofdm(dev, 0x22, 0x16);
31280 + write_phy_ofdm(dev, 0x23, 0x70); //FIXME maybe not needed
31281 + write_phy_ofdm(dev, 0x24, 0x70);
31282 + write_phy_ofdm(dev, 0x25, 0x0);
31283 + write_phy_ofdm(dev, 0x26, 0x10);
31284 + write_phy_ofdm(dev, 0x27, 0x88);
31287 + write_nic_dword(dev, 0x94, 0x3dc00002); //BAND DEPEND.
31288 +// write_nic_dword(dev, 0x94, 0x15c00002); //BAND DEPEND.
31290 + write_phy_cck(dev, 0x4, 0x18);
31291 + write_phy_cck(dev, 0x43, 0x18);
31292 + write_phy_cck(dev, 0x6, 0xdc);
31293 + write_phy_cck(dev, 0x44, 0x2b);
31294 + write_phy_cck(dev, 0x45, 0x2b);
31295 + write_phy_cck(dev, 0x46, 0x25);
31296 + write_phy_cck(dev, 0x47, 0x15);
31297 + write_phy_cck(dev, 0x48, 0x0);
31298 + write_phy_cck(dev, 0x49, 0x0);
31299 + write_phy_cck(dev, 0x4a, 0x0);
31300 + write_phy_cck(dev, 0x4b, 0x0);
31301 +// write_phy_cck(dev, 0x4c, 0x5);
31303 + write_phy_cck(dev, 0x41, 0x9d); /* Energy Threshold */
31304 + // TESTR 0xb 8187
31305 + write_phy_cck(dev, 0x10, 0x93);// & 0xfb);
31307 + //rtl8255_set_gain(dev, 1); /* FIXME this '1' is random */
31309 + rtl8255_SetTXPowerLevel(dev, priv->chan);
31311 + write_phy_cck(dev, 0x10, 0x93 |0x4); /* Rx ant B, 0xd3 for A */
31312 + write_phy_ofdm(dev, 0x26, 0x90); /* Rx ant B, 0x10 for A */
31314 + rtl8185_tx_antenna(dev, 0x3); /* TX ant B, 0x0 for A*/
31315 + /* make sure is waken up! */
31316 + rtl8180_set_anaparam(dev, RTL8255_ANAPARAM_ON);
31317 + rtl8185_set_anaparam2(dev, RTL8255_ANAPARAM2_ON);
31319 + rtl8255_set_band_param(dev,BAND_BG);
31321 + write_phy_cck(dev, 0x41, 0x9d);
31323 + rtl8255_set_gain(dev, 4);
31324 + //rtl8255_set_energy_threshold(dev);
31325 + write_phy_cck(dev, 0x41, 0x9d);
31326 + rtl8255_rf_set_chan(dev, priv->chan);
31328 + write_nic_word(dev, BRSR, brsr);
31332 +++ b/drivers/staging/rtl8187se/r8180_rtl8255.h
31335 + This is part of the rtl8180-sa2400 driver
31336 + released under the GPL (See file COPYING for details).
31337 + Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it>
31339 + This files contains programming code for the rtl8255
31342 + *Many* thanks to Realtek Corp. for their great support!
31346 +#define RTL8255_ANAPARAM_ON 0xa0000b59
31347 +#define RTL8255_ANAPARAM2_ON 0x840cf311
31350 +void rtl8255_rf_init(struct net_device *dev);
31351 +void rtl8255_rf_set_chan(struct net_device *dev,short ch);
31352 +void rtl8255_rf_close(struct net_device *dev);
31354 +++ b/drivers/staging/rtl8187se/r8180_sa2400.c
31357 + This files contains PHILIPS SA2400 radio frontend programming routines.
31359 + This is part of rtl8180 OpenSource driver
31360 + Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
31361 + Released under the terms of GPL (General Public Licence)
31363 + Parts of this driver are based on the GPL part of the
31364 + official realtek driver
31366 + Parts of this driver are based on the rtl8180 driver skeleton
31367 + from Patric Schenke & Andres Salomon
31369 + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
31371 + Code at http://che.ojctech.com/~dyoung/rtw/ has been useful to me to
31372 + understand some things.
31374 + Code from rtl8181 project has been useful to me to understand some things.
31376 + We want to tanks the Authors of such projects and the Ndiswrapper
31381 +#include "r8180.h"
31382 +#include "r8180_hw.h"
31383 +#include "r8180_sa2400.h"
31386 +//#define DEBUG_SA2400
31388 +u32 sa2400_chan[] = {
31389 + 0x0, //dummy channel 0
31407 +void rf_stabilize(struct net_device *dev)
31409 + force_pci_posting(dev);
31410 + mdelay(3); //for now use a great value.. we may optimize in future
31414 +void write_sa2400(struct net_device *dev,u8 adr, u32 data)
31416 +// struct r8180_priv *priv = ieee80211_priv(dev);
31419 + // philips sa2400 expects 24 bits data
31421 + /*if(adr == 4 && priv->digphy){
31422 + phy_config=0x60000000;
31424 + phy_config=0xb0000000;
31427 + phy_config = 0xb0000000; // MAC will bang bits to the sa2400
31429 + phy_config |= (((u32)(adr&0xf))<< 24);
31430 + phy_config |= (data & 0xffffff);
31431 + write_nic_dword(dev,PHY_CONFIG,phy_config);
31432 +#ifdef DEBUG_SA2400
31433 + DMESG("Writing sa2400: %x (adr %x)",phy_config,adr);
31435 + rf_stabilize(dev);
31440 +void sa2400_write_phy_antenna(struct net_device *dev,short ch)
31442 + struct r8180_priv *priv = ieee80211_priv(dev);
31445 + ant = SA2400_ANTENNA;
31446 + if(priv->antb) /*default antenna is antenna B */
31447 + ant |= BB_ANTENNA_B;
31449 + ant |= BB_ANTATTEN_CHAN14;
31450 + write_phy(dev,0x10,ant);
31451 + //DMESG("BB antenna %x ",ant);
31455 +/* from the rtl8181 embedded driver */
31456 +short sa2400_rf_set_sens(struct net_device *dev, short sens)
31459 + if ((sens > 85) || (sens < 54)) return -1;
31461 + write_sa2400(dev,5,0x1dfb | (sens-54) << 15 |(finetune<<20)); // AGC 0xc9dfb
31467 +void sa2400_rf_set_chan(struct net_device *dev, short ch)
31469 + struct r8180_priv *priv = ieee80211_priv(dev);
31470 + u32 txpw = 0xff & priv->chtxpwr[ch];
31471 + u32 chan = sa2400_chan[ch];
31473 + write_sa2400(dev,7,txpw);
31474 + //write_phy(dev,0x10,0xd1);
31475 + sa2400_write_phy_antenna(dev,ch);
31476 + write_sa2400(dev,0,chan);
31477 + write_sa2400(dev,1,0xbb50);
31478 + write_sa2400(dev,2,0x80);
31479 + write_sa2400(dev,3,0);
31483 +void sa2400_rf_close(struct net_device *dev)
31485 + write_sa2400(dev, 4, 0);
31489 +void sa2400_rf_init(struct net_device *dev)
31491 + struct r8180_priv *priv = ieee80211_priv(dev);
31495 + write_nic_byte(dev,PHY_DELAY,0x6); //this is general
31496 + write_nic_byte(dev,CARRIER_SENSE_COUNTER,0x4c); //this is general
31498 + /*these are philips sa2400 specific*/
31499 + anaparam = read_nic_dword(dev,ANAPARAM);
31500 + anaparam = anaparam &~ (1<<ANAPARAM_TXDACOFF_SHIFT);
31502 + anaparam = anaparam &~ANAPARAM_PWR1_MASK;
31503 + anaparam = anaparam &~ANAPARAM_PWR0_MASK;
31504 + if(priv->digphy){
31505 + anaparam |= (SA2400_DIG_ANAPARAM_PWR1_ON<<ANAPARAM_PWR1_SHIFT);
31506 + anaparam |= (SA2400_ANAPARAM_PWR0_ON<<ANAPARAM_PWR0_SHIFT);
31508 + anaparam |= (SA2400_ANA_ANAPARAM_PWR1_ON<<ANAPARAM_PWR1_SHIFT);
31511 + rtl8180_set_anaparam(dev,anaparam);
31513 + firdac = (priv->digphy) ? (1<<SA2400_REG4_FIRDAC_SHIFT) : 0;
31514 + write_sa2400(dev,0,sa2400_chan[priv->chan]);
31515 + write_sa2400(dev,1,0xbb50);
31516 + write_sa2400(dev,2,0x80);
31517 + write_sa2400(dev,3,0);
31518 + write_sa2400(dev,4,0x19340 | firdac);
31519 + write_sa2400(dev,5,0xc9dfb); // AGC
31520 + write_sa2400(dev,4,0x19348 | firdac); //calibrates VCO
31523 + write_sa2400(dev,4,0x1938c); /*???*/
31525 + write_sa2400(dev,4,0x19340 | firdac);
31527 + write_sa2400(dev,0,sa2400_chan[priv->chan]);
31528 + write_sa2400(dev,1,0xbb50);
31529 + write_sa2400(dev,2,0x80);
31530 + write_sa2400(dev,3,0);
31531 + write_sa2400(dev,4,0x19344 | firdac); //calibrates filter
31533 + /* new from rtl8180 embedded driver (rtl8181 project) */
31534 + write_sa2400(dev,6,0x13ff | (1<<23)); // MANRX
31535 + write_sa2400(dev,8,0); //VCO
31537 + if(!priv->digphy)
31539 + rtl8180_set_anaparam(dev, anaparam | \
31540 + (1<<ANAPARAM_TXDACOFF_SHIFT));
31542 + rtl8180_conttx_enable(dev);
31544 + write_sa2400(dev, 4, 0x19341); // calibrates DC
31546 + /* a 5us sleep is required here,
31547 + we rely on the 3ms delay introduced in write_sa2400
31549 + write_sa2400(dev, 4, 0x19345);
31550 + /* a 20us sleep is required here,
31551 + we rely on the 3ms delay introduced in write_sa2400
31553 + rtl8180_conttx_disable(dev);
31555 + rtl8180_set_anaparam(dev, anaparam);
31559 + write_sa2400(dev,4,0x19341 | firdac ); //RTX MODE
31561 + // Set tx power level !?
31564 + /*baseband configuration*/
31565 + write_phy(dev,0,0x98);
31566 + write_phy(dev,3,0x38);
31567 + write_phy(dev,4,0xe0);
31568 + write_phy(dev,5,0x90);
31569 + write_phy(dev,6,0x1a);
31570 + write_phy(dev,7,0x64);
31572 + /*Should be done something more here??*/
31574 + sa2400_write_phy_antenna(dev,priv->chan);
31576 + write_phy(dev,0x11,0x80);
31577 + if(priv->diversity)
31578 + write_phy(dev,0x12,0xc7);
31580 + write_phy(dev,0x12,0x47);
31582 + write_phy(dev,0x13,0x90 | priv->cs_treshold );
31584 + write_phy(dev,0x19,0x0);
31585 + write_phy(dev,0x1a,0xa0);
31587 + sa2400_rf_set_chan(dev,priv->chan);
31590 +++ b/drivers/staging/rtl8187se/r8180_sa2400.h
31593 + This is part of rtl8180 OpenSource driver - v 0.7
31594 + Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
31595 + Released under the terms of GPL (General Public Licence)
31597 + Parts of this driver are based on the GPL part of the official realtek driver
31598 + Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
31599 + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
31601 + We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
31604 +#define SA2400_ANTENNA 0x91
31605 +#define SA2400_DIG_ANAPARAM_PWR1_ON 0x8
31606 +#define SA2400_ANA_ANAPARAM_PWR1_ON 0x28
31607 +#define SA2400_ANAPARAM_PWR0_ON 0x3
31609 +#define SA2400_RF_MAX_SENS 85
31610 +#define SA2400_RF_DEF_SENS 80
31612 +#define SA2400_REG4_FIRDAC_SHIFT 7
31614 +void sa2400_rf_init(struct net_device *dev);
31615 +void sa2400_rf_set_chan(struct net_device *dev,short ch);
31616 +short sa2400_rf_set_sens(struct net_device *dev,short sens);
31617 +void sa2400_rf_close(struct net_device *dev);
31619 +++ b/drivers/staging/rtl8187se/r8180_wx.c
31622 + This file contains wireless extension handlers.
31624 + This is part of rtl8180 OpenSource driver.
31625 + Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it>
31626 + Released under the terms of GPL (General Public Licence)
31628 + Parts of this driver are based on the GPL part
31629 + of the official realtek driver.
31631 + Parts of this driver are based on the rtl8180 driver skeleton
31632 + from Patric Schenke & Andres Salomon.
31634 + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver.
31636 + We want to tanks the Authors of those projects and the Ndiswrapper
31641 +#include "r8180.h"
31642 +#include "r8180_hw.h"
31643 +#include "r8180_sa2400.h"
31645 +#ifdef ENABLE_DOT11D
31646 +#include "dot11d.h"
31649 +//#define RATE_COUNT 4
31650 +u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000,
31651 + 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000};
31653 +#define RATE_COUNT (sizeof(rtl8180_rates)/sizeof(rtl8180_rates[0]))
31655 +static CHANNEL_LIST DefaultChannelPlan[] = {
31656 +// {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14}, //Default channel plan
31657 + {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64},19}, //FCC
31658 + {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC
31659 + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI
31660 + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Spain. Change to ETSI.
31661 + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //France. Change to ETSI.
31662 + {{14,36,40,44,48,52,56,60,64},9}, //MKK
31663 + {{1,2,3,4,5,6,7,8,9,10,11,12,13,14, 36,40,44,48,52,56,60,64},22},//MKK1
31664 + {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //Israel.
31665 + {{1,2,3,4,5,6,7,8,9,10,11,12,13,34,38,42,46},17}, // For 11a , TELEC
31666 + {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14} //For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626
31668 +static int r8180_wx_get_freq(struct net_device *dev,
31669 + struct iw_request_info *a,
31670 + union iwreq_data *wrqu, char *b)
31672 + struct r8180_priv *priv = ieee80211_priv(dev);
31674 + return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b);
31678 +int r8180_wx_set_key(struct net_device *dev, struct iw_request_info *info,
31679 + union iwreq_data *wrqu, char *key)
31681 + struct r8180_priv *priv = ieee80211_priv(dev);
31682 + struct iw_point *erq = &(wrqu->encoding);
31684 + if(priv->ieee80211->bHwRadioOff)
31687 + if (erq->flags & IW_ENCODE_DISABLED) {
31691 +/* i = erq->flags & IW_ENCODE_INDEX;
31692 + if (i < 1 || i > 4)
31695 + if (erq->length > 0) {
31697 + //int len = erq->length <= 5 ? 5 : 13;
31699 + u32* tkey= (u32*) key;
31700 + priv->key0[0] = tkey[0];
31701 + priv->key0[1] = tkey[1];
31702 + priv->key0[2] = tkey[2];
31703 + priv->key0[3] = tkey[3] &0xff;
31704 + DMESG("Setting wep key to %x %x %x %x",
31705 + tkey[0],tkey[1],tkey[2],tkey[3]);
31706 + rtl8180_set_hw_wep(dev);
31712 +static int r8180_wx_set_beaconinterval(struct net_device *dev, struct iw_request_info *aa,
31713 + union iwreq_data *wrqu, char *b)
31715 + int *parms = (int *)b;
31716 + int bi = parms[0];
31718 + struct r8180_priv *priv = ieee80211_priv(dev);
31720 + if(priv->ieee80211->bHwRadioOff)
31723 + down(&priv->wx_sem);
31724 + DMESG("setting beacon interval to %x",bi);
31726 + priv->ieee80211->current_network.beacon_interval=bi;
31727 + rtl8180_commit(dev);
31728 + up(&priv->wx_sem);
31735 +static int r8180_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
31736 + union iwreq_data *wrqu, char *b)
31738 + struct r8180_priv *priv = ieee80211_priv(dev);
31739 + return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b);
31744 +static int r8180_wx_get_rate(struct net_device *dev,
31745 + struct iw_request_info *info,
31746 + union iwreq_data *wrqu, char *extra)
31748 + struct r8180_priv *priv = ieee80211_priv(dev);
31749 + return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra);
31754 +static int r8180_wx_set_rate(struct net_device *dev,
31755 + struct iw_request_info *info,
31756 + union iwreq_data *wrqu, char *extra)
31759 + struct r8180_priv *priv = ieee80211_priv(dev);
31762 + if(priv->ieee80211->bHwRadioOff)
31765 + down(&priv->wx_sem);
31767 + ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra);
31769 + up(&priv->wx_sem);
31775 +static int r8180_wx_set_crcmon(struct net_device *dev,
31776 + struct iw_request_info *info,
31777 + union iwreq_data *wrqu, char *extra)
31779 + struct r8180_priv *priv = ieee80211_priv(dev);
31780 + int *parms = (int *)extra;
31781 + int enable = (parms[0] > 0);
31782 + short prev = priv->crcmon;
31785 + if(priv->ieee80211->bHwRadioOff)
31788 + down(&priv->wx_sem);
31795 + DMESG("bad CRC in monitor mode are %s",
31796 + priv->crcmon ? "accepted" : "rejected");
31798 + if(prev != priv->crcmon && priv->up){
31799 + rtl8180_down(dev);
31803 + up(&priv->wx_sem);
31809 +static int r8180_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
31810 + union iwreq_data *wrqu, char *b)
31812 + struct r8180_priv *priv = ieee80211_priv(dev);
31816 + if(priv->ieee80211->bHwRadioOff)
31819 + down(&priv->wx_sem);
31821 +// printk("set mode ENABLE_IPS\n");
31822 + if(priv->bInactivePs){
31823 + if(wrqu->mode == IW_MODE_ADHOC)
31827 + ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b);
31829 + //rtl8180_commit(dev);
31831 + up(&priv->wx_sem);
31835 +//YJ,add,080819,for hidden ap
31836 +struct iw_range_with_scan_capa
31838 + /* Informative stuff (to choose between different interface) */
31839 + __u32 throughput; /* To give an idea... */
31840 + /* In theory this value should be the maximum benchmarked
31841 + * TCP/IP throughput, because with most of these devices the
31842 + * bit rate is meaningless (overhead an co) to estimate how
31843 + * fast the connection will go and pick the fastest one.
31844 + * I suggest people to play with Netperf or any benchmark...
31847 + /* NWID (or domain id) */
31848 + __u32 min_nwid; /* Minimal NWID we are able to set */
31849 + __u32 max_nwid; /* Maximal NWID we are able to set */
31851 + /* Old Frequency (backward compat - moved lower ) */
31852 + __u16 old_num_channels;
31853 + __u8 old_num_frequency;
31855 + /* Scan capabilities */
31858 +//YJ,add,080819,for hidden ap
31861 +static int rtl8180_wx_get_range(struct net_device *dev,
31862 + struct iw_request_info *info,
31863 + union iwreq_data *wrqu, char *extra)
31865 + struct iw_range *range = (struct iw_range *)extra;
31866 + struct r8180_priv *priv = ieee80211_priv(dev);
31869 + //struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range; //YJ,add,080819,for hidden ap
31871 + wrqu->data.length = sizeof(*range);
31872 + memset(range, 0, sizeof(*range));
31874 + /* Let's try to keep this struct in the same order as in
31875 + * linux/include/wireless.h
31878 + /* TODO: See what values we can set, and remove the ones we can't
31879 + * set, or fill them with some default data.
31882 + /* ~5 Mb/s real (802.11b) */
31883 + range->throughput = 5 * 1000 * 1000;
31885 + // TODO: Not used in 802.11b?
31886 +// range->min_nwid; /* Minimal NWID we are able to set */
31887 + // TODO: Not used in 802.11b?
31888 +// range->max_nwid; /* Maximal NWID we are able to set */
31890 + /* Old Frequency (backward compat - moved lower ) */
31891 +// range->old_num_channels;
31892 +// range->old_num_frequency;
31893 +// range->old_freq[6]; /* Filler to keep "version" at the same offset */
31894 + if(priv->rf_set_sens != NULL)
31895 + range->sensitivity = priv->max_sens; /* signal level threshold range */
31897 + range->max_qual.qual = 100;
31898 + /* TODO: Find real max RSSI and stick here */
31899 + range->max_qual.level = 0;
31900 + range->max_qual.noise = -98;
31901 + range->max_qual.updated = 7; /* Updated all three */
31903 + range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
31904 + /* TODO: Find real 'good' to 'bad' threshol value for RSSI */
31905 + range->avg_qual.level = 20 + -98;
31906 + range->avg_qual.noise = 0;
31907 + range->avg_qual.updated = 7; /* Updated all three */
31909 + range->num_bitrates = RATE_COUNT;
31911 + for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) {
31912 + range->bitrate[i] = rtl8180_rates[i];
31915 + range->min_frag = MIN_FRAG_THRESHOLD;
31916 + range->max_frag = MAX_FRAG_THRESHOLD;
31918 + range->pm_capa = 0;
31920 + range->we_version_compiled = WIRELESS_EXT;
31921 + range->we_version_source = 16;
31923 +// range->retry_capa; /* What retry options are supported */
31924 +// range->retry_flags; /* How to decode max/min retry limit */
31925 +// range->r_time_flags; /* How to decode max/min retry life */
31926 +// range->min_retry; /* Minimal number of retries */
31927 +// range->max_retry; /* Maximal number of retries */
31928 +// range->min_r_time; /* Minimal retry lifetime */
31929 +// range->max_r_time; /* Maximal retry lifetime */
31931 + range->num_channels = 14;
31933 + for (i = 0, val = 0; i < 14; i++) {
31935 + // Include only legal frequencies for some countries
31936 +#ifdef ENABLE_DOT11D
31937 + if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) {
31939 + if ((priv->ieee80211->channel_map)[i+1]) {
31941 + range->freq[val].i = i + 1;
31942 + range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000;
31943 + range->freq[val].e = 1;
31946 + // FIXME: do we need to set anything for channels
31947 + // we don't use ?
31950 + if (val == IW_MAX_FREQUENCIES)
31954 + range->num_frequency = val;
31955 + range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
31956 + IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
31958 + //tmp->scan_capa = 0x01; //YJ,add,080819,for hidden ap
31964 +static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
31965 + union iwreq_data *wrqu, char *b)
31967 + struct r8180_priv *priv = ieee80211_priv(dev);
31969 + struct ieee80211_device* ieee = priv->ieee80211;
31972 + if(priv->ieee80211->bHwRadioOff)
31975 +//YJ,add,080819, for hidden ap
31976 + //printk("==*&*&*&==>%s in\n", __func__);
31977 + //printk("=*&*&*&*===>flag:%x, %x\n", wrqu->data.flags, IW_SCAN_THIS_ESSID);
31978 + if (wrqu->data.flags & IW_SCAN_THIS_ESSID)
31980 + struct iw_scan_req* req = (struct iw_scan_req*)b;
31981 + if (req->essid_len)
31983 + //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid);
31984 + ieee->current_network.ssid_len = req->essid_len;
31985 + memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
31986 + //printk("=====>network ssid:%s\n", ieee->current_network.ssid);
31989 +//YJ,add,080819, for hidden ap, end
31991 + down(&priv->wx_sem);
31994 +// printk("set scan ENABLE_IPS\n");
31995 + priv->ieee80211->actscanning = true;
31996 + if(priv->bInactivePs && (priv->ieee80211->state != IEEE80211_LINKED)){
31998 +// down(&priv->ieee80211->wx_sem);
32000 +// if (priv->ieee80211->iw_mode == IW_MODE_MONITOR || !(priv->ieee80211->proto_started)){
32002 +// up(&priv->ieee80211->wx_sem);
32003 +// up(&priv->wx_sem);
32007 + // queue_work(priv->ieee80211->wq, &priv->ieee80211->wx_sync_scan_wq);
32008 + //printk("start scan============================>\n");
32009 + ieee80211_softmac_ips_scan_syncro(priv->ieee80211);
32010 +//ieee80211_start_scan(priv->ieee80211);
32011 + /* intentionally forget to up sem */
32012 +// up(&priv->ieee80211->wx_sem);
32018 + //YJ,add,080828, prevent scan in BusyTraffic
32019 + //FIXME: Need to consider last scan time
32020 + if ((priv->link_detect.bBusyTraffic) && (true))
32023 + printk("Now traffic is busy, please try later!\n");
32026 + //YJ,add,080828, prevent scan in BusyTraffic,end
32027 + ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b);
32033 + up(&priv->wx_sem);
32039 +static int r8180_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
32040 + union iwreq_data *wrqu, char *b)
32044 + struct r8180_priv *priv = ieee80211_priv(dev);
32046 + down(&priv->wx_sem);
32048 + ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b);
32052 + up(&priv->wx_sem);
32057 +static int r8180_wx_set_essid(struct net_device *dev,
32058 + struct iw_request_info *a,
32059 + union iwreq_data *wrqu, char *b)
32061 + struct r8180_priv *priv = ieee80211_priv(dev);
32065 + if(priv->ieee80211->bHwRadioOff)
32068 + down(&priv->wx_sem);
32070 + //printk("set essid ENABLE_IPS\n");
32071 + if(priv->bInactivePs)
32074 +// printk("haha:set essid %s essid_len = %d essid_flgs = %d\n",b, wrqu->essid.length, wrqu->essid.flags);
32076 + ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b);
32078 + up(&priv->wx_sem);
32083 +static int r8180_wx_get_essid(struct net_device *dev,
32084 + struct iw_request_info *a,
32085 + union iwreq_data *wrqu, char *b)
32088 + struct r8180_priv *priv = ieee80211_priv(dev);
32090 + down(&priv->wx_sem);
32092 + ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
32094 + up(&priv->wx_sem);
32100 +static int r8180_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
32101 + union iwreq_data *wrqu, char *b)
32104 + struct r8180_priv *priv = ieee80211_priv(dev);
32107 + if(priv->ieee80211->bHwRadioOff)
32110 + down(&priv->wx_sem);
32112 + ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
32114 + up(&priv->wx_sem);
32119 +static int r8180_wx_get_name(struct net_device *dev,
32120 + struct iw_request_info *info,
32121 + union iwreq_data *wrqu, char *extra)
32123 + struct r8180_priv *priv = ieee80211_priv(dev);
32124 + return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
32127 +static int r8180_wx_set_frag(struct net_device *dev,
32128 + struct iw_request_info *info,
32129 + union iwreq_data *wrqu, char *extra)
32131 + struct r8180_priv *priv = ieee80211_priv(dev);
32133 + if(priv->ieee80211->bHwRadioOff)
32136 + if (wrqu->frag.disabled)
32137 + priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
32139 + if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
32140 + wrqu->frag.value > MAX_FRAG_THRESHOLD)
32143 + priv->ieee80211->fts = wrqu->frag.value & ~0x1;
32150 +static int r8180_wx_get_frag(struct net_device *dev,
32151 + struct iw_request_info *info,
32152 + union iwreq_data *wrqu, char *extra)
32154 + struct r8180_priv *priv = ieee80211_priv(dev);
32156 + wrqu->frag.value = priv->ieee80211->fts;
32157 + wrqu->frag.fixed = 0; /* no auto select */
32158 + wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
32164 +static int r8180_wx_set_wap(struct net_device *dev,
32165 + struct iw_request_info *info,
32166 + union iwreq_data *awrq,
32170 + struct r8180_priv *priv = ieee80211_priv(dev);
32172 + if(priv->ieee80211->bHwRadioOff)
32175 + down(&priv->wx_sem);
32177 + ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra);
32179 + up(&priv->wx_sem);
32185 +static int r8180_wx_get_wap(struct net_device *dev,
32186 + struct iw_request_info *info,
32187 + union iwreq_data *wrqu, char *extra)
32189 + struct r8180_priv *priv = ieee80211_priv(dev);
32191 + return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra);
32195 +static int r8180_wx_set_enc(struct net_device *dev,
32196 + struct iw_request_info *info,
32197 + union iwreq_data *wrqu, char *key)
32199 + struct r8180_priv *priv = ieee80211_priv(dev);
32202 + if(priv->ieee80211->bHwRadioOff)
32206 + down(&priv->wx_sem);
32208 + if(priv->hw_wep) ret = r8180_wx_set_key(dev,info,wrqu,key);
32210 + DMESG("Setting SW wep key");
32211 + ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key);
32214 + up(&priv->wx_sem);
32219 +static int r8180_wx_get_enc(struct net_device *dev,
32220 + struct iw_request_info *info,
32221 + union iwreq_data *wrqu, char *key)
32223 + struct r8180_priv *priv = ieee80211_priv(dev);
32225 + return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
32229 +static int r8180_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union
32230 + iwreq_data *wrqu, char *p){
32232 + struct r8180_priv *priv = ieee80211_priv(dev);
32233 + int *parms=(int*)p;
32234 + int mode=parms[0];
32236 + if(priv->ieee80211->bHwRadioOff)
32239 + priv->ieee80211->active_scan = mode;
32245 +/* added by christian */
32247 +static int r8180_wx_set_monitor_type(struct net_device *dev, struct iw_request_info *aa, union
32248 + iwreq_data *wrqu, char *p){
32250 + struct r8180_priv *priv = ieee80211_priv(dev);
32251 + int *parms=(int*)p;
32252 + int mode=parms[0];
32254 + if(priv->ieee80211->iw_mode != IW_MODE_MONITOR) return -1;
32255 + priv->prism_hdr = mode;
32256 + if(!mode)dev->type=ARPHRD_IEEE80211;
32257 + else dev->type=ARPHRD_IEEE80211_PRISM;
32258 + DMESG("using %s RX encap", mode ? "AVS":"80211");
32263 +//of r8180_wx_set_monitor_type
32264 +/* end added christian */
32266 +static int r8180_wx_set_retry(struct net_device *dev,
32267 + struct iw_request_info *info,
32268 + union iwreq_data *wrqu, char *extra)
32270 + struct r8180_priv *priv = ieee80211_priv(dev);
32273 + if(priv->ieee80211->bHwRadioOff)
32276 + down(&priv->wx_sem);
32278 + if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
32279 + wrqu->retry.disabled){
32283 + if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){
32288 + if(wrqu->retry.value > R8180_MAX_RETRY){
32292 + if (wrqu->retry.flags & IW_RETRY_MAX) {
32293 + priv->retry_rts = wrqu->retry.value;
32294 + DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
32297 + priv->retry_data = wrqu->retry.value;
32298 + DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
32302 + * We might try to write directly the TX config register
32303 + * or to restart just the (R)TX process.
32304 + * I'm unsure if whole reset is really needed
32307 + rtl8180_commit(dev);
32310 + rtl8180_rtx_disable(dev);
32311 + rtl8180_rx_enable(dev);
32312 + rtl8180_tx_enable(dev);
32317 + up(&priv->wx_sem);
32322 +static int r8180_wx_get_retry(struct net_device *dev,
32323 + struct iw_request_info *info,
32324 + union iwreq_data *wrqu, char *extra)
32326 + struct r8180_priv *priv = ieee80211_priv(dev);
32329 + wrqu->retry.disabled = 0; /* can't be disabled */
32331 + if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
32332 + IW_RETRY_LIFETIME)
32335 + if (wrqu->retry.flags & IW_RETRY_MAX) {
32336 + wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
32337 + wrqu->retry.value = priv->retry_rts;
32339 + wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN;
32340 + wrqu->retry.value = priv->retry_data;
32342 + //DMESG("returning %d",wrqu->retry.value);
32348 +static int r8180_wx_get_sens(struct net_device *dev,
32349 + struct iw_request_info *info,
32350 + union iwreq_data *wrqu, char *extra)
32352 + struct r8180_priv *priv = ieee80211_priv(dev);
32353 + if(priv->rf_set_sens == NULL)
32354 + return -1; /* we have not this support for this radio */
32355 + wrqu->sens.value = priv->sens;
32360 +static int r8180_wx_set_sens(struct net_device *dev,
32361 + struct iw_request_info *info,
32362 + union iwreq_data *wrqu, char *extra)
32365 + struct r8180_priv *priv = ieee80211_priv(dev);
32369 + if(priv->ieee80211->bHwRadioOff)
32372 + down(&priv->wx_sem);
32373 + //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value);
32374 + if(priv->rf_set_sens == NULL) {
32375 + err= -1; /* we have not this support for this radio */
32378 + if(priv->rf_set_sens(dev, wrqu->sens.value) == 0)
32379 + priv->sens = wrqu->sens.value;
32384 + up(&priv->wx_sem);
32390 +static int r8180_wx_set_rawtx(struct net_device *dev,
32391 + struct iw_request_info *info,
32392 + union iwreq_data *wrqu, char *extra)
32394 + struct r8180_priv *priv = ieee80211_priv(dev);
32397 + if(priv->ieee80211->bHwRadioOff)
32400 + down(&priv->wx_sem);
32402 + ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
32404 + up(&priv->wx_sem);
32410 +static int r8180_wx_get_power(struct net_device *dev,
32411 + struct iw_request_info *info,
32412 + union iwreq_data *wrqu, char *extra)
32415 + struct r8180_priv *priv = ieee80211_priv(dev);
32417 + down(&priv->wx_sem);
32419 + ret = ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
32421 + up(&priv->wx_sem);
32426 +static int r8180_wx_set_power(struct net_device *dev,
32427 + struct iw_request_info *info,
32428 + union iwreq_data *wrqu, char *extra)
32431 + struct r8180_priv *priv = ieee80211_priv(dev);
32434 + if(priv->ieee80211->bHwRadioOff)
32437 + down(&priv->wx_sem);
32438 + printk("=>>>>>>>>>>=============================>set power:%d,%d!\n",wrqu->power.disabled, wrqu->power.flags);
32439 + if (wrqu->power.disabled==0) {
32440 + wrqu->power.flags|=IW_POWER_ALL_R;
32441 + wrqu->power.flags|=IW_POWER_TIMEOUT;
32442 + wrqu->power.value =1000;
32445 + ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
32447 + up(&priv->wx_sem);
32452 +static int r8180_wx_set_rts(struct net_device *dev,
32453 + struct iw_request_info *info,
32454 + union iwreq_data *wrqu, char *extra)
32456 + struct r8180_priv *priv = ieee80211_priv(dev);
32459 + if(priv->ieee80211->bHwRadioOff)
32462 + if (wrqu->rts.disabled)
32463 + priv->rts = DEFAULT_RTS_THRESHOLD;
32465 + if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
32466 + wrqu->rts.value > MAX_RTS_THRESHOLD)
32469 + priv->rts = wrqu->rts.value;
32474 +static int r8180_wx_get_rts(struct net_device *dev,
32475 + struct iw_request_info *info,
32476 + union iwreq_data *wrqu, char *extra)
32478 + struct r8180_priv *priv = ieee80211_priv(dev);
32482 + wrqu->rts.value = priv->rts;
32483 + wrqu->rts.fixed = 0; /* no auto select */
32484 + wrqu->rts.disabled = (wrqu->rts.value == 0);
32488 +static int dummy(struct net_device *dev, struct iw_request_info *a,
32489 + union iwreq_data *wrqu,char *b)
32495 +static int r8180_wx_get_psmode(struct net_device *dev,
32496 + struct iw_request_info *info,
32497 + union iwreq_data *wrqu, char *extra)
32499 + struct r8180_priv *priv = ieee80211_priv(dev);
32500 + struct ieee80211_device *ieee;
32505 + down(&priv->wx_sem);
32508 + ieee = priv->ieee80211;
32509 + if(ieee->ps == IEEE80211_PS_DISABLED) {
32510 + *((unsigned int *)extra) = IEEE80211_PS_DISABLED;
32513 + *((unsigned int *)extra) = IW_POWER_TIMEOUT;
32514 + if (ieee->ps & IEEE80211_PS_MBCAST)
32515 + *((unsigned int *)extra) |= IW_POWER_ALL_R;
32517 + *((unsigned int *)extra) |= IW_POWER_UNICAST_R;
32521 + up(&priv->wx_sem);
32525 +static int r8180_wx_set_psmode(struct net_device *dev,
32526 + struct iw_request_info *info,
32527 + union iwreq_data *wrqu, char *extra)
32529 + struct r8180_priv *priv = ieee80211_priv(dev);
32530 + //struct ieee80211_device *ieee;
32535 + down(&priv->wx_sem);
32537 + ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
32539 + up(&priv->wx_sem);
32546 +static int r8180_wx_get_iwmode(struct net_device *dev,
32547 + struct iw_request_info *info,
32548 + union iwreq_data *wrqu, char *extra)
32550 + struct r8180_priv *priv = ieee80211_priv(dev);
32551 + struct ieee80211_device *ieee;
32556 + down(&priv->wx_sem);
32558 + ieee = priv->ieee80211;
32560 + strcpy(extra, "802.11");
32561 + if(ieee->modulation & IEEE80211_CCK_MODULATION) {
32562 + strcat(extra, "b");
32563 + if(ieee->modulation & IEEE80211_OFDM_MODULATION)
32564 + strcat(extra, "/g");
32565 + } else if(ieee->modulation & IEEE80211_OFDM_MODULATION)
32566 + strcat(extra, "g");
32568 + up(&priv->wx_sem);
32572 +static int r8180_wx_set_iwmode(struct net_device *dev,
32573 + struct iw_request_info *info,
32574 + union iwreq_data *wrqu, char *extra)
32576 + struct r8180_priv *priv = ieee80211_priv(dev);
32577 + struct ieee80211_device *ieee = priv->ieee80211;
32578 + int *param = (int *)extra;
32580 + int modulation = 0, mode = 0;
32583 + if(priv->ieee80211->bHwRadioOff)
32586 + down(&priv->wx_sem);
32588 + if (*param == 1) {
32589 + modulation |= IEEE80211_CCK_MODULATION;
32591 + printk(KERN_INFO "B mode!\n");
32592 + } else if (*param == 2) {
32593 + modulation |= IEEE80211_OFDM_MODULATION;
32595 + printk(KERN_INFO "G mode!\n");
32596 + } else if (*param == 3) {
32597 + modulation |= IEEE80211_CCK_MODULATION;
32598 + modulation |= IEEE80211_OFDM_MODULATION;
32599 + mode = IEEE_B|IEEE_G;
32600 + printk(KERN_INFO "B/G mode!\n");
32603 + if(ieee->proto_started) {
32604 + ieee80211_stop_protocol(ieee);
32605 + ieee->mode = mode;
32606 + ieee->modulation = modulation;
32607 + ieee80211_start_protocol(ieee);
32609 + ieee->mode = mode;
32610 + ieee->modulation = modulation;
32611 +// ieee80211_start_protocol(ieee);
32614 + up(&priv->wx_sem);
32618 +static int r8180_wx_get_preamble(struct net_device *dev,
32619 + struct iw_request_info *info,
32620 + union iwreq_data *wrqu, char *extra)
32622 + struct r8180_priv *priv = ieee80211_priv(dev);
32626 + down(&priv->wx_sem);
32630 + *extra = (char) priv->plcp_preamble_mode; // 0:auto 1:short 2:long
32631 + up(&priv->wx_sem);
32635 +static int r8180_wx_set_preamble(struct net_device *dev,
32636 + struct iw_request_info *info,
32637 + union iwreq_data *wrqu, char *extra)
32639 + struct r8180_priv *priv = ieee80211_priv(dev);
32643 + if(priv->ieee80211->bHwRadioOff)
32646 + down(&priv->wx_sem);
32647 + if (*extra<0||*extra>2)
32650 + priv->plcp_preamble_mode = *((short *)extra) ;
32654 + up(&priv->wx_sem);
32658 +static int r8180_wx_get_siglevel(struct net_device *dev,
32659 + struct iw_request_info *info,
32660 + union iwreq_data *wrqu, char *extra)
32662 + struct r8180_priv *priv = ieee80211_priv(dev);
32663 + //struct ieee80211_network *network = &(priv->ieee80211->current_network);
32668 + down(&priv->wx_sem);
32669 + // Modify by hikaru 6.5
32670 + *((int *)extra) = priv->wstats.qual.level;//for interface test ,it should be the priv->wstats.qual.level;
32674 + up(&priv->wx_sem);
32678 +static int r8180_wx_get_sigqual(struct net_device *dev,
32679 + struct iw_request_info *info,
32680 + union iwreq_data *wrqu, char *extra)
32682 + struct r8180_priv *priv = ieee80211_priv(dev);
32683 + //struct ieee80211_network *network = &(priv->ieee80211->current_network);
32688 + down(&priv->wx_sem);
32689 + // Modify by hikaru 6.5
32690 + *((int *)extra) = priv->wstats.qual.qual;//for interface test ,it should be the priv->wstats.qual.qual;
32694 + up(&priv->wx_sem);
32698 +static int r8180_wx_reset_stats(struct net_device *dev,
32699 + struct iw_request_info *info,
32700 + union iwreq_data *wrqu, char *extra)
32702 + struct r8180_priv *priv =ieee80211_priv(dev);
32703 + down(&priv->wx_sem);
32705 + priv->stats.txrdu = 0;
32706 + priv->stats.rxrdu = 0;
32707 + priv->stats.rxnolast = 0;
32708 + priv->stats.rxnodata = 0;
32709 + priv->stats.rxnopointer = 0;
32710 + priv->stats.txnperr = 0;
32711 + priv->stats.txresumed = 0;
32712 + priv->stats.rxerr = 0;
32713 + priv->stats.rxoverflow = 0;
32714 + priv->stats.rxint = 0;
32716 + priv->stats.txnpokint = 0;
32717 + priv->stats.txhpokint = 0;
32718 + priv->stats.txhperr = 0;
32719 + priv->stats.ints = 0;
32720 + priv->stats.shints = 0;
32721 + priv->stats.txoverflow = 0;
32722 + priv->stats.rxdmafail = 0;
32723 + priv->stats.txbeacon = 0;
32724 + priv->stats.txbeaconerr = 0;
32725 + priv->stats.txlpokint = 0;
32726 + priv->stats.txlperr = 0;
32727 + priv->stats.txretry =0;//20060601
32728 + priv->stats.rxcrcerrmin=0;
32729 + priv->stats.rxcrcerrmid=0;
32730 + priv->stats.rxcrcerrmax=0;
32731 + priv->stats.rxicverr=0;
32733 + up(&priv->wx_sem);
32738 +static int r8180_wx_radio_on(struct net_device *dev,
32739 + struct iw_request_info *info,
32740 + union iwreq_data *wrqu, char *extra)
32742 + struct r8180_priv *priv =ieee80211_priv(dev);
32744 + if(priv->ieee80211->bHwRadioOff)
32748 + down(&priv->wx_sem);
32749 + priv->rf_wakeup(dev);
32751 + up(&priv->wx_sem);
32757 +static int r8180_wx_radio_off(struct net_device *dev,
32758 + struct iw_request_info *info,
32759 + union iwreq_data *wrqu, char *extra)
32761 + struct r8180_priv *priv =ieee80211_priv(dev);
32763 + if(priv->ieee80211->bHwRadioOff)
32767 + down(&priv->wx_sem);
32768 + priv->rf_sleep(dev);
32770 + up(&priv->wx_sem);
32775 +static int r8180_wx_get_channelplan(struct net_device *dev,
32776 + struct iw_request_info *info,
32777 + union iwreq_data *wrqu, char *extra)
32779 + struct r8180_priv *priv = ieee80211_priv(dev);
32783 + down(&priv->wx_sem);
32784 + *extra = priv->channel_plan;
32788 + up(&priv->wx_sem);
32792 +static int r8180_wx_set_channelplan(struct net_device *dev,
32793 + struct iw_request_info *info,
32794 + union iwreq_data *wrqu, char *extra)
32796 + struct r8180_priv *priv = ieee80211_priv(dev);
32797 + //struct ieee80211_device *ieee = netdev_priv(dev);
32798 + int *val = (int *)extra;
32800 + printk("-----in fun %s\n", __FUNCTION__);
32802 + if(priv->ieee80211->bHwRadioOff)
32805 + //unsigned long flags;
32806 + down(&priv->wx_sem);
32807 + if (DefaultChannelPlan[*val].Len != 0){
32808 + priv ->channel_plan = *val;
32809 + // Clear old channel map
32810 + for (i=1;i<=MAX_CHANNEL_NUMBER;i++)
32812 +#ifdef ENABLE_DOT11D
32813 + GET_DOT11D_INFO(priv->ieee80211)->channel_map[i] = 0;
32815 + priv->ieee80211->channel_map[i] = 0;
32818 + // Set new channel map
32819 + for (i=1;i<=DefaultChannelPlan[*val].Len;i++)
32821 +#ifdef ENABLE_DOT11D
32822 + GET_DOT11D_INFO(priv->ieee80211)->channel_map[DefaultChannelPlan[*val].Channel[i-1]] = 1;
32824 + priv->ieee80211->channel_map[DefaultChannelPlan[*val].Channel[i-1]] = 1;
32828 + up(&priv->wx_sem);
32833 +static int r8180_wx_get_version(struct net_device *dev,
32834 + struct iw_request_info *info,
32835 + union iwreq_data *wrqu, char *extra)
32837 + struct r8180_priv *priv = ieee80211_priv(dev);
32838 + //struct ieee80211_device *ieee;
32840 + down(&priv->wx_sem);
32841 + strcpy(extra, "1020.0808");
32842 + up(&priv->wx_sem);
32847 +//added by amy 080818
32848 +//receive datarate from user typing valid rate is from 2 to 108 (1 - 54M), if input 0, return to normal rate adaptive.
32849 +static int r8180_wx_set_forcerate(struct net_device *dev,
32850 + struct iw_request_info *info,
32851 + union iwreq_data *wrqu, char *extra)
32853 + struct r8180_priv *priv = ieee80211_priv(dev);
32854 + u8 forcerate = *extra;
32856 + down(&priv->wx_sem);
32858 + printk("==============>%s(): forcerate is %d\n",__FUNCTION__,forcerate);
32859 + if((forcerate == 2) || (forcerate == 4) || (forcerate == 11) || (forcerate == 22) || (forcerate == 12) ||
32860 + (forcerate == 18) || (forcerate == 24) || (forcerate == 36) || (forcerate == 48) || (forcerate == 72) ||
32861 + (forcerate == 96) || (forcerate == 108))
32863 + priv->ForcedDataRate = 1;
32864 + priv->ieee80211->rate = forcerate * 5;
32866 + else if(forcerate == 0)
32868 + priv->ForcedDataRate = 0;
32869 + printk("OK! return rate adaptive\n");
32872 + printk("ERR: wrong rate\n");
32873 + up(&priv->wx_sem);
32877 +static int r8180_wx_set_enc_ext(struct net_device *dev,
32878 + struct iw_request_info *info,
32879 + union iwreq_data *wrqu, char *extra)
32882 + struct r8180_priv *priv = ieee80211_priv(dev);
32883 + //printk("===>%s()\n", __FUNCTION__);
32887 + if(priv->ieee80211->bHwRadioOff)
32890 + down(&priv->wx_sem);
32891 + ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
32892 + up(&priv->wx_sem);
32896 +static int r8180_wx_set_auth(struct net_device *dev,
32897 + struct iw_request_info *info,
32898 + struct iw_param *data, char *extra)
32900 + //printk("====>%s()\n", __FUNCTION__);
32901 + struct r8180_priv *priv = ieee80211_priv(dev);
32904 + if(priv->ieee80211->bHwRadioOff)
32907 + down(&priv->wx_sem);
32908 + ret = ieee80211_wx_set_auth(priv->ieee80211, info, data, extra);
32909 + up(&priv->wx_sem);
32913 +static int r8180_wx_set_mlme(struct net_device *dev,
32914 + struct iw_request_info *info,
32915 + union iwreq_data *wrqu, char *extra)
32917 + //printk("====>%s()\n", __FUNCTION__);
32920 + struct r8180_priv *priv = ieee80211_priv(dev);
32923 + if(priv->ieee80211->bHwRadioOff)
32927 + down(&priv->wx_sem);
32929 + ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
32931 + up(&priv->wx_sem);
32934 +static int r8180_wx_set_gen_ie(struct net_device *dev,
32935 + struct iw_request_info *info,
32936 + struct iw_point *data, char *extra)
32938 +// printk("====>%s(), len:%d\n", __FUNCTION__, data->length);
32940 + struct r8180_priv *priv = ieee80211_priv(dev);
32943 + if(priv->ieee80211->bHwRadioOff)
32946 + down(&priv->wx_sem);
32948 + ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->length);
32950 + up(&priv->wx_sem);
32951 + //printk("<======%s(), ret:%d\n", __FUNCTION__, ret);
32956 +static iw_handler r8180_wx_handlers[] =
32958 + NULL, /* SIOCSIWCOMMIT */
32959 + r8180_wx_get_name, /* SIOCGIWNAME */
32960 + dummy, /* SIOCSIWNWID */
32961 + dummy, /* SIOCGIWNWID */
32962 + r8180_wx_set_freq, /* SIOCSIWFREQ */
32963 + r8180_wx_get_freq, /* SIOCGIWFREQ */
32964 + r8180_wx_set_mode, /* SIOCSIWMODE */
32965 + r8180_wx_get_mode, /* SIOCGIWMODE */
32966 + r8180_wx_set_sens, /* SIOCSIWSENS */
32967 + r8180_wx_get_sens, /* SIOCGIWSENS */
32968 + NULL, /* SIOCSIWRANGE */
32969 + rtl8180_wx_get_range, /* SIOCGIWRANGE */
32970 + NULL, /* SIOCSIWPRIV */
32971 + NULL, /* SIOCGIWPRIV */
32972 + NULL, /* SIOCSIWSTATS */
32973 + NULL, /* SIOCGIWSTATS */
32974 + dummy, /* SIOCSIWSPY */
32975 + dummy, /* SIOCGIWSPY */
32976 + NULL, /* SIOCGIWTHRSPY */
32977 + NULL, /* SIOCWIWTHRSPY */
32978 + r8180_wx_set_wap, /* SIOCSIWAP */
32979 + r8180_wx_get_wap, /* SIOCGIWAP */
32980 + r8180_wx_set_mlme, /* SIOCSIWMLME*/
32981 + dummy, /* SIOCGIWAPLIST -- depricated */
32982 + r8180_wx_set_scan, /* SIOCSIWSCAN */
32983 + r8180_wx_get_scan, /* SIOCGIWSCAN */
32984 + r8180_wx_set_essid, /* SIOCSIWESSID */
32985 + r8180_wx_get_essid, /* SIOCGIWESSID */
32986 + dummy, /* SIOCSIWNICKN */
32987 + dummy, /* SIOCGIWNICKN */
32988 + NULL, /* -- hole -- */
32989 + NULL, /* -- hole -- */
32990 + r8180_wx_set_rate, /* SIOCSIWRATE */
32991 + r8180_wx_get_rate, /* SIOCGIWRATE */
32992 + r8180_wx_set_rts, /* SIOCSIWRTS */
32993 + r8180_wx_get_rts, /* SIOCGIWRTS */
32994 + r8180_wx_set_frag, /* SIOCSIWFRAG */
32995 + r8180_wx_get_frag, /* SIOCGIWFRAG */
32996 + dummy, /* SIOCSIWTXPOW */
32997 + dummy, /* SIOCGIWTXPOW */
32998 + r8180_wx_set_retry, /* SIOCSIWRETRY */
32999 + r8180_wx_get_retry, /* SIOCGIWRETRY */
33000 + r8180_wx_set_enc, /* SIOCSIWENCODE */
33001 + r8180_wx_get_enc, /* SIOCGIWENCODE */
33002 + r8180_wx_set_power, /* SIOCSIWPOWER */
33003 + r8180_wx_get_power, /* SIOCGIWPOWER */
33004 + NULL, /*---hole---*/
33005 + NULL, /*---hole---*/
33006 + r8180_wx_set_gen_ie, /* SIOCSIWGENIE */
33007 + NULL, /* SIOCSIWGENIE */
33008 + r8180_wx_set_auth, /* SIOCSIWAUTH */
33009 + NULL, /* SIOCSIWAUTH */
33010 + r8180_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
33011 + NULL, /* SIOCSIWENCODEEXT */
33012 + NULL, /* SIOCSIWPMKSA */
33013 + NULL, /*---hole---*/
33017 +static const struct iw_priv_args r8180_private_args[] = {
33019 + SIOCIWFIRSTPRIV + 0x0,
33020 + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
33022 + { SIOCIWFIRSTPRIV + 0x1,
33027 + SIOCIWFIRSTPRIV + 0x2,
33028 + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "beaconint"
33030 + { SIOCIWFIRSTPRIV + 0x3,
33034 + /* added by christian */
33036 + // SIOCIWFIRSTPRIV + 0x2,
33037 + // IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "prismhdr"
33039 + /* end added by christian */
33041 + SIOCIWFIRSTPRIV + 0x4,
33042 + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
33045 + { SIOCIWFIRSTPRIV + 0x5,
33050 + SIOCIWFIRSTPRIV + 0x6,
33051 + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
33054 + { SIOCIWFIRSTPRIV + 0x7,
33059 +// SIOCIWFIRSTPRIV + 0x5,
33060 +// 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpsmode"
33063 +// SIOCIWFIRSTPRIV + 0x6,
33064 +// IW_PRIV_SIZE_FIXED, 0, "setpsmode"
33066 +//set/get mode have been realized in public handlers
33069 + SIOCIWFIRSTPRIV + 0x8,
33070 + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setiwmode"
33073 + SIOCIWFIRSTPRIV + 0x9,
33074 + 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getiwmode"
33077 + SIOCIWFIRSTPRIV + 0xA,
33078 + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpreamble"
33081 + SIOCIWFIRSTPRIV + 0xB,
33082 + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpreamble"
33084 + { SIOCIWFIRSTPRIV + 0xC,
33088 + SIOCIWFIRSTPRIV + 0xD,
33089 + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getrssi"
33091 + { SIOCIWFIRSTPRIV + 0xE,
33095 + SIOCIWFIRSTPRIV + 0xF,
33096 + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getlinkqual"
33099 + SIOCIWFIRSTPRIV + 0x10,
33100 + 0, 0, "resetstats"
33103 + SIOCIWFIRSTPRIV + 0x11,
33107 + SIOCIWFIRSTPRIV + 0x12,
33111 + SIOCIWFIRSTPRIV + 0x13,
33115 + SIOCIWFIRSTPRIV + 0x14,
33116 + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setchannel"
33119 + SIOCIWFIRSTPRIV + 0x15,
33120 + 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel"
33123 + SIOCIWFIRSTPRIV + 0x16,
33127 + SIOCIWFIRSTPRIV + 0x17,
33128 + 0,IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getversion"
33131 + SIOCIWFIRSTPRIV + 0x18,
33132 + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setrate"
33137 +static iw_handler r8180_private_handler[] = {
33138 + r8180_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
33140 + r8180_wx_set_beaconinterval,
33142 + //r8180_wx_set_monitor_type,
33143 + r8180_wx_set_scan_type,
33145 + r8180_wx_set_rawtx,
33147 + r8180_wx_set_iwmode,
33148 + r8180_wx_get_iwmode,
33149 + r8180_wx_set_preamble,
33150 + r8180_wx_get_preamble,
33152 + r8180_wx_get_siglevel,
33154 + r8180_wx_get_sigqual,
33155 + r8180_wx_reset_stats,
33156 + dummy,//r8180_wx_get_stats
33157 + r8180_wx_radio_on,
33158 + r8180_wx_radio_off,
33159 + r8180_wx_set_channelplan,
33160 + r8180_wx_get_channelplan,
33162 + r8180_wx_get_version,
33163 + r8180_wx_set_forcerate,
33166 +#if WIRELESS_EXT >= 17
33167 +static inline int is_same_network(struct ieee80211_network *src,
33168 + struct ieee80211_network *dst,
33169 + struct ieee80211_device *ieee)
33171 + /* A network is only a duplicate if the channel, BSSID, ESSID
33172 + * and the capability field (in particular IBSS and BSS) all match.
33173 + * We treat all <hidden> with the same BSSID and channel
33174 + * as one network */
33175 + return (((src->ssid_len == dst->ssid_len)||(ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod, 080819,for hidden ap
33176 + //((src->ssid_len == dst->ssid_len) &&
33177 + (src->channel == dst->channel) &&
33178 + !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
33179 + (!memcmp(src->ssid, dst->ssid, src->ssid_len)||(ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod, 080819,for hidden ap
33180 + //!memcmp(src->ssid, dst->ssid, src->ssid_len) &&
33181 + ((src->capability & WLAN_CAPABILITY_IBSS) ==
33182 + (dst->capability & WLAN_CAPABILITY_IBSS)) &&
33183 + ((src->capability & WLAN_CAPABILITY_BSS) ==
33184 + (dst->capability & WLAN_CAPABILITY_BSS)));
33187 +//WB modefied to show signal to GUI on 18-01-2008
33188 +static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
33190 + struct r8180_priv *priv = ieee80211_priv(dev);
33191 + struct ieee80211_device* ieee = priv->ieee80211;
33192 + struct iw_statistics* wstats = &priv->wstats;
33193 + //struct ieee80211_network* target = NULL;
33194 + int tmp_level = 0;
33195 + int tmp_qual = 0;
33196 + int tmp_noise = 0;
33197 + //unsigned long flag;
33199 + if (ieee->state < IEEE80211_LINKED)
33201 + wstats->qual.qual = 0;
33202 + wstats->qual.level = 0;
33203 + wstats->qual.noise = 0;
33204 + wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
33208 + spin_lock_irqsave(&ieee->lock, flag);
33209 + list_for_each_entry(target, &ieee->network_list, list)
33211 + if (is_same_network(target, &ieee->current_network, ieee))
33213 + printk("it's same network:%s\n", target->ssid);
33217 + tmp_level = target->stats.signalstrength;
33218 + tmp_qual = target->stats.signal;
33223 + tmp_level = (15*tmp_level + target->stats.signalstrength)/16;
33224 + tmp_qual = (15*tmp_qual + target->stats.signal)/16;
33227 + tmp_level = target->stats.signal;
33228 + tmp_qual = target->stats.signalstrength;
33229 + tmp_noise = target->stats.noise;
33230 + printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
33235 + spin_unlock_irqrestore(&ieee->lock, flag);
33237 + tmp_level = (&ieee->current_network)->stats.signal;
33238 + tmp_qual = (&ieee->current_network)->stats.signalstrength;
33239 + tmp_noise = (&ieee->current_network)->stats.noise;
33240 + //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise);
33242 +// printk("level:%d\n", tmp_level);
33243 + wstats->qual.level = tmp_level;
33244 + wstats->qual.qual = tmp_qual;
33245 + wstats->qual.noise = tmp_noise;
33246 + wstats->qual.updated = IW_QUAL_ALL_UPDATED| IW_QUAL_DBM;
33252 +struct iw_handler_def r8180_wx_handlers_def={
33253 + .standard = r8180_wx_handlers,
33254 + .num_standard = sizeof(r8180_wx_handlers) / sizeof(iw_handler),
33255 + .private = r8180_private_handler,
33256 + .num_private = sizeof(r8180_private_handler) / sizeof(iw_handler),
33257 + .num_private_args = sizeof(r8180_private_args) / sizeof(struct iw_priv_args),
33258 +#if WIRELESS_EXT >= 17
33259 + .get_wireless_stats = r8180_get_wireless_stats,
33261 + .private_args = (struct iw_priv_args *)r8180_private_args,
33266 +++ b/drivers/staging/rtl8187se/r8180_wx.h
33269 + This is part of rtl8180 OpenSource driver - v 0.3
33270 + Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it>
33271 + Released under the terms of GPL (General Public Licence)
33273 + Parts of this driver are based on the GPL part of the official realtek driver
33274 + Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon
33275 + Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver
33277 + We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
33280 +/* this file (will) contains wireless extension handlers*/
33282 +#ifndef R8180_WX_H
33283 +#define R8180_WX_H
33284 +#include <linux/wireless.h>
33285 +#include "ieee80211.h"
33286 +extern struct iw_handler_def r8180_wx_handlers_def;
33290 +++ b/drivers/staging/rtl8187se/r8185b_init.c
33293 +Copyright (c) Realtek Semiconductor Corp. All rights reserved.
33299 + Hardware Initialization and Hardware IO for RTL8185B
33301 +Major Change History:
33303 + ---------- --------------- -------------------------------
33304 + 2006-11-15 Xiong Created
33307 + This file is ported from RTL8185B Windows driver.
33312 +/*--------------------------Include File------------------------------------*/
33313 +#include <linux/spinlock.h>
33314 +#include "r8180_hw.h"
33315 +#include "r8180.h"
33316 +#include "r8180_sa2400.h" /* PHILIPS Radio frontend */
33317 +#include "r8180_max2820.h" /* MAXIM Radio frontend */
33318 +#include "r8180_gct.h" /* GCT Radio frontend */
33319 +#include "r8180_rtl8225.h" /* RTL8225 Radio frontend */
33320 +#include "r8180_rtl8255.h" /* RTL8255 Radio frontend */
33321 +#include "r8180_93cx6.h" /* Card EEPROM */
33322 +#include "r8180_wx.h"
33324 +#ifdef CONFIG_RTL8180_PM
33325 +#include "r8180_pm.h"
33328 +#ifdef ENABLE_DOT11D
33329 +#include "dot11d.h"
33332 +#ifdef CONFIG_RTL8185B
33334 +//#define CONFIG_RTL8180_IO_MAP
33336 +#define TC_3W_POLL_MAX_TRY_CNT 5
33337 +#ifdef CONFIG_RTL818X_S
33338 +static u8 MAC_REG_TABLE[][2]={
33340 + // 0x34(BRSR), 0xBE(RATE_FALLBACK_CTL), 0x1E0(ARFR) would set in HwConfigureRTL8185()
33341 + // 0x272(RFSW_CTRL), 0x1CE(AESMSK_QC) set in InitializeAdapter8185().
33342 + // 0x1F0~0x1F8 set in MacConfig_85BASIC()
33343 + {0x08, 0xae}, {0x0a, 0x72}, {0x5b, 0x42},
33344 + {0x84, 0x88}, {0x85, 0x24}, {0x88, 0x54}, {0x8b, 0xb8}, {0x8c, 0x03},
33345 + {0x8d, 0x40}, {0x8e, 0x00}, {0x8f, 0x00}, {0x5b, 0x18}, {0x91, 0x03},
33346 + {0x94, 0x0F}, {0x95, 0x32},
33347 + {0x96, 0x00}, {0x97, 0x07}, {0xb4, 0x22}, {0xdb, 0x00},
33348 + {0xf0, 0x32}, {0xf1, 0x32}, {0xf2, 0x00}, {0xf3, 0x00}, {0xf4, 0x32},
33349 + {0xf5, 0x43}, {0xf6, 0x00}, {0xf7, 0x00}, {0xf8, 0x46}, {0xf9, 0xa4},
33350 + {0xfa, 0x00}, {0xfb, 0x00}, {0xfc, 0x96}, {0xfd, 0xa4}, {0xfe, 0x00},
33354 + // For Flextronics system Logo PCIHCT failure:
33355 + // 0x1C4~0x1CD set no-zero value to avoid PCI configuration space 0x45[7]=1
33357 + {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x04}, {0x5b, 0x00}, {0x60, 0x24},
33358 + {0x61, 0x97}, {0x62, 0xF0}, {0x63, 0x09}, {0x80, 0x0F}, {0x81, 0xFF},
33359 + {0x82, 0xFF}, {0x83, 0x03},
33360 + {0xC4, 0x22}, {0xC5, 0x22}, {0xC6, 0x22}, {0xC7, 0x22}, {0xC8, 0x22}, //lzm add 080826
33361 + {0xC9, 0x22}, {0xCA, 0x22}, {0xCB, 0x22}, {0xCC, 0x22}, {0xCD, 0x22},//lzm add 080826
33367 + {0x0c, 0x04}, {0x4c, 0x30}, {0x4d, 0x08}, {0x50, 0x05}, {0x51, 0xf5},
33368 + {0x52, 0x04}, {0x53, 0xa0}, {0x54, 0xff}, {0x55, 0xff}, {0x56, 0xff},
33369 + {0x57, 0xff}, {0x58, 0x08}, {0x59, 0x08}, {0x5a, 0x08}, {0x5b, 0x08},
33370 + {0x60, 0x08}, {0x61, 0x08}, {0x62, 0x08}, {0x63, 0x08}, {0x64, 0x2f},
33371 + {0x8c, 0x3f}, {0x8d, 0x3f}, {0x8e, 0x3f},
33372 + {0x8f, 0x3f}, {0xc4, 0xff}, {0xc5, 0xff}, {0xc6, 0xff}, {0xc7, 0xff},
33373 + {0xc8, 0x00}, {0xc9, 0x00}, {0xca, 0x80}, {0xcb, 0x00},
33376 + {0x5e, 0x00},{0x9f, 0x03}
33380 +static u8 ZEBRA_AGC[]={
33382 + 0x7E,0x7E,0x7E,0x7E,0x7D,0x7C,0x7B,0x7A,0x79,0x78,0x77,0x76,0x75,0x74,0x73,0x72,
33383 + 0x71,0x70,0x6F,0x6E,0x6D,0x6C,0x6B,0x6A,0x69,0x68,0x67,0x66,0x65,0x64,0x63,0x62,
33384 + 0x48,0x47,0x46,0x45,0x44,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x08,0x07,
33385 + 0x06,0x05,0x04,0x03,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
33386 + 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x10,0x11,0x12,0x13,0x15,0x16,
33387 + 0x17,0x17,0x18,0x18,0x19,0x1a,0x1a,0x1b,0x1b,0x1c,0x1c,0x1d,0x1d,0x1d,0x1e,0x1e,
33388 + 0x1f,0x1f,0x1f,0x20,0x20,0x20,0x20,0x21,0x21,0x21,0x22,0x22,0x22,0x23,0x23,0x24,
33389 + 0x24,0x25,0x25,0x25,0x26,0x26,0x27,0x27,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F,0x2F
33392 +static u32 ZEBRA_RF_RX_GAIN_TABLE[]={
33393 + 0x0096,0x0076,0x0056,0x0036,0x0016,0x01f6,0x01d6,0x01b6,
33394 + 0x0196,0x0176,0x00F7,0x00D7,0x00B7,0x0097,0x0077,0x0057,
33395 + 0x0037,0x00FB,0x00DB,0x00BB,0x00FF,0x00E3,0x00C3,0x00A3,
33396 + 0x0083,0x0063,0x0043,0x0023,0x0003,0x01E3,0x01C3,0x01A3,
33397 + 0x0183,0x0163,0x0143,0x0123,0x0103
33400 +static u8 OFDM_CONFIG[]={
33401 + // OFDM reg0x06[7:0]=0xFF: Enable power saving mode in RX
33402 + // OFDM reg0x3C[4]=1'b1: Enable RX power saving mode
33403 + // ofdm 0x3a = 0x7b ,(original : 0xfb) For ECS shielding room TP test
33406 + 0x10, 0x0F, 0x0A, 0x0C, 0x14, 0xFA, 0xFF, 0x50,
33407 + 0x00, 0x50, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00,
33409 + 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xA8, 0x26,
33410 + 0x32, 0x33, 0x06, 0xA5, 0x6F, 0x55, 0xC8, 0xBB,
33412 + 0x0A, 0xE1, 0x2C, 0x4A, 0x86, 0x83, 0x34, 0x00,
33413 + 0x4F, 0x24, 0x6F, 0xC2, 0x03, 0x40, 0x80, 0x00,
33415 + 0xC0, 0xC1, 0x58, 0xF1, 0x00, 0xC4, 0x90, 0x3e,
33416 + 0xD8, 0x3C, 0x7B, 0x10, 0x10
33419 + static u8 MAC_REG_TABLE[][2]={
33421 + {0xf0, 0x32}, {0xf1, 0x32}, {0xf2, 0x00}, {0xf3, 0x00}, {0xf4, 0x32},
33422 + {0xf5, 0x43}, {0xf6, 0x00}, {0xf7, 0x00}, {0xf8, 0x46}, {0xf9, 0xa4},
33423 + {0xfa, 0x00}, {0xfb, 0x00}, {0xfc, 0x96}, {0xfd, 0xa4}, {0xfe, 0x00},
33428 + {0x58, 0x4b}, {0x59, 0x00}, {0x5a, 0x4b}, {0x5b, 0x00}, {0x60, 0x4b},
33429 + {0x61, 0x09}, {0x62, 0x4b}, {0x63, 0x09}, {0xce, 0x0f}, {0xcf, 0x00},
33430 + {0xe0, 0xff}, {0xe1, 0x0f}, {0xe2, 0x00}, {0xf0, 0x4e}, {0xf1, 0x01},
33431 + {0xf2, 0x02}, {0xf3, 0x03}, {0xf4, 0x04}, {0xf5, 0x05}, {0xf6, 0x06},
33432 + {0xf7, 0x07}, {0xf8, 0x08},
33437 + {0x0c, 0x04}, {0x21, 0x61}, {0x22, 0x68}, {0x23, 0x6f}, {0x24, 0x76},
33438 + {0x25, 0x7d}, {0x26, 0x84}, {0x27, 0x8d}, {0x4d, 0x08}, {0x4e, 0x00},
33439 + {0x50, 0x05}, {0x51, 0xf5}, {0x52, 0x04}, {0x53, 0xa0}, {0x54, 0x1f},
33440 + {0x55, 0x23}, {0x56, 0x45}, {0x57, 0x67}, {0x58, 0x08}, {0x59, 0x08},
33441 + {0x5a, 0x08}, {0x5b, 0x08}, {0x60, 0x08}, {0x61, 0x08}, {0x62, 0x08},
33442 + {0x63, 0x08}, {0x64, 0xcf}, {0x72, 0x56}, {0x73, 0x9a},
33446 + {0x34, 0xff}, {0x35, 0x0f}, {0x5b, 0x40}, {0x84, 0x88}, {0x85, 0x24},
33447 + {0x88, 0x54}, {0x8b, 0xb8}, {0x8c, 0x07}, {0x8d, 0x00}, {0x94, 0x1b},
33448 + {0x95, 0x12}, {0x96, 0x00}, {0x97, 0x06}, {0x9d, 0x1a}, {0x9f, 0x10},
33449 + {0xb4, 0x22}, {0xbe, 0x80}, {0xdb, 0x00}, {0xee, 0x00}, {0x5b, 0x42},
33465 + {0x8c, 0x01}, {0x8d, 0x10},{0x8e, 0x08}, {0x8f, 0x00}
33469 +static u8 ZEBRA_AGC[]={
33471 + 0x5e,0x5e,0x5e,0x5e,0x5d,0x5b,0x59,0x57,0x55,0x53,0x51,0x4f,0x4d,0x4b,0x49,0x47,
33472 + 0x45,0x43,0x41,0x3f,0x3d,0x3b,0x39,0x37,0x35,0x33,0x31,0x2f,0x2d,0x2b,0x29,0x27,
33473 + 0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x11,0x0f,0x0d,0x0b,0x09,0x07,
33474 + 0x05,0x03,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
33475 + 0x19,0x19,0x19,0x019,0x19,0x19,0x19,0x19,0x19,0x19,0x1e,0x1f,0x20,0x21,0x21,0x22,
33476 + 0x23,0x24,0x24,0x25,0x25,0x26,0x26,0x27,0x27,0x28,0x28,0x28,0x29,0x2a,0x2a,0x2b,
33477 + 0x2b,0x2b,0x2c,0x2c,0x2c,0x2d,0x2d,0x2d,0x2e,0x2e,0x2f,0x30,0x31,0x31,0x31,0x31,
33478 + 0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31,0x31
33481 +static u32 ZEBRA_RF_RX_GAIN_TABLE[]={
33483 + 0x0400,0x0401,0x0402,0x0403,0x0404,0x0405,0x0408,0x0409,
33484 + 0x040a,0x040b,0x0502,0x0503,0x0504,0x0505,0x0540,0x0541,
33485 + 0x0542,0x0543,0x0544,0x0545,0x0580,0x0581,0x0582,0x0583,
33486 + 0x0584,0x0585,0x0588,0x0589,0x058a,0x058b,0x0643,0x0644,
33487 + 0x0645,0x0680,0x0681,0x0682,0x0683,0x0684,0x0685,0x0688,
33488 + 0x0689,0x068a,0x068b,0x068c,0x0742,0x0743,0x0744,0x0745,
33489 + 0x0780,0x0781,0x0782,0x0783,0x0784,0x0785,0x0788,0x0789,
33490 + 0x078a,0x078b,0x078c,0x078d,0x0790,0x0791,0x0792,0x0793,
33491 + 0x0794,0x0795,0x0798,0x0799,0x079a,0x079b,0x079c,0x079d,
33492 + 0x07a0,0x07a1,0x07a2,0x07a3,0x07a4,0x07a5,0x07a8,0x07a9,
33493 + 0x03aa,0x03ab,0x03ac,0x03ad,0x03b0,0x03b1,0x03b2,0x03b3,
33494 + 0x03b4,0x03b5,0x03b8,0x03b9,0x03ba,0x03bb,0x03bb
33497 +// 2006.07.13, SD3 szuyitasi:
33498 +// OFDM.0x03=0x0C (original is 0x0F)
33499 +// Use the new SD3 given param, by shien chang, 2006.07.14
33500 +static u8 OFDM_CONFIG[]={
33501 + 0x10, 0x0d, 0x01, 0x0C, 0x14, 0xfb, 0x0f, 0x60, 0x00, 0x60,
33502 + 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00,
33503 + 0x00, 0x00, 0xa8, 0x46, 0xb2, 0x33, 0x07, 0xa5, 0x6f, 0x55,
33504 + 0xc8, 0xb3, 0x0a, 0xe1, 0x1c, 0x8a, 0xb6, 0x83, 0x34, 0x0f,
33505 + 0x4f, 0x23, 0x6f, 0xc2, 0x6b, 0x40, 0x80, 0x00, 0xc0, 0xc1,
33506 + 0x58, 0xf1, 0x00, 0xe4, 0x90, 0x3e, 0x6d, 0x3c, 0xff, 0x07
33510 +/*---------------------------------------------------------------
33512 + * the code is ported from Windows source code
33513 + ----------------------------------------------------------------*/
33516 +PlatformIOWrite1Byte(
33517 + struct net_device *dev,
33522 +#ifndef CONFIG_RTL8180_IO_MAP
33523 + write_nic_byte(dev, offset, data);
33524 + read_nic_byte(dev, offset); // To make sure write operation is completed, 2005.11.09, by rcnjko.
33527 + u32 Page = (offset >> 8);
33531 + case 0: // Page 0
33532 + write_nic_byte(dev, offset, data);
33535 + case 1: // Page 1
33536 + case 2: // Page 2
33537 + case 3: // Page 3
33539 + u8 psr = read_nic_byte(dev, PSR);
33541 + write_nic_byte(dev, PSR, ((psr & 0xfc) | (u8)Page)); // Switch to page N.
33542 + write_nic_byte(dev, (offset & 0xff), data);
33543 + write_nic_byte(dev, PSR, (psr & 0xfc)); // Switch to page 0.
33548 + // Illegal page number.
33549 + DMESGE("PlatformIOWrite1Byte(): illegal page number: %d, offset: %#X", Page, offset);
33556 +PlatformIOWrite2Byte(
33557 + struct net_device *dev,
33562 +#ifndef CONFIG_RTL8180_IO_MAP
33563 + write_nic_word(dev, offset, data);
33564 + read_nic_word(dev, offset); // To make sure write operation is completed, 2005.11.09, by rcnjko.
33568 + u32 Page = (offset >> 8);
33572 + case 0: // Page 0
33573 + write_nic_word(dev, offset, data);
33576 + case 1: // Page 1
33577 + case 2: // Page 2
33578 + case 3: // Page 3
33580 + u8 psr = read_nic_byte(dev, PSR);
33582 + write_nic_byte(dev, PSR, ((psr & 0xfc) | (u8)Page)); // Switch to page N.
33583 + write_nic_word(dev, (offset & 0xff), data);
33584 + write_nic_byte(dev, PSR, (psr & 0xfc)); // Switch to page 0.
33589 + // Illegal page number.
33590 + DMESGE("PlatformIOWrite2Byte(): illegal page number: %d, offset: %#X", Page, offset);
33595 +u8 PlatformIORead1Byte(struct net_device *dev, u32 offset);
33598 +PlatformIOWrite4Byte(
33599 + struct net_device *dev,
33604 +#ifndef CONFIG_RTL8180_IO_MAP
33606 +if (offset == PhyAddr)
33607 + {//For Base Band configuration.
33608 + unsigned char cmdByte;
33609 + unsigned long dataBytes;
33610 + unsigned char idx;
33613 + cmdByte = (u8)(data & 0x000000ff);
33614 + dataBytes = data>>8;
33617 + // 071010, rcnjko:
33618 + // The critical section is only BB read/write race condition.
33620 + // 1. We assume NO one will access BB at DIRQL, otherwise, system will crash for
33621 + // acquiring the spinlock in such context.
33622 + // 2. PlatformIOWrite4Byte() MUST NOT be recursive.
33624 +// NdisAcquireSpinLock( &(pDevice->IoSpinLock) );
33626 + for(idx = 0; idx < 30; idx++)
33627 + { // Make sure command bit is clear before access it.
33628 + u1bTmp = PlatformIORead1Byte(dev, PhyAddr);
33629 + if((u1bTmp & BIT7) == 0)
33635 + for(idx=0; idx < 3; idx++)
33637 + PlatformIOWrite1Byte(dev,offset+1+idx,((u8*)&dataBytes)[idx] );
33639 + write_nic_byte(dev, offset, cmdByte);
33641 +// NdisReleaseSpinLock( &(pDevice->IoSpinLock) );
33645 + write_nic_dword(dev, offset, data);
33646 + read_nic_dword(dev, offset); // To make sure write operation is completed, 2005.11.09, by rcnjko.
33649 + u32 Page = (offset >> 8);
33653 + case 0: // Page 0
33654 + write_nic_word(dev, offset, data);
33657 + case 1: // Page 1
33658 + case 2: // Page 2
33659 + case 3: // Page 3
33661 + u8 psr = read_nic_byte(dev, PSR);
33663 + write_nic_byte(dev, PSR, ((psr & 0xfc) | (u8)Page)); // Switch to page N.
33664 + write_nic_dword(dev, (offset & 0xff), data);
33665 + write_nic_byte(dev, PSR, (psr & 0xfc)); // Switch to page 0.
33670 + // Illegal page number.
33671 + DMESGE("PlatformIOWrite4Byte(): illegal page number: %d, offset: %#X", Page, offset);
33678 +PlatformIORead1Byte(
33679 + struct net_device *dev,
33685 +#ifndef CONFIG_RTL8180_IO_MAP
33686 + data = read_nic_byte(dev, offset);
33689 + u32 Page = (offset >> 8);
33693 + case 0: // Page 0
33694 + data = read_nic_byte(dev, offset);
33697 + case 1: // Page 1
33698 + case 2: // Page 2
33699 + case 3: // Page 3
33701 + u8 psr = read_nic_byte(dev, PSR);
33703 + write_nic_byte(dev, PSR, ((psr & 0xfc) | (u8)Page)); // Switch to page N.
33704 + data = read_nic_byte(dev, (offset & 0xff));
33705 + write_nic_byte(dev, PSR, (psr & 0xfc)); // Switch to page 0.
33710 + // Illegal page number.
33711 + DMESGE("PlatformIORead1Byte(): illegal page number: %d, offset: %#X", Page, offset);
33720 +PlatformIORead2Byte(
33721 + struct net_device *dev,
33727 +#ifndef CONFIG_RTL8180_IO_MAP
33728 + data = read_nic_word(dev, offset);
33731 + u32 Page = (offset >> 8);
33735 + case 0: // Page 0
33736 + data = read_nic_word(dev, offset);
33739 + case 1: // Page 1
33740 + case 2: // Page 2
33741 + case 3: // Page 3
33743 + u8 psr = read_nic_byte(dev, PSR);
33745 + write_nic_byte(dev, PSR, ((psr & 0xfc) | (u8)Page)); // Switch to page N.
33746 + data = read_nic_word(dev, (offset & 0xff));
33747 + write_nic_byte(dev, PSR, (psr & 0xfc)); // Switch to page 0.
33752 + // Illegal page number.
33753 + DMESGE("PlatformIORead2Byte(): illegal page number: %d, offset: %#X", Page, offset);
33762 +PlatformIORead4Byte(
33763 + struct net_device *dev,
33769 +#ifndef CONFIG_RTL8180_IO_MAP
33770 + data = read_nic_dword(dev, offset);
33773 + u32 Page = (offset >> 8);
33777 + case 0: // Page 0
33778 + data = read_nic_dword(dev, offset);
33781 + case 1: // Page 1
33782 + case 2: // Page 2
33783 + case 3: // Page 3
33785 + u8 psr = read_nic_byte(dev, PSR);
33787 + write_nic_byte(dev, PSR, ((psr & 0xfc) | (u8)Page)); // Switch to page N.
33788 + data = read_nic_dword(dev, (offset & 0xff));
33789 + write_nic_byte(dev, PSR, (psr & 0xfc)); // Switch to page 0.
33794 + // Illegal page number.
33795 + DMESGE("PlatformIORead4Byte(): illegal page number: %d, offset: %#X\n", Page, offset);
33804 +SetOutputEnableOfRfPins(
33805 + struct net_device *dev
33808 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
33810 + switch(priv->rf_chip)
33812 + case RFCHIPID_RTL8225:
33815 + write_nic_word(dev, RFPinsEnable, 0x1bff);
33816 + //write_nic_word(dev, RFPinsEnable, 0x1fff);
33822 +ZEBRA_RFSerialWrite(
33823 + struct net_device *dev,
33829 + ThreeWireReg twreg;
33831 + u16 oval,oval2,oval3;
33833 + u16 UshortBuffer;
33836 +#ifdef CONFIG_RTL818X_S
33837 + // RTL8187S HSSI Read/Write Function
33838 + u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
33839 + u1bTmp |= RF_SW_CFG_SI; //reg08[1]=1 Serial Interface(SI)
33840 + write_nic_byte(dev, RF_SW_CONFIG, u1bTmp);
33842 + UshortBuffer = read_nic_word(dev, RFPinsOutput);
33843 + oval = UshortBuffer & 0xfff8; // We shall clear bit0, 1, 2 first, 2005.10.28, by rcnjko.
33845 + oval2 = read_nic_word(dev, RFPinsEnable);
33846 + oval3 = read_nic_word(dev, RFPinsSelect);
33848 + // <RJ_NOTE> 3-wire should be controled by HW when we finish SW 3-wire programming. 2005.08.10, by rcnjko.
33851 + write_nic_word(dev, RFPinsEnable, (oval2|0x0007)); // Set To Output Enable
33852 + write_nic_word(dev, RFPinsSelect, (oval3|0x0007)); // Set To SW Switch
33855 + // Add this to avoid hardware and software 3-wire conflict.
33856 + // 2005.03.01, by rcnjko.
33857 + twreg.longData = 0;
33858 + twreg.struc.enableB = 1;
33859 + write_nic_word(dev, RFPinsOutput, (twreg.longData|oval)); // Set SI_EN (RFLE)
33861 + twreg.struc.enableB = 0;
33862 + write_nic_word(dev, RFPinsOutput, (twreg.longData|oval)); // Clear SI_EN (RFLE)
33865 + mask = (low2high)?0x01:((u32)0x01<<(totalLength-1));
33867 + for(i=0; i<totalLength/2; i++)
33869 + twreg.struc.data = ((data2Write&mask)!=0) ? 1 : 0;
33870 + write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
33871 + twreg.struc.clk = 1;
33872 + write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
33873 + write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
33875 + mask = (low2high)?(mask<<1):(mask>>1);
33876 + twreg.struc.data = ((data2Write&mask)!=0) ? 1 : 0;
33877 + write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
33878 + write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
33879 + twreg.struc.clk = 0;
33880 + write_nic_word(dev, RFPinsOutput, (twreg.longData|oval));
33881 + mask = (low2high)?(mask<<1):(mask>>1);
33884 + twreg.struc.enableB = 1;
33885 + twreg.struc.clk = 0;
33886 + twreg.struc.data = 0;
33887 + write_nic_word(dev, RFPinsOutput, twreg.longData|oval);
33890 + write_nic_word(dev, RFPinsOutput, oval|0x0004);
33891 + write_nic_word(dev, RFPinsSelect, oval3|0x0000);
33893 + SetOutputEnableOfRfPins(dev);
33900 + struct net_device *dev,
33902 + u8 nDataBufBitCnt,
33913 + // Check if WE and RE are cleared.
33914 + for(TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++)
33916 + u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
33917 + if( (u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0 )
33923 + if (TryCnt == TC_3W_POLL_MAX_TRY_CNT)
33924 + panic("HwThreeWire(): CmdReg: %#X RE|WE bits are not clear!!\n", u1bTmp);
33926 + // RTL8187S HSSI Read/Write Function
33927 + u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
33931 + u1bTmp |= RF_SW_CFG_SI; //reg08[1]=1 Serial Interface(SI)
33934 + u1bTmp &= ~RF_SW_CFG_SI; //reg08[1]=0 Parallel Interface(PI)
33937 + write_nic_byte(dev, RF_SW_CONFIG, u1bTmp);
33941 + // jong: HW SI read must set reg84[3]=0.
33942 + u1bTmp = read_nic_byte(dev, RFPinsSelect);
33944 + write_nic_byte(dev, RFPinsSelect, u1bTmp );
33946 + // Fill up data buffer for write operation.
33950 + if(nDataBufBitCnt == 16)
33952 + write_nic_word(dev, SW_3W_DB0, *((u16*)pDataBuf));
33954 + else if(nDataBufBitCnt == 64) // RTL8187S shouldn't enter this case
33956 + write_nic_dword(dev, SW_3W_DB0, *((u32*)pDataBuf));
33957 + write_nic_dword(dev, SW_3W_DB1, *((u32*)(pDataBuf + 4)));
33962 + int ByteCnt = nDataBufBitCnt / 8;
33963 + //printk("%d\n",nDataBufBitCnt);
33964 + if ((nDataBufBitCnt % 8) != 0)
33965 + panic("HwThreeWire(): nDataBufBitCnt(%d) should be multiple of 8!!!\n",
33968 + if (nDataBufBitCnt > 64)
33969 + panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n",
33972 + for(idx = 0; idx < ByteCnt; idx++)
33974 + write_nic_byte(dev, (SW_3W_DB0+idx), *(pDataBuf+idx));
33982 + // SI - reg274[3:0] : RF register's Address
33983 + write_nic_word(dev, SW_3W_DB0, *((u16*)pDataBuf) );
33987 + // PI - reg274[15:12] : RF register's Address
33988 + write_nic_word(dev, SW_3W_DB0, (*((u16*)pDataBuf)) << 12);
33992 + // Set up command: WE or RE.
33995 + write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_WE);
33999 + write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_RE);
34002 + // Check if DONE is set.
34003 + for(TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++)
34005 + u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
34006 + if( (u1bTmp & SW_3W_CMD1_DONE) != 0 )
34013 + write_nic_byte(dev, SW_3W_CMD1, 0);
34015 + // Read back data for read operation.
34020 + //Serial Interface : reg363_362[11:0]
34021 + *((u16*)pDataBuf) = read_nic_word(dev, SI_DATA_READ) ;
34025 + //Parallel Interface : reg361_360[11:0]
34026 + *((u16*)pDataBuf) = read_nic_word(dev, PI_DATA_READ);
34029 + *((u16*)pDataBuf) &= 0x0FFF;
34040 + struct net_device *dev,
34042 + u8 nDataBufBitCnt,
34053 + // Check if WE and RE are cleared.
34054 + for(TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++)
34056 + u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
34057 + if( (u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0 )
34063 + if (TryCnt == TC_3W_POLL_MAX_TRY_CNT)
34064 + panic("HwThreeWire(): CmdReg: %#X RE|WE bits are not clear!!\n", u1bTmp);
34066 + // Fill up data buffer for write operation.
34067 + if(nDataBufBitCnt == 16)
34069 + write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf));
34071 + else if(nDataBufBitCnt == 64)
34073 + write_nic_dword(dev, SW_3W_DB0, *((u32 *)pDataBuf));
34074 + write_nic_dword(dev, SW_3W_DB1, *((u32 *)(pDataBuf + 4)));
34079 + int ByteCnt = nDataBufBitCnt / 8;
34081 + if ((nDataBufBitCnt % 8) != 0)
34082 + panic("HwThreeWire(): nDataBufBitCnt(%d) should be multiple of 8!!!\n",
34085 + if (nDataBufBitCnt > 64)
34086 + panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n",
34089 + for(idx = 0; idx < ByteCnt; idx++)
34091 + write_nic_byte(dev, (SW_3W_DB0+idx), *(pDataBuf+idx));
34095 + // Fill up length field.
34096 + u1bTmp = (u8)(nDataBufBitCnt - 1); // Number of bits - 1.
34098 + u1bTmp |= SW_3W_CMD0_HOLD;
34099 + write_nic_byte(dev, SW_3W_CMD0, u1bTmp);
34101 + // Set up command: WE or RE.
34104 + write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_WE);
34108 + write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_RE);
34111 + // Check if WE and RE are cleared and DONE is set.
34112 + for(TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++)
34114 + u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
34115 + if( (u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0 &&
34116 + (u1bTmp & SW_3W_CMD1_DONE) != 0 )
34122 + if(TryCnt == TC_3W_POLL_MAX_TRY_CNT)
34124 + //RT_ASSERT(TryCnt != TC_3W_POLL_MAX_TRY_CNT,
34125 + // ("HwThreeWire(): CmdReg: %#X RE|WE bits are not clear or DONE is not set!!\n", u1bTmp));
34126 + // Workaround suggested by wcchu: clear WE here. 2006.07.07, by rcnjko.
34127 + write_nic_byte(dev, SW_3W_CMD1, 0);
34130 + // Read back data for read operation.
34131 + // <RJ_TODO> I am not sure if this is correct output format of a read operation.
34134 + if(nDataBufBitCnt == 16)
34136 + *((u16 *)pDataBuf) = read_nic_word(dev, SW_3W_DB0);
34138 + else if(nDataBufBitCnt == 64)
34140 + *((u32 *)pDataBuf) = read_nic_dword(dev, SW_3W_DB0);
34141 + *((u32 *)(pDataBuf + 4)) = read_nic_dword(dev, SW_3W_DB1);
34146 + int ByteCnt = nDataBufBitCnt / 8;
34148 + if ((nDataBufBitCnt % 8) != 0)
34149 + panic("HwThreeWire(): nDataBufBitCnt(%d) should be multiple of 8!!!\n",
34152 + if (nDataBufBitCnt > 64)
34153 + panic("HwThreeWire(): nDataBufBitCnt(%d) should <= 64!!!\n",
34156 + for(idx = 0; idx < ByteCnt; idx++)
34158 + *(pDataBuf+idx) = read_nic_byte(dev, (SW_3W_DB0+idx));
34171 + struct net_device *dev,
34180 + //u32 RF_Read = 0;
34181 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
34184 + switch(priv->rf_chip)
34186 + case RFCHIPID_RTL8225:
34187 + case RF_ZEBRA2: // Annie 2006-05-12.
34188 + case RF_ZEBRA4: //by amy
34189 + switch(priv->RegThreeWireMode)
34191 + case SW_THREE_WIRE:
34192 + { // Perform SW 3-wire programming by driver.
34193 + data2Write = (data << 4) | (u32)(offset & 0x0f);
34196 + ZEBRA_RFSerialWrite(dev, data2Write, len, low2high);
34200 + case HW_THREE_WIRE:
34201 + { // Pure HW 3-wire.
34202 + data2Write = (data << 4) | (u32)(offset & 0x0f);
34206 + (u8 *)(&data2Write), // pDataBuf,
34207 + len, // nDataBufBitCnt,
34212 + #ifdef CONFIG_RTL818X_S
34213 + case HW_THREE_WIRE_PI: //Parallel Interface
34214 + { // Pure HW 3-wire.
34215 + data2Write = (data << 4) | (u32)(offset & 0x0f);
34219 + (u8*)(&data2Write), // pDataBuf,
34220 + len, // nDataBufBitCnt,
34224 + //printk("33333\n");
34228 + case HW_THREE_WIRE_SI: //Serial Interface
34229 + { // Pure HW 3-wire.
34230 + data2Write = (data << 4) | (u32)(offset & 0x0f);
34232 +// printk(" enter ZEBRA_RFSerialWrite\n ");
34234 +// ZEBRA_RFSerialWrite(dev, data2Write, len, low2high);
34238 + (u8*)(&data2Write), // pDataBuf,
34239 + len, // nDataBufBitCnt,
34243 +// printk(" exit ZEBRA_RFSerialWrite\n ");
34250 + DMESGE("RF_WriteReg(): invalid RegThreeWireMode(%d) !!!", priv->RegThreeWireMode);
34256 + DMESGE("RF_WriteReg(): unknown RFChipID: %#X", priv->rf_chip);
34263 +ZEBRA_RFSerialRead(
34264 + struct net_device *dev,
34272 + ThreeWireReg twreg;
34274 + u16 oval,oval2,oval3,tmp, wReg80;
34277 + ThreeWireReg tdata;
34278 + //PHAL_DATA_8187 pHalData = GetHalData8187(pAdapter);
34279 +#ifdef CONFIG_RTL818X_S
34280 + { // RTL8187S HSSI Read/Write Function
34281 + u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
34282 + u1bTmp |= RF_SW_CFG_SI; //reg08[1]=1 Serial Interface(SI)
34283 + write_nic_byte(dev, RF_SW_CONFIG, u1bTmp);
34287 + wReg80 = oval = read_nic_word(dev, RFPinsOutput);
34288 + oval2 = read_nic_word(dev, RFPinsEnable);
34289 + oval3 = read_nic_word(dev, RFPinsSelect);
34291 + write_nic_word(dev, RFPinsEnable, oval2|0xf);
34292 + write_nic_word(dev, RFPinsSelect, oval3|0xf);
34296 + // We must clear BIT0-3 here, otherwise,
34297 + // SW_Enalbe will be true when we first call ZEBRA_RFSerialRead() after 8187MPVC open,
34298 + // which will cause the value read become 0. 2005.04.11, by rcnjko.
34301 + // Avoid collision with hardware three-wire.
34302 + twreg.longData = 0;
34303 + twreg.struc.enableB = 1;
34304 + write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(4);
34306 + twreg.longData = 0;
34307 + twreg.struc.enableB = 0;
34308 + twreg.struc.clk = 0;
34309 + twreg.struc.read_write = 0;
34310 + write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(5);
34312 + mask = (low2high) ? 0x01 : ((u32)0x01<<(32-1));
34313 + for(i = 0; i < wLength/2; i++)
34315 + twreg.struc.data = ((data2Write&mask) != 0) ? 1 : 0;
34316 + write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(1);
34317 + twreg.struc.clk = 1;
34318 + write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
34319 + write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
34321 + mask = (low2high) ? (mask<<1): (mask>>1);
34325 + // Commented out by Jackie, 2004.08.26. <RJ_NOTE> We must comment out the following two lines for we cannot pull down VCOPDN during RF Serail Read.
34326 + //PlatformEFIOWrite2Byte(pAdapter, RFPinsEnable, 0xe); // turn off data enable
34327 + //PlatformEFIOWrite2Byte(pAdapter, RFPinsSelect, 0xe);
34329 + twreg.struc.read_write=1;
34330 + write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
34331 + twreg.struc.clk = 0;
34332 + write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
34335 + twreg.struc.data = ((data2Write&mask) != 0) ? 1: 0;
34336 + write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
34337 + write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
34339 + twreg.struc.clk = 0;
34340 + write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(1);
34342 + mask = (low2high) ? (mask<<1) : (mask>>1);
34345 + twreg.struc.clk = 0;
34346 + twreg.struc.data = 0;
34347 + write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
34348 + mask = (low2high) ? 0x01 : ((u32)0x01 << (12-1));
34351 + // 061016, by rcnjko:
34352 + // We must set data pin to HW controled, otherwise RF can't driver it and
34353 + // value RF register won't be able to read back properly.
34355 + write_nic_word(dev, RFPinsEnable, ( ((oval2|0x0E) & (~0x01))) );
34357 + for(i = 0; i < rLength; i++)
34359 + write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(1);
34360 + twreg.struc.clk = 1;
34361 + write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
34362 + write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
34363 + write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
34364 + tmp = read_nic_word(dev, RFPinsInput);
34365 + tdata.longData = tmp;
34366 + *data2Read |= tdata.struc.clk ? mask : 0;
34368 + twreg.struc.clk = 0;
34369 + write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
34371 + mask = (low2high) ? (mask<<1) : (mask>>1);
34373 + twreg.struc.enableB = 1;
34374 + twreg.struc.clk = 0;
34375 + twreg.struc.data = 0;
34376 + twreg.struc.read_write = 1;
34377 + write_nic_word(dev, RFPinsOutput, twreg.longData|oval); udelay(2);
34379 + //PlatformEFIOWrite2Byte(pAdapter, RFPinsEnable, oval2|0x8); // Set To Output Enable
34380 + write_nic_word(dev, RFPinsEnable, oval2); // Set To Output Enable, <RJ_NOTE> We cannot enable BIT3 here, otherwise, we will failed to switch channel. 2005.04.12.
34381 + //PlatformEFIOWrite2Byte(pAdapter, RFPinsEnable, 0x1bff);
34382 + write_nic_word(dev, RFPinsSelect, oval3); // Set To SW Switch
34383 + //PlatformEFIOWrite2Byte(pAdapter, RFPinsSelect, 0x0488);
34384 + write_nic_word(dev, RFPinsOutput, 0x3a0);
34385 + //PlatformEFIOWrite2Byte(pAdapter, RFPinsOutput, 0x0480);
34391 + struct net_device *dev,
34395 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
34402 + switch(priv->rf_chip)
34404 + case RFCHIPID_RTL8225:
34407 + switch(priv->RegThreeWireMode)
34409 +#ifdef CONFIG_RTL818X_S
34410 + case HW_THREE_WIRE_PI: // For 87S Parallel Interface.
34412 + data2Write = ((u32)(offset&0x0f));
34416 + (u8*)(&data2Write), // pDataBuf,
34417 + wlen, // nDataBufBitCnt,
34420 + dataRead= data2Write;
34424 + case HW_THREE_WIRE_SI: // For 87S Serial Interface.
34426 + data2Write = ((u32)(offset&0x0f)) ;
34430 + (u8*)(&data2Write), // pDataBuf,
34431 + wlen, // nDataBufBitCnt,
34435 + dataRead= data2Write;
34440 + // Perform SW 3-wire programming by driver.
34443 + data2Write = ((u32)(offset&0x1f)) << 27; // For Zebra E-cut. 2005.04.11, by rcnjko.
34447 + ZEBRA_RFSerialRead(dev, data2Write, wlen,&dataRead,rlen, low2high);
34461 +// by Owen on 04/07/14 for writing BB register successfully
34464 + struct net_device *dev,
34468 + //u8 TimeoutCounter;
34469 + u8 RegisterContent;
34472 + UCharData = (u8)((Data & 0x0000ff00) >> 8);
34473 + PlatformIOWrite4Byte(dev, PhyAddr, Data);
34474 + //for(TimeoutCounter = 10; TimeoutCounter > 0; TimeoutCounter--)
34476 + PlatformIOWrite4Byte(dev, PhyAddr, Data & 0xffffff7f);
34477 + RegisterContent = PlatformIORead1Byte(dev, PhyDataR);
34478 + //if(UCharData == RegisterContent)
34485 + struct net_device *dev,
34489 + //u8 TimeoutCounter;
34490 + u8 RegisterContent;
34492 + PlatformIOWrite4Byte(dev, PhyAddr, addr & 0xffffff7f);
34493 + RegisterContent = PlatformIORead1Byte(dev, PhyDataR);
34495 + return RegisterContent;
34498 +#ifdef CONFIG_RTL818X_S
34501 +// Perform Antenna settings with antenna diversity on 87SE.
34502 +// Created by Roger, 2008.01.25.
34505 +SetAntennaConfig87SE(
34506 + struct net_device *dev,
34507 + u8 DefaultAnt, // 0: Main, 1: Aux.
34508 + bool bAntDiversity // 1:Enable, 0: Disable.
34511 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
34512 + bool bAntennaSwitched = true;
34514 + //printk("SetAntennaConfig87SE(): DefaultAnt(%d), bAntDiversity(%d)\n", DefaultAnt, bAntDiversity);
34516 + // Threshold for antenna diversity.
34517 + write_phy_cck(dev, 0x0c, 0x09); // Reg0c : 09
34519 + if( bAntDiversity ) // Enable Antenna Diversity.
34521 + if( DefaultAnt == 1 ) // aux antenna
34523 + // Mac register, aux antenna
34524 + write_nic_byte(dev, ANTSEL, 0x00);
34526 + // Config CCK RX antenna.
34527 + write_phy_cck(dev, 0x11, 0xbb); // Reg11 : bb
34528 + write_phy_cck(dev, 0x01, 0xc7); // Reg01 : c7
34530 + // Config OFDM RX antenna.
34531 + write_phy_ofdm(dev, 0x0D, 0x54); // Reg0d : 54
34532 + write_phy_ofdm(dev, 0x18, 0xb2); // Reg18 : b2
34534 + else // use main antenna
34536 + // Mac register, main antenna
34537 + write_nic_byte(dev, ANTSEL, 0x03);
34539 + // Config CCK RX antenna.
34540 + write_phy_cck(dev, 0x11, 0x9b); // Reg11 : 9b
34541 + write_phy_cck(dev, 0x01, 0xc7); // Reg01 : c7
34543 + // Config OFDM RX antenna.
34544 + write_phy_ofdm(dev, 0x0d, 0x5c); // Reg0d : 5c
34545 + write_phy_ofdm(dev, 0x18, 0xb2); // Reg18 : b2
34548 + else // Disable Antenna Diversity.
34550 + if( DefaultAnt == 1 ) // aux Antenna
34552 + // Mac register, aux antenna
34553 + write_nic_byte(dev, ANTSEL, 0x00);
34555 + // Config CCK RX antenna.
34556 + write_phy_cck(dev, 0x11, 0xbb); // Reg11 : bb
34557 + write_phy_cck(dev, 0x01, 0x47); // Reg01 : 47
34559 + // Config OFDM RX antenna.
34560 + write_phy_ofdm(dev, 0x0D, 0x54); // Reg0d : 54
34561 + write_phy_ofdm(dev, 0x18, 0x32); // Reg18 : 32
34563 + else // main Antenna
34565 + // Mac register, main antenna
34566 + write_nic_byte(dev, ANTSEL, 0x03);
34568 + // Config CCK RX antenna.
34569 + write_phy_cck(dev, 0x11, 0x9b); // Reg11 : 9b
34570 + write_phy_cck(dev, 0x01, 0x47); // Reg01 : 47
34572 + // Config OFDM RX antenna.
34573 + write_phy_ofdm(dev, 0x0D, 0x5c); // Reg0d : 5c
34574 + write_phy_ofdm(dev, 0x18, 0x32); // Reg18 : 32
34577 + priv->CurrAntennaIndex = DefaultAnt; // Update default settings.
34578 + return bAntennaSwitched;
34582 +/*---------------------------------------------------------------
34583 + * Hardware Initialization.
34584 + * the code is ported from Windows source code
34585 + ----------------------------------------------------------------*/
34588 +ZEBRA_Config_85BASIC_HardCode(
34589 + struct net_device *dev
34593 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
34596 + u32 u4bRegOffset, u4bRegValue, u4bRF23, u4bRF24;
34599 +#ifdef CONFIG_RTL818X_S
34601 + //=============================================================================
34602 + // 87S_PCIE :: RADIOCFG.TXT
34603 + //=============================================================================
34606 + // Page1 : reg16-reg30
34607 + RF_WriteReg(dev, 0x00, 0x013f); mdelay(1); // switch to page1
34608 + u4bRF23= RF_ReadReg(dev, 0x08); mdelay(1);
34609 + u4bRF24= RF_ReadReg(dev, 0x09); mdelay(1);
34611 + if (u4bRF23==0x818 && u4bRF24==0x70C && priv->card_8185 == VERSION_8187S_C)
34612 + priv->card_8185 = VERSION_8187S_D;
34614 + // Page0 : reg0-reg15
34616 +// RF_WriteReg(dev, 0x00, 0x003f); mdelay(1);//1
34617 + RF_WriteReg(dev, 0x00, 0x009f); mdelay(1);// 1
34619 + RF_WriteReg(dev, 0x01, 0x06e0); mdelay(1);
34621 +// RF_WriteReg(dev, 0x02, 0x004c); mdelay(1);//2
34622 + RF_WriteReg(dev, 0x02, 0x004d); mdelay(1);// 2
34624 +// RF_WriteReg(dev, 0x03, 0x0000); mdelay(1);//3
34625 + RF_WriteReg(dev, 0x03, 0x07f1); mdelay(1);// 3
34627 + RF_WriteReg(dev, 0x04, 0x0975); mdelay(1);
34628 + RF_WriteReg(dev, 0x05, 0x0c72); mdelay(1);
34629 + RF_WriteReg(dev, 0x06, 0x0ae6); mdelay(1);
34630 + RF_WriteReg(dev, 0x07, 0x00ca); mdelay(1);
34631 + RF_WriteReg(dev, 0x08, 0x0e1c); mdelay(1);
34632 + RF_WriteReg(dev, 0x09, 0x02f0); mdelay(1);
34633 + RF_WriteReg(dev, 0x0a, 0x09d0); mdelay(1);
34634 + RF_WriteReg(dev, 0x0b, 0x01ba); mdelay(1);
34635 + RF_WriteReg(dev, 0x0c, 0x0640); mdelay(1);
34636 + RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1);
34637 + RF_WriteReg(dev, 0x0e, 0x0020); mdelay(1);
34638 + RF_WriteReg(dev, 0x0f, 0x0990); mdelay(1);
34641 + // Page1 : reg16-reg30
34642 + RF_WriteReg(dev, 0x00, 0x013f); mdelay(1);
34644 + RF_WriteReg(dev, 0x03, 0x0806); mdelay(1);
34646 + if(priv->card_8185 < VERSION_8187S_C)
34648 + RF_WriteReg(dev, 0x04, 0x03f7); mdelay(1);
34649 + RF_WriteReg(dev, 0x05, 0x05ab); mdelay(1);
34650 + RF_WriteReg(dev, 0x06, 0x00c1); mdelay(1);
34654 + RF_WriteReg(dev, 0x04, 0x03a7); mdelay(1);
34655 + RF_WriteReg(dev, 0x05, 0x059b); mdelay(1);
34656 + RF_WriteReg(dev, 0x06, 0x0081); mdelay(1);
34660 + RF_WriteReg(dev, 0x07, 0x01A0); mdelay(1);
34661 +// Don't write RF23/RF24 to make a difference between 87S C cut and D cut. asked by SD3 stevenl.
34662 +// RF_WriteReg(dev, 0x08, 0x0597); mdelay(1);
34663 +// RF_WriteReg(dev, 0x09, 0x050a); mdelay(1);
34664 + RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1);
34665 + RF_WriteReg(dev, 0x0b, 0x0418); mdelay(1);
34667 + if(priv->card_8185 == VERSION_8187S_D)
34669 + RF_WriteReg(dev, 0x0c, 0x0fbe); mdelay(1);
34670 + RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1);
34671 + RF_WriteReg(dev, 0x0e, 0x0807); mdelay(1); // RX LO buffer
34675 + RF_WriteReg(dev, 0x0c, 0x0fbe); mdelay(1);
34676 + RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1);
34677 + RF_WriteReg(dev, 0x0e, 0x0806); mdelay(1); // RX LO buffer
34680 + RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1);
34682 +// RF_WriteReg(dev, 0x00, 0x017f); mdelay(1);//6
34683 + RF_WriteReg(dev, 0x00, 0x01d7); mdelay(1);// 6
34685 + RF_WriteReg(dev, 0x03, 0x0e00); mdelay(1);
34686 + RF_WriteReg(dev, 0x04, 0x0e50); mdelay(1);
34687 + for(i=0;i<=36;i++)
34689 + RF_WriteReg(dev, 0x01, i); mdelay(1);
34690 + RF_WriteReg(dev, 0x02, ZEBRA_RF_RX_GAIN_TABLE[i]); mdelay(1);
34691 + //DbgPrint("RF - 0x%x = 0x%x", i, ZEBRA_RF_RX_GAIN_TABLE[i]);
34694 + RF_WriteReg(dev, 0x05, 0x0203); mdelay(1); /// 203, 343
34695 + //RF_WriteReg(dev, 0x06, 0x0300); mdelay(1); // 400
34696 + RF_WriteReg(dev, 0x06, 0x0200); mdelay(1); // 400
34698 + RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); // switch to reg16-reg30, and HSSI disable 137
34699 + mdelay(10); // Deay 10 ms. //0xfd
34701 +// RF_WriteReg(dev, 0x0c, 0x09be); mdelay(1); // 7
34702 + //RF_WriteReg(dev, 0x0c, 0x07be); mdelay(1);
34703 + //mdelay(10); // Deay 10 ms. //0xfd
34705 + RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1); // Z4 synthesizer loop filter setting, 392
34706 + mdelay(10); // Deay 10 ms. //0xfd
34708 + RF_WriteReg(dev, 0x00, 0x0037); mdelay(1); // switch to reg0-reg15, and HSSI disable
34709 + mdelay(10); // Deay 10 ms. //0xfd
34711 + RF_WriteReg(dev, 0x04, 0x0160); mdelay(1); // CBC on, Tx Rx disable, High gain
34712 + mdelay(10); // Deay 10 ms. //0xfd
34714 + RF_WriteReg(dev, 0x07, 0x0080); mdelay(1); // Z4 setted channel 1
34715 + mdelay(10); // Deay 10 ms. //0xfd
34717 + RF_WriteReg(dev, 0x02, 0x088D); mdelay(1); // LC calibration
34718 + mdelay(200); // Deay 200 ms. //0xfd
34719 + mdelay(10); // Deay 10 ms. //0xfd
34720 + mdelay(10); // Deay 10 ms. //0xfd
34722 + RF_WriteReg(dev, 0x00, 0x0137); mdelay(1); // switch to reg16-reg30 137, and HSSI disable 137
34723 + mdelay(10); // Deay 10 ms. //0xfd
34725 + RF_WriteReg(dev, 0x07, 0x0000); mdelay(1);
34726 + RF_WriteReg(dev, 0x07, 0x0180); mdelay(1);
34727 + RF_WriteReg(dev, 0x07, 0x0220); mdelay(1);
34728 + RF_WriteReg(dev, 0x07, 0x03E0); mdelay(1);
34730 + // DAC calibration off 20070702
34731 + RF_WriteReg(dev, 0x06, 0x00c1); mdelay(1);
34732 + RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1);
34734 + // For crystal calibration, added by Roger, 2007.12.11.
34735 + if( priv->bXtalCalibration ) // reg 30.
34736 + { // enable crystal calibration.
34737 + // RF Reg[30], (1)Xin:[12:9], Xout:[8:5], addr[4:0].
34738 + // (2)PA Pwr delay timer[15:14], default: 2.4us, set BIT15=0
34739 + // (3)RF signal on/off when calibration[13], default: on, set BIT13=0.
34740 + // So we should minus 4 BITs offset.
34741 + RF_WriteReg(dev, 0x0f, (priv->XtalCal_Xin<<5)|(priv->XtalCal_Xout<<1)|BIT11|BIT9); mdelay(1);
34742 + printk("ZEBRA_Config_85BASIC_HardCode(): (%02x)\n",
34743 + (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) | BIT11| BIT9);
34746 + { // using default value. Xin=6, Xout=6.
34747 + RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1);
34750 +// RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1); //-by amy 080312
34752 + RF_WriteReg(dev, 0x00, 0x00bf); mdelay(1); // switch to reg0-reg15, and HSSI enable
34753 +// RF_WriteReg(dev, 0x0d, 0x009f); mdelay(1); // Rx BB start calibration, 00c//-edward
34754 + RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1); // Rx BB start calibration, 00c//+edward
34755 + RF_WriteReg(dev, 0x02, 0x004d); mdelay(1); // temperature meter off
34756 + RF_WriteReg(dev, 0x04, 0x0975); mdelay(1); // Rx mode
34757 + mdelay(10); // Deay 10 ms. //0xfe
34758 + mdelay(10); // Deay 10 ms. //0xfe
34759 + mdelay(10); // Deay 10 ms. //0xfe
34760 + RF_WriteReg(dev, 0x00, 0x0197); mdelay(1); // Rx mode//+edward
34761 + RF_WriteReg(dev, 0x05, 0x05ab); mdelay(1); // Rx mode//+edward
34762 + RF_WriteReg(dev, 0x00, 0x009f); mdelay(1); // Rx mode//+edward
34765 + RF_WriteReg(dev, 0x00, 0x0197); mdelay(1);
34766 + RF_WriteReg(dev, 0x05, 0x05ab); mdelay(1);
34767 + RF_WriteReg(dev, 0x00, 0x009F); mdelay(1);
34769 + RF_WriteReg(dev, 0x01, 0x0000); mdelay(1); // Rx mode//+edward
34770 + RF_WriteReg(dev, 0x02, 0x0000); mdelay(1); // Rx mode//+edward
34771 + //power save parameters.
34772 + u1b24E = read_nic_byte(dev, 0x24E);
34773 + write_nic_byte(dev, 0x24E, (u1b24E & (~(BIT5|BIT6))));
34775 + //=============================================================================
34777 + //=============================================================================
34779 + //=============================================================================
34781 + /* [POWER SAVE] Power Saving Parameters by jong. 2007-11-27
34782 + CCK reg0x00[7]=1'b1 :power saving for TX (default)
34783 + CCK reg0x00[6]=1'b1: power saving for RX (default)
34784 + CCK reg0x06[4]=1'b1: turn off channel estimation related circuits if not doing channel estimation.
34785 + CCK reg0x06[3]=1'b1: turn off unused circuits before cca = 1
34786 + CCK reg0x06[2]=1'b1: turn off cck's circuit if macrst =0
34789 + write_nic_dword(dev, PHY_ADR, 0x0100c880);
34790 + write_nic_dword(dev, PHY_ADR, 0x01001c86);
34791 + write_nic_dword(dev, PHY_ADR, 0x01007890);
34792 + write_nic_dword(dev, PHY_ADR, 0x0100d0ae);
34793 + write_nic_dword(dev, PHY_ADR, 0x010006af);
34794 + write_nic_dword(dev, PHY_ADR, 0x01004681);
34796 + write_phy_cck(dev,0x00,0xc8);
34797 + write_phy_cck(dev,0x06,0x1c);
34798 + write_phy_cck(dev,0x10,0x78);
34799 + write_phy_cck(dev,0x2e,0xd0);
34800 + write_phy_cck(dev,0x2f,0x06);
34801 + write_phy_cck(dev,0x01,0x46);
34804 + write_nic_byte(dev, CCK_TXAGC, 0x10);
34805 + write_nic_byte(dev, OFDM_TXAGC, 0x1B);
34806 + write_nic_byte(dev, ANTSEL, 0x03);
34808 + //=============================================================================
34810 + //=============================================================================
34812 + RF_WriteReg(dev, 0x00, 0x00b7); mdelay(1);
34813 + RF_WriteReg(dev, 0x01, 0x0ee0); mdelay(1);
34814 + RF_WriteReg(dev, 0x02, 0x044d); mdelay(1);
34815 + RF_WriteReg(dev, 0x03, 0x0441); mdelay(1);
34816 + RF_WriteReg(dev, 0x04, 0x08c3); mdelay(1);
34817 + RF_WriteReg(dev, 0x05, 0x0c72); mdelay(1);
34818 + RF_WriteReg(dev, 0x06, 0x00e6); mdelay(1);
34819 + RF_WriteReg(dev, 0x07, 0x082a); mdelay(1);
34820 + RF_WriteReg(dev, 0x08, 0x003f); mdelay(1);
34821 + RF_WriteReg(dev, 0x09, 0x0335); mdelay(1);
34822 + RF_WriteReg(dev, 0x0a, 0x09d4); mdelay(1);
34823 + RF_WriteReg(dev, 0x0b, 0x07bb); mdelay(1);
34824 + RF_WriteReg(dev, 0x0c, 0x0850); mdelay(1);
34825 + RF_WriteReg(dev, 0x0d, 0x0cdf); mdelay(1);
34826 + RF_WriteReg(dev, 0x0e, 0x002b); mdelay(1);
34827 + RF_WriteReg(dev, 0x0f, 0x0114); mdelay(1);
34829 + RF_WriteReg(dev, 0x00, 0x01b7); mdelay(1);
34832 + for(i=1;i<=95;i++)
34834 + RF_WriteReg(dev, 0x01, i); mdelay(1);
34835 + RF_WriteReg(dev, 0x02, ZEBRA_RF_RX_GAIN_TABLE[i]); mdelay(1);
34836 + //DbgPrint("RF - 0x%x = 0x%x", i, ZEBRA_RF_RX_GAIN_TABLE[i]);
34839 + RF_WriteReg(dev, 0x03, 0x0080); mdelay(1); // write reg 18
34840 + RF_WriteReg(dev, 0x05, 0x0004); mdelay(1); // write reg 20
34841 + RF_WriteReg(dev, 0x00, 0x00b7); mdelay(1); // switch to reg0-reg15
34845 + RF_WriteReg(dev, 0x02, 0x0c4d); mdelay(1);
34846 + mdelay(100); // Deay 100 ms. //0xfe
34847 + mdelay(100); // Deay 100 ms. //0xfe
34848 + RF_WriteReg(dev, 0x02, 0x044d); mdelay(1);
34849 + RF_WriteReg(dev, 0x00, 0x02bf); mdelay(1); //0x002f disable 6us corner change, 06f--> enable
34851 + //=============================================================================
34853 + //=============================================================================
34855 + //=============================================================================
34857 + //=============================================================================
34859 + //=============================================================================
34860 + // Follow WMAC RTL8225_Config()
34861 + //=============================================================================
34864 + write_nic_byte(dev, CCK_TXAGC, 0x03);
34865 + write_nic_byte(dev, OFDM_TXAGC, 0x07);
34866 + write_nic_byte(dev, ANTSEL, 0x03);
34868 + //=============================================================================
34870 + // OFDM BBP setup
34871 +// SetOutputEnableOfRfPins(dev);//by amy
34876 + //=============================================================================
34878 + //=============================================================================
34880 +// PlatformIOWrite4Byte( dev, PhyAddr, 0x00001280); // Annie, 2006-05-05
34881 + write_phy_ofdm(dev, 0x00, 0x12);
34882 + //WriteBBPortUchar(dev, 0x00001280);
34884 + for (i=0; i<128; i++)
34886 + //DbgPrint("AGC - [%x+1] = 0x%x\n", i, ZEBRA_AGC[i+1]);
34888 + data = ZEBRA_AGC[i+1];
34889 + data = data << 8;
34890 + data = data | 0x0000008F;
34892 + addr = i + 0x80; //enable writing AGC table
34893 + addr = addr << 8;
34894 + addr = addr | 0x0000008E;
34896 + WriteBBPortUchar(dev, data);
34897 + WriteBBPortUchar(dev, addr);
34898 + WriteBBPortUchar(dev, 0x0000008E);
34901 + PlatformIOWrite4Byte( dev, PhyAddr, 0x00001080); // Annie, 2006-05-05
34902 + //WriteBBPortUchar(dev, 0x00001080);
34904 + //=============================================================================
34906 + //=============================================================================
34908 + //=============================================================================
34910 + for(i=0; i<60; i++)
34913 + u4bRegValue=OFDM_CONFIG[i];
34915 + //DbgPrint("OFDM - 0x%x = 0x%x\n", u4bRegOffset, u4bRegValue);
34917 + WriteBBPortUchar(dev,
34919 + (u4bRegOffset & 0x7f) |
34920 + ((u4bRegValue & 0xff) << 8)));
34923 + //=============================================================================
34924 +//by amy for antenna
34925 + //=============================================================================
34927 +#ifdef CONFIG_RTL818X_S
34928 + // Config Sw/Hw Combinational Antenna Diversity. Added by Roger, 2008.02.26.
34929 + SetAntennaConfig87SE(dev, priv->bDefaultAntenna1, priv->bSwAntennaDiverity);
34933 + // Config Sw/Hw Antenna Diversity
34934 + if( priv->bSwAntennaDiverity ) // Use SW+Hw Antenna Diversity
34936 + if( priv->bDefaultAntenna1 == true ) // aux antenna
34938 + // Mac register, aux antenna
34939 + write_nic_byte(dev, ANTSEL, 0x00);
34940 + // Config CCK RX antenna.
34941 + write_phy_cck(dev, 0x11, 0xbb); // Reg11 : bb
34942 + write_phy_cck(dev, 0x0c, 0x09); // Reg0c : 09
34943 + write_phy_cck(dev, 0x01, 0xc7); // Reg01 : c7
34944 + // Config OFDM RX antenna.
34945 + write_phy_ofdm(dev, 0x0d, 0x54); // Reg0d : 54
34946 + write_phy_ofdm(dev, 0x18, 0xb2); // Reg18 : b2
34948 + else // main antenna
34950 + // Mac register, main antenna
34951 + write_nic_byte(dev, ANTSEL, 0x03);
34953 + // Config CCK RX antenna.
34954 + write_phy_cck(dev, 0x11, 0x9b); // Reg11 : 9b
34955 + write_phy_cck(dev, 0x0c, 0x09); // Reg0c : 09
34956 + write_phy_cck(dev, 0x01, 0xc7); // Reg01 : c7
34957 + // Config OFDM RX antenna.
34958 + write_phy_ofdm(dev, 0x0d, 0x5c); // Reg0d : 5c
34959 + write_phy_ofdm(dev, 0x18, 0xb2); // Reg18 : b2
34962 + else // Disable Antenna Diversity
34964 + if( priv->bDefaultAntenna1 == true ) // aux Antenna
34966 + // Mac register, aux antenna
34967 + write_nic_byte(dev, ANTSEL, 0x00);
34968 + // Config CCK RX antenna.
34969 + write_phy_cck(dev, 0x11, 0xbb); // Reg11 : bb
34970 + write_phy_cck(dev, 0x0c, 0x09); // Reg0c : 09
34971 + write_phy_cck(dev, 0x01, 0x47); // Reg01 : 47
34972 + // Config OFDM RX antenna.
34973 + write_phy_ofdm(dev, 0x0d, 0x54); // Reg0d : 54
34974 + write_phy_ofdm(dev, 0x18, 0x32); // Reg18 : 32
34976 + else // main Antenna
34978 + // Mac register, main antenna
34979 + write_nic_byte(dev, ANTSEL, 0x03);
34980 + // Config CCK RX antenna.
34981 + write_phy_cck(dev, 0x11, 0x9b); // Reg11 : 9b
34982 + write_phy_cck(dev, 0x0c, 0x09); // Reg0c : 09
34983 + write_phy_cck(dev, 0x01, 0x47); // Reg01 : 47
34984 + // Config OFDM RX antenna.
34985 + write_phy_ofdm(dev, 0x0d, 0x5c); // Reg0d : 5c
34986 + write_phy_ofdm(dev, 0x18, 0x32); // Reg18 : 32
34990 +//by amy for antenna
34995 +UpdateInitialGain(
34996 + struct net_device *dev
34999 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
35000 + //unsigned char* IGTable;
35001 + //u8 DIG_CurrentInitialGain = 4;
35002 + //unsigned char u1Tmp;
35005 + if(priv->eRFPowerState != eRfOn)
35007 + //Don't access BB/RF under disable PLL situation.
35008 + //RT_TRACE(COMP_DIG, DBG_LOUD, ("UpdateInitialGain - pHalData->eRFPowerState!=eRfOn\n"));
35009 + // Back to the original state
35010 + priv->InitialGain= priv->InitialGainBackUp;
35014 + switch(priv->rf_chip)
35018 + // Dynamic set initial gain, by shien chang, 2006.07.14
35019 + switch(priv->InitialGain)
35021 + case 1: //m861dBm
35022 + DMESG("RTL8185B + 8225 Initial Gain State 1: -82 dBm \n");
35023 + write_nic_dword(dev, PhyAddr, 0x2697); mdelay(1);
35024 + write_nic_dword(dev, PhyAddr, 0x86a4); mdelay(1);
35025 + write_nic_dword(dev, PhyAddr, 0xfa85); mdelay(1);
35028 + case 2: //m862dBm
35029 + DMESG("RTL8185B + 8225 Initial Gain State 2: -82 dBm \n");
35030 + write_nic_dword(dev, PhyAddr, 0x2697); mdelay(1);
35031 + write_nic_dword(dev, PhyAddr, 0x86a4); mdelay(1);
35032 + write_nic_dword(dev, PhyAddr, 0xfb85); mdelay(1);
35035 + case 3: //m863dBm
35036 + DMESG("RTL8185B + 8225 Initial Gain State 3: -82 dBm \n");
35037 + write_nic_dword(dev, PhyAddr, 0x2697); mdelay(1);
35038 + write_nic_dword(dev, PhyAddr, 0x96a4); mdelay(1);
35039 + write_nic_dword(dev, PhyAddr, 0xfb85); mdelay(1);
35042 + case 4: //m864dBm
35043 + DMESG("RTL8185B + 8225 Initial Gain State 4: -78 dBm \n");
35044 + write_nic_dword(dev, PhyAddr, 0x2697); mdelay(1);
35045 + write_nic_dword(dev, PhyAddr, 0xa6a4); mdelay(1);
35046 + write_nic_dword(dev, PhyAddr, 0xfb85); mdelay(1);
35050 + DMESG("RTL8185B + 8225 Initial Gain State 5: -74 dBm \n");
35051 + write_nic_dword(dev, PhyAddr, 0x3697); mdelay(1);
35052 + write_nic_dword(dev, PhyAddr, 0xa6a4); mdelay(1);
35053 + write_nic_dword(dev, PhyAddr, 0xfb85); mdelay(1);
35057 + DMESG("RTL8185B + 8225 Initial Gain State 6: -70 dBm \n");
35058 + write_nic_dword(dev, PhyAddr, 0x4697); mdelay(1);
35059 + write_nic_dword(dev, PhyAddr, 0xa6a4); mdelay(1);
35060 + write_nic_dword(dev, PhyAddr, 0xfb85); mdelay(1);
35064 + DMESG("RTL8185B + 8225 Initial Gain State 7: -66 dBm \n");
35065 + write_nic_dword(dev, PhyAddr, 0x5697); mdelay(1);
35066 + write_nic_dword(dev, PhyAddr, 0xa6a4); mdelay(1);
35067 + write_nic_dword(dev, PhyAddr, 0xfb85); mdelay(1);
35071 + DMESG("RTL8185B + 8225 Initial Gain State 1: -82 dBm (default)\n");
35072 + write_nic_dword(dev, PhyAddr, 0x2697); mdelay(1);
35073 + write_nic_dword(dev, PhyAddr, 0x86a4); mdelay(1);
35074 + write_nic_dword(dev, PhyAddr, 0xfa85); mdelay(1);
35080 + // Dynamic set initial gain, follow 87B
35081 + switch(priv->InitialGain)
35083 + case 1: //m861dBm
35084 + //DMESG("RTL8187 + 8225 Initial Gain State 1: -82 dBm \n");
35085 + write_phy_ofdm(dev, 0x17, 0x26); mdelay(1);
35086 + write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
35087 + write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
35090 + case 2: //m862dBm
35091 + //DMESG("RTL8187 + 8225 Initial Gain State 2: -82 dBm \n");
35092 + write_phy_ofdm(dev, 0x17, 0x36); mdelay(1);
35093 + write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
35094 + write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
35097 + case 3: //m863dBm
35098 + //DMESG("RTL8187 + 8225 Initial Gain State 3: -82 dBm \n");
35099 + write_phy_ofdm(dev, 0x17, 0x36); mdelay(1);
35100 + write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
35101 + write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
35104 + case 4: //m864dBm
35105 + //DMESG("RTL8187 + 8225 Initial Gain State 4: -78 dBm \n");
35106 + write_phy_ofdm(dev, 0x17, 0x46); mdelay(1);
35107 + write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
35108 + write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
35112 + //DMESG("RTL8187 + 8225 Initial Gain State 5: -74 dBm \n");
35113 + write_phy_ofdm(dev, 0x17, 0x46); mdelay(1);
35114 + write_phy_ofdm(dev, 0x24, 0x96); mdelay(1);
35115 + write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
35119 + //DMESG ("RTL8187 + 8225 Initial Gain State 6: -70 dBm \n");
35120 + write_phy_ofdm(dev, 0x17, 0x56); mdelay(1);
35121 + write_phy_ofdm(dev, 0x24, 0x96); mdelay(1);
35122 + write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
35126 + //DMESG("RTL8187 + 8225 Initial Gain State 7: -66 dBm \n");
35127 + write_phy_ofdm(dev, 0x17, 0x56); mdelay(1);
35128 + write_phy_ofdm(dev, 0x24, 0xa6); mdelay(1);
35129 + write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
35133 + //DMESG("RTL8187 + 8225 Initial Gain State 8:\n");
35134 + write_phy_ofdm(dev, 0x17, 0x66); mdelay(1);
35135 + write_phy_ofdm(dev, 0x24, 0xb6); mdelay(1);
35136 + write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
35141 + //DMESG("RTL8187 + 8225 Initial Gain State 1: -82 dBm (default)\n");
35142 + write_phy_ofdm(dev, 0x17, 0x26); mdelay(1);
35143 + write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
35144 + write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
35151 + DMESG("UpdateInitialGain(): unknown RFChipID: %#X\n", priv->rf_chip);
35155 +#ifdef CONFIG_RTL818X_S
35158 +// Tx Power tracking mechanism routine on 87SE.
35159 +// Created by Roger, 2007.12.11.
35162 +InitTxPwrTracking87SE(
35163 + struct net_device *dev
35166 + //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
35169 + u4bRfReg = RF_ReadReg(dev, 0x02);
35171 + // Enable Thermal meter indication.
35172 + //printk("InitTxPwrTracking87SE(): Enable thermal meter indication, Write RF[0x02] = %#x", u4bRfReg|PWR_METER_EN);
35173 + RF_WriteReg(dev, 0x02, u4bRfReg|PWR_METER_EN); mdelay(1);
35179 + struct net_device *dev
35182 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
35183 + write_nic_dword(dev, RCR, priv->ReceiveConfig);
35184 + priv->RFProgType = read_nic_byte(dev, CONFIG4) & 0x03;
35186 + switch(priv->rf_chip)
35190 + ZEBRA_Config_85BASIC_HardCode( dev);
35194 +#ifdef CONFIG_RTL818X_S
35195 + // Set default initial gain state to 4, approved by SD3 DZ, by Bruce, 2007-06-06.
35196 + if(priv->bDigMechanism)
35198 + if(priv->InitialGain == 0)
35199 + priv->InitialGain = 4;
35200 + //printk("PhyConfig8185(): DIG is enabled, set default initial gain index to %d\n", priv->InitialGain);
35204 + // Enable thermal meter indication to implement TxPower tracking on 87SE.
35205 + // We initialize thermal meter here to avoid unsuccessful configuration.
35206 + // Added by Roger, 2007.12.11.
35208 + if(priv->bTxPowerTrack)
35209 + InitTxPwrTracking87SE(dev);
35213 + priv->InitialGainBackUp= priv->InitialGain;
35214 + UpdateInitialGain(dev);
35223 +HwConfigureRTL8185(
35224 + struct net_device *dev
35227 + //RTL8185_TODO: Determine Retrylimit, TxAGC, AutoRateFallback control.
35228 +// u8 bUNIVERSAL_CONTROL_RL = 1;
35229 + u8 bUNIVERSAL_CONTROL_RL = 0;
35231 + u8 bUNIVERSAL_CONTROL_AGC = 1;
35232 + u8 bUNIVERSAL_CONTROL_ANT = 1;
35233 + u8 bAUTO_RATE_FALLBACK_CTL = 1;
35235 + //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
35236 + //struct ieee80211_device *ieee = priv->ieee80211;
35237 + //if(IS_WIRELESS_MODE_A(dev) || IS_WIRELESS_MODE_G(dev))
35238 +//{by amy 080312 if((ieee->mode == IEEE_G)||(ieee->mode == IEEE_A))
35240 +// write_nic_word(dev, BRSR, 0xffff);
35244 +// write_nic_word(dev, BRSR, 0x000f);
35247 + write_nic_word(dev, BRSR, 0x0fff);
35249 + val8 = read_nic_byte(dev, CW_CONF);
35251 + if(bUNIVERSAL_CONTROL_RL)
35252 + val8 = val8 & 0xfd;
35254 + val8 = val8 | 0x02;
35256 + write_nic_byte(dev, CW_CONF, val8);
35259 + val8 = read_nic_byte(dev, TXAGC_CTL);
35260 + if(bUNIVERSAL_CONTROL_AGC)
35262 + write_nic_byte(dev, CCK_TXAGC, 128);
35263 + write_nic_byte(dev, OFDM_TXAGC, 128);
35264 + val8 = val8 & 0xfe;
35268 + val8 = val8 | 0x01 ;
35272 + write_nic_byte(dev, TXAGC_CTL, val8);
35274 + // Tx Antenna including Feedback control
35275 + val8 = read_nic_byte(dev, TXAGC_CTL );
35277 + if(bUNIVERSAL_CONTROL_ANT)
35279 + write_nic_byte(dev, ANTSEL, 0x00);
35280 + val8 = val8 & 0xfd;
35284 + val8 = val8 & (val8|0x02); //xiong-2006-11-15
35287 + write_nic_byte(dev, TXAGC_CTL, val8);
35289 + // Auto Rate fallback control
35290 + val8 = read_nic_byte(dev, RATE_FALLBACK);
35292 + if( bAUTO_RATE_FALLBACK_CTL )
35294 + val8 |= RATE_FALLBACK_CTL_ENABLE | RATE_FALLBACK_CTL_AUTO_STEP1;
35296 + // <RJ_TODO_8185B> We shall set up the ARFR according to user's setting.
35297 + //write_nic_word(dev, ARFR, 0x0fff); // set 1M ~ 54M
35300 + PlatformIOWrite2Byte(dev, ARFR, 0x0fff); // set 1M ~ 54M
35302 +#ifdef CONFIG_RTL818X_S
35303 + // Aadded by Roger, 2007.11.15.
35304 + PlatformIOWrite2Byte(dev, ARFR, 0x0fff); //set 1M ~ 54Mbps.
35306 + PlatformIOWrite2Byte(dev, ARFR, 0x0c00); //set 48Mbps, 54Mbps.
35307 + // By SD3 szuyi's request. by Roger, 2007.03.26.
35314 + write_nic_byte(dev, RATE_FALLBACK, val8);
35320 +MacConfig_85BASIC_HardCode(
35321 + struct net_device *dev)
35323 + //============================================================================
35325 + //============================================================================
35326 + int nLinesRead = 0;
35328 + u32 u4bRegOffset, u4bRegValue,u4bPageIndex = 0;
35331 + nLinesRead=sizeof(MAC_REG_TABLE)/2;
35333 + for(i = 0; i < nLinesRead; i++) //nLinesRead=101
35335 + u4bRegOffset=MAC_REG_TABLE[i][0];
35336 + u4bRegValue=MAC_REG_TABLE[i][1];
35338 + if(u4bRegOffset == 0x5e)
35340 + u4bPageIndex = u4bRegValue;
35344 + u4bRegOffset |= (u4bPageIndex << 8);
35346 + //DbgPrint("MAC - 0x%x = 0x%x\n", u4bRegOffset, u4bRegValue);
35347 + write_nic_byte(dev, u4bRegOffset, (u8)u4bRegValue);
35349 + //============================================================================
35355 +MacConfig_85BASIC(
35356 + struct net_device *dev)
35360 + MacConfig_85BASIC_HardCode(dev);
35362 + //============================================================================
35364 + // Follow TID_AC_MAP of WMac.
35365 + write_nic_word(dev, TID_AC_MAP, 0xfa50);
35367 + // Interrupt Migration, Jong suggested we use set 0x0000 first, 2005.12.14, by rcnjko.
35368 + write_nic_word(dev, IntMig, 0x0000);
35370 + // Prevent TPC to cause CRC error. Added by Annie, 2006-06-10.
35371 + PlatformIOWrite4Byte(dev, 0x1F0, 0x00000000);
35372 + PlatformIOWrite4Byte(dev, 0x1F4, 0x00000000);
35373 + PlatformIOWrite1Byte(dev, 0x1F8, 0x00);
35375 + // Asked for by SD3 CM Lin, 2006.06.27, by rcnjko.
35376 + //PlatformIOWrite4Byte(dev, RFTiming, 0x00004001);
35379 + write_nic_dword(dev, RFTiming, 0x00004001);
35381 +#ifdef CONFIG_RTL818X_S
35382 + // power save parameter based on "87SE power save parameters 20071127.doc", as follow.
35384 + //Enable DA10 TX power saving
35385 + u1DA = read_nic_byte(dev, PHYPR);
35386 + write_nic_byte(dev, PHYPR, (u1DA | BIT2) );
35389 + write_nic_word(dev, 0x360, 0x1000);
35390 + write_nic_word(dev, 0x362, 0x1000);
35393 + write_nic_word(dev, 0x370, 0x0560);
35394 + write_nic_word(dev, 0x372, 0x0560);
35395 + write_nic_word(dev, 0x374, 0x0DA4);
35396 + write_nic_word(dev, 0x376, 0x0DA4);
35397 + write_nic_word(dev, 0x378, 0x0560);
35398 + write_nic_word(dev, 0x37A, 0x0560);
35399 + write_nic_word(dev, 0x37C, 0x00EC);
35400 +// write_nic_word(dev, 0x37E, 0x00FE);//-edward
35401 + write_nic_word(dev, 0x37E, 0x00EC);//+edward
35403 + write_nic_dword(dev, RFTiming, 0x00004003);
35405 + write_nic_byte(dev, 0x24E,0x01);
35414 +GetSupportedWirelessMode8185(
35415 + struct net_device *dev
35418 + u8 btSupportedWirelessMode = 0;
35419 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
35421 + switch(priv->rf_chip)
35425 + btSupportedWirelessMode = (WIRELESS_MODE_B | WIRELESS_MODE_G);
35428 + btSupportedWirelessMode = WIRELESS_MODE_B;
35432 + return btSupportedWirelessMode;
35436 +ActUpdateChannelAccessSetting(
35437 + struct net_device *dev,
35438 + WIRELESS_MODE WirelessMode,
35439 + PCHANNEL_ACCESS_SETTING ChnlAccessSetting
35442 + struct r8180_priv *priv = ieee80211_priv(dev);
35443 + struct ieee80211_device *ieee = priv->ieee80211;
35445 + AC_PARAM AcParam;
35446 + //PSTA_QOS pStaQos = Adapter->MgntInfo.pStaQos;
35447 + u8 bFollowLegacySetting = 0;
35451 + // <RJ_TODO_8185B>
35452 + // TODO: We still don't know how to set up these registers, just follow WMAC to
35453 + // verify 8185B FPAG.
35455 + // <RJ_TODO_8185B>
35456 + // Jong said CWmin/CWmax register are not functional in 8185B,
35457 + // so we shall fill channel access realted register into AC parameter registers,
35458 + // even in nQBss.
35460 + ChnlAccessSetting->SIFS_Timer = 0x22; // Suggested by Jong, 2005.12.08.
35461 + ChnlAccessSetting->DIFS_Timer = 0x1C; // 2006.06.02, by rcnjko.
35462 + ChnlAccessSetting->SlotTimeTimer = 9; // 2006.06.02, by rcnjko.
35463 + ChnlAccessSetting->EIFS_Timer = 0x5B; // Suggested by wcchu, it is the default value of EIFS register, 2005.12.08.
35464 + ChnlAccessSetting->CWminIndex = 3; // 2006.06.02, by rcnjko.
35465 + ChnlAccessSetting->CWmaxIndex = 7; // 2006.06.02, by rcnjko.
35467 + write_nic_byte(dev, SIFS, ChnlAccessSetting->SIFS_Timer);
35468 + //Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_SLOT_TIME, &ChnlAccessSetting->SlotTimeTimer ); // Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29.
35469 + write_nic_byte(dev, SLOT, ChnlAccessSetting->SlotTimeTimer); // Rewrited from directly use PlatformEFIOWrite1Byte(), by Annie, 2006-03-29.
35471 + u1bAIFS = aSifsTime + (2 * ChnlAccessSetting->SlotTimeTimer );
35473 + //write_nic_byte(dev, AC_VO_PARAM, u1bAIFS);
35474 + //write_nic_byte(dev, AC_VI_PARAM, u1bAIFS);
35475 + //write_nic_byte(dev, AC_BE_PARAM, u1bAIFS);
35476 + //write_nic_byte(dev, AC_BK_PARAM, u1bAIFS);
35478 + write_nic_byte(dev, EIFS, ChnlAccessSetting->EIFS_Timer);
35480 + write_nic_byte(dev, AckTimeOutReg, 0x5B); // <RJ_EXPR_QOS> Suggested by wcchu, it is the default value of EIFS register, 2005.12.08.
35483 + // <RJ_TODO_NOW_8185B> Update ECWmin/ECWmax, AIFS, TXOP Limit of each AC to the value defined by SPEC.
35484 + if( pStaQos->CurrentQosMode > QOS_DISABLE )
35486 + if(pStaQos->QBssWirelessMode == WirelessMode)
35488 + // Follow AC Parameters of the QBSS.
35489 + for(eACI = 0; eACI < AC_MAX; eACI++)
35491 + Adapter->HalFunc.SetHwRegHandler(Adapter, HW_VAR_AC_PARAM, (pu1Byte)(&(pStaQos->WMMParamEle.AcParam[eACI])) );
35496 + // Follow Default WMM AC Parameters.
35497 + bFollowLegacySetting = 1;
35502 + { // Legacy 802.11.
35503 + bFollowLegacySetting = 1;
35507 + // this setting is copied from rtl8187B. xiong-2006-11-13
35508 + if(bFollowLegacySetting)
35513 + // Follow 802.11 seeting to AC parameter, all AC shall use the same parameter.
35514 + // 2005.12.01, by rcnjko.
35516 + AcParam.longData = 0;
35517 + AcParam.f.AciAifsn.f.AIFSN = 2; // Follow 802.11 DIFS.
35518 + AcParam.f.AciAifsn.f.ACM = 0;
35519 + AcParam.f.Ecw.f.ECWmin = ChnlAccessSetting->CWminIndex; // Follow 802.11 CWmin.
35520 + AcParam.f.Ecw.f.ECWmax = ChnlAccessSetting->CWmaxIndex; // Follow 802.11 CWmax.
35521 + AcParam.f.TXOPLimit = 0;
35523 + //lzm reserved 080826
35525 +#ifdef THOMAS_TURBO
35526 + // For turbo mode setting. port from 87B by Isaiah 2008-08-01
35527 + if( ieee->current_network.Turbo_Enable == 1 )
35528 + AcParam.f.TXOPLimit = 0x01FF;
35530 + // For 87SE with Intel 4965 Ad-Hoc mode have poor throughput (19MB)
35531 + if (ieee->iw_mode == IW_MODE_ADHOC)
35532 + AcParam.f.TXOPLimit = 0x0020;
35535 + for(eACI = 0; eACI < AC_MAX; eACI++)
35537 + AcParam.f.AciAifsn.f.ACI = (u8)eACI;
35539 + PAC_PARAM pAcParam = (PAC_PARAM)(&AcParam);
35544 + // Retrive paramters to udpate.
35545 + eACI = pAcParam->f.AciAifsn.f.ACI;
35546 + u1bAIFS = pAcParam->f.AciAifsn.f.AIFSN * ChnlAccessSetting->SlotTimeTimer + aSifsTime;
35547 + u4bAcParam = ( (((u32)(pAcParam->f.TXOPLimit)) << AC_PARAM_TXOP_LIMIT_OFFSET) |
35548 + (((u32)(pAcParam->f.Ecw.f.ECWmax)) << AC_PARAM_ECW_MAX_OFFSET) |
35549 + (((u32)(pAcParam->f.Ecw.f.ECWmin)) << AC_PARAM_ECW_MIN_OFFSET) |
35550 + (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET));
35555 + //write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
35559 + //write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
35563 + //write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
35567 + //write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
35571 + DMESGW( "SetHwReg8185(): invalid ACI: %d !\n", eACI);
35575 + // Cehck ACM bit.
35576 + // If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13.
35577 + //write_nic_byte(dev, ACM_CONTROL, pAcParam->f.AciAifsn);
35579 + PACI_AIFSN pAciAifsn = (PACI_AIFSN)(&pAcParam->f.AciAifsn);
35580 + AC_CODING eACI = pAciAifsn->f.ACI;
35582 + //modified Joseph
35583 + //for 8187B AsynIORead issue
35585 + u8 AcmCtrl = pHalData->AcmControl;
35589 + if( pAciAifsn->f.ACM )
35590 + { // ACM bit is 1.
35594 + AcmCtrl |= (BEQ_ACM_EN|BEQ_ACM_CTL|ACM_HW_EN); // or 0x21
35598 + AcmCtrl |= (VIQ_ACM_EN|VIQ_ACM_CTL|ACM_HW_EN); // or 0x42
35602 + AcmCtrl |= (VOQ_ACM_EN|VOQ_ACM_CTL|ACM_HW_EN); // or 0x84
35606 + DMESGW("SetHwReg8185(): [HW_VAR_ACM_CTRL] ACM set failed: eACI is %d\n", eACI );
35611 + { // ACM bit is 0.
35615 + AcmCtrl &= ( (~BEQ_ACM_EN) & (~BEQ_ACM_CTL) & (~ACM_HW_EN) ); // and 0xDE
35619 + AcmCtrl &= ( (~VIQ_ACM_EN) & (~VIQ_ACM_CTL) & (~ACM_HW_EN) ); // and 0xBD
35623 + AcmCtrl &= ( (~VOQ_ACM_EN) & (~VOQ_ACM_CTL) & (~ACM_HW_EN) ); // and 0x7B
35631 + //printk(KERN_WARNING "SetHwReg8185(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl);
35634 + pHalData->AcmControl = AcmCtrl;
35636 + //write_nic_byte(dev, ACM_CONTROL, AcmCtrl);
35637 + write_nic_byte(dev, ACM_CONTROL, 0);
35647 +ActSetWirelessMode8185(
35648 + struct net_device *dev,
35649 + u8 btWirelessMode
35652 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
35653 + struct ieee80211_device *ieee = priv->ieee80211;
35654 + //PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo);
35655 + u8 btSupportedWirelessMode = GetSupportedWirelessMode8185(dev);
35657 + if( (btWirelessMode & btSupportedWirelessMode) == 0 )
35658 + { // Don't switch to unsupported wireless mode, 2006.02.15, by rcnjko.
35659 + DMESGW("ActSetWirelessMode8185(): WirelessMode(%d) is not supported (%d)!\n",
35660 + btWirelessMode, btSupportedWirelessMode);
35664 + // 1. Assign wireless mode to swtich if necessary.
35665 + if (btWirelessMode == WIRELESS_MODE_AUTO)
35667 + if((btSupportedWirelessMode & WIRELESS_MODE_A))
35669 + btWirelessMode = WIRELESS_MODE_A;
35671 + else if((btSupportedWirelessMode & WIRELESS_MODE_G))
35673 + btWirelessMode = WIRELESS_MODE_G;
35675 + else if((btSupportedWirelessMode & WIRELESS_MODE_B))
35677 + btWirelessMode = WIRELESS_MODE_B;
35681 + DMESGW("ActSetWirelessMode8185(): No valid wireless mode supported, btSupportedWirelessMode(%x)!!!\n",
35682 + btSupportedWirelessMode);
35683 + btWirelessMode = WIRELESS_MODE_B;
35688 + // 2. Swtich band: RF or BB specific actions,
35689 + // for example, refresh tables in omc8255, or change initial gain if necessary.
35690 + switch(priv->rf_chip)
35695 + // Nothing to do for Zebra to switch band.
35696 + // Update current wireless mode if we swtich to specified band successfully.
35697 + ieee->mode = (WIRELESS_MODE)btWirelessMode;
35702 + DMESGW("ActSetWirelessMode8185(): unsupported RF: 0x%X !!!\n", priv->rf_chip);
35706 + // 3. Change related setting.
35707 + if( ieee->mode == WIRELESS_MODE_A ){
35708 + DMESG("WIRELESS_MODE_A\n");
35710 + else if( ieee->mode == WIRELESS_MODE_B ){
35711 + DMESG("WIRELESS_MODE_B\n");
35713 + else if( ieee->mode == WIRELESS_MODE_G ){
35714 + DMESG("WIRELESS_MODE_G\n");
35717 + ActUpdateChannelAccessSetting( dev, ieee->mode, &priv->ChannelAccessSetting);
35720 +void rtl8185b_irq_enable(struct net_device *dev)
35722 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
35724 + priv->irq_enabled = 1;
35725 + write_nic_dword(dev, IMR, priv->IntrMask);
35727 +//by amy for power save
35729 +DrvIFIndicateDisassociation(
35730 + struct net_device *dev,
35734 + //printk("==> DrvIFIndicateDisassociation()\n");
35736 + // nothing is needed after disassociation request.
35738 + //printk("<== DrvIFIndicateDisassociation()\n");
35741 +MgntDisconnectIBSS(
35742 + struct net_device *dev
35745 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
35748 + //printk("XXXXXXXXXX MgntDisconnect IBSS\n");
35750 + DrvIFIndicateDisassociation(dev, unspec_reason);
35752 +// PlatformZeroMemory( pMgntInfo->Bssid, 6 );
35753 + for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i] = 0x55;
35755 + priv->ieee80211->state = IEEE80211_NOLINK;
35759 + // Vista add a Adhoc profile, HW radio off untill OID_DOT11_RESET_REQUEST
35760 + // Driver would set MSR=NO_LINK, then HW Radio ON, MgntQueue Stuck.
35761 + // Because Bcn DMA isn't complete, mgnt queue would stuck until Bcn packet send.
35763 + // Disable Beacon Queue Own bit, suggested by jong
35764 +// Adapter->HalFunc.SetTxDescOWNHandler(Adapter, BEACON_QUEUE, 0, 0);
35765 + ieee80211_stop_send_beacons(priv->ieee80211);
35767 + priv->ieee80211->link_change(dev);
35768 + notify_wx_assoc_event(priv->ieee80211);
35770 + // Stop SW Beacon.Use hw beacon so do not need to do so.by amy
35772 + if(pMgntInfo->bEnableSwBeaconTimer)
35774 + // SwBeaconTimer will stop if pMgntInfo->mIbss==FALSE, see SwBeaconCallback() for details.
35775 +// comment out by haich, 2007.10.01
35776 +//#if DEV_BUS_TYPE==USB_INTERFACE
35777 + PlatformCancelTimer( Adapter, &pMgntInfo->SwBeaconTimer);
35782 +// MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE );
35786 +MlmeDisassociateRequest(
35787 + struct net_device *dev,
35792 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
35795 + SendDisassociation(priv->ieee80211, asSta, asRsn );
35797 + if( memcmp(priv->ieee80211->current_network.bssid, asSta, 6 ) == 0 ){
35798 + //ShuChen TODO: change media status.
35799 + //ShuChen TODO: What to do when disassociate.
35800 + DrvIFIndicateDisassociation(dev, unspec_reason);
35803 + // pMgntInfo->AsocTimestamp = 0;
35804 + for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i] = 0x22;
35805 +// pMgntInfo->mBrates.Length = 0;
35806 +// Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_BASIC_RATE, (pu1Byte)(&pMgntInfo->mBrates) );
35808 + ieee80211_disassociate(priv->ieee80211);
35817 + struct net_device *dev,
35821 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
35824 +// Commented out by rcnjko, 2005.01.27:
35825 +// I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE().
35827 +// //2004/09/15, kcwu, the key should be cleared, or the new handshaking will not success
35828 +// SecClearAllKeys(Adapter);
35830 + // In WPA WPA2 need to Clear all key ... because new key will set after new handshaking.
35832 + if( pMgntInfo->SecurityInfo.AuthMode > RT_802_11AuthModeAutoSwitch ||
35833 + (pMgntInfo->bAPSuportCCKM && pMgntInfo->bCCX8021xenable) ) // In CCKM mode will Clear key
35835 + SecClearAllKeys(Adapter);
35836 + RT_TRACE(COMP_SEC, DBG_LOUD,("======>CCKM clear key..."))
35839 + // 2004.10.11, by rcnjko.
35840 + //MlmeDisassociateRequest( Adapter, pMgntInfo->Bssid, disas_lv_ss );
35841 + MlmeDisassociateRequest( dev, priv->ieee80211->current_network.bssid, asRsn );
35843 + priv->ieee80211->state = IEEE80211_NOLINK;
35844 +// pMgntInfo->AsocTimestamp = 0;
35848 + struct net_device *dev,
35852 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
35854 + // Schedule an workitem to wake up for ps mode, 070109, by rcnjko.
35857 + if(pMgntInfo->mPss != eAwake)
35860 + // Using AwkaeTimer to prevent mismatch ps state.
35861 + // In the timer the state will be changed according to the RF is being awoke or not. By Bruce, 2007-10-31.
35863 + // PlatformScheduleWorkItem( &(pMgntInfo->AwakeWorkItem) );
35864 + PlatformSetTimer( Adapter, &(pMgntInfo->AwakeTimer), 0 );
35868 + // Indication of disassociation event.
35869 + //DrvIFIndicateDisassociation(Adapter, asRsn);
35870 +#ifdef ENABLE_DOT11D
35871 + if(IS_DOT11D_ENABLE(priv->ieee80211))
35872 + Dot11d_Reset(priv->ieee80211);
35874 + // In adhoc mode, update beacon frame.
35875 + if( priv->ieee80211->state == IEEE80211_LINKED )
35877 + if( priv->ieee80211->iw_mode == IW_MODE_ADHOC )
35879 +// RT_TRACE(COMP_MLME, DBG_LOUD, ("MgntDisconnect() ===> MgntDisconnectIBSS\n"));
35880 + //printk("MgntDisconnect() ===> MgntDisconnectIBSS\n");
35881 + MgntDisconnectIBSS(dev);
35883 + if( priv->ieee80211->iw_mode == IW_MODE_INFRA )
35885 + // We clear key here instead of MgntDisconnectAP() because that
35886 + // MgntActSet_802_11_DISASSOCIATE() is an interface called by OS,
35887 + // e.g. OID_802_11_DISASSOCIATE in Windows while as MgntDisconnectAP() is
35888 + // used to handle disassociation related things to AP, e.g. send Disassoc
35889 + // frame to AP. 2005.01.27, by rcnjko.
35890 +// SecClearAllKeys(Adapter);
35892 +// RT_TRACE(COMP_MLME, DBG_LOUD, ("MgntDisconnect() ===> MgntDisconnectAP\n"));
35893 + //printk("MgntDisconnect() ===> MgntDisconnectAP\n");
35894 + MgntDisconnectAP(dev, asRsn);
35897 + // Inidicate Disconnect, 2005.02.23, by rcnjko.
35898 +// MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE);
35905 +// Chang RF Power State.
35906 +// Note that, only MgntActSet_RF_State() is allowed to set HW_VAR_RF_STATE.
35913 + struct net_device *dev,
35914 + RT_RF_POWER_STATE eRFPowerState
35917 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
35918 + bool bResult = false;
35920 +// printk("---------> SetRFPowerState(): eRFPowerState(%d)\n", eRFPowerState);
35921 + if(eRFPowerState == priv->eRFPowerState)
35923 +// printk("<--------- SetRFPowerState(): discard the request for eRFPowerState(%d) is the same.\n", eRFPowerState);
35927 + switch(priv->rf_chip)
35931 + bResult = SetZebraRFPowerState8185(dev, eRFPowerState);
35935 + printk("SetRFPowerState8185(): unknown RFChipID: 0x%X!!!\n", priv->rf_chip);
35938 +// printk("<--------- SetRFPowerState(): bResult(%d)\n", bResult);
35943 +HalEnableRx8185Dummy(
35944 + struct net_device *dev
35949 +HalDisableRx8185Dummy(
35950 + struct net_device *dev
35956 +MgntActSet_RF_State(
35957 + struct net_device *dev,
35958 + RT_RF_POWER_STATE StateToSet,
35962 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
35963 + bool bActionAllowed = false;
35964 + bool bConnectBySSID = false;
35965 + RT_RF_POWER_STATE rtState;
35966 + u16 RFWaitCounter = 0;
35967 + unsigned long flag;
35968 +// printk("===>MgntActSet_RF_State(): StateToSet(%d), ChangeSource(0x%x)\n",StateToSet, ChangeSource);
35970 + // Prevent the race condition of RF state change. By Bruce, 2007-11-28.
35971 + // Only one thread can change the RF state at one time, and others should wait to be executed.
35976 +// down(&priv->rf_state);
35977 + spin_lock_irqsave(&priv->rf_ps_lock,flag);
35978 + if(priv->RFChangeInProgress)
35980 +// printk("====================>haha111111111\n");
35981 +// up(&priv->rf_state);
35982 +// RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): RF Change in progress! Wait to set..StateToSet(%d).\n", StateToSet));
35983 + spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
35984 + // Set RF after the previous action is done.
35985 + while(priv->RFChangeInProgress)
35987 + RFWaitCounter ++;
35988 +// RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): Wait 1 ms (%d times)...\n", RFWaitCounter));
35989 + udelay(1000); // 1 ms
35991 + // Wait too long, return FALSE to avoid to be stuck here.
35992 + if(RFWaitCounter > 1000) // 1sec
35994 +// RT_ASSERT(FALSE, ("MgntActSet_RF_State(): Wait too logn to set RF\n"));
35995 + printk("MgntActSet_RF_State(): Wait too long to set RF\n");
35996 + // TODO: Reset RF state?
36003 +// printk("========================>haha2\n");
36004 + priv->RFChangeInProgress = true;
36005 +// up(&priv->rf_state);
36006 + spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
36011 + rtState = priv->eRFPowerState;
36014 + switch(StateToSet)
36018 + // Turn On RF no matter the IPS setting because we need to update the RF state to Ndis under Vista, or
36019 + // the Windows does not allow the driver to perform site survey any more. By Bruce, 2007-10-02.
36021 + priv->RfOffReason &= (~ChangeSource);
36023 + if(! priv->RfOffReason)
36025 + priv->RfOffReason = 0;
36026 + bActionAllowed = true;
36028 + if(rtState == eRfOff && ChangeSource >=RF_CHANGE_BY_HW && !priv->bInHctTest)
36030 + bConnectBySSID = true;
36034 +// RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State - eRfon reject pMgntInfo->RfOffReason= 0x%x, ChangeSource=0x%X\n", pMgntInfo->RfOffReason, ChangeSource));
36039 + // 070125, rcnjko: we always keep connected in AP mode.
36041 + if (priv->RfOffReason > RF_CHANGE_BY_IPS)
36044 + // 060808, Annie:
36045 + // Disconnect to current BSS when radio off. Asked by QuanTa.
36049 + // Calling MgntDisconnect() instead of MgntActSet_802_11_DISASSOCIATE(),
36050 + // because we do NOT need to set ssid to dummy ones.
36051 + // Revised by Roger, 2007.12.04.
36053 + MgntDisconnect( dev, disas_lv_ss );
36055 + // Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI.
36056 + // 2007.05.28, by shien chang.
36057 +// PlatformZeroMemory( pMgntInfo->bssDesc, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC );
36058 +// pMgntInfo->NumBssDesc = 0;
36059 +// PlatformZeroMemory( pMgntInfo->bssDesc4Query, sizeof(RT_WLAN_BSS)*MAX_BSS_DESC );
36060 +// pMgntInfo->NumBssDesc4Query = 0;
36065 + priv->RfOffReason |= ChangeSource;
36066 + bActionAllowed = true;
36070 + priv->RfOffReason |= ChangeSource;
36071 + bActionAllowed = true;
36078 + if(bActionAllowed)
36080 +// RT_TRACE(COMP_RF, DBG_LOUD, ("MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, pMgntInfo->RfOffReason));
36081 + // Config HW to the specified mode.
36082 +// printk("MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, priv->RfOffReason);
36083 + SetRFPowerState(dev, StateToSet);
36086 + if(StateToSet == eRfOn)
36088 + HalEnableRx8185Dummy(dev);
36089 + if(bConnectBySSID)
36091 + // by amy not supported
36092 +// MgntActSet_802_11_SSID(Adapter, Adapter->MgntInfo.Ssid.Octet, Adapter->MgntInfo.Ssid.Length, TRUE );
36096 + else if(StateToSet == eRfOff)
36098 + HalDisableRx8185Dummy(dev);
36103 + // printk("MgntActSet_RF_State(): Action is rejected.... StateToSet(%d), ChangeSource(%#X), RfOffReason(%#X)\n", StateToSet, ChangeSource, priv->RfOffReason);
36106 + // Release RF spinlock
36107 +// down(&priv->rf_state);
36108 + spin_lock_irqsave(&priv->rf_ps_lock,flag);
36109 + priv->RFChangeInProgress = false;
36110 +// up(&priv->rf_state);
36111 + spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
36112 +// printk("<===MgntActSet_RF_State()\n");
36113 + return bActionAllowed;
36116 +InactivePowerSave(
36117 + struct net_device *dev
36120 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
36124 + // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem
36125 + // is really scheduled.
36126 + // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the
36127 + // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing
36128 + // blocks the IPS procedure of switching RF.
36129 + // By Bruce, 2007-12-25.
36131 + priv->bSwRfProcessing = true;
36133 + MgntActSet_RF_State(dev, priv->eInactivePowerState, RF_CHANGE_BY_IPS);
36136 + // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20.
36139 + while( index < 4 )
36141 + if( ( pMgntInfo->SecurityInfo.PairwiseEncAlgorithm == WEP104_Encryption ) ||
36142 + (pMgntInfo->SecurityInfo.PairwiseEncAlgorithm == WEP40_Encryption) )
36144 + if( pMgntInfo->SecurityInfo.KeyLen[index] != 0)
36145 + pAdapter->HalFunc.SetKeyHandler(pAdapter, index, 0, FALSE, pMgntInfo->SecurityInfo.PairwiseEncAlgorithm, TRUE, FALSE);
36151 + priv->bSwRfProcessing = false;
36156 +// Enter the inactive power save mode. RF will be off
36157 +// 2007.08.17, by shien chang.
36161 + struct net_device *dev
36164 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
36165 + RT_RF_POWER_STATE rtState;
36166 + //printk("==============================>enter IPS\n");
36167 + if (priv->bInactivePs)
36169 + rtState = priv->eRFPowerState;
36172 + // Added by Bruce, 2007-12-25.
36173 + // Do not enter IPS in the following conditions:
36174 + // (1) RF is already OFF or Sleep
36175 + // (2) bSwRfProcessing (indicates the IPS is still under going)
36176 + // (3) Connectted (only disconnected can trigger IPS)
36177 + // (4) IBSS (send Beacon)
36178 + // (5) AP mode (send Beacon)
36180 + if (rtState == eRfOn && !priv->bSwRfProcessing
36181 + && (priv->ieee80211->state != IEEE80211_LINKED ))
36183 + // printk("IPSEnter(): Turn off RF.\n");
36184 + priv->eInactivePowerState = eRfOff;
36185 + InactivePowerSave(dev);
36188 +// printk("priv->eRFPowerState is %d\n",priv->eRFPowerState);
36192 + struct net_device *dev
36195 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
36196 + RT_RF_POWER_STATE rtState;
36197 + //printk("===================================>leave IPS\n");
36198 + if (priv->bInactivePs)
36200 + rtState = priv->eRFPowerState;
36201 + if ((rtState == eRfOff || rtState == eRfSleep) && (!priv->bSwRfProcessing) && priv->RfOffReason <= RF_CHANGE_BY_IPS)
36203 +// printk("IPSLeave(): Turn on RF.\n");
36204 + priv->eInactivePowerState = eRfOn;
36205 + InactivePowerSave(dev);
36208 +// printk("priv->eRFPowerState is %d\n",priv->eRFPowerState);
36210 +//by amy for power save
36211 +void rtl8185b_adapter_start(struct net_device *dev)
36213 + struct r8180_priv *priv = ieee80211_priv(dev);
36214 + struct ieee80211_device *ieee = priv->ieee80211;
36216 + u8 SupportedWirelessMode;
36217 + u8 InitWirelessMode;
36218 + u8 bInvalidWirelessMode = 0;
36221 + //u8 u1tmp,u2tmp;
36226 + //rtl8180_rtx_disable(dev);
36228 + write_nic_byte(dev,0x24e, (BIT5|BIT6|BIT0));
36230 + rtl8180_reset(dev);
36232 + priv->dma_poll_mask = 0;
36233 + priv->dma_poll_stop_mask = 0;
36235 + //rtl8180_beacon_tx_disable(dev);
36237 + HwConfigureRTL8185(dev);
36239 + write_nic_dword(dev, MAC0, ((u32*)dev->dev_addr)[0]);
36240 + write_nic_word(dev, MAC4, ((u32*)dev->dev_addr)[1] & 0xffff );
36242 + write_nic_byte(dev, MSR, read_nic_byte(dev, MSR) & 0xf3); // default network type to 'No Link'
36244 + //write_nic_byte(dev, BRSR, 0x0); // Set BRSR= 1M
36246 + write_nic_word(dev, BcnItv, 100);
36247 + write_nic_word(dev, AtimWnd, 2);
36249 + //PlatformEFIOWrite2Byte(dev, FEMR, 0xFFFF);
36250 + PlatformIOWrite2Byte(dev, FEMR, 0xFFFF);
36252 + write_nic_byte(dev, WPA_CONFIG, 0);
36254 + MacConfig_85BASIC(dev);
36256 + // Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07, by rcnjko.
36257 + // BT_DEMO_BOARD type
36258 + PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x569a);
36260 +//#ifdef CONFIG_RTL818X_S
36261 + // for jong required
36262 +// PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x9a56);
36266 + //PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x9a56);
36268 + //-----------------------------------------------------------------------------
36269 + // Set up PHY related.
36270 + //-----------------------------------------------------------------------------
36271 + // Enable Config3.PARAM_En to revise AnaaParm.
36272 + write_nic_byte(dev, CR9346, 0xc0); // enable config register write
36274 + tmpu8 = read_nic_byte(dev, CONFIG3);
36275 +#ifdef CONFIG_RTL818X_S
36276 + write_nic_byte(dev, CONFIG3, (tmpu8 |CONFIG3_PARM_En) );
36278 + write_nic_byte(dev, CONFIG3, (tmpu8 |CONFIG3_PARM_En | CONFIG3_CLKRUN_En) );
36281 + // Turn on Analog power.
36282 + // Asked for by William, otherwise, MAC 3-wire can't work, 2006.06.27, by rcnjko.
36283 + write_nic_dword(dev, ANAPARAM2, ANAPARM2_ASIC_ON);
36284 + write_nic_dword(dev, ANAPARAM, ANAPARM_ASIC_ON);
36286 +#ifdef CONFIG_RTL818X_S
36287 + write_nic_word(dev, ANAPARAM3, 0x0010);
36289 + write_nic_byte(dev, ANAPARAM3, 0x00);
36293 + write_nic_byte(dev, CONFIG3, tmpu8);
36294 + write_nic_byte(dev, CR9346, 0x00);
36295 +//{by amy 080312 for led
36296 + // enable EEM0 and EEM1 in 9346CR
36297 + btCR9346 = read_nic_byte(dev, CR9346);
36298 + write_nic_byte(dev, CR9346, (btCR9346|0xC0) );
36300 + // B cut use LED1 to control HW RF on/off
36301 + TmpU1b = read_nic_byte(dev, CONFIG5);
36302 + TmpU1b = TmpU1b & ~BIT3;
36303 + write_nic_byte(dev,CONFIG5, TmpU1b);
36305 + // disable EEM0 and EEM1 in 9346CR
36306 + btCR9346 &= ~(0xC0);
36307 + write_nic_byte(dev, CR9346, btCR9346);
36309 + //Enable Led (suggested by Jong)
36310 + // B-cut RF Radio on/off 5e[3]=0
36311 + btPSR = read_nic_byte(dev, PSR);
36312 + write_nic_byte(dev, PSR, (btPSR | BIT3));
36313 +//by amy 080312 for led}
36314 + // setup initial timing for RFE.
36315 + write_nic_word(dev, RFPinsOutput, 0x0480);
36316 + SetOutputEnableOfRfPins(dev);
36317 + write_nic_word(dev, RFPinsSelect, 0x2488);
36320 + PhyConfig8185(dev);
36322 + // We assume RegWirelessMode has already been initialized before,
36323 + // however, we has to validate the wireless mode here and provide a reasonble
36324 + // initialized value if necessary. 2005.01.13, by rcnjko.
36325 + SupportedWirelessMode = GetSupportedWirelessMode8185(dev);
36326 + if( (ieee->mode != WIRELESS_MODE_B) &&
36327 + (ieee->mode != WIRELESS_MODE_G) &&
36328 + (ieee->mode != WIRELESS_MODE_A) &&
36329 + (ieee->mode != WIRELESS_MODE_AUTO))
36330 + { // It should be one of B, G, A, or AUTO.
36331 + bInvalidWirelessMode = 1;
36334 + { // One of B, G, A, or AUTO.
36335 + // Check if the wireless mode is supported by RF.
36336 + if( (ieee->mode != WIRELESS_MODE_AUTO) &&
36337 + (ieee->mode & SupportedWirelessMode) == 0 )
36339 + bInvalidWirelessMode = 1;
36343 + if(bInvalidWirelessMode || ieee->mode==WIRELESS_MODE_AUTO)
36344 + { // Auto or other invalid value.
36345 + // Assigne a wireless mode to initialize.
36346 + if((SupportedWirelessMode & WIRELESS_MODE_A))
36348 + InitWirelessMode = WIRELESS_MODE_A;
36350 + else if((SupportedWirelessMode & WIRELESS_MODE_G))
36352 + InitWirelessMode = WIRELESS_MODE_G;
36354 + else if((SupportedWirelessMode & WIRELESS_MODE_B))
36356 + InitWirelessMode = WIRELESS_MODE_B;
36360 + DMESGW("InitializeAdapter8185(): No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n",
36361 + SupportedWirelessMode);
36362 + InitWirelessMode = WIRELESS_MODE_B;
36365 + // Initialize RegWirelessMode if it is not a valid one.
36366 + if(bInvalidWirelessMode)
36368 + ieee->mode = (WIRELESS_MODE)InitWirelessMode;
36372 + { // One of B, G, A.
36373 + InitWirelessMode = ieee->mode;
36375 +//by amy for power save
36377 +// printk("initialize ENABLE_IPS\n");
36378 + priv->eRFPowerState = eRfOff;
36379 + priv->RfOffReason = 0;
36382 + // u32 tmp = jiffies;
36383 + MgntActSet_RF_State(dev, eRfOn, 0);
36384 + // tmp2 = jiffies;
36385 + // printk("rf on cost jiffies:%lx\n", (tmp2-tmp)*1000/HZ);
36387 +// DrvIFIndicateCurrentPhyStatus(priv);
36389 + // If inactive power mode is enabled, disable rf while in disconnected state.
36390 + // 2007.07.16, by shien chang.
36392 + if (priv->bInactivePs)
36395 + // u32 tmp = jiffies;
36396 + MgntActSet_RF_State(dev,eRfOff, RF_CHANGE_BY_IPS);
36397 + // tmp2 = jiffies;
36398 + // printk("rf off cost jiffies:%lx\n", (tmp2-tmp)*1000/HZ);
36403 +//by amy for power save
36405 + // Turn off RF if necessary. 2005.08.23, by rcnjko.
36406 + // We shall turn off RF after setting CMDR, otherwise,
36407 + // RF will be turnned on after we enable MAC Tx/Rx.
36408 + if(Adapter->MgntInfo.RegRfOff == TRUE)
36410 + SetRFPowerState8185(Adapter, RF_OFF);
36414 + SetRFPowerState8185(Adapter, RF_ON);
36418 +/* //these is equal with above TODO.
36419 + write_nic_byte(dev, CR9346, 0xc0); // enable config register write
36420 + write_nic_byte(dev, CONFIG3, read_nic_byte(dev, CONFIG3) | CONFIG3_PARM_En);
36421 + RF_WriteReg(dev, 0x4, 0x9FF);
36422 + write_nic_dword(dev, ANAPARAM2, ANAPARM2_ASIC_ON);
36423 + write_nic_dword(dev, ANAPARAM, ANAPARM_ASIC_ON);
36424 + write_nic_byte(dev, CONFIG3, (read_nic_byte(dev, CONFIG3)&(~CONFIG3_PARM_En)));
36425 + write_nic_byte(dev, CR9346, 0x00);
36428 + ActSetWirelessMode8185(dev, (u8)(InitWirelessMode));
36430 + //-----------------------------------------------------------------------------
36432 + rtl8185b_irq_enable(dev);
36434 + netif_start_queue(dev);
36439 +void rtl8185b_rx_enable(struct net_device *dev)
36443 + /* for now we accept data, management & ctl frame*/
36444 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
36446 + rxconf=read_nic_dword(dev,RX_CONF);
36447 + rxconf = rxconf &~ MAC_FILTER_MASK;
36448 + rxconf = rxconf | (1<<ACCEPT_MNG_FRAME_SHIFT);
36449 + rxconf = rxconf | (1<<ACCEPT_DATA_FRAME_SHIFT);
36450 + rxconf = rxconf | (1<<ACCEPT_BCAST_FRAME_SHIFT);
36451 + rxconf = rxconf | (1<<ACCEPT_MCAST_FRAME_SHIFT);
36452 +// rxconf = rxconf | (1<<ACCEPT_CRCERR_FRAME_SHIFT);
36453 + if (dev->flags & IFF_PROMISC) DMESG ("NIC in promisc mode");
36455 + if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
36456 + dev->flags & IFF_PROMISC){
36457 + rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
36459 + rxconf = rxconf | (1<<ACCEPT_NICMAC_FRAME_SHIFT);
36460 + if(priv->card_8185 == 0)
36461 + rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
36464 + /*if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
36465 + rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
36466 + rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
36469 + if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
36470 + rxconf = rxconf | (1<<ACCEPT_CTL_FRAME_SHIFT);
36471 + rxconf = rxconf | (1<<ACCEPT_ICVERR_FRAME_SHIFT);
36472 + rxconf = rxconf | (1<<ACCEPT_PWR_FRAME_SHIFT);
36475 + if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
36476 + rxconf = rxconf | (1<<ACCEPT_CRCERR_FRAME_SHIFT);
36478 + //if(!priv->card_8185){
36479 + rxconf = rxconf &~ RX_FIFO_THRESHOLD_MASK;
36480 + rxconf = rxconf | (RX_FIFO_THRESHOLD_NONE<<RX_FIFO_THRESHOLD_SHIFT);
36483 + rxconf = rxconf | (1<<RX_AUTORESETPHY_SHIFT);
36484 + rxconf = rxconf &~ MAX_RX_DMA_MASK;
36485 + rxconf = rxconf | (MAX_RX_DMA_2048<<MAX_RX_DMA_SHIFT);
36487 + //if(!priv->card_8185)
36488 + rxconf = rxconf | RCR_ONLYERLPKT;
36490 + rxconf = rxconf &~ RCR_CS_MASK;
36491 + if(!priv->card_8185)
36492 + rxconf |= (priv->rcr_csense<<RCR_CS_SHIFT);
36493 +// rxconf &=~ 0xfff00000;
36494 +// rxconf |= 0x90100000;//9014f76f;
36495 + write_nic_dword(dev, RX_CONF, rxconf);
36498 + if (dev->flags & IFF_PROMISC) DMESG ("NIC in promisc mode");
36500 + if(priv->ieee80211->iw_mode == IW_MODE_MONITOR || \
36501 + dev->flags & IFF_PROMISC){
36502 + priv->ReceiveConfig = priv->ReceiveConfig & (~RCR_APM);
36503 + priv->ReceiveConfig = priv->ReceiveConfig | RCR_AAP;
36506 + /*if(priv->ieee80211->iw_mode == IW_MODE_MASTER){
36507 + rxconf = rxconf | (1<<ACCEPT_ALLMAC_FRAME_SHIFT);
36508 + rxconf = rxconf | (1<<RX_CHECK_BSSID_SHIFT);
36511 + if(priv->ieee80211->iw_mode == IW_MODE_MONITOR){
36512 + priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACF | RCR_APWRMGT | RCR_AICV;
36515 + if( priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
36516 + priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACRC32;
36518 + write_nic_dword(dev, RCR, priv->ReceiveConfig);
36520 + fix_rx_fifo(dev);
36523 + DMESG("rxconf: %x %x",priv->ReceiveConfig ,read_nic_dword(dev,RCR));
36525 + cmd=read_nic_byte(dev,CMD);
36526 + write_nic_byte(dev,CMD,cmd | (1<<CMD_RX_ENABLE_SHIFT));
36530 +void rtl8185b_tx_enable(struct net_device *dev)
36536 + struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
36539 + txconf= read_nic_dword(dev,TX_CONF);
36540 + if(priv->card_8185){
36543 + byte = read_nic_byte(dev,CW_CONF);
36544 + byte &= ~(1<<CW_CONF_PERPACKET_CW_SHIFT);
36545 + byte &= ~(1<<CW_CONF_PERPACKET_RETRY_SHIFT);
36546 + write_nic_byte(dev, CW_CONF, byte);
36548 + tx_agc_ctl = read_nic_byte(dev, TX_AGC_CTL);
36549 + tx_agc_ctl &= ~(1<<TX_AGC_CTL_PERPACKET_GAIN_SHIFT);
36550 + tx_agc_ctl &= ~(1<<TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT);
36551 + tx_agc_ctl |=(1<<TX_AGC_CTL_FEEDBACK_ANT);
36552 + write_nic_byte(dev, TX_AGC_CTL, tx_agc_ctl);
36554 + write_nic_word(dev, 0x5e, 0x01);
36555 + force_pci_posting(dev);
36557 + write_nic_word(dev, 0xfe, 0x10);
36558 + force_pci_posting(dev);
36560 + write_nic_word(dev, 0x5e, 0x00);
36561 + force_pci_posting(dev);
36564 + write_nic_byte(dev, 0xec, 0x3f); /* Disable early TX */
36567 + if(priv->card_8185){
36569 + txconf = txconf &~ (1<<TCR_PROBE_NOTIMESTAMP_SHIFT);
36574 + txconf= txconf &~ (1<<TX_CONF_HEADER_AUTOICREMENT_SHIFT);
36576 + txconf= txconf | (1<<TX_CONF_HEADER_AUTOICREMENT_SHIFT);
36579 + txconf = txconf &~ TX_LOOPBACK_MASK;
36580 + txconf = txconf | (TX_LOOPBACK_NONE <<TX_LOOPBACK_SHIFT);
36581 + txconf = txconf &~ TCR_DPRETRY_MASK;
36582 + txconf = txconf &~ TCR_RTSRETRY_MASK;
36583 + txconf = txconf | (priv->retry_data<<TX_DPRETRY_SHIFT);
36584 + txconf = txconf | (priv->retry_rts<<TX_RTSRETRY_SHIFT);
36585 + txconf = txconf &~ (1<<TX_NOCRC_SHIFT);
36587 + if(priv->card_8185){
36588 + if(priv->hw_plcp_len)
36589 + txconf = txconf &~ TCR_PLCP_LEN;
36591 + txconf = txconf | TCR_PLCP_LEN;
36593 + txconf = txconf &~ TCR_SAT;
36595 + txconf = txconf &~ TCR_MXDMA_MASK;
36596 + txconf = txconf | (TCR_MXDMA_2048<<TCR_MXDMA_SHIFT);
36597 + txconf = txconf | TCR_CWMIN;
36598 + txconf = txconf | TCR_DISCW;
36600 +// if(priv->ieee80211->hw_wep)
36601 +// txconf=txconf &~ (1<<TX_NOICV_SHIFT);
36603 + txconf=txconf | (1<<TX_NOICV_SHIFT);
36605 + write_nic_dword(dev,TX_CONF,txconf);
36608 + write_nic_dword(dev, TCR, priv->TransmitConfig);
36609 + byte = read_nic_byte(dev, MSR);
36610 + byte |= MSR_LINK_ENEDCA;
36611 + write_nic_byte(dev, MSR, byte);
36613 + fix_tx_fifo(dev);
36616 + DMESG("txconf: %x %x",priv->TransmitConfig,read_nic_dword(dev,TCR));
36619 + cmd=read_nic_byte(dev,CMD);
36620 + write_nic_byte(dev,CMD,cmd | (1<<CMD_TX_ENABLE_SHIFT));
36622 + //write_nic_dword(dev,TX_CONF,txconf);
36626 + rtl8180_set_mode(dev,EPROM_CMD_CONFIG);
36627 + write_nic_byte(dev, TX_DMA_POLLING, priv->dma_poll_mask);
36628 + rtl8180_set_mode(dev,EPROM_CMD_NORMAL);